From de2adbc658fffde30ffe22a9a5b14ecd96a4f69c Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Fri, 21 Jul 2023 13:38:34 +0300 Subject: [PATCH 01/80] first not tested commit with spine extension and atlas resource --- .../CodeGeneration/EventsCodeGenerator.cpp | 1 + .../Extensions/Metadata/ValueTypeMetadata.h | 3 +- .../IDE/Project/ArbitraryResourceWorker.cpp | 11 + .../IDE/Project/ArbitraryResourceWorker.h | 5 + .../GDCore/IDE/Project/ResourcesInUseHelper.h | 6 + Core/GDCore/IDE/Project/ResourcesRenamer.h | 3 + .../Project/CustomObjectConfiguration.cpp | 2 + Core/GDCore/Project/ResourcesManager.cpp | 16 + Core/GDCore/Project/ResourcesManager.h | 26 + Extensions/Spine/JsExtension.js | 560 +++ .../Spine/spineruntimeobject-pixi-renderer.ts | 176 + Extensions/Spine/spineruntimeobject.ts | 169 + GDJS/Runtime/types/project-data.d.ts | 3 +- GDJS/package-lock.json | 171 + GDJS/package.json | 1 + GDevelop.js/Bindings/Bindings.idl | 5 + .../Bindings/ObjectJsImplementation.cpp | 2 + GDevelop.js/scripts/generate-types.js | 4 +- GDevelop.js/types/gdatlasresource.js | 6 + GDevelop.js/types/gdresource.js | 4 +- GDevelop.js/types/libgdevelop.js | 1 + newIDE/app/package-lock.json | 2584 ++++++++++--- newIDE/app/package.json | 1 + newIDE/app/src/AssetStore/InstallAsset.js | 2 + .../AssetStore/ResourceStore/ResourceCard.js | 11 + .../ParameterFields/AtlasResourceField.js | 51 + .../EventsSheet/ParameterRenderingService.js | 4 +- .../BrowserJsExtensionsLoader.js | 6 + .../ObjectsRendering/PixiResourcesLoader.js | 34 + .../FileToCloudProjectResourceUploader.js | 1 + ...FileToCloudProjectResourceUploader.spec.js | 3 + .../ResourcesList/ResourcePreview/index.js | 1 + .../app/src/ResourcesList/ResourceSource.js | 9 +- .../ResourceStore/ResourceStore.stories.js | 8 + .../ParameterFields/ResourceFields.stories.js | 18 + newIDE/electron-app/app/package-lock.json | 4 +- newIDE/electron-app/yarn.lock | 3244 +++++++++-------- 37 files changed, 5065 insertions(+), 2091 deletions(-) create mode 100644 Extensions/Spine/JsExtension.js create mode 100644 Extensions/Spine/spineruntimeobject-pixi-renderer.ts create mode 100644 Extensions/Spine/spineruntimeobject.ts create mode 100644 GDevelop.js/types/gdatlasresource.js create mode 100644 newIDE/app/src/EventsSheet/ParameterFields/AtlasResourceField.js diff --git a/Core/GDCore/Events/CodeGeneration/EventsCodeGenerator.cpp b/Core/GDCore/Events/CodeGeneration/EventsCodeGenerator.cpp index 79a6721d9c92..21b6af3bb2a3 100644 --- a/Core/GDCore/Events/CodeGeneration/EventsCodeGenerator.cpp +++ b/Core/GDCore/Events/CodeGeneration/EventsCodeGenerator.cpp @@ -728,6 +728,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes( metadata.GetType() == "tilesetResource" || metadata.GetType() == "videoResource" || metadata.GetType() == "model3DResource" || + metadata.GetType() == "atlasResource" || // Deprecated, old parameter names: metadata.GetType() == "password" || metadata.GetType() == "musicfile" || metadata.GetType() == "soundfile" || metadata.GetType() == "police") { diff --git a/Core/GDCore/Extensions/Metadata/ValueTypeMetadata.h b/Core/GDCore/Extensions/Metadata/ValueTypeMetadata.h index bf8001ce5966..3c46e9ae11f9 100644 --- a/Core/GDCore/Extensions/Metadata/ValueTypeMetadata.h +++ b/Core/GDCore/Extensions/Metadata/ValueTypeMetadata.h @@ -187,7 +187,8 @@ class GD_CORE_API ValueTypeMetadata { parameterType == "jsonResource" || parameterType == "tilemapResource" || parameterType == "tilesetResource" || - parameterType == "model3DResource"; + parameterType == "model3DResource" || + parameterType == "atlasResource"; } return false; } diff --git a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp index 055ca5e0ddb8..95ef97c79ebd 100644 --- a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp +++ b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp @@ -50,6 +50,11 @@ void ArbitraryResourceWorker::ExposeModel3D(gd::String& resourceName){ // do. }; +void ArbitraryResourceWorker::ExposeAtlas(gd::String& resourceName){ + // Nothing to do by default - each child class can define here the action to + // do. +}; + void ArbitraryResourceWorker::ExposeVideo(gd::String& videoName){ // Nothing to do by default - each child class can define here the action to // do. @@ -153,6 +158,8 @@ void ArbitraryResourceWorker::ExposeEmbeddeds(gd::String& resourceName) { ExposeVideo(potentiallyUpdatedTargetResourceName); } else if (targetResourceKind == "model3D") { ExposeModel3D(potentiallyUpdatedTargetResourceName); + } else if (targetResourceKind == "atlas") { + ExposeAtlas(potentiallyUpdatedTargetResourceName); } if (potentiallyUpdatedTargetResourceName != targetResourceName) { @@ -244,6 +251,10 @@ class ResourceWorkerInEventsWorker : public ArbitraryEventsWorker { gd::String updatedParameterValue = parameterValue; worker.ExposeModel3D(updatedParameterValue); instruction.SetParameter(parameterIndex, updatedParameterValue); + } else if (parameterMetadata.GetType() == "atlasResource") { + gd::String updatedParameterValue = parameterValue; + worker.ExposeAtlas(updatedParameterValue); + instruction.SetParameter(parameterIndex, updatedParameterValue); } }); diff --git a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.h b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.h index 1faf8690f893..553b6a8454fa 100644 --- a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.h +++ b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.h @@ -89,6 +89,11 @@ class GD_CORE_API ArbitraryResourceWorker { * \brief Expose a 3D model, which is always a reference to a "model3D" resource. */ virtual void ExposeModel3D(gd::String &resourceName); + + /** + * \brief Expose an atlas, which is always a reference to a "atlas" resource. + */ + virtual void ExposeAtlas(gd::String &resourceName); /** * \brief Expose a video, which is always a reference to a "video" resource. diff --git a/Core/GDCore/IDE/Project/ResourcesInUseHelper.h b/Core/GDCore/IDE/Project/ResourcesInUseHelper.h index 5c1ebf35f9a1..430c5376b2d9 100644 --- a/Core/GDCore/IDE/Project/ResourcesInUseHelper.h +++ b/Core/GDCore/IDE/Project/ResourcesInUseHelper.h @@ -45,6 +45,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker { std::set& GetAllVideos() { return GetAll("video"); }; std::set& GetAllBitmapFonts() { return GetAll("bitmapFont"); }; std::set& GetAll3DModels() { return GetAll("model3D"); }; + std::set& GetAllAtlases() { return GetAll("atlas"); }; std::set& GetAll(const gd::String& resourceType) { if (resourceType == "image") return allImages; if (resourceType == "audio") return allAudios; @@ -55,6 +56,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker { if (resourceType == "video") return allVideos; if (resourceType == "bitmapFont") return allBitmapFonts; if (resourceType == "model3D") return allModel3Ds; + if (resourceType == "atlas") return allAtlases; return emptyResources; }; @@ -89,6 +91,9 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker { virtual void ExposeModel3D(gd::String& resourceName) override { allModel3Ds.insert(resourceName); }; + virtual void ExposeAtlas(gd::String& resourceName) override { + allAtlases.insert(resourceName); + }; protected: std::set allImages; @@ -100,6 +105,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker { std::set allVideos; std::set allBitmapFonts; std::set allModel3Ds; + std::set allAtlases; std::set emptyResources; }; diff --git a/Core/GDCore/IDE/Project/ResourcesRenamer.h b/Core/GDCore/IDE/Project/ResourcesRenamer.h index 648223ab35c8..9065517650ef 100644 --- a/Core/GDCore/IDE/Project/ResourcesRenamer.h +++ b/Core/GDCore/IDE/Project/ResourcesRenamer.h @@ -62,6 +62,9 @@ class ResourcesRenamer : public gd::ArbitraryResourceWorker { virtual void ExposeModel3D(gd::String& resourceName) override { RenameIfNeeded(resourceName); }; + virtual void ExposeAtlas(gd::String& resourceName) override { + RenameIfNeeded(resourceName); + }; private: void RenameIfNeeded(gd::String& resourceName) { diff --git a/Core/GDCore/Project/CustomObjectConfiguration.cpp b/Core/GDCore/Project/CustomObjectConfiguration.cpp index 08bdd8ab3ea6..6118c662fe1a 100644 --- a/Core/GDCore/Project/CustomObjectConfiguration.cpp +++ b/Core/GDCore/Project/CustomObjectConfiguration.cpp @@ -155,6 +155,8 @@ void CustomObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker& wor worker.ExposeBitmapFont(newPropertyValue); } else if (resourceType == "model3D") { worker.ExposeModel3D(newPropertyValue); + } else if (resourceType == "atlas") { + worker.ExposeAtlas(newPropertyValue); } if (newPropertyValue != oldPropertyValue) { diff --git a/Core/GDCore/Project/ResourcesManager.cpp b/Core/GDCore/Project/ResourcesManager.cpp index 35cdecf816bb..f4e5b6d61415 100644 --- a/Core/GDCore/Project/ResourcesManager.cpp +++ b/Core/GDCore/Project/ResourcesManager.cpp @@ -93,6 +93,8 @@ std::shared_ptr ResourcesManager::CreateResource( return std::make_shared(); else if (kind == "model3D") return std::make_shared(); + else if (kind == "atlas") + return std::make_shared(); std::cout << "Bad resource created (type: " << kind << ")" << std::endl; return std::make_shared(); @@ -752,6 +754,20 @@ void Model3DResource::SerializeTo(SerializerElement& element) const { element.SetAttribute("file", GetFile()); } +void AtlasResource::SetFile(const gd::String& newFile) { + file = NormalizePathSeparator(newFile); +} + +void AtlasResource::UnserializeFrom(const SerializerElement& element) { + SetUserAdded(element.GetBoolAttribute("userAdded")); + SetFile(element.GetStringAttribute("file")); +} + +void AtlasResource::SerializeTo(SerializerElement& element) const { + element.SetAttribute("userAdded", IsUserAdded()); + element.SetAttribute("file", GetFile()); +} + ResourceFolder::ResourceFolder(const ResourceFolder& other) { Init(other); } ResourceFolder& ResourceFolder::operator=(const ResourceFolder& other) { diff --git a/Core/GDCore/Project/ResourcesManager.h b/Core/GDCore/Project/ResourcesManager.h index 3567b8a67922..78a0a14e123b 100644 --- a/Core/GDCore/Project/ResourcesManager.h +++ b/Core/GDCore/Project/ResourcesManager.h @@ -507,6 +507,32 @@ class GD_CORE_API Model3DResource : public Resource { gd::String file; }; +/** + * \brief Describe an atlas file used by a project. + * + * \see Resource + * \ingroup ResourcesManagement + */ +class GD_CORE_API AtlasResource : public Resource { + public: + AtlasResource() : Resource() { SetKind("atlas"); }; + virtual ~AtlasResource(){}; + virtual AtlasResource* Clone() const override { + return new AtlasResource(*this); + } + + virtual const gd::String& GetFile() const override { return file; }; + virtual void SetFile(const gd::String& newFile) override; + + virtual bool UseFile() const override { return true; } + void SerializeTo(SerializerElement& element) const override; + + void UnserializeFrom(const SerializerElement& element) override; + + private: + gd::String file; +}; + /** * \brief Inventory all resources used by a project * diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js new file mode 100644 index 000000000000..638049c3ea21 --- /dev/null +++ b/Extensions/Spine/JsExtension.js @@ -0,0 +1,560 @@ +// @flow +/** + * This is a declaration of an extension for GDevelop 5. + * + * ℹ️ Changes in this file are watched and automatically imported if the editor + * is running. You can also manually run `node import-GDJS-Runtime.js` (in newIDE/app/scripts). + * + * The file must be named "JsExtension.js", otherwise GDevelop won't load it. + * ⚠️ If you make a change and the extension is not loaded, open the developer console + * and search for any errors. + * + * More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md + */ + +/*:: +// Import types to allow Flow to do static type checking on this file. +// Extensions declaration are typed using Flow (like the editor), but the files +// for the game engine are checked with TypeScript annotations. +import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js' +*/ + +module.exports = { + createExtension: function ( + _ /*: (string) => string */, + gd /*: libGDevelop */ + ) { + const extension = new gd.PlatformExtension(); + extension + .setExtensionInformation( + 'Spine', + _('Spine'), + _( + 'Displays a text using a "Bitmap Font" (an image representing characters). This is more performant than a traditional Text object and it allows for complete control on the characters aesthetic.' + ), + 'Aurélien Vivet', + 'Open source (MIT License)' + ) + .setExtensionHelpPath('/objects/bitmap_text') + .setCategory('Text'); + extension + .addInstructionOrExpressionGroupMetadata(_('Spine')) + .setIcon('JsPlatform/Extensions/bitmapfont32.png'); + + const bitmapTextObject = new gd.ObjectJsImplementation(); + // $FlowExpectedError + bitmapTextObject.updateProperty = function ( + objectContent, + propertyName, + newValue + ) { + if (propertyName in objectContent) { + if (typeof objectContent[propertyName] === 'boolean') + objectContent[propertyName] = newValue === '1'; + else if (typeof objectContent[propertyName] === 'number') + objectContent[propertyName] = parseFloat(newValue); + else objectContent[propertyName] = newValue; + return true; + } + + return false; + }; + // $FlowExpectedError + bitmapTextObject.getProperties = function (objectContent) { + const objectProperties = new gd.MapStringPropertyDescriptor(); + + objectProperties + .getOrCreate('jsonResourceName') + .setValue(objectContent.jsonResourceName) + .setType('resource') + .addExtraInfo('json') + .setLabel(_('Spine JSON')) + .setGroup(_('Spine Files')); + + objectProperties + .getOrCreate('atlasResourceName') + .setValue(objectContent.atlasResourceName) + .setType('resource') + .addExtraInfo('atlas') + .setLabel(_('Atlas file')) + .setGroup(_('Spine Files')); + + objectProperties + .getOrCreate('imageResourceName') + .setValue(objectContent.textureAtlasResourceName) + .setType('resource') + .addExtraInfo('image') + .setLabel(_('Spine atlas image')) + .setGroup(_('Spine Files')); + + objectProperties + .getOrCreate('opacity') + .setValue(objectContent.opacity.toString()) + .setType('number') + .setLabel(_('Opacity (0-255)')) + .setGroup(_('Appearance')); + + objectProperties + .getOrCreate('scale') + .setValue(objectContent.scale.toString()) + .setType('number') + .setLabel(_('Text scale')) + .setGroup(_('Appearance')); + + return objectProperties; + }; + bitmapTextObject.setRawJSONContent( + JSON.stringify({ + opacity: 255, + scale: 1, + jsonResourceName: '', + atlasResourceName: '', + imageResourceName: '', + }) + ); + + // $FlowExpectedError + bitmapTextObject.updateInitialInstanceProperty = function ( + objectContent, + instance, + propertyName, + newValue, + project, + layout + ) { + return false; + }; + // $FlowExpectedError + bitmapTextObject.getInitialInstanceProperties = function ( + content, + instance, + project, + layout + ) { + var instanceProperties = new gd.MapStringPropertyDescriptor(); + return instanceProperties; + }; + + const object = extension + .addObject( + 'SpineObject', + _('Spine'), + _( + 'Display and animate Spine skeleton. Select Spine files (json, atlas, image).' + ), + 'JsPlatform/Extensions/bitmapfont32.png', + bitmapTextObject + ) + .setIncludeFile('Extensions/Spine/spineruntimeobject.js') + .addIncludeFile( + 'Extensions/Spine/spineruntimeobject-pixi-renderer.js' + ) + .setCategoryFullName(_('Text')); + + object + .addExpressionAndConditionAndAction( + 'number', + 'Opacity', + _('Opacity'), + _('the opacity, between 0 (fully transparent) and 255 (opaque)'), + _('the opacity'), + '', + 'res/conditions/opacity24.png' + ) + .addParameter('object', _('Bitmap text'), 'SpineObject', false) + .useStandardParameters( + 'number', + gd.ParameterOptions.makeNewOptions().setDescription( + _('Opacity (0-255)') + ) + ) + .setFunctionName('setOpacity') + .setGetter('getOpacity'); + + object + .addExpressionAndConditionAndAction( + 'number', + 'Scale', + _('Scale'), + _('the scale (1 by default)'), + _('the scale'), + '', + 'res/actions/scale24_black.png' + ) + .addParameter('object', _('Bitmap text'), 'SpineObject', false) + .useStandardParameters( + 'number', + gd.ParameterOptions.makeNewOptions().setDescription( + _('Scale (1 by default)') + ) + ) + .setFunctionName('setScale') + .setGetter('getScale'); + + return extension; + }, + + /** + * You can optionally add sanity tests that will check the basic working + * of your extension behaviors/objects by instantiating behaviors/objects + * and setting the property to a given value. + * + * If you don't have any tests, you can simply return an empty array. + * + * But it is recommended to create tests for the behaviors/objects properties you created + * to avoid mistakes. + */ + runExtensionSanityTests: function ( + gd /*: libGDevelop */, + extension /*: gdPlatformExtension*/ + ) { + return []; + }, + /** + * Register editors for objects. + * + * ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change. + */ + registerEditorConfigurations: function ( + objectsEditorService /*: ObjectsEditorService */ + ) { + objectsEditorService.registerEditorConfiguration( + 'Spine::SpineObject', + objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({ + helpPagePath: '/objects/bitmap_text', + }) + ); + }, + /** + * Register renderers for instance of objects on the scene editor. + * + * ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change. + */ + registerInstanceRenderers: function ( + objectsRenderingService /*: ObjectsRenderingService */ + ) { + const RenderedInstance = objectsRenderingService.RenderedInstance; + const PIXI = objectsRenderingService.PIXI; + + /** The bitmap font used in case another font can't be loaded. */ + let defaultBitmapFont = null; + + const defaultBitmapFontInstallKey = 'GD-DEFAULT-BITMAP-FONT'; + + /** + * Map counting the number of "reference" to a bitmap font. This is useful + * to uninstall a bitmap font when not used anymore. + */ + const bitmapFontUsageCount = {}; + + /** + * We patch the installed font to use a name that is unique for each font data and texture, + * to avoid conflicts between different font files using the same font name (by default, the + * font name used by Pixi is the one inside the font data, but this name is not necessarily unique. + * For example, 2 resources can use the same font, or we can have multiple objects with the same + * font data and different textures). + */ + const patchBitmapFont = (bitmapFont, bitmapFontInstallKey) => { + const defaultName = bitmapFont.font; + bitmapFont.font = bitmapFontInstallKey; + PIXI.BitmapFont.available[bitmapFontInstallKey] = bitmapFont; + + delete PIXI.BitmapFont.available[defaultName]; + return PIXI.BitmapFont.available[bitmapFontInstallKey]; + }; + + /** + * Return a default bitmap font to be used in case another font can't be loaded. + */ + const getDefaultBitmapFont = () => { + if (defaultBitmapFont) return defaultBitmapFont; + + const defaultBitmapFontStyle = new PIXI.TextStyle({ + fontFamily: 'Arial', + fontSize: 20, + padding: 5, + align: 'left', + fill: '#ffffff', + wordWrap: true, + lineHeight: 20, + }); + + defaultBitmapFont = patchBitmapFont( + PIXI.BitmapFont.from( + defaultBitmapFontStyle.fontFamily, + defaultBitmapFontStyle, + { + chars: [ + [' ', '~'], // All the printable ASCII characters + ], + } + ), + defaultBitmapFontInstallKey + ); + return defaultBitmapFont; + }; + + /** + * Given a bitmap font resource name and a texture atlas resource name, returns the PIXI.BitmapFont + * for it. + * The font must be released with `releaseBitmapFont` when not used anymore - so that it can be removed + * from memory when not used by any instance. + * + * @param pixiResourcesLoader + * @param project + * @param bitmapFontResourceName + * @param textureAtlasResourceName + */ + const obtainBitmapFont = ( + pixiResourcesLoader, + project, + bitmapFontResourceName, + textureAtlasResourceName + ) => { + const bitmapFontInstallKey = + bitmapFontResourceName + '@' + textureAtlasResourceName; + + if (PIXI.BitmapFont.available[bitmapFontInstallKey]) { + // Return the existing BitmapFont that is already in memory and already installed. + bitmapFontUsageCount[bitmapFontInstallKey] = + (bitmapFontUsageCount[bitmapFontInstallKey] || 0) + 1; + return Promise.resolve(PIXI.BitmapFont.available[bitmapFontInstallKey]); + } + + // Get the atlas texture, the bitmap font data and install the font: + const texture = pixiResourcesLoader.getPIXITexture( + project, + textureAtlasResourceName + ); + + const loadBitmapFont = () => + pixiResourcesLoader + .getBitmapFontData(project, bitmapFontResourceName) + .then((fontData) => { + if (!texture.valid) + throw new Error( + 'Tried to install a BitmapFont with an invalid texture.' + ); + + const bitmapFont = patchBitmapFont( + PIXI.BitmapFont.install(fontData, texture), + bitmapFontInstallKey + ); + bitmapFontUsageCount[bitmapFontInstallKey] = + (bitmapFontUsageCount[bitmapFontInstallKey] || 0) + 1; + + return bitmapFont; + }) + .catch((err) => { + console.warn('Unable to load font data:', err); + console.info( + 'Is the texture atlas properly set for the Spine object? The default font will be used instead.' + ); + + const bitmapFont = getDefaultBitmapFont(); + return bitmapFont; + }); + + if (!texture.valid) { + // Post pone texture update if texture is not loaded. + // (otherwise, the bitmap font would not get updated when the + // texture is loaded and updated). + return new Promise((resolve) => { + texture.once('update', () => { + resolve(loadBitmapFont()); + }); + }); + } else { + // We're ready to load the bitmap font now, as the texture + // is already loaded. + return loadBitmapFont(); + } + }; + + /** + * When a font is not used by an object anymore (object destroyed or font changed), + * call this function to decrease the internal count of objects using the font. + * + * Fonts are unloaded when not used anymore. + */ + const releaseBitmapFont = (bitmapFontInstallKey) => { + if (bitmapFontInstallKey === defaultBitmapFontInstallKey) { + // Never uninstall the default bitmap font. + return; + } + + if (!bitmapFontUsageCount[bitmapFontInstallKey]) { + console.error( + 'BitmapFont with name ' + + bitmapFontInstallKey + + ' was tried to be released but was never marked as used.' + ); + return; + } + bitmapFontUsageCount[bitmapFontInstallKey]--; + + if (bitmapFontUsageCount[bitmapFontInstallKey] === 0) { + PIXI.BitmapFont.uninstall(bitmapFontInstallKey); + console.info( + 'Uninstalled BitmapFont "' + bitmapFontInstallKey + '" from memory.' + ); + } + }; + + /** + * Renderer for instances of Spine inside the IDE. + * + * @extends RenderedSpineInstance + * @class RenderedSpineInstance + * @constructor + */ + function RenderedSpineInstance( + project, + layout, + instance, + associatedObjectConfiguration, + pixiContainer, + pixiResourcesLoader + ) { + RenderedInstance.call( + this, + project, + layout, + instance, + associatedObjectConfiguration, + pixiContainer, + pixiResourcesLoader + ); + + // We'll track changes of the font to trigger the loading of the new font. + this._currentBitmapFontResourceName = ''; + this._currentTextureAtlasResourceName = ''; + + this._pixiObject = new PIXI.Spine('', { + // Use a default font. The proper font will be loaded in `update` method. + fontName: getDefaultBitmapFont().font, + }); + + this._pixiObject.anchor.x = 0.5; + this._pixiObject.anchor.y = 0.5; + this._pixiContainer.addChild(this._pixiObject); + this.update(); + } + RenderedSpineInstance.prototype = Object.create( + RenderedInstance.prototype + ); + + /** + * Return the path to the thumbnail of the specified object. + */ + RenderedSpineInstance.getThumbnail = function ( + project, + resourcesLoader, + objectConfiguration + ) { + return 'JsPlatform/Extensions/bitmapfont24.png'; + }; + + // This is called to update the PIXI object on the scene editor + RenderedSpineInstance.prototype.update = function () { + const properties = this._associatedObjectConfiguration.getProperties(); + + // Update the rendered text properties (note: Pixi is only + // applying changes if there were changed). + const rawText = properties.get('text').getValue(); + this._pixiObject.text = rawText; + + const opacity = properties.get('opacity').getValue(); + this._pixiObject.alpha = opacity / 255; + + const align = properties.get('align').getValue(); + this._pixiObject.align = align; + + const color = properties.get('tint').getValue(); + this._pixiObject.tint = + objectsRenderingService.rgbOrHexToHexNumber(color); + + const scale = properties.get('scale').getValue() || 1; + this._pixiObject.scale.set(scale); + + // Track the changes in font to load the new requested font. + const bitmapFontResourceName = properties + .get('bitmapFontResourceName') + .getValue(); + const textureAtlasResourceName = properties + .get('textureAtlasResourceName') + .getValue(); + + if ( + this._currentBitmapFontResourceName !== bitmapFontResourceName || + this._currentTextureAtlasResourceName !== textureAtlasResourceName + ) { + // Release the old font (if it was installed). + releaseBitmapFont(this._pixiObject.fontName); + + // Temporarily go back to the default font, as the PIXI.Spine + // object does not support being displayed with a font not installed at all. + // It will be replaced as soon as the proper font is loaded. + this._pixiObject.fontName = getDefaultBitmapFont().font; + + this._currentBitmapFontResourceName = bitmapFontResourceName; + this._currentTextureAtlasResourceName = textureAtlasResourceName; + obtainBitmapFont( + this._pixiResourcesLoader, + this._project, + this._currentBitmapFontResourceName, + this._currentTextureAtlasResourceName + ).then((bitmapFont) => { + this._pixiObject.fontName = bitmapFont.font; + this._pixiObject.fontSize = bitmapFont.size; + this._pixiObject.dirty = true; + }); + } + + // Set up the wrapping width if enabled. + const wordWrap = properties.get('wordWrap').getValue() === 'true'; + if (wordWrap && this._instance.hasCustomSize()) { + this._pixiObject.maxWidth = + this.getCustomWidth() / this._pixiObject.scale.x; + this._pixiObject.dirty = true; + } else { + this._pixiObject.maxWidth = 0; + this._pixiObject.dirty = true; + } + + this._pixiObject.position.x = + this._instance.getX() + (this._pixiObject.textWidth * scale) / 2; + this._pixiObject.position.y = + this._instance.getY() + (this._pixiObject.textHeight * scale) / 2; + this._pixiObject.rotation = RenderedInstance.toRad( + this._instance.getAngle() + ); + }; + + RenderedSpineInstance.prototype.onRemovedFromScene = function () { + RenderedInstance.prototype.onRemovedFromScene.call(this); + + releaseBitmapFont(this._pixiObject.fontName); + this._pixiObject.destroy(); + }; + + /** + * Return the width of the instance, when it's not resized. + */ + RenderedSpineInstance.prototype.getDefaultWidth = function () { + return this._pixiObject.width; + }; + + /** + * Return the height of the instance, when it's not resized. + */ + RenderedSpineInstance.prototype.getDefaultHeight = function () { + return this._pixiObject.height; + }; + + objectsRenderingService.registerInstanceRenderer( + 'Spine::SpineObject', + RenderedSpineInstance + ); + }, +}; diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts new file mode 100644 index 000000000000..b99b4e19513d --- /dev/null +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -0,0 +1,176 @@ +namespace gdjs { + import PIXI = GlobalPIXIModule.PIXI; + + /** + * The PIXI.js renderer for the Bitmap Text runtime object. + */ + export class SpineRuntimeObjectPixiRenderer { + _object: gdjs.SpineRuntimeObject; + _pixiObject: PIXI.BitmapText; + + /** + * @param runtimeObject The object to render + * @param instanceContainer The container in which the object is + */ + constructor( + runtimeObject: gdjs.SpineRuntimeObject, + instanceContainer: gdjs.RuntimeInstanceContainer + ) { + this._object = runtimeObject; + + // Obtain the bitmap font to use in the object. + const bitmapFont = instanceContainer + .getGame() + .getBitmapFontManager() + .obtainBitmapFont( + runtimeObject._bitmapFontResourceName, + runtimeObject._textureAtlasResourceName + ); + this._pixiObject = new PIXI.BitmapText(runtimeObject._text, { + fontName: bitmapFont.font, + fontSize: bitmapFont.size, + }); + + // Set the object on the scene + instanceContainer + .getLayer('') + .getRenderer() + .addRendererObject(this._pixiObject, runtimeObject.getZOrder()); + + // Set the anchor in the center, so that the object rotates around + // its center. + // @ts-ignore + this._pixiObject.anchor.x = 0.5; + // @ts-ignore + this._pixiObject.anchor.y = 0.5; + + this.updateAlignment(); + this.updateTextContent(); + this.updateAngle(); + this.updateOpacity(); + this.updateScale(); + this.updateWrappingWidth(); + this.updateTint(); + } + + getRendererObject() { + return this._pixiObject; + } + + onDestroy() { + // Mark the font from the object as not used anymore. + this._object + .getInstanceContainer() + .getGame() + .getBitmapFontManager() + .releaseBitmapFont(this._pixiObject.fontName); + + this._pixiObject.destroy(); + } + + getFontSize() { + return this._pixiObject.fontSize; + } + + updateFont(): void { + // Get the new bitmap font to use + const bitmapFont = this._object + .getInstanceContainer() + .getGame() + .getBitmapFontManager() + .obtainBitmapFont( + this._object._bitmapFontResourceName, + this._object._textureAtlasResourceName + ); + + // Mark the old font as not used anymore + this._object + .getInstanceContainer() + .getGame() + .getBitmapFontManager() + .releaseBitmapFont(this._pixiObject.fontName); + + // Update the font used by the object: + this._pixiObject.fontName = bitmapFont.font; + this._pixiObject.fontSize = bitmapFont.size; + this.updatePosition(); + } + + updateTint(): void { + this._pixiObject.tint = gdjs.rgbToHexNumber( + this._object._tint[0], + this._object._tint[1], + this._object._tint[2] + ); + this._pixiObject.dirty = true; + } + + /** + * Get the tint of the bitmap object as a "R;G;B" string. + * @returns the tint of bitmap object in "R;G;B" format. + */ + getTint(): string { + return ( + this._object._tint[0] + + ';' + + this._object._tint[1] + + ';' + + this._object._tint[2] + ); + } + + updateScale(): void { + this._pixiObject.scale.set(Math.max(this._object._scale, 0)); + this.updatePosition(); + } + + getScale() { + return Math.max(this._pixiObject.scale.x, this._pixiObject.scale.y); + } + + updateWrappingWidth(): void { + if (this._object._wordWrap) { + this._pixiObject.maxWidth = + this._object._wrappingWidth / this._object._scale; + this._pixiObject.dirty = true; + } else { + this._pixiObject.maxWidth = 0; + this._pixiObject.dirty = true; + } + this.updatePosition(); + } + + updateTextContent(): void { + this._pixiObject.text = this._object._text; + this.updatePosition(); + } + + updateAlignment(): void { + // @ts-ignore - assume align is always a valid value. + this._pixiObject.align = this._object._align; + this.updatePosition(); + } + + updatePosition(): void { + this._pixiObject.position.x = this._object.x + this.getWidth() / 2; + this._pixiObject.position.y = this._object.y + this.getHeight() / 2; + } + + updateAngle(): void { + this._pixiObject.rotation = gdjs.toRad(this._object.angle); + } + + updateOpacity(): void { + this._pixiObject.alpha = this._object._opacity / 255; + } + + getWidth(): float { + return this._pixiObject.textWidth * this.getScale(); + } + + getHeight(): float { + return this._pixiObject.textHeight * this.getScale(); + } + } + export const SpineRuntimeObjectRenderer = SpineRuntimeObjectPixiRenderer; +} diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts new file mode 100644 index 000000000000..0c9d3c3cdb1f --- /dev/null +++ b/Extensions/Spine/spineruntimeobject.ts @@ -0,0 +1,169 @@ +namespace gdjs { + /** Base parameters for {@link gdjs.SpineRuntimeObject} */ + export type SpineObjectDataType = { + /** The base parameters of the Bitmap Text */ + content: { + /** The opacity of the text. */ + opacity: float; + /** The scale of the spine. */ + scale: float; + jsonResourceName: string; + atlasResourceName: string; + imageResourceName: string; + }; + }; + export type SpineObjectData = ObjectData & SpineObjectDataType; + + /** + * Displays a text using a "Bitmap Font", generated in a external editor like bmFont. + * This is more efficient/faster to render than a traditional text (which needs + * to have its whole texture re-rendered anytime it changes). + * + * Bitmap Font can be created with softwares like: + * * BMFont (Windows, free): http://www.angelcode.com/products/bmfont/|http://www.angelcode.com/products/bmfont/ + * * Glyph Designer (OS X, commercial): http://www.71squared.com/en/glyphdesigner|http://www.71squared.com/en/glyphdesigner + * * Littera (Web-based, free): http://kvazars.com/littera/|http://kvazars.com/littera/ + */ + export class SpineRuntimeObject extends gdjs.RuntimeObject { + _opacity: float; + _scale: number; + + _renderer: gdjs.SpineRuntimeObjectPixiRenderer; + + jsonResourceName: string; + atlasResourceName: string; + imageResourceName: string; + + /** + * @param instanceContainer The container the object belongs to. + * @param objectData The object data used to initialize the object + */ + constructor( + instanceContainer: gdjs.RuntimeInstanceContainer, + objectData: SpineObjectData + ) { + super(instanceContainer, objectData); + + this._opacity = objectData.content.opacity; + this._scale = objectData.content.scale; + this.jsonResourceName = objectData.content.jsonResourceName; + this.atlasResourceName = objectData.content.atlasResourceName; + this.imageResourceName = objectData.content.imageResourceName; + + this._renderer = new gdjs.SpineRuntimeObjectRenderer( + this, + instanceContainer + ); + + + // *ALWAYS* call `this.onCreated()` at the very end of your object constructor. + this.onCreated(); + } + + getRendererObject() { + return this._renderer.getRendererObject(); + } + + // @ts-ignore + updateFromObjectData( + oldObjectData: SpineObjectDataType, + newObjectData: SpineObjectDataType + ): boolean { + if (oldObjectData.content.opacity !== newObjectData.content.opacity) { + this.setOpacity(newObjectData.content.opacity); + } + if (oldObjectData.content.scale !== newObjectData.content.scale) { + this.setScale(newObjectData.content.scale); + } + + return true; + } + + onDestroyFromScene(instanceContainer: gdjs.RuntimeInstanceContainer): void { + super.onDestroyFromScene(instanceContainer); + this._renderer.onDestroy(); + } + + setScale(scale: float): void { + this._scale = scale; + this._renderer.updateScale(); + this.invalidateHitboxes(); + } + + getScale(): float { + return this._scale; + } + + getFontSize(): float { + return this._renderer.getFontSize(); + } + + /** + * Set object position on X axis. + * @param x The new position X of the object. + */ + setX(x: float): void { + super.setX(x); + this._renderer.updatePosition(); + } + + /** + * Set object position on Y axis. + * @param y The new position Y of the object. + */ + setY(y: float): void { + super.setY(y); + this._renderer.updatePosition(); + } + + /** + * Set the angle of the object. + * @param angle The new angle of the object. + */ + setAngle(angle: float): void { + super.setAngle(angle); + this._renderer.updateAngle(); + } + + /** + * Set object opacity. + * @param opacity The new opacity of the object (0-255). + */ + setOpacity(opacity: float): void { + if (opacity < 0) { + opacity = 0; + } + if (opacity > 255) { + opacity = 255; + } + this._opacity = opacity; + this._renderer.updateOpacity(); + } + + /** + * Get object opacity. + */ + getOpacity(): float { + return this._opacity; + } + + /** + * Get the width of the object. + */ + getWidth(): float { + return this._renderer.getWidth(); + } + + /** + * Get the height of the object. + */ + getHeight(): float { + return this._renderer.getHeight(); + } + } + gdjs.registerObject( + 'Spine::SpineObject', + // @ts-ignore + gdjs.SpineRuntimeObject + ); +} diff --git a/GDJS/Runtime/types/project-data.d.ts b/GDJS/Runtime/types/project-data.d.ts index 4377f7d7b83b..e2a4dc4d16cc 100644 --- a/GDJS/Runtime/types/project-data.d.ts +++ b/GDJS/Runtime/types/project-data.d.ts @@ -273,4 +273,5 @@ declare type ResourceKind = | 'tilemap' | 'tileset' | 'bitmapFont' - | 'model3D'; + | 'model3D' + | 'atlas'; diff --git a/GDJS/package-lock.json b/GDJS/package-lock.json index ee1f80daf721..a09a105901a5 100644 --- a/GDJS/package-lock.json +++ b/GDJS/package-lock.json @@ -20,6 +20,7 @@ "lebab": "^3.1.0", "minimist": "^1.2.5", "patch-package": "^6.4.7", + "pixi-spine": "^3.0.0", "pixi.js": "6.1.2", "prettier": "2.1.2", "recursive-readdir": "^2.2.2", @@ -333,6 +334,92 @@ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, + "node_modules/@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", + "dev": true, + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/core": "^6.1.0", + "@pixi/display": "^6.1.0", + "@pixi/graphics": "^6.1.0", + "@pixi/math": "^6.1.0", + "@pixi/mesh": "^6.1.0", + "@pixi/mesh-extras": "^6.1.0", + "@pixi/sprite": "^6.1.0", + "@pixi/utils": "^6.1.0" + } + }, + "node_modules/@pixi-spine/loader-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-base/-/loader-base-3.1.2.tgz", + "integrity": "sha512-llg0RuuWiqVkyoQA+ceORV0sfUtrWGJj4jQ6erDFn2hMnob+QGzh+qwHSTMAnTNZTINEMfiUxmcwbmUYwTd8Ag==", + "dev": true, + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/core": "^6.1.0", + "@pixi/loaders": "^6.1.0" + } + }, + "node_modules/@pixi-spine/loader-uni": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-uni/-/loader-uni-3.1.2.tgz", + "integrity": "sha512-5th9gXqNQWMSuOu3euMw2kHETlncxU7LIFvOYqTMsKnwrOAIsPjHSF/4Sat1d3EAvvdMrYm4LmhHklgrAfk6UA==", + "dev": true, + "dependencies": { + "@pixi-spine/base": "~3.1.2", + "@pixi-spine/loader-base": "~3.1.2", + "@pixi-spine/runtime-3.7": "~3.1.2", + "@pixi-spine/runtime-3.8": "~3.1.2", + "@pixi-spine/runtime-4.1": "~3.1.2" + }, + "peerDependencies": { + "@pixi/loaders": "^6.1.0" + } + }, + "node_modules/@pixi-spine/runtime-3.7": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.7/-/runtime-3.7-3.1.2.tgz", + "integrity": "sha512-dMcw5x9jG+0itzzbPsJUn8hvhxzRXRzbm/kCUQ51iyFfLZQIK1LoPck4XPVuXckwFjU1qCT+tDZSEGBMYs5//A==", + "dev": true, + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/math": "^6.1.0" + } + }, + "node_modules/@pixi-spine/runtime-3.8": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.8/-/runtime-3.8-3.1.2.tgz", + "integrity": "sha512-AgS3mUC+5HQ/ehJO5Wo4oBoLg8F+tssF5WXi3FnnjqOaMcO+Ag232ForoL2iYHW40TKx0xMi5MpXsSafgS1i1A==", + "dev": true, + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/math": "^6.1.0" + } + }, + "node_modules/@pixi-spine/runtime-4.1": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-4.1/-/runtime-4.1-3.1.2.tgz", + "integrity": "sha512-XtaKAuLTtJ3o3llcUTr0d94dnRTyYHlss+x4VsYm1H38r4DUmQTBS13nisW0pgS3fY60D8AbEJkYVW7mwokxag==", + "dev": true, + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/math": "^6.1.0" + } + }, "node_modules/@pixi/accessibility": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-6.1.2.tgz", @@ -2387,6 +2474,20 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pixi-spine": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pixi-spine/-/pixi-spine-3.1.2.tgz", + "integrity": "sha512-rTTwXhBl5gZFZ793zdM/to0bifU8K4aa1gD0ilOiCqC/pgw5OxCcKnoRW3i05ythjzI3GlN6G0MDblOe2myr3w==", + "dev": true, + "dependencies": { + "@pixi-spine/base": "~3.1.2", + "@pixi-spine/loader-base": "~3.1.2", + "@pixi-spine/loader-uni": "~3.1.2", + "@pixi-spine/runtime-3.7": "~3.1.2", + "@pixi-spine/runtime-3.8": "~3.1.2", + "@pixi-spine/runtime-4.1": "~3.1.2" + } + }, "node_modules/pixi.js": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-6.1.2.tgz", @@ -3566,6 +3667,62 @@ } } }, + "@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", + "dev": true, + "requires": {} + }, + "@pixi-spine/loader-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-base/-/loader-base-3.1.2.tgz", + "integrity": "sha512-llg0RuuWiqVkyoQA+ceORV0sfUtrWGJj4jQ6erDFn2hMnob+QGzh+qwHSTMAnTNZTINEMfiUxmcwbmUYwTd8Ag==", + "dev": true, + "requires": { + "@pixi-spine/base": "~3.1.2" + } + }, + "@pixi-spine/loader-uni": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-uni/-/loader-uni-3.1.2.tgz", + "integrity": "sha512-5th9gXqNQWMSuOu3euMw2kHETlncxU7LIFvOYqTMsKnwrOAIsPjHSF/4Sat1d3EAvvdMrYm4LmhHklgrAfk6UA==", + "dev": true, + "requires": { + "@pixi-spine/base": "~3.1.2", + "@pixi-spine/loader-base": "~3.1.2", + "@pixi-spine/runtime-3.7": "~3.1.2", + "@pixi-spine/runtime-3.8": "~3.1.2", + "@pixi-spine/runtime-4.1": "~3.1.2" + } + }, + "@pixi-spine/runtime-3.7": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.7/-/runtime-3.7-3.1.2.tgz", + "integrity": "sha512-dMcw5x9jG+0itzzbPsJUn8hvhxzRXRzbm/kCUQ51iyFfLZQIK1LoPck4XPVuXckwFjU1qCT+tDZSEGBMYs5//A==", + "dev": true, + "requires": { + "@pixi-spine/base": "~3.1.2" + } + }, + "@pixi-spine/runtime-3.8": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.8/-/runtime-3.8-3.1.2.tgz", + "integrity": "sha512-AgS3mUC+5HQ/ehJO5Wo4oBoLg8F+tssF5WXi3FnnjqOaMcO+Ag232ForoL2iYHW40TKx0xMi5MpXsSafgS1i1A==", + "dev": true, + "requires": { + "@pixi-spine/base": "~3.1.2" + } + }, + "@pixi-spine/runtime-4.1": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-4.1/-/runtime-4.1-3.1.2.tgz", + "integrity": "sha512-XtaKAuLTtJ3o3llcUTr0d94dnRTyYHlss+x4VsYm1H38r4DUmQTBS13nisW0pgS3fY60D8AbEJkYVW7mwokxag==", + "dev": true, + "requires": { + "@pixi-spine/base": "~3.1.2" + } + }, "@pixi/accessibility": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-6.1.2.tgz", @@ -5133,6 +5290,20 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "pixi-spine": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pixi-spine/-/pixi-spine-3.1.2.tgz", + "integrity": "sha512-rTTwXhBl5gZFZ793zdM/to0bifU8K4aa1gD0ilOiCqC/pgw5OxCcKnoRW3i05ythjzI3GlN6G0MDblOe2myr3w==", + "dev": true, + "requires": { + "@pixi-spine/base": "~3.1.2", + "@pixi-spine/loader-base": "~3.1.2", + "@pixi-spine/loader-uni": "~3.1.2", + "@pixi-spine/runtime-3.7": "~3.1.2", + "@pixi-spine/runtime-3.8": "~3.1.2", + "@pixi-spine/runtime-4.1": "~3.1.2" + } + }, "pixi.js": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-6.1.2.tgz", diff --git a/GDJS/package.json b/GDJS/package.json index c4d367184d47..958df03ab072 100644 --- a/GDJS/package.json +++ b/GDJS/package.json @@ -17,6 +17,7 @@ "minimist": "^1.2.5", "patch-package": "^6.4.7", "pixi.js": "6.1.2", + "pixi-spine": "^3.0.0", "prettier": "2.1.2", "recursive-readdir": "^2.2.2", "shelljs": "^0.8.4", diff --git a/GDevelop.js/Bindings/Bindings.idl b/GDevelop.js/Bindings/Bindings.idl index a28e7db55202..22e087d581e2 100644 --- a/GDevelop.js/Bindings/Bindings.idl +++ b/GDevelop.js/Bindings/Bindings.idl @@ -1050,6 +1050,11 @@ interface Model3DResource { }; Model3DResource implements Resource; +interface AtlasResource { + void AtlasResource(); +}; +AtlasResource implements Resource; + interface InitialInstance { void InitialInstance(); diff --git a/GDevelop.js/Bindings/ObjectJsImplementation.cpp b/GDevelop.js/Bindings/ObjectJsImplementation.cpp index f47408963f10..04711e80df25 100644 --- a/GDevelop.js/Bindings/ObjectJsImplementation.cpp +++ b/GDevelop.js/Bindings/ObjectJsImplementation.cpp @@ -195,6 +195,8 @@ void ObjectJsImplementation::ExposeResources(gd::ArbitraryResourceWorker& worker worker.ExposeBitmapFont(newPropertyValue); } else if (resourceType == "model3D") { worker.ExposeModel3D(newPropertyValue); + } else if (resourceType == "atlas") { + worker.ExposeAtlas(newPropertyValue); } if (newPropertyValue != oldPropertyValue) { diff --git a/GDevelop.js/scripts/generate-types.js b/GDevelop.js/scripts/generate-types.js index d9dc770de7ac..3b245947940f 100644 --- a/GDevelop.js/scripts/generate-types.js +++ b/GDevelop.js/scripts/generate-types.js @@ -328,13 +328,13 @@ type ParticleEmitterObject_RendererType = 0 | 1 | 2` shell.sed( '-i', /setKind\(kind: string\): void/, - "setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D'): void", + "setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas'): void", 'types/gdresource.js' ); shell.sed( '-i', /getKind\(\): string/, - "getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D'", + "getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas'", 'types/gdresource.js' ); diff --git a/GDevelop.js/types/gdatlasresource.js b/GDevelop.js/types/gdatlasresource.js new file mode 100644 index 000000000000..ebdfa06c8c90 --- /dev/null +++ b/GDevelop.js/types/gdatlasresource.js @@ -0,0 +1,6 @@ +// Automatically generated by GDevelop.js/scripts/generate-types.js +declare class gdAtlasResource extends gdResource { + constructor(): void; + delete(): void; + ptr: number; +}; \ No newline at end of file diff --git a/GDevelop.js/types/gdresource.js b/GDevelop.js/types/gdresource.js index bc122052f290..bb3bda31d152 100644 --- a/GDevelop.js/types/gdresource.js +++ b/GDevelop.js/types/gdresource.js @@ -4,8 +4,8 @@ declare class gdResource { clone(): gdResource; setName(name: string): void; getName(): string; - setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D'): void; - getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D'; + setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas'): void; + getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas'; isUserAdded(): boolean; setUserAdded(yes: boolean): void; useFile(): boolean; diff --git a/GDevelop.js/types/libgdevelop.js b/GDevelop.js/types/libgdevelop.js index 14d67534e3b8..f8575e6266b6 100644 --- a/GDevelop.js/types/libgdevelop.js +++ b/GDevelop.js/types/libgdevelop.js @@ -104,6 +104,7 @@ declare class libGDevelop { TilemapResource: Class; TilesetResource: Class; Model3DResource: Class; + AtlasResource: Class; InitialInstance: Class; InitialInstancesContainer: Class; HighestZOrderFinder: Class; diff --git a/newIDE/app/package-lock.json b/newIDE/app/package-lock.json index c2679d6622e5..474be8fd0298 100644 --- a/newIDE/app/package-lock.json +++ b/newIDE/app/package-lock.json @@ -32,6 +32,7 @@ "lodash": "4.17.4", "node-require-function": "^1.2.0", "pixi-simple-gesture": "github:4ian/pixi-simple-gesture#v0.3.3", + "pixi-spine": "^3.0.0", "pixi.js-legacy": "6.1.2", "posthog-js": "^1.57.2", "prop-types": "^15.5.10", @@ -6059,312 +6060,515 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@pixi/accessibility": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.7": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.7/-/runtime-3.7-3.1.2.tgz", + "integrity": "sha512-dMcw5x9jG+0itzzbPsJUn8hvhxzRXRzbm/kCUQ51iyFfLZQIK1LoPck4XPVuXckwFjU1qCT+tDZSEGBMYs5//A==", + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2", - "@pixi/utils": "6.1.2" + "@pixi/constants": "^6.1.0", + "@pixi/math": "^6.1.0" } }, - "node_modules/@pixi/app": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2" - } - }, - "node_modules/@pixi/canvas-display": { - "version": "6.1.2", - "license": "MIT", + "@pixi/constants": "^6.1.0", + "@pixi/core": "^6.1.0", + "@pixi/display": "^6.1.0", + "@pixi/graphics": "^6.1.0", + "@pixi/math": "^6.1.0", + "@pixi/mesh": "^6.1.0", + "@pixi/mesh-extras": "^6.1.0", + "@pixi/sprite": "^6.1.0", + "@pixi/utils": "^6.1.0" + } + }, + "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/core": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", + "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", + "peer": true, + "dependencies": { + "@types/offscreencanvas": "^2019.6.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/pixijs" + }, "peerDependencies": { - "@pixi/display": "6.1.2" - } - }, - "node_modules/@pixi/canvas-extract": { - "version": "6.1.2", - "license": "MIT", + "@pixi/constants": "6.5.10", + "@pixi/extensions": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/runner": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/ticker": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/display": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", + "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "peer": true, "peerDependencies": { - "@pixi/canvas-renderer": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/utils": "6.1.2" + "@pixi/constants": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi/canvas-graphics": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/graphics": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", + "integrity": "sha512-KPHGJ910fi8bRQQ+VcTIgrK+bKIm8yAQaZKPqMtm14HzHPGcES6HkgeNY1sd7m8J4aS9btm5wOSyFu0p5IzTpA==", + "peer": true, "peerDependencies": { - "@pixi/canvas-display": "6.1.2", - "@pixi/canvas-renderer": "6.1.2", - "@pixi/constants": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/graphics": "6.1.2", - "@pixi/math": "6.1.2" - } - }, - "node_modules/@pixi/canvas-mesh": { - "version": "6.1.2", - "license": "MIT", + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/sprite": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/mesh": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.5.10.tgz", + "integrity": "sha512-tUNPsdp5/t/yRsCmfxIcufIfbQVzgAlMNgQ1igWOkSxzhB7vlEbZ8ZLLW5tQcNyM/r7Nhjz+RoB+RD+/BCtvlA==", + "peer": true, "peerDependencies": { - "@pixi/canvas-display": "6.1.2", - "@pixi/canvas-renderer": "6.1.2", - "@pixi/constants": "6.1.2", - "@pixi/mesh": "6.1.2", - "@pixi/mesh-extras": "6.1.2", - "@pixi/settings": "6.1.2" - } - }, - "node_modules/@pixi/canvas-particle-container": { - "version": "6.1.2", - "license": "MIT", + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/mesh-extras": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.5.10.tgz", + "integrity": "sha512-UCG7OOPPFeikrX09haCibCMR0jPQ4UJ+4HiYiAv/3dahq5eEzBx+yAwVtxcVCjonkTf/lu5SzmHdzpsbHLx5aw==", + "peer": true, "peerDependencies": { - "@pixi/particle-container": "6.1.2" + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/mesh": "6.5.10", + "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi/canvas-prepare": { - "version": "6.1.2", - "license": "MIT", - "peerDependencies": { - "@pixi/canvas-renderer": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/prepare": "6.1.2" - } + "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/runner": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", + "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", + "peer": true }, - "node_modules/@pixi/canvas-renderer": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/settings": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", + "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", + "peer": true, "peerDependencies": { - "@pixi/constants": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/settings": "6.1.2", - "@pixi/utils": "6.1.2" + "@pixi/constants": "6.5.10" } }, - "node_modules/@pixi/canvas-sprite": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/sprite": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", + "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", + "peer": true, "peerDependencies": { - "@pixi/canvas-display": "6.1.2", - "@pixi/canvas-renderer": "6.1.2", - "@pixi/constants": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/sprite": "6.1.2", - "@pixi/utils": "6.1.2" - } - }, - "node_modules/@pixi/canvas-sprite-tiling": { - "version": "6.1.2", - "license": "MIT", + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/ticker": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", + "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", + "peer": true, "peerDependencies": { - "@pixi/canvas-renderer": "6.1.2", - "@pixi/canvas-sprite": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/sprite-tiling": "6.1.2", - "@pixi/utils": "6.1.2" + "@pixi/extensions": "6.5.10", + "@pixi/settings": "6.5.10" } }, - "node_modules/@pixi/canvas-text": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/utils": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", + "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "peer": true, + "dependencies": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.4", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + }, "peerDependencies": { - "@pixi/canvas-sprite": "6.1.2", - "@pixi/sprite": "6.1.2", - "@pixi/text": "6.1.2" + "@pixi/constants": "6.5.10", + "@pixi/settings": "6.5.10" } }, - "node_modules/@pixi/compressed-textures": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.7/node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true + }, + "node_modules/@pixi-spine/runtime-3.8": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.8/-/runtime-3.8-3.1.2.tgz", + "integrity": "sha512-AgS3mUC+5HQ/ehJO5Wo4oBoLg8F+tssF5WXi3FnnjqOaMcO+Ag232ForoL2iYHW40TKx0xMi5MpXsSafgS1i1A==", + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, "peerDependencies": { - "@pixi/constants": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/loaders": "6.1.2", - "@pixi/utils": "6.1.2" + "@pixi/constants": "^6.1.0", + "@pixi/math": "^6.1.0" } }, - "node_modules/@pixi/constants": { - "version": "6.1.2", - "license": "MIT" - }, - "node_modules/@pixi/core": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/core": "^6.1.0", + "@pixi/display": "^6.1.0", + "@pixi/graphics": "^6.1.0", + "@pixi/math": "^6.1.0", + "@pixi/mesh": "^6.1.0", + "@pixi/mesh-extras": "^6.1.0", + "@pixi/sprite": "^6.1.0", + "@pixi/utils": "^6.1.0" + } + }, + "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/core": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", + "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", + "peer": true, + "dependencies": { + "@types/offscreencanvas": "^2019.6.4" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/pixijs" }, "peerDependencies": { - "@pixi/constants": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/runner": "6.1.2", - "@pixi/settings": "6.1.2", - "@pixi/ticker": "6.1.2", - "@pixi/utils": "6.1.2" - } - }, - "node_modules/@pixi/display": { - "version": "6.1.2", - "license": "MIT", + "@pixi/constants": "6.5.10", + "@pixi/extensions": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/runner": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/ticker": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/display": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", + "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "peer": true, "peerDependencies": { - "@pixi/math": "6.1.2", - "@pixi/settings": "6.1.2", - "@pixi/utils": "6.1.2" + "@pixi/constants": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi/extract": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/graphics": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", + "integrity": "sha512-KPHGJ910fi8bRQQ+VcTIgrK+bKIm8yAQaZKPqMtm14HzHPGcES6HkgeNY1sd7m8J4aS9btm5wOSyFu0p5IzTpA==", + "peer": true, "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/utils": "6.1.2" - } - }, - "node_modules/@pixi/filter-alpha": { - "version": "6.1.2", - "license": "MIT", + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/sprite": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/mesh": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.5.10.tgz", + "integrity": "sha512-tUNPsdp5/t/yRsCmfxIcufIfbQVzgAlMNgQ1igWOkSxzhB7vlEbZ8ZLLW5tQcNyM/r7Nhjz+RoB+RD+/BCtvlA==", + "peer": true, "peerDependencies": { - "@pixi/core": "6.1.2" - } - }, - "node_modules/@pixi/filter-blur": { - "version": "6.1.2", - "license": "MIT", + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/mesh-extras": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.5.10.tgz", + "integrity": "sha512-UCG7OOPPFeikrX09haCibCMR0jPQ4UJ+4HiYiAv/3dahq5eEzBx+yAwVtxcVCjonkTf/lu5SzmHdzpsbHLx5aw==", + "peer": true, "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/settings": "6.1.2" + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/mesh": "6.5.10", + "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi/filter-color-matrix": { - "version": "6.1.2", - "license": "MIT", - "peerDependencies": { - "@pixi/core": "6.1.2" - } + "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/runner": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", + "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", + "peer": true }, - "node_modules/@pixi/filter-displacement": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/settings": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", + "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", + "peer": true, "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/math": "6.1.2" + "@pixi/constants": "6.5.10" } }, - "node_modules/@pixi/filter-fxaa": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/sprite": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", + "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", + "peer": true, "peerDependencies": { - "@pixi/core": "6.1.2" + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/ticker": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", + "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", + "peer": true, + "peerDependencies": { + "@pixi/extensions": "6.5.10", + "@pixi/settings": "6.5.10" } }, - "node_modules/@pixi/filter-noise": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/utils": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", + "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "peer": true, + "dependencies": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.4", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + }, "peerDependencies": { - "@pixi/core": "6.1.2" + "@pixi/constants": "6.5.10", + "@pixi/settings": "6.5.10" } }, - "node_modules/@pixi/graphics": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-3.8/node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true + }, + "node_modules/@pixi-spine/runtime-4.1": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-4.1/-/runtime-4.1-3.1.2.tgz", + "integrity": "sha512-XtaKAuLTtJ3o3llcUTr0d94dnRTyYHlss+x4VsYm1H38r4DUmQTBS13nisW0pgS3fY60D8AbEJkYVW7mwokxag==", + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, "peerDependencies": { - "@pixi/constants": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/sprite": "6.1.2", - "@pixi/utils": "6.1.2" + "@pixi/constants": "^6.1.0", + "@pixi/math": "^6.1.0" } }, - "node_modules/@pixi/interaction": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/ticker": "6.1.2", - "@pixi/utils": "6.1.2" + "@pixi/constants": "^6.1.0", + "@pixi/core": "^6.1.0", + "@pixi/display": "^6.1.0", + "@pixi/graphics": "^6.1.0", + "@pixi/math": "^6.1.0", + "@pixi/mesh": "^6.1.0", + "@pixi/mesh-extras": "^6.1.0", + "@pixi/sprite": "^6.1.0", + "@pixi/utils": "^6.1.0" + } + }, + "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/core": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", + "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", + "peer": true, + "dependencies": { + "@types/offscreencanvas": "^2019.6.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/pixijs" + }, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/extensions": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/runner": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/ticker": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/display": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", + "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi/loaders": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/graphics": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", + "integrity": "sha512-KPHGJ910fi8bRQQ+VcTIgrK+bKIm8yAQaZKPqMtm14HzHPGcES6HkgeNY1sd7m8J4aS9btm5wOSyFu0p5IzTpA==", + "peer": true, "peerDependencies": { - "@pixi/constants": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/utils": "6.1.2" + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/sprite": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/mesh": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.5.10.tgz", + "integrity": "sha512-tUNPsdp5/t/yRsCmfxIcufIfbQVzgAlMNgQ1igWOkSxzhB7vlEbZ8ZLLW5tQcNyM/r7Nhjz+RoB+RD+/BCtvlA==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/mesh-extras": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.5.10.tgz", + "integrity": "sha512-UCG7OOPPFeikrX09haCibCMR0jPQ4UJ+4HiYiAv/3dahq5eEzBx+yAwVtxcVCjonkTf/lu5SzmHdzpsbHLx5aw==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/mesh": "6.5.10", + "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi/math": { - "version": "6.1.2", - "license": "MIT" + "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/runner": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", + "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", + "peer": true }, - "node_modules/@pixi/mesh": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/settings": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", + "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", + "peer": true, "peerDependencies": { - "@pixi/constants": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/settings": "6.1.2", - "@pixi/utils": "6.1.2" + "@pixi/constants": "6.5.10" } }, - "node_modules/@pixi/mesh-extras": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/sprite": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", + "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", + "peer": true, "peerDependencies": { - "@pixi/constants": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/mesh": "6.1.2", - "@pixi/utils": "6.1.2" - } - }, - "node_modules/@pixi/mixin-cache-as-bitmap": { - "version": "6.1.2", - "license": "MIT", + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/ticker": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", + "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", + "peer": true, "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/settings": "6.1.2", - "@pixi/sprite": "6.1.2", - "@pixi/utils": "6.1.2" + "@pixi/extensions": "6.5.10", + "@pixi/settings": "6.5.10" } }, - "node_modules/@pixi/mixin-get-child-by-name": { - "version": "6.1.2", - "license": "MIT", + "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/utils": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", + "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "peer": true, + "dependencies": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.4", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + }, "peerDependencies": { - "@pixi/display": "6.1.2" + "@pixi/constants": "6.5.10", + "@pixi/settings": "6.5.10" } }, - "node_modules/@pixi/mixin-get-global-position": { - "version": "6.1.2", - "license": "MIT", - "peerDependencies": { - "@pixi/display": "6.1.2", - "@pixi/math": "6.1.2" - } + "node_modules/@pixi-spine/runtime-4.1/node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true }, - "node_modules/@pixi/particle-container": { - "version": "6.1.2", - "license": "MIT", - "peerDependencies": { - "@pixi/constants": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/utils": "6.1.2" - } + "node_modules/@pixi/constants": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.5.10.tgz", + "integrity": "sha512-PUF2Y9YISRu5eVrVVHhHCWpc/KmxQTg3UH8rIUs8UI9dCK41/wsPd3pEahzf7H47v7x1HCohVZcFO3XQc1bUDw==", + "peer": true + }, + "node_modules/@pixi/extensions": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/extensions/-/extensions-6.5.10.tgz", + "integrity": "sha512-EIUGza+E+sCy3dupuIjvRK/WyVyfSzHb5XsxRaxNrPwvG1iIUIqNqZ3owLYCo4h17fJWrj/yXVufNNtUKQccWQ==", + "peer": true + }, + "node_modules/@pixi/math": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.5.10.tgz", + "integrity": "sha512-fxeu7ykVbMGxGV2S3qRTupHToeo1hdWBm8ihyURn3BMqJZe2SkZEECPd5RyvIuuNUtjRnmhkZRnF3Jsz2S+L0g==", + "peer": true }, "node_modules/@pixi/polyfill": { "version": "6.1.2", @@ -6374,18 +6578,6 @@ "promise-polyfill": "^8.2.0" } }, - "node_modules/@pixi/prepare": { - "version": "6.1.2", - "license": "MIT", - "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2", - "@pixi/graphics": "6.1.2", - "@pixi/settings": "6.1.2", - "@pixi/text": "6.1.2", - "@pixi/ticker": "6.1.2" - } - }, "node_modules/@pixi/runner": { "version": "6.1.2", "license": "MIT" @@ -6397,74 +6589,6 @@ "ismobilejs": "^1.1.0" } }, - "node_modules/@pixi/sprite": { - "version": "6.1.2", - "license": "MIT", - "peerDependencies": { - "@pixi/constants": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/settings": "6.1.2", - "@pixi/utils": "6.1.2" - } - }, - "node_modules/@pixi/sprite-animated": { - "version": "6.1.2", - "license": "MIT", - "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/sprite": "6.1.2", - "@pixi/ticker": "6.1.2" - } - }, - "node_modules/@pixi/sprite-tiling": { - "version": "6.1.2", - "license": "MIT", - "peerDependencies": { - "@pixi/constants": "6.1.2", - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/sprite": "6.1.2", - "@pixi/utils": "6.1.2" - } - }, - "node_modules/@pixi/spritesheet": { - "version": "6.1.2", - "license": "MIT", - "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/loaders": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/utils": "6.1.2" - } - }, - "node_modules/@pixi/text": { - "version": "6.1.2", - "license": "MIT", - "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/settings": "6.1.2", - "@pixi/sprite": "6.1.2", - "@pixi/utils": "6.1.2" - } - }, - "node_modules/@pixi/text-bitmap": { - "version": "6.1.2", - "license": "MIT", - "peerDependencies": { - "@pixi/core": "6.1.2", - "@pixi/display": "6.1.2", - "@pixi/loaders": "6.1.2", - "@pixi/math": "6.1.2", - "@pixi/mesh": "6.1.2", - "@pixi/settings": "6.1.2", - "@pixi/text": "6.1.2", - "@pixi/utils": "6.1.2" - } - }, "node_modules/@pixi/ticker": { "version": "6.1.2", "license": "MIT", @@ -6472,20 +6596,6 @@ "@pixi/settings": "6.1.2" } }, - "node_modules/@pixi/utils": { - "version": "6.1.2", - "license": "MIT", - "dependencies": { - "@types/earcut": "^2.1.0", - "earcut": "^2.2.2", - "eventemitter3": "^3.1.0", - "url": "^0.11.0" - }, - "peerDependencies": { - "@pixi/constants": "6.1.2", - "@pixi/settings": "6.1.2" - } - }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", @@ -15852,6 +15962,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/offscreencanvas": { + "version": "2019.7.0", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz", + "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==", + "peer": true + }, "node_modules/@types/overlayscrollbars": { "version": "1.12.1", "dev": true, @@ -22767,8 +22883,9 @@ } }, "node_modules/eventemitter3": { - "version": "3.1.2", - "license": "MIT" + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, "node_modules/events": { "version": "1.1.1", @@ -25512,12 +25629,6 @@ "node": ">=8.0" } }, - "node_modules/http-proxy/node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, "node_modules/https-browserify": { "version": "1.0.0", "dev": true, @@ -34297,6 +34408,210 @@ "resolved": "git+ssh://git@github.com/4ian/pixi-simple-gesture.git#c84e0cc3c62edeca019e708d9897ef6b97a0d18a", "license": "MIT" }, + "node_modules/pixi-spine": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pixi-spine/-/pixi-spine-3.1.2.tgz", + "integrity": "sha512-rTTwXhBl5gZFZ793zdM/to0bifU8K4aa1gD0ilOiCqC/pgw5OxCcKnoRW3i05ythjzI3GlN6G0MDblOe2myr3w==", + "dependencies": { + "@pixi-spine/base": "~3.1.2", + "@pixi-spine/loader-base": "~3.1.2", + "@pixi-spine/loader-uni": "~3.1.2", + "@pixi-spine/runtime-3.7": "~3.1.2", + "@pixi-spine/runtime-3.8": "~3.1.2", + "@pixi-spine/runtime-4.1": "~3.1.2" + } + }, + "node_modules/pixi-spine/node_modules/@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/core": "^6.1.0", + "@pixi/display": "^6.1.0", + "@pixi/graphics": "^6.1.0", + "@pixi/math": "^6.1.0", + "@pixi/mesh": "^6.1.0", + "@pixi/mesh-extras": "^6.1.0", + "@pixi/sprite": "^6.1.0", + "@pixi/utils": "^6.1.0" + } + }, + "node_modules/pixi-spine/node_modules/@pixi-spine/loader-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-base/-/loader-base-3.1.2.tgz", + "integrity": "sha512-llg0RuuWiqVkyoQA+ceORV0sfUtrWGJj4jQ6erDFn2hMnob+QGzh+qwHSTMAnTNZTINEMfiUxmcwbmUYwTd8Ag==", + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/core": "^6.1.0", + "@pixi/loaders": "^6.1.0" + } + }, + "node_modules/pixi-spine/node_modules/@pixi-spine/loader-uni": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-uni/-/loader-uni-3.1.2.tgz", + "integrity": "sha512-5th9gXqNQWMSuOu3euMw2kHETlncxU7LIFvOYqTMsKnwrOAIsPjHSF/4Sat1d3EAvvdMrYm4LmhHklgrAfk6UA==", + "dependencies": { + "@pixi-spine/base": "~3.1.2", + "@pixi-spine/loader-base": "~3.1.2", + "@pixi-spine/runtime-3.7": "~3.1.2", + "@pixi-spine/runtime-3.8": "~3.1.2", + "@pixi-spine/runtime-4.1": "~3.1.2" + }, + "peerDependencies": { + "@pixi/loaders": "^6.1.0" + } + }, + "node_modules/pixi-spine/node_modules/@pixi/core": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", + "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", + "peer": true, + "dependencies": { + "@types/offscreencanvas": "^2019.6.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/pixijs" + }, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/extensions": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/runner": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/ticker": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/pixi-spine/node_modules/@pixi/display": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", + "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/pixi-spine/node_modules/@pixi/graphics": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", + "integrity": "sha512-KPHGJ910fi8bRQQ+VcTIgrK+bKIm8yAQaZKPqMtm14HzHPGcES6HkgeNY1sd7m8J4aS9btm5wOSyFu0p5IzTpA==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/sprite": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/pixi-spine/node_modules/@pixi/loaders": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/loaders/-/loaders-6.5.10.tgz", + "integrity": "sha512-AuK7mXBmyVsDFL9DDFPB8sqP8fwQ2NOktvu98bQuJl0/p/UeK/0OAQnF3wcf3FeBv5YGXfNHL21c2DCisjKfTg==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/pixi-spine/node_modules/@pixi/mesh": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.5.10.tgz", + "integrity": "sha512-tUNPsdp5/t/yRsCmfxIcufIfbQVzgAlMNgQ1igWOkSxzhB7vlEbZ8ZLLW5tQcNyM/r7Nhjz+RoB+RD+/BCtvlA==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/pixi-spine/node_modules/@pixi/mesh-extras": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.5.10.tgz", + "integrity": "sha512-UCG7OOPPFeikrX09haCibCMR0jPQ4UJ+4HiYiAv/3dahq5eEzBx+yAwVtxcVCjonkTf/lu5SzmHdzpsbHLx5aw==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/mesh": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/pixi-spine/node_modules/@pixi/runner": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", + "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", + "peer": true + }, + "node_modules/pixi-spine/node_modules/@pixi/settings": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", + "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.5.10" + } + }, + "node_modules/pixi-spine/node_modules/@pixi/sprite": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", + "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/core": "6.5.10", + "@pixi/display": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" + } + }, + "node_modules/pixi-spine/node_modules/@pixi/ticker": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", + "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", + "peer": true, + "peerDependencies": { + "@pixi/extensions": "6.5.10", + "@pixi/settings": "6.5.10" + } + }, + "node_modules/pixi-spine/node_modules/@pixi/utils": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", + "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "peer": true, + "dependencies": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.4", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + }, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/settings": "6.5.10" + } + }, + "node_modules/pixi-spine/node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true + }, "node_modules/pixi.js": { "version": "6.1.2", "license": "MIT", @@ -34363,6 +34678,625 @@ "url": "https://opencollective.com/pixijs" } }, + "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-display": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-display/-/canvas-display-6.1.2.tgz", + "integrity": "sha512-UWLfqDFs0H+KUw1jp+PczCJ0VCQ5BQij9JWsSCvFSM/0ZFLdWctlQjUYMimrQhLgyqYEDV6QsqXZOginbN4uvA==", + "peerDependencies": { + "@pixi/display": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-extract": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-extract/-/canvas-extract-6.1.2.tgz", + "integrity": "sha512-d2XvW8dlg7kIyXV6BfEjViUzGfd1ZAjP61e5zLKxs62kXhy4qEQb2J8J80bfPEEBivJ7Uj+ozdLlt/ZwuYVo1Q==", + "peerDependencies": { + "@pixi/canvas-renderer": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-graphics": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-graphics/-/canvas-graphics-6.1.2.tgz", + "integrity": "sha512-cgsDUWAcp03fpdsb5EET+XflQjcrfri0ubaebKlvb9Whv2tv/+ZUI/WFv900F0GSNtS/H/AMSwlPykZIqtzRYw==", + "peerDependencies": { + "@pixi/canvas-display": "6.1.2", + "@pixi/canvas-renderer": "6.1.2", + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/graphics": "6.1.2", + "@pixi/math": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-mesh": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-mesh/-/canvas-mesh-6.1.2.tgz", + "integrity": "sha512-WKFEiTfHUkeszL+LqtmA5aAno79msxm8Eo5tqANzpQm27J7OEpF3KySnUSJ/LP+A4Rdbt2YGPF4jzuLezBalTA==", + "peerDependencies": { + "@pixi/canvas-display": "6.1.2", + "@pixi/canvas-renderer": "6.1.2", + "@pixi/constants": "6.1.2", + "@pixi/mesh": "6.1.2", + "@pixi/mesh-extras": "6.1.2", + "@pixi/settings": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-particle-container": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-particle-container/-/canvas-particle-container-6.1.2.tgz", + "integrity": "sha512-IPUCzU+WAI0d0XkfrpkaehYDkkuUfxUUdE8QSEZx9xQNljeKIgQVL3Muv35IWhxjJ3PkaJ26ad+4brXxTHHPsg==", + "peerDependencies": { + "@pixi/particle-container": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-prepare": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-prepare/-/canvas-prepare-6.1.2.tgz", + "integrity": "sha512-YmAgQmuIebi3IiPpuxKd05qhJ+WL8MpH0lTxNSpV+Vcrsn6eDRyVMBW0asji4SAQqDmH+xwSePLkr9MH8OvQhg==", + "peerDependencies": { + "@pixi/canvas-renderer": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/prepare": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-renderer": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-renderer/-/canvas-renderer-6.1.2.tgz", + "integrity": "sha512-pSO+K9yZcly2hyvVCfAU0SlmVztdxEl7Hji4h9Sj/iNyNXl77vWNYW8u+69IwWpXAq6WVxmaJBNCYdg47DzBIA==", + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-sprite": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-sprite/-/canvas-sprite-6.1.2.tgz", + "integrity": "sha512-HJpcU2WZOOlRtpZpdCOzqu0Y2xg2C7tLy556ynpxiPV5KrC+T3lNlFwZoLddPCCoVo5ph3K+Hb090SnfsY1v0Q==", + "peerDependencies": { + "@pixi/canvas-display": "6.1.2", + "@pixi/canvas-renderer": "6.1.2", + "@pixi/constants": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/sprite": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-sprite-tiling": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-sprite-tiling/-/canvas-sprite-tiling-6.1.2.tgz", + "integrity": "sha512-MYHOXarrlvqRiAfdjHoVYD4HOKT/ij0MejXbw/3vQmBUM9e9tDm46TFSc5FysEDqJ2ts0C/PTACR3wqL++ZNlw==", + "peerDependencies": { + "@pixi/canvas-renderer": "6.1.2", + "@pixi/canvas-sprite": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/sprite-tiling": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-text": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-text/-/canvas-text-6.1.2.tgz", + "integrity": "sha512-73MX5hNiCvtAosdOHPJ7QHE6/0YVkpgXDA9DR0Z5OpFg9Hncj350x60n6Vbe6178A1u8itXHp7CJ0Iw8nTN2hw==", + "peerDependencies": { + "@pixi/canvas-sprite": "6.1.2", + "@pixi/sprite": "6.1.2", + "@pixi/text": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/constants": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.1.2.tgz", + "integrity": "sha512-rPHWzGDI/PKD0/p8mrsoednpDhbvfidcen2Vozz7KNO5SS/ljqyiZLEbHwYK/xhc2Z7QvXVuDuPaWl9FBCRiQg==", + "peer": true + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/core": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.1.2.tgz", + "integrity": "sha512-S+f0qmVkrePor2XKA6A70Axo8ui+HiZgkl1J7AWVtl6MI49+3tXra9Ww3xmp/6jEdIUQyyN5sC8cg8dF/lgmBw==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/pixijs" + }, + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/runner": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/ticker": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/display": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.1.2.tgz", + "integrity": "sha512-JbX9GF6kOg8n8mcOFvcVZBpDRZtB/u7I+L0taOMHHtQ16bdBQ9+CxYgvOi9FLyWQNKl4utnnviQx4t8Km01POQ==", + "peer": true, + "peerDependencies": { + "@pixi/math": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/graphics": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.1.2.tgz", + "integrity": "sha512-aNQ9242RV3Lg4hLmU4rN9jGKhE84vjkxEWswpyqChDqh5vOeahSjZo4DR+qIsEUwEo/OgRY1kvpWY4+2xzMSjg==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/sprite": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/math": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.1.2.tgz", + "integrity": "sha512-tARAZaR01bifqQFW5P714k+Kb8KntKoxVSxbxkY58RSibpoCBFZ8ZnrlT4HY3ovIx66KhH7JJeVhCsXG2d/ggg==", + "peer": true + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/mesh": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.1.2.tgz", + "integrity": "sha512-3aEke7cXq+EIsuVW8G/Ro5GekbZRDFSSxOtbpzNoSjNdTgnKb3OcNaaygu8tK+ZN2uXxN2u91d6f0ki8Y6VnUA==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/mesh-extras": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.1.2.tgz", + "integrity": "sha512-MtOHfbfDJ0RyNq3S1frm/+erxCyrayZFOJA0bBIFvHW5WeolAcLo+pNGlmh/1qufDTnMK3UM16mOzAz9qNA7wA==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/mesh": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/particle-container": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-6.1.2.tgz", + "integrity": "sha512-2IvY0nkH8tc7dY6Gk/RyCaSWaPWNEEurPeEkDYhYUcL/ktlqD65PzHQVMZ20nhW5hnHx4bn2H4S1U/5ilvg8Tg==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/prepare": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-6.1.2.tgz", + "integrity": "sha512-qHoS/knfchT7ZvpV1MwJQaS5zb8uvlO2paKRLN76aZR4dHKCpRzVWHJ+5EuSEacbbzX8ElBMTCI0iV1V7L1Jiw==", + "peer": true, + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/graphics": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/text": "6.1.2", + "@pixi/ticker": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/sprite": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.1.2.tgz", + "integrity": "sha512-AzK2UW+VcZ+6sKW++9qokhSMFG35zSAOpRoWk5QgRhbVkdh2L0BB7nK5Z8PZgqmTGCzSq2NvVlzosryPWmLMNw==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/sprite-tiling": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-6.1.2.tgz", + "integrity": "sha512-6tOlag2M+bn5aNPi/iyORY/IqB9Gfan5MnaG3HarfZdSlSwQH0yklDePBrG2DQ/X6Rmb94DJd0PxJdCujtFJTg==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/sprite": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/text": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/text/-/text-6.1.2.tgz", + "integrity": "sha512-9JQ4hEanM946uMvjg4a7uIhnAoGYE6lyxwDUlHw4j/o+8jYN49STc64G+s9Rj7iRw76tudqM2ejphBE+rzC0XQ==", + "peer": true, + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/sprite": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/utils": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.1.2.tgz", + "integrity": "sha512-7lacouw8UPAQ0NbBbMEYOff/VRy0qVPV0VuAdKkmrlKu53n6NkocATnUGwdNOHmSNLMAgVu4e30ihwNORrRMAQ==", + "peer": true, + "dependencies": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.2", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + }, + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/settings": "6.1.2" + } + }, + "node_modules/pixi.js-legacy/node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true + }, + "node_modules/pixi.js/node_modules/@pixi/accessibility": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-6.1.2.tgz", + "integrity": "sha512-riXpC4PBJYaAG5aWUZ3ud+zhF2ulqnNGCMvlcf/RfuNHlI0jd3SQ0/sxI9OwT0usnxjUDd8beDk8txJGmrX8Fw==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/app": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/app/-/app-6.1.2.tgz", + "integrity": "sha512-fv8kyFw2w8kX9UZNetlNAerM7Uszr2BSXKIMqB8lITpeE7XlnNpDussdF9z87fBjSYgMD3bdWSkhdj54QY6n9A==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/compressed-textures": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/compressed-textures/-/compressed-textures-6.1.2.tgz", + "integrity": "sha512-BcOaXKS4+6fTOnORt6o2uKUJGpwTIDhIzF+t0ekd9UGhfLykFHIALdgCYPU1e4GvtWWDfaYYhIwWWa8sX+FWTQ==", + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/loaders": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/constants": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.1.2.tgz", + "integrity": "sha512-rPHWzGDI/PKD0/p8mrsoednpDhbvfidcen2Vozz7KNO5SS/ljqyiZLEbHwYK/xhc2Z7QvXVuDuPaWl9FBCRiQg==" + }, + "node_modules/pixi.js/node_modules/@pixi/core": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.1.2.tgz", + "integrity": "sha512-S+f0qmVkrePor2XKA6A70Axo8ui+HiZgkl1J7AWVtl6MI49+3tXra9Ww3xmp/6jEdIUQyyN5sC8cg8dF/lgmBw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/pixijs" + }, + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/runner": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/ticker": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/display": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.1.2.tgz", + "integrity": "sha512-JbX9GF6kOg8n8mcOFvcVZBpDRZtB/u7I+L0taOMHHtQ16bdBQ9+CxYgvOi9FLyWQNKl4utnnviQx4t8Km01POQ==", + "peerDependencies": { + "@pixi/math": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/extract": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-6.1.2.tgz", + "integrity": "sha512-1vnAOJEaaRsTWyRa4OCodVubvZ0Ib3LVkg5MFU+bDsgnczwUiZEOvtaQKOAiO1F9rEdNdvuo/TQyWlJAuHB73Q==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/filter-alpha": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-alpha/-/filter-alpha-6.1.2.tgz", + "integrity": "sha512-8qvW6FrJ8liyswfQJrFKRo679j1vhszxsa/A0unXJYGkD8fRlnoywr2gci+yEb/AyEiuwJF59v2YtWjFjkJ2fA==", + "peerDependencies": { + "@pixi/core": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/filter-blur": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-blur/-/filter-blur-6.1.2.tgz", + "integrity": "sha512-4uJUVtuiuQbPBqXwUS7aUoe8SAnjcmAwKR+KClgn/4XvwIXaULvQcmSUTyrROmWeNTGm6LgVcX4pbb8aO5lWLg==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/settings": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/filter-color-matrix": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-color-matrix/-/filter-color-matrix-6.1.2.tgz", + "integrity": "sha512-xHd0OFdJr2nuqUKSjpf9W2OQwrfmQ7v00eiqeBA9azFmMJ4XmsRmAaej+mgBM2L9j4gZmbGE/5h5ZA80NCAHfg==", + "peerDependencies": { + "@pixi/core": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/filter-displacement": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-displacement/-/filter-displacement-6.1.2.tgz", + "integrity": "sha512-LOQJUfsIcgGkURT7/cqdb9sDjhGO9eQXPb8YHeMyBgKouby0On9REFbueE0cwfuY/MGcfru55JH8okcG7YXj2w==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/math": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/filter-fxaa": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-fxaa/-/filter-fxaa-6.1.2.tgz", + "integrity": "sha512-Gx2i8DCSKXhnUz0/rFsTmSaGVXl+kyZnD7/e1WojZD4M/2DPzQXqfbmi2OxsR1dyFBH6utNjmYP8xIvQ4JmSMw==", + "peerDependencies": { + "@pixi/core": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/filter-noise": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-noise/-/filter-noise-6.1.2.tgz", + "integrity": "sha512-sPYw3fuxycnVa12C66RhJGeK32XXfX7ANvH5ZRf6i3NwsnmlEZfid8zrujt23xdY0UNqHxwYyg2RrQS9mLDanw==", + "peerDependencies": { + "@pixi/core": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/graphics": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.1.2.tgz", + "integrity": "sha512-aNQ9242RV3Lg4hLmU4rN9jGKhE84vjkxEWswpyqChDqh5vOeahSjZo4DR+qIsEUwEo/OgRY1kvpWY4+2xzMSjg==", + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/sprite": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/interaction": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/interaction/-/interaction-6.1.2.tgz", + "integrity": "sha512-0Hw6ZTXW8jgwq1Ek4wu+JqbSpIeOGvUR9mYuh8Ucrsi089Zavv/sOtAVVO8Zq1psFUjsU+BXSuOZmgOi2xwHFQ==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/ticker": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/loaders": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/loaders/-/loaders-6.1.2.tgz", + "integrity": "sha512-InzcLF6Xl9DAp8O2w93r+xEfL9tZYe+CMjVKxJCEebee8JliurRX5Tpq/POi1QwwApi5HaQdpbZ5akQGZGA/+Q==", + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/math": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.1.2.tgz", + "integrity": "sha512-tARAZaR01bifqQFW5P714k+Kb8KntKoxVSxbxkY58RSibpoCBFZ8ZnrlT4HY3ovIx66KhH7JJeVhCsXG2d/ggg==" + }, + "node_modules/pixi.js/node_modules/@pixi/mesh": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.1.2.tgz", + "integrity": "sha512-3aEke7cXq+EIsuVW8G/Ro5GekbZRDFSSxOtbpzNoSjNdTgnKb3OcNaaygu8tK+ZN2uXxN2u91d6f0ki8Y6VnUA==", + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/mesh-extras": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.1.2.tgz", + "integrity": "sha512-MtOHfbfDJ0RyNq3S1frm/+erxCyrayZFOJA0bBIFvHW5WeolAcLo+pNGlmh/1qufDTnMK3UM16mOzAz9qNA7wA==", + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/mesh": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/mixin-cache-as-bitmap": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-6.1.2.tgz", + "integrity": "sha512-8H5SZ6KTKI0WIYPNasjgGDanwUuIyyWtug/qK8j/LNuvVZmj9xfeQnih+Zi727SxKLrnD2mPWXWzSbDrp0MpnQ==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/sprite": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/mixin-get-child-by-name": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-6.1.2.tgz", + "integrity": "sha512-9WCGFWiY8fisUCir51Q3JKMSw16M5KSzDxAHVyNlinBv71ifH+AZgdzeogDbQf1ysP4BL2K956czPv19GbcANw==", + "peerDependencies": { + "@pixi/display": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/mixin-get-global-position": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mixin-get-global-position/-/mixin-get-global-position-6.1.2.tgz", + "integrity": "sha512-E7+yo2Cv+qrIXeH8x3tr98H4qEY3vn+IYTbJP0m7/hVA98qTOoP866MJUBNwgwtbRgNEQJwGuGs+m/yK2mcW7w==", + "peerDependencies": { + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/particle-container": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-6.1.2.tgz", + "integrity": "sha512-2IvY0nkH8tc7dY6Gk/RyCaSWaPWNEEurPeEkDYhYUcL/ktlqD65PzHQVMZ20nhW5hnHx4bn2H4S1U/5ilvg8Tg==", + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/prepare": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-6.1.2.tgz", + "integrity": "sha512-qHoS/knfchT7ZvpV1MwJQaS5zb8uvlO2paKRLN76aZR4dHKCpRzVWHJ+5EuSEacbbzX8ElBMTCI0iV1V7L1Jiw==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/graphics": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/text": "6.1.2", + "@pixi/ticker": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/sprite": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.1.2.tgz", + "integrity": "sha512-AzK2UW+VcZ+6sKW++9qokhSMFG35zSAOpRoWk5QgRhbVkdh2L0BB7nK5Z8PZgqmTGCzSq2NvVlzosryPWmLMNw==", + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/sprite-animated": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite-animated/-/sprite-animated-6.1.2.tgz", + "integrity": "sha512-jriUtbIw1v0AB3sIObM1t7eAIPuB4gtokao6k09EURMepoCQJlYSKIq5FVlmLYU/zf1t7/f/dtpZ65UEKXDytw==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/sprite": "6.1.2", + "@pixi/ticker": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/sprite-tiling": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-6.1.2.tgz", + "integrity": "sha512-6tOlag2M+bn5aNPi/iyORY/IqB9Gfan5MnaG3HarfZdSlSwQH0yklDePBrG2DQ/X6Rmb94DJd0PxJdCujtFJTg==", + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/sprite": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/spritesheet": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/spritesheet/-/spritesheet-6.1.2.tgz", + "integrity": "sha512-PP+sChFaE8vK0PHwChKYeDuFSvYK+Eb6M+eX2pMt3MoXIurGvlrybexUTqTNubxQHWnoLqGIfqq1MWdjmGrs8A==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/loaders": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/text": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/text/-/text-6.1.2.tgz", + "integrity": "sha512-9JQ4hEanM946uMvjg4a7uIhnAoGYE6lyxwDUlHw4j/o+8jYN49STc64G+s9Rj7iRw76tudqM2ejphBE+rzC0XQ==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/sprite": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/text-bitmap": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/text-bitmap/-/text-bitmap-6.1.2.tgz", + "integrity": "sha512-QpvFC9izghqVo4zkj5mS6PmqKVtd8ArdapYxbxOVystE+gI8IKq7ZJgvvPuaj+9aqCUy20jiMPoLvfSyVGIhUg==", + "peerDependencies": { + "@pixi/core": "6.1.2", + "@pixi/display": "6.1.2", + "@pixi/loaders": "6.1.2", + "@pixi/math": "6.1.2", + "@pixi/mesh": "6.1.2", + "@pixi/settings": "6.1.2", + "@pixi/text": "6.1.2", + "@pixi/utils": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/@pixi/utils": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.1.2.tgz", + "integrity": "sha512-7lacouw8UPAQ0NbBbMEYOff/VRy0qVPV0VuAdKkmrlKu53n6NkocATnUGwdNOHmSNLMAgVu4e30ihwNORrRMAQ==", + "dependencies": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.2", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + }, + "peerDependencies": { + "@pixi/constants": "6.1.2", + "@pixi/settings": "6.1.2" + } + }, + "node_modules/pixi.js/node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + }, "node_modules/pkg-conf": { "version": "3.1.0", "dev": true, @@ -39734,10 +40668,6 @@ "decimal.js-light": "^2.4.1" } }, - "node_modules/recharts/node_modules/eventemitter3": { - "version": "4.0.7", - "license": "MIT" - }, "node_modules/recharts/node_modules/lodash": { "version": "4.17.21", "license": "MIT" @@ -50094,135 +51024,317 @@ } } }, - "@pixi/accessibility": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/app": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/canvas-display": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/canvas-extract": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/canvas-graphics": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/canvas-mesh": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/canvas-particle-container": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/canvas-prepare": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/canvas-renderer": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/canvas-sprite": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/canvas-sprite-tiling": { - "version": "6.1.2", - "requires": {} + "@pixi-spine/runtime-3.7": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.7/-/runtime-3.7-3.1.2.tgz", + "integrity": "sha512-dMcw5x9jG+0itzzbPsJUn8hvhxzRXRzbm/kCUQ51iyFfLZQIK1LoPck4XPVuXckwFjU1qCT+tDZSEGBMYs5//A==", + "requires": { + "@pixi-spine/base": "~3.1.2" + }, + "dependencies": { + "@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", + "requires": {} + }, + "@pixi/core": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", + "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", + "peer": true, + "requires": { + "@types/offscreencanvas": "^2019.6.4" + } + }, + "@pixi/display": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", + "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "peer": true, + "requires": {} + }, + "@pixi/graphics": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", + "integrity": "sha512-KPHGJ910fi8bRQQ+VcTIgrK+bKIm8yAQaZKPqMtm14HzHPGcES6HkgeNY1sd7m8J4aS9btm5wOSyFu0p5IzTpA==", + "peer": true, + "requires": {} + }, + "@pixi/mesh": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.5.10.tgz", + "integrity": "sha512-tUNPsdp5/t/yRsCmfxIcufIfbQVzgAlMNgQ1igWOkSxzhB7vlEbZ8ZLLW5tQcNyM/r7Nhjz+RoB+RD+/BCtvlA==", + "peer": true, + "requires": {} + }, + "@pixi/mesh-extras": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.5.10.tgz", + "integrity": "sha512-UCG7OOPPFeikrX09haCibCMR0jPQ4UJ+4HiYiAv/3dahq5eEzBx+yAwVtxcVCjonkTf/lu5SzmHdzpsbHLx5aw==", + "peer": true, + "requires": {} + }, + "@pixi/runner": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", + "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", + "peer": true + }, + "@pixi/settings": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", + "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", + "peer": true, + "requires": {} + }, + "@pixi/sprite": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", + "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", + "peer": true, + "requires": {} + }, + "@pixi/ticker": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", + "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", + "peer": true, + "requires": {} + }, + "@pixi/utils": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", + "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "peer": true, + "requires": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.4", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + } + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true + } + } }, - "@pixi/canvas-text": { - "version": "6.1.2", - "requires": {} + "@pixi-spine/runtime-3.8": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.8/-/runtime-3.8-3.1.2.tgz", + "integrity": "sha512-AgS3mUC+5HQ/ehJO5Wo4oBoLg8F+tssF5WXi3FnnjqOaMcO+Ag232ForoL2iYHW40TKx0xMi5MpXsSafgS1i1A==", + "requires": { + "@pixi-spine/base": "~3.1.2" + }, + "dependencies": { + "@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", + "requires": {} + }, + "@pixi/core": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", + "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", + "peer": true, + "requires": { + "@types/offscreencanvas": "^2019.6.4" + } + }, + "@pixi/display": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", + "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "peer": true, + "requires": {} + }, + "@pixi/graphics": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", + "integrity": "sha512-KPHGJ910fi8bRQQ+VcTIgrK+bKIm8yAQaZKPqMtm14HzHPGcES6HkgeNY1sd7m8J4aS9btm5wOSyFu0p5IzTpA==", + "peer": true, + "requires": {} + }, + "@pixi/mesh": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.5.10.tgz", + "integrity": "sha512-tUNPsdp5/t/yRsCmfxIcufIfbQVzgAlMNgQ1igWOkSxzhB7vlEbZ8ZLLW5tQcNyM/r7Nhjz+RoB+RD+/BCtvlA==", + "peer": true, + "requires": {} + }, + "@pixi/mesh-extras": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.5.10.tgz", + "integrity": "sha512-UCG7OOPPFeikrX09haCibCMR0jPQ4UJ+4HiYiAv/3dahq5eEzBx+yAwVtxcVCjonkTf/lu5SzmHdzpsbHLx5aw==", + "peer": true, + "requires": {} + }, + "@pixi/runner": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", + "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", + "peer": true + }, + "@pixi/settings": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", + "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", + "peer": true, + "requires": {} + }, + "@pixi/sprite": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", + "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", + "peer": true, + "requires": {} + }, + "@pixi/ticker": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", + "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", + "peer": true, + "requires": {} + }, + "@pixi/utils": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", + "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "peer": true, + "requires": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.4", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + } + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true + } + } }, - "@pixi/compressed-textures": { - "version": "6.1.2", - "requires": {} + "@pixi-spine/runtime-4.1": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-4.1/-/runtime-4.1-3.1.2.tgz", + "integrity": "sha512-XtaKAuLTtJ3o3llcUTr0d94dnRTyYHlss+x4VsYm1H38r4DUmQTBS13nisW0pgS3fY60D8AbEJkYVW7mwokxag==", + "requires": { + "@pixi-spine/base": "~3.1.2" + }, + "dependencies": { + "@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", + "requires": {} + }, + "@pixi/core": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", + "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", + "peer": true, + "requires": { + "@types/offscreencanvas": "^2019.6.4" + } + }, + "@pixi/display": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", + "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "peer": true, + "requires": {} + }, + "@pixi/graphics": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", + "integrity": "sha512-KPHGJ910fi8bRQQ+VcTIgrK+bKIm8yAQaZKPqMtm14HzHPGcES6HkgeNY1sd7m8J4aS9btm5wOSyFu0p5IzTpA==", + "peer": true, + "requires": {} + }, + "@pixi/mesh": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.5.10.tgz", + "integrity": "sha512-tUNPsdp5/t/yRsCmfxIcufIfbQVzgAlMNgQ1igWOkSxzhB7vlEbZ8ZLLW5tQcNyM/r7Nhjz+RoB+RD+/BCtvlA==", + "peer": true, + "requires": {} + }, + "@pixi/mesh-extras": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.5.10.tgz", + "integrity": "sha512-UCG7OOPPFeikrX09haCibCMR0jPQ4UJ+4HiYiAv/3dahq5eEzBx+yAwVtxcVCjonkTf/lu5SzmHdzpsbHLx5aw==", + "peer": true, + "requires": {} + }, + "@pixi/runner": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", + "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", + "peer": true + }, + "@pixi/settings": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", + "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", + "peer": true, + "requires": {} + }, + "@pixi/sprite": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", + "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", + "peer": true, + "requires": {} + }, + "@pixi/ticker": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", + "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", + "peer": true, + "requires": {} + }, + "@pixi/utils": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", + "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "peer": true, + "requires": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.4", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + } + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true + } + } }, "@pixi/constants": { - "version": "6.1.2" - }, - "@pixi/core": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/display": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/extract": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/filter-alpha": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/filter-blur": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/filter-color-matrix": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/filter-displacement": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/filter-fxaa": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/filter-noise": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/graphics": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/interaction": { - "version": "6.1.2", - "requires": {} + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.5.10.tgz", + "integrity": "sha512-PUF2Y9YISRu5eVrVVHhHCWpc/KmxQTg3UH8rIUs8UI9dCK41/wsPd3pEahzf7H47v7x1HCohVZcFO3XQc1bUDw==", + "peer": true }, - "@pixi/loaders": { - "version": "6.1.2", - "requires": {} + "@pixi/extensions": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/extensions/-/extensions-6.5.10.tgz", + "integrity": "sha512-EIUGza+E+sCy3dupuIjvRK/WyVyfSzHb5XsxRaxNrPwvG1iIUIqNqZ3owLYCo4h17fJWrj/yXVufNNtUKQccWQ==", + "peer": true }, "@pixi/math": { - "version": "6.1.2" - }, - "@pixi/mesh": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/mesh-extras": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/mixin-cache-as-bitmap": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/mixin-get-child-by-name": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/mixin-get-global-position": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/particle-container": { - "version": "6.1.2", - "requires": {} + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.5.10.tgz", + "integrity": "sha512-fxeu7ykVbMGxGV2S3qRTupHToeo1hdWBm8ihyURn3BMqJZe2SkZEECPd5RyvIuuNUtjRnmhkZRnF3Jsz2S+L0g==", + "peer": true }, "@pixi/polyfill": { "version": "6.1.2", @@ -50231,10 +51343,6 @@ "promise-polyfill": "^8.2.0" } }, - "@pixi/prepare": { - "version": "6.1.2", - "requires": {} - }, "@pixi/runner": { "version": "6.1.2" }, @@ -50244,43 +51352,10 @@ "ismobilejs": "^1.1.0" } }, - "@pixi/sprite": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/sprite-animated": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/sprite-tiling": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/spritesheet": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/text": { - "version": "6.1.2", - "requires": {} - }, - "@pixi/text-bitmap": { - "version": "6.1.2", - "requires": {} - }, "@pixi/ticker": { "version": "6.1.2", "requires": {} }, - "@pixi/utils": { - "version": "6.1.2", - "requires": { - "@types/earcut": "^2.1.0", - "earcut": "^2.2.2", - "eventemitter3": "^3.1.0", - "url": "^0.11.0" - } - }, "@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", @@ -56330,6 +57405,12 @@ "version": "4.1.3", "dev": true }, + "@types/offscreencanvas": { + "version": "2019.7.0", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz", + "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==", + "peer": true + }, "@types/overlayscrollbars": { "version": "1.12.1", "dev": true @@ -61255,7 +62336,9 @@ "dev": true }, "eventemitter3": { - "version": "3.1.2" + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, "events": { "version": "1.1.1" @@ -63093,14 +64176,6 @@ "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", "requires-port": "^1.0.0" - }, - "dependencies": { - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - } } }, "http-proxy-agent": { @@ -69411,6 +70486,136 @@ "version": "git+ssh://git@github.com/4ian/pixi-simple-gesture.git#c84e0cc3c62edeca019e708d9897ef6b97a0d18a", "from": "pixi-simple-gesture@github:4ian/pixi-simple-gesture#v0.3.3" }, + "pixi-spine": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pixi-spine/-/pixi-spine-3.1.2.tgz", + "integrity": "sha512-rTTwXhBl5gZFZ793zdM/to0bifU8K4aa1gD0ilOiCqC/pgw5OxCcKnoRW3i05ythjzI3GlN6G0MDblOe2myr3w==", + "requires": { + "@pixi-spine/base": "~3.1.2", + "@pixi-spine/loader-base": "~3.1.2", + "@pixi-spine/loader-uni": "~3.1.2", + "@pixi-spine/runtime-3.7": "~3.1.2", + "@pixi-spine/runtime-3.8": "~3.1.2", + "@pixi-spine/runtime-4.1": "~3.1.2" + }, + "dependencies": { + "@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", + "requires": {} + }, + "@pixi-spine/loader-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-base/-/loader-base-3.1.2.tgz", + "integrity": "sha512-llg0RuuWiqVkyoQA+ceORV0sfUtrWGJj4jQ6erDFn2hMnob+QGzh+qwHSTMAnTNZTINEMfiUxmcwbmUYwTd8Ag==", + "requires": { + "@pixi-spine/base": "~3.1.2" + } + }, + "@pixi-spine/loader-uni": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-uni/-/loader-uni-3.1.2.tgz", + "integrity": "sha512-5th9gXqNQWMSuOu3euMw2kHETlncxU7LIFvOYqTMsKnwrOAIsPjHSF/4Sat1d3EAvvdMrYm4LmhHklgrAfk6UA==", + "requires": { + "@pixi-spine/base": "~3.1.2", + "@pixi-spine/loader-base": "~3.1.2", + "@pixi-spine/runtime-3.7": "~3.1.2", + "@pixi-spine/runtime-3.8": "~3.1.2", + "@pixi-spine/runtime-4.1": "~3.1.2" + } + }, + "@pixi/core": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", + "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", + "peer": true, + "requires": { + "@types/offscreencanvas": "^2019.6.4" + } + }, + "@pixi/display": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", + "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "peer": true, + "requires": {} + }, + "@pixi/graphics": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", + "integrity": "sha512-KPHGJ910fi8bRQQ+VcTIgrK+bKIm8yAQaZKPqMtm14HzHPGcES6HkgeNY1sd7m8J4aS9btm5wOSyFu0p5IzTpA==", + "peer": true, + "requires": {} + }, + "@pixi/loaders": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/loaders/-/loaders-6.5.10.tgz", + "integrity": "sha512-AuK7mXBmyVsDFL9DDFPB8sqP8fwQ2NOktvu98bQuJl0/p/UeK/0OAQnF3wcf3FeBv5YGXfNHL21c2DCisjKfTg==", + "peer": true, + "requires": {} + }, + "@pixi/mesh": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.5.10.tgz", + "integrity": "sha512-tUNPsdp5/t/yRsCmfxIcufIfbQVzgAlMNgQ1igWOkSxzhB7vlEbZ8ZLLW5tQcNyM/r7Nhjz+RoB+RD+/BCtvlA==", + "peer": true, + "requires": {} + }, + "@pixi/mesh-extras": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.5.10.tgz", + "integrity": "sha512-UCG7OOPPFeikrX09haCibCMR0jPQ4UJ+4HiYiAv/3dahq5eEzBx+yAwVtxcVCjonkTf/lu5SzmHdzpsbHLx5aw==", + "peer": true, + "requires": {} + }, + "@pixi/runner": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", + "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", + "peer": true + }, + "@pixi/settings": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", + "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", + "peer": true, + "requires": {} + }, + "@pixi/sprite": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", + "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", + "peer": true, + "requires": {} + }, + "@pixi/ticker": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", + "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", + "peer": true, + "requires": {} + }, + "@pixi/utils": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", + "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "peer": true, + "requires": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.4", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + } + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true + } + } + }, "pixi.js": { "version": "6.1.2", "requires": { @@ -69449,6 +70654,202 @@ "@pixi/text-bitmap": "6.1.2", "@pixi/ticker": "6.1.2", "@pixi/utils": "6.1.2" + }, + "dependencies": { + "@pixi/accessibility": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-6.1.2.tgz", + "integrity": "sha512-riXpC4PBJYaAG5aWUZ3ud+zhF2ulqnNGCMvlcf/RfuNHlI0jd3SQ0/sxI9OwT0usnxjUDd8beDk8txJGmrX8Fw==", + "requires": {} + }, + "@pixi/app": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/app/-/app-6.1.2.tgz", + "integrity": "sha512-fv8kyFw2w8kX9UZNetlNAerM7Uszr2BSXKIMqB8lITpeE7XlnNpDussdF9z87fBjSYgMD3bdWSkhdj54QY6n9A==", + "requires": {} + }, + "@pixi/compressed-textures": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/compressed-textures/-/compressed-textures-6.1.2.tgz", + "integrity": "sha512-BcOaXKS4+6fTOnORt6o2uKUJGpwTIDhIzF+t0ekd9UGhfLykFHIALdgCYPU1e4GvtWWDfaYYhIwWWa8sX+FWTQ==", + "requires": {} + }, + "@pixi/constants": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.1.2.tgz", + "integrity": "sha512-rPHWzGDI/PKD0/p8mrsoednpDhbvfidcen2Vozz7KNO5SS/ljqyiZLEbHwYK/xhc2Z7QvXVuDuPaWl9FBCRiQg==" + }, + "@pixi/core": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.1.2.tgz", + "integrity": "sha512-S+f0qmVkrePor2XKA6A70Axo8ui+HiZgkl1J7AWVtl6MI49+3tXra9Ww3xmp/6jEdIUQyyN5sC8cg8dF/lgmBw==", + "requires": {} + }, + "@pixi/display": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.1.2.tgz", + "integrity": "sha512-JbX9GF6kOg8n8mcOFvcVZBpDRZtB/u7I+L0taOMHHtQ16bdBQ9+CxYgvOi9FLyWQNKl4utnnviQx4t8Km01POQ==", + "requires": {} + }, + "@pixi/extract": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-6.1.2.tgz", + "integrity": "sha512-1vnAOJEaaRsTWyRa4OCodVubvZ0Ib3LVkg5MFU+bDsgnczwUiZEOvtaQKOAiO1F9rEdNdvuo/TQyWlJAuHB73Q==", + "requires": {} + }, + "@pixi/filter-alpha": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-alpha/-/filter-alpha-6.1.2.tgz", + "integrity": "sha512-8qvW6FrJ8liyswfQJrFKRo679j1vhszxsa/A0unXJYGkD8fRlnoywr2gci+yEb/AyEiuwJF59v2YtWjFjkJ2fA==", + "requires": {} + }, + "@pixi/filter-blur": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-blur/-/filter-blur-6.1.2.tgz", + "integrity": "sha512-4uJUVtuiuQbPBqXwUS7aUoe8SAnjcmAwKR+KClgn/4XvwIXaULvQcmSUTyrROmWeNTGm6LgVcX4pbb8aO5lWLg==", + "requires": {} + }, + "@pixi/filter-color-matrix": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-color-matrix/-/filter-color-matrix-6.1.2.tgz", + "integrity": "sha512-xHd0OFdJr2nuqUKSjpf9W2OQwrfmQ7v00eiqeBA9azFmMJ4XmsRmAaej+mgBM2L9j4gZmbGE/5h5ZA80NCAHfg==", + "requires": {} + }, + "@pixi/filter-displacement": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-displacement/-/filter-displacement-6.1.2.tgz", + "integrity": "sha512-LOQJUfsIcgGkURT7/cqdb9sDjhGO9eQXPb8YHeMyBgKouby0On9REFbueE0cwfuY/MGcfru55JH8okcG7YXj2w==", + "requires": {} + }, + "@pixi/filter-fxaa": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-fxaa/-/filter-fxaa-6.1.2.tgz", + "integrity": "sha512-Gx2i8DCSKXhnUz0/rFsTmSaGVXl+kyZnD7/e1WojZD4M/2DPzQXqfbmi2OxsR1dyFBH6utNjmYP8xIvQ4JmSMw==", + "requires": {} + }, + "@pixi/filter-noise": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/filter-noise/-/filter-noise-6.1.2.tgz", + "integrity": "sha512-sPYw3fuxycnVa12C66RhJGeK32XXfX7ANvH5ZRf6i3NwsnmlEZfid8zrujt23xdY0UNqHxwYyg2RrQS9mLDanw==", + "requires": {} + }, + "@pixi/graphics": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.1.2.tgz", + "integrity": "sha512-aNQ9242RV3Lg4hLmU4rN9jGKhE84vjkxEWswpyqChDqh5vOeahSjZo4DR+qIsEUwEo/OgRY1kvpWY4+2xzMSjg==", + "requires": {} + }, + "@pixi/interaction": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/interaction/-/interaction-6.1.2.tgz", + "integrity": "sha512-0Hw6ZTXW8jgwq1Ek4wu+JqbSpIeOGvUR9mYuh8Ucrsi089Zavv/sOtAVVO8Zq1psFUjsU+BXSuOZmgOi2xwHFQ==", + "requires": {} + }, + "@pixi/loaders": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/loaders/-/loaders-6.1.2.tgz", + "integrity": "sha512-InzcLF6Xl9DAp8O2w93r+xEfL9tZYe+CMjVKxJCEebee8JliurRX5Tpq/POi1QwwApi5HaQdpbZ5akQGZGA/+Q==", + "requires": {} + }, + "@pixi/math": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.1.2.tgz", + "integrity": "sha512-tARAZaR01bifqQFW5P714k+Kb8KntKoxVSxbxkY58RSibpoCBFZ8ZnrlT4HY3ovIx66KhH7JJeVhCsXG2d/ggg==" + }, + "@pixi/mesh": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.1.2.tgz", + "integrity": "sha512-3aEke7cXq+EIsuVW8G/Ro5GekbZRDFSSxOtbpzNoSjNdTgnKb3OcNaaygu8tK+ZN2uXxN2u91d6f0ki8Y6VnUA==", + "requires": {} + }, + "@pixi/mesh-extras": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.1.2.tgz", + "integrity": "sha512-MtOHfbfDJ0RyNq3S1frm/+erxCyrayZFOJA0bBIFvHW5WeolAcLo+pNGlmh/1qufDTnMK3UM16mOzAz9qNA7wA==", + "requires": {} + }, + "@pixi/mixin-cache-as-bitmap": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-6.1.2.tgz", + "integrity": "sha512-8H5SZ6KTKI0WIYPNasjgGDanwUuIyyWtug/qK8j/LNuvVZmj9xfeQnih+Zi727SxKLrnD2mPWXWzSbDrp0MpnQ==", + "requires": {} + }, + "@pixi/mixin-get-child-by-name": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-6.1.2.tgz", + "integrity": "sha512-9WCGFWiY8fisUCir51Q3JKMSw16M5KSzDxAHVyNlinBv71ifH+AZgdzeogDbQf1ysP4BL2K956czPv19GbcANw==", + "requires": {} + }, + "@pixi/mixin-get-global-position": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mixin-get-global-position/-/mixin-get-global-position-6.1.2.tgz", + "integrity": "sha512-E7+yo2Cv+qrIXeH8x3tr98H4qEY3vn+IYTbJP0m7/hVA98qTOoP866MJUBNwgwtbRgNEQJwGuGs+m/yK2mcW7w==", + "requires": {} + }, + "@pixi/particle-container": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-6.1.2.tgz", + "integrity": "sha512-2IvY0nkH8tc7dY6Gk/RyCaSWaPWNEEurPeEkDYhYUcL/ktlqD65PzHQVMZ20nhW5hnHx4bn2H4S1U/5ilvg8Tg==", + "requires": {} + }, + "@pixi/prepare": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-6.1.2.tgz", + "integrity": "sha512-qHoS/knfchT7ZvpV1MwJQaS5zb8uvlO2paKRLN76aZR4dHKCpRzVWHJ+5EuSEacbbzX8ElBMTCI0iV1V7L1Jiw==", + "requires": {} + }, + "@pixi/sprite": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.1.2.tgz", + "integrity": "sha512-AzK2UW+VcZ+6sKW++9qokhSMFG35zSAOpRoWk5QgRhbVkdh2L0BB7nK5Z8PZgqmTGCzSq2NvVlzosryPWmLMNw==", + "requires": {} + }, + "@pixi/sprite-animated": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite-animated/-/sprite-animated-6.1.2.tgz", + "integrity": "sha512-jriUtbIw1v0AB3sIObM1t7eAIPuB4gtokao6k09EURMepoCQJlYSKIq5FVlmLYU/zf1t7/f/dtpZ65UEKXDytw==", + "requires": {} + }, + "@pixi/sprite-tiling": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-6.1.2.tgz", + "integrity": "sha512-6tOlag2M+bn5aNPi/iyORY/IqB9Gfan5MnaG3HarfZdSlSwQH0yklDePBrG2DQ/X6Rmb94DJd0PxJdCujtFJTg==", + "requires": {} + }, + "@pixi/spritesheet": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/spritesheet/-/spritesheet-6.1.2.tgz", + "integrity": "sha512-PP+sChFaE8vK0PHwChKYeDuFSvYK+Eb6M+eX2pMt3MoXIurGvlrybexUTqTNubxQHWnoLqGIfqq1MWdjmGrs8A==", + "requires": {} + }, + "@pixi/text": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/text/-/text-6.1.2.tgz", + "integrity": "sha512-9JQ4hEanM946uMvjg4a7uIhnAoGYE6lyxwDUlHw4j/o+8jYN49STc64G+s9Rj7iRw76tudqM2ejphBE+rzC0XQ==", + "requires": {} + }, + "@pixi/text-bitmap": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/text-bitmap/-/text-bitmap-6.1.2.tgz", + "integrity": "sha512-QpvFC9izghqVo4zkj5mS6PmqKVtd8ArdapYxbxOVystE+gI8IKq7ZJgvvPuaj+9aqCUy20jiMPoLvfSyVGIhUg==", + "requires": {} + }, + "@pixi/utils": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.1.2.tgz", + "integrity": "sha512-7lacouw8UPAQ0NbBbMEYOff/VRy0qVPV0VuAdKkmrlKu53n6NkocATnUGwdNOHmSNLMAgVu4e30ihwNORrRMAQ==", + "requires": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.2", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + } + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + } } }, "pixi.js-legacy": { @@ -69465,6 +70866,168 @@ "@pixi/canvas-sprite-tiling": "6.1.2", "@pixi/canvas-text": "6.1.2", "pixi.js": "6.1.2" + }, + "dependencies": { + "@pixi/canvas-display": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-display/-/canvas-display-6.1.2.tgz", + "integrity": "sha512-UWLfqDFs0H+KUw1jp+PczCJ0VCQ5BQij9JWsSCvFSM/0ZFLdWctlQjUYMimrQhLgyqYEDV6QsqXZOginbN4uvA==", + "requires": {} + }, + "@pixi/canvas-extract": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-extract/-/canvas-extract-6.1.2.tgz", + "integrity": "sha512-d2XvW8dlg7kIyXV6BfEjViUzGfd1ZAjP61e5zLKxs62kXhy4qEQb2J8J80bfPEEBivJ7Uj+ozdLlt/ZwuYVo1Q==", + "requires": {} + }, + "@pixi/canvas-graphics": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-graphics/-/canvas-graphics-6.1.2.tgz", + "integrity": "sha512-cgsDUWAcp03fpdsb5EET+XflQjcrfri0ubaebKlvb9Whv2tv/+ZUI/WFv900F0GSNtS/H/AMSwlPykZIqtzRYw==", + "requires": {} + }, + "@pixi/canvas-mesh": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-mesh/-/canvas-mesh-6.1.2.tgz", + "integrity": "sha512-WKFEiTfHUkeszL+LqtmA5aAno79msxm8Eo5tqANzpQm27J7OEpF3KySnUSJ/LP+A4Rdbt2YGPF4jzuLezBalTA==", + "requires": {} + }, + "@pixi/canvas-particle-container": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-particle-container/-/canvas-particle-container-6.1.2.tgz", + "integrity": "sha512-IPUCzU+WAI0d0XkfrpkaehYDkkuUfxUUdE8QSEZx9xQNljeKIgQVL3Muv35IWhxjJ3PkaJ26ad+4brXxTHHPsg==", + "requires": {} + }, + "@pixi/canvas-prepare": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-prepare/-/canvas-prepare-6.1.2.tgz", + "integrity": "sha512-YmAgQmuIebi3IiPpuxKd05qhJ+WL8MpH0lTxNSpV+Vcrsn6eDRyVMBW0asji4SAQqDmH+xwSePLkr9MH8OvQhg==", + "requires": {} + }, + "@pixi/canvas-renderer": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-renderer/-/canvas-renderer-6.1.2.tgz", + "integrity": "sha512-pSO+K9yZcly2hyvVCfAU0SlmVztdxEl7Hji4h9Sj/iNyNXl77vWNYW8u+69IwWpXAq6WVxmaJBNCYdg47DzBIA==", + "requires": {} + }, + "@pixi/canvas-sprite": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-sprite/-/canvas-sprite-6.1.2.tgz", + "integrity": "sha512-HJpcU2WZOOlRtpZpdCOzqu0Y2xg2C7tLy556ynpxiPV5KrC+T3lNlFwZoLddPCCoVo5ph3K+Hb090SnfsY1v0Q==", + "requires": {} + }, + "@pixi/canvas-sprite-tiling": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-sprite-tiling/-/canvas-sprite-tiling-6.1.2.tgz", + "integrity": "sha512-MYHOXarrlvqRiAfdjHoVYD4HOKT/ij0MejXbw/3vQmBUM9e9tDm46TFSc5FysEDqJ2ts0C/PTACR3wqL++ZNlw==", + "requires": {} + }, + "@pixi/canvas-text": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/canvas-text/-/canvas-text-6.1.2.tgz", + "integrity": "sha512-73MX5hNiCvtAosdOHPJ7QHE6/0YVkpgXDA9DR0Z5OpFg9Hncj350x60n6Vbe6178A1u8itXHp7CJ0Iw8nTN2hw==", + "requires": {} + }, + "@pixi/constants": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.1.2.tgz", + "integrity": "sha512-rPHWzGDI/PKD0/p8mrsoednpDhbvfidcen2Vozz7KNO5SS/ljqyiZLEbHwYK/xhc2Z7QvXVuDuPaWl9FBCRiQg==", + "peer": true + }, + "@pixi/core": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.1.2.tgz", + "integrity": "sha512-S+f0qmVkrePor2XKA6A70Axo8ui+HiZgkl1J7AWVtl6MI49+3tXra9Ww3xmp/6jEdIUQyyN5sC8cg8dF/lgmBw==", + "peer": true, + "requires": {} + }, + "@pixi/display": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.1.2.tgz", + "integrity": "sha512-JbX9GF6kOg8n8mcOFvcVZBpDRZtB/u7I+L0taOMHHtQ16bdBQ9+CxYgvOi9FLyWQNKl4utnnviQx4t8Km01POQ==", + "peer": true, + "requires": {} + }, + "@pixi/graphics": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.1.2.tgz", + "integrity": "sha512-aNQ9242RV3Lg4hLmU4rN9jGKhE84vjkxEWswpyqChDqh5vOeahSjZo4DR+qIsEUwEo/OgRY1kvpWY4+2xzMSjg==", + "peer": true, + "requires": {} + }, + "@pixi/math": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.1.2.tgz", + "integrity": "sha512-tARAZaR01bifqQFW5P714k+Kb8KntKoxVSxbxkY58RSibpoCBFZ8ZnrlT4HY3ovIx66KhH7JJeVhCsXG2d/ggg==", + "peer": true + }, + "@pixi/mesh": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.1.2.tgz", + "integrity": "sha512-3aEke7cXq+EIsuVW8G/Ro5GekbZRDFSSxOtbpzNoSjNdTgnKb3OcNaaygu8tK+ZN2uXxN2u91d6f0ki8Y6VnUA==", + "peer": true, + "requires": {} + }, + "@pixi/mesh-extras": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.1.2.tgz", + "integrity": "sha512-MtOHfbfDJ0RyNq3S1frm/+erxCyrayZFOJA0bBIFvHW5WeolAcLo+pNGlmh/1qufDTnMK3UM16mOzAz9qNA7wA==", + "peer": true, + "requires": {} + }, + "@pixi/particle-container": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-6.1.2.tgz", + "integrity": "sha512-2IvY0nkH8tc7dY6Gk/RyCaSWaPWNEEurPeEkDYhYUcL/ktlqD65PzHQVMZ20nhW5hnHx4bn2H4S1U/5ilvg8Tg==", + "peer": true, + "requires": {} + }, + "@pixi/prepare": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-6.1.2.tgz", + "integrity": "sha512-qHoS/knfchT7ZvpV1MwJQaS5zb8uvlO2paKRLN76aZR4dHKCpRzVWHJ+5EuSEacbbzX8ElBMTCI0iV1V7L1Jiw==", + "peer": true, + "requires": {} + }, + "@pixi/sprite": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.1.2.tgz", + "integrity": "sha512-AzK2UW+VcZ+6sKW++9qokhSMFG35zSAOpRoWk5QgRhbVkdh2L0BB7nK5Z8PZgqmTGCzSq2NvVlzosryPWmLMNw==", + "peer": true, + "requires": {} + }, + "@pixi/sprite-tiling": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-6.1.2.tgz", + "integrity": "sha512-6tOlag2M+bn5aNPi/iyORY/IqB9Gfan5MnaG3HarfZdSlSwQH0yklDePBrG2DQ/X6Rmb94DJd0PxJdCujtFJTg==", + "peer": true, + "requires": {} + }, + "@pixi/text": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/text/-/text-6.1.2.tgz", + "integrity": "sha512-9JQ4hEanM946uMvjg4a7uIhnAoGYE6lyxwDUlHw4j/o+8jYN49STc64G+s9Rj7iRw76tudqM2ejphBE+rzC0XQ==", + "peer": true, + "requires": {} + }, + "@pixi/utils": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.1.2.tgz", + "integrity": "sha512-7lacouw8UPAQ0NbBbMEYOff/VRy0qVPV0VuAdKkmrlKu53n6NkocATnUGwdNOHmSNLMAgVu4e30ihwNORrRMAQ==", + "peer": true, + "requires": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.2", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + } + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true + } } }, "pkg-conf": { @@ -73002,9 +74565,6 @@ "reduce-css-calc": "^2.1.8" }, "dependencies": { - "eventemitter3": { - "version": "4.0.7" - }, "lodash": { "version": "4.17.21" } diff --git a/newIDE/app/package.json b/newIDE/app/package.json index ee205d231e36..e3f671b8c91d 100644 --- a/newIDE/app/package.json +++ b/newIDE/app/package.json @@ -55,6 +55,7 @@ "lodash": "4.17.4", "node-require-function": "^1.2.0", "pixi-simple-gesture": "github:4ian/pixi-simple-gesture#v0.3.3", + "pixi-spine": "^3.0.0", "pixi.js-legacy": "6.1.2", "posthog-js": "^1.57.2", "prop-types": "^15.5.10", diff --git a/newIDE/app/src/AssetStore/InstallAsset.js b/newIDE/app/src/AssetStore/InstallAsset.js index b99e16209379..ff5c3da0ed5c 100644 --- a/newIDE/app/src/AssetStore/InstallAsset.js +++ b/newIDE/app/src/AssetStore/InstallAsset.js @@ -121,6 +121,8 @@ export const installResource = ( newResource = new gd.JsonResource(); } else if (serializedResource.kind === 'model3D') { newResource = new gd.Model3DResource(); + } else if (serializedResource.kind === 'atlas') { + newResource = new gd.AtlasResource(); } else { throw new Error( `Resource of kind "${serializedResource.kind}" is not supported.` diff --git a/newIDE/app/src/AssetStore/ResourceStore/ResourceCard.js b/newIDE/app/src/AssetStore/ResourceStore/ResourceCard.js index 9784869d7e3a..fa03afa345e3 100644 --- a/newIDE/app/src/AssetStore/ResourceStore/ResourceCard.js +++ b/newIDE/app/src/AssetStore/ResourceStore/ResourceCard.js @@ -221,6 +221,17 @@ export const ResourceCard = ({ resource, onChoose, size }: Props) => { ); + case 'atlas': + return ( + + + + + + Choose} /> + + + ); default: return null; } diff --git a/newIDE/app/src/EventsSheet/ParameterFields/AtlasResourceField.js b/newIDE/app/src/EventsSheet/ParameterFields/AtlasResourceField.js new file mode 100644 index 000000000000..f8515e2a6296 --- /dev/null +++ b/newIDE/app/src/EventsSheet/ParameterFields/AtlasResourceField.js @@ -0,0 +1,51 @@ +// @flow +import { Trans } from '@lingui/macro'; + +import * as React from 'react'; +import ResourceSelector, { + type ResourceSelectorInterface, +} from '../../ResourcesList/ResourceSelector'; +import ResourcesLoader from '../../ResourcesLoader'; +import { + type ParameterFieldProps, + type ParameterFieldInterface, + type FieldFocusFunction, +} from './ParameterFieldCommons'; + +export default React.forwardRef( + function AtlasResourceField(props: ParameterFieldProps, ref) { + const field = React.useRef(null); + const focus: FieldFocusFunction = options => { + if (field.current) field.current.focus(options); + }; + React.useImperativeHandle(ref, () => ({ + focus, + })); + + if (!props.resourceManagementProps || !props.project) { + console.error( + 'Missing project or resourceManagementProps for AtlasResourceField' + ); + return null; + } + + return ( + Choose the atlas file (.atlas) to use + } + onRequestClose={props.onRequestClose} + onApply={props.onApply} + ref={field} + /> + ); + } +); diff --git a/newIDE/app/src/EventsSheet/ParameterRenderingService.js b/newIDE/app/src/EventsSheet/ParameterRenderingService.js index 176e9e69662a..0c049a99dc0e 100644 --- a/newIDE/app/src/EventsSheet/ParameterRenderingService.js +++ b/newIDE/app/src/EventsSheet/ParameterRenderingService.js @@ -64,6 +64,7 @@ import IdentifierField from './ParameterFields/IdentifierField'; import TilemapResourceField from './ParameterFields/TilemapResourceField'; import TilesetResourceField from './ParameterFields/TilesetResourceField'; import Model3DResourceField from './ParameterFields/Model3DResourceField'; +import AtlasResourceField from './ParameterFields/AtlasResourceField'; const gd: libGDevelop = global.gd; @@ -94,6 +95,7 @@ const components = { bitmapFontResource: BitmapFontResourceField, fontResource: FontResourceField, model3DResource: Model3DResourceField, + atlasResource: AtlasResourceField, color: ColorExpressionField, police: DefaultField, //TODO forceMultiplier: ForceMultiplierField, @@ -151,7 +153,7 @@ const userFriendlyTypeName: { [string]: MessageDescriptor } = { fontResource: t`Font resource`, jsonResource: t`JSON resource`, tilemapResource: t`Tile map resource`, - model3DResource: t`3D model resource`, + atlasResource: t`Atlas resource`, color: t`Color`, forceMultiplier: t`Instant or permanent force`, sceneName: t`Scene name`, diff --git a/newIDE/app/src/JsExtensionsLoader/BrowserJsExtensionsLoader.js b/newIDE/app/src/JsExtensionsLoader/BrowserJsExtensionsLoader.js index a98faf5762d3..4f0056b50a6b 100644 --- a/newIDE/app/src/JsExtensionsLoader/BrowserJsExtensionsLoader.js +++ b/newIDE/app/src/JsExtensionsLoader/BrowserJsExtensionsLoader.js @@ -171,6 +171,12 @@ const jsExtensions = [ extensionModule: require('GDJS-for-web-app-only/Runtime/Extensions/3D/JsExtension.js'), objectsRenderingServiceModules: {}, }, + { + name: 'Spine', + // $FlowExpectedError - this path is ignored for Flow. + extensionModule: require('GDJS-for-web-app-only/Runtime/Extensions/Spine/JsExtension.js'), + objectsRenderingServiceModules: {}, + }, ]; type MakeExtensionsLoaderArguments = {| diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 1c28884f49d8..96567ac259f8 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -530,4 +530,38 @@ export default class PixiResourcesLoader { }) .then(response => response.data); } + + static getResourceAtlasData( + project: gdProject, + resourceName: string + ): Promise { + if (!project.getResourcesManager().hasResource(resourceName)) { + return Promise.reject(`Unknown atlas file ${resourceName}.`); + } + + const resource = project.getResourcesManager().getResource(resourceName); + if (resource.getKind() !== 'atlas') { + return Promise.reject(`The resource called ${resourceName} is not a json file.`); + } + + const url = ResourcesLoader.getResourceFullUrl(project, resourceName, { + isResourceForPixi: true, + }); + + // const gltfLoader = getOrCreateGltfLoader(); + // gltfLoader.withCredentials = checkIfCredentialsRequired(url); + // return new Promise((resolve, reject) => { + // gltfLoader.load( + // url, + // gltf => { + // traverseToSetBasicMaterialFromMeshes(gltf.scene); + // resolve(gltf); + // }, + // undefined, + // error => { + // reject(error); + // } + // ); + // }); + } } diff --git a/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.js b/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.js index 372b907aa41d..f2c9c2b6c073 100644 --- a/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.js +++ b/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.js @@ -40,6 +40,7 @@ const resourceKindToInputAcceptedMimes = { tileset: ['application/json'], bitmapFont: [], model3D: ['model/gltf-binary'], + atlas: [], }; export const getInputAcceptedMimesAndExtensions = ( diff --git a/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.spec.js b/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.spec.js index e5f11ab6c824..9f757b6989cd 100644 --- a/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.spec.js +++ b/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.spec.js @@ -31,5 +31,8 @@ describe('FileToCloudProjectResourceUploader', () => { expect(getInputAcceptedMimesAndExtensions('model3D')).toMatchInlineSnapshot( `"model/gltf-binary,.glb"` ); + expect(getInputAcceptedMimesAndExtensions('atlas')).toMatchInlineSnapshot( + `".atlas"` + ); }); }); diff --git a/newIDE/app/src/ResourcesList/ResourcePreview/index.js b/newIDE/app/src/ResourcesList/ResourcePreview/index.js index 39e4068e2283..0ac244914758 100644 --- a/newIDE/app/src/ResourcesList/ResourcePreview/index.js +++ b/newIDE/app/src/ResourcesList/ResourcePreview/index.js @@ -76,6 +76,7 @@ export default class ResourcePreview extends React.PureComponent { case 'tilemap': case 'tileset': case 'model3D': + case 'atlas': return } />; case 'video': return ( diff --git a/newIDE/app/src/ResourcesList/ResourceSource.js b/newIDE/app/src/ResourcesList/ResourceSource.js index 8d1c43295f80..93511809648a 100644 --- a/newIDE/app/src/ResourcesList/ResourceSource.js +++ b/newIDE/app/src/ResourcesList/ResourceSource.js @@ -24,7 +24,8 @@ export type ResourceKind = | 'tilemap' | 'tileset' | 'bitmapFont' - | 'model3D'; + | 'model3D' + | 'atlas'; export const allResourceKindsAndMetadata = [ { @@ -81,6 +82,12 @@ export const allResourceKindsAndMetadata = [ fileExtensions: ['glb'], createNewResource: () => new gd.Model3DResource(), }, + { + kind: 'Atlas', + displayName: t`Atlas`, + fileExtensions: ['atlas'], + createNewResource: () => new gd.AtlasResource(), + }, ]; const constructors = {}; diff --git a/newIDE/app/src/stories/componentStories/AssetStore/ResourceStore/ResourceStore.stories.js b/newIDE/app/src/stories/componentStories/AssetStore/ResourceStore/ResourceStore.stories.js index c6e0aee1945b..11928106df3a 100644 --- a/newIDE/app/src/stories/componentStories/AssetStore/ResourceStore/ResourceStore.stories.js +++ b/newIDE/app/src/stories/componentStories/AssetStore/ResourceStore/ResourceStore.stories.js @@ -53,3 +53,11 @@ export const Model3DResource = () => ( ); + +export const AtlasResource = () => ( + + + + + +); diff --git a/newIDE/app/src/stories/componentStories/ParameterFields/ResourceFields.stories.js b/newIDE/app/src/stories/componentStories/ParameterFields/ResourceFields.stories.js index 71fd5493859a..d0e690f107c3 100644 --- a/newIDE/app/src/stories/componentStories/ParameterFields/ResourceFields.stories.js +++ b/newIDE/app/src/stories/componentStories/ParameterFields/ResourceFields.stories.js @@ -18,6 +18,7 @@ import FontResourceField from '../../../EventsSheet/ParameterFields/FontResource import JsonResourceField from '../../../EventsSheet/ParameterFields/JsonResourceField'; import TilemapResourceField from '../../../EventsSheet/ParameterFields/TilemapResourceField'; import Model3DResourceField from '../../../EventsSheet/ParameterFields/Model3DResourceField'; +import AtlasResourceField from '../../../EventsSheet/ParameterFields/AtlasResourceField'; export const AllResourceFields = () => ( @@ -157,6 +158,23 @@ export const AllResourceFields = () => ( )} /> + + ( + + )} + /> + ); diff --git a/newIDE/electron-app/app/package-lock.json b/newIDE/electron-app/app/package-lock.json index dd80bbe76a1e..2152420aa4cd 100644 --- a/newIDE/electron-app/app/package-lock.json +++ b/newIDE/electron-app/app/package-lock.json @@ -1,12 +1,12 @@ { "name": "gdevelop", - "version": "5.2.166", + "version": "5.2.167", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gdevelop", - "version": "5.2.166", + "version": "5.2.167", "license": "MIT", "dependencies": { "@electron/remote": "^2.0.8", diff --git a/newIDE/electron-app/yarn.lock b/newIDE/electron-app/yarn.lock index a6340f26c1a5..5bd050682487 100644 --- a/newIDE/electron-app/yarn.lock +++ b/newIDE/electron-app/yarn.lock @@ -3,1674 +3,1780 @@ "@develar/schema-utils@~2.6.5": - version "2.6.5" - resolved "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz" - integrity sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig== + "integrity" "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==" + "resolved" "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz" + "version" "2.6.5" dependencies: - ajv "^6.12.0" - ajv-keywords "^3.4.1" + "ajv" "^6.12.0" + "ajv-keywords" "^3.4.1" "@electron/get@^1.13.0": - version "1.14.1" - resolved "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz" - integrity sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw== - dependencies: - debug "^4.1.1" - env-paths "^2.2.0" - fs-extra "^8.1.0" - got "^9.6.0" - progress "^2.0.3" - semver "^6.2.0" - sumchecker "^3.0.1" + "integrity" "sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw==" + "resolved" "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz" + "version" "1.14.1" + dependencies: + "debug" "^4.1.1" + "env-paths" "^2.2.0" + "fs-extra" "^8.1.0" + "got" "^9.6.0" + "progress" "^2.0.3" + "semver" "^6.2.0" + "sumchecker" "^3.0.1" optionalDependencies: - global-agent "^3.0.0" - global-tunnel-ng "^2.7.1" + "global-agent" "^3.0.0" + "global-tunnel-ng" "^2.7.1" "@electron/remote@^2.0.8": - version "2.0.8" - resolved "https://registry.npmjs.org/@electron/remote/-/remote-2.0.8.tgz" - integrity sha512-P10v3+iFCIvEPeYzTWWGwwHmqWnjoh8RYnbtZAb3RlQefy4guagzIwcWtfftABIfm6JJTNQf4WPSKWZOpLmHXw== + "integrity" "sha512-P10v3+iFCIvEPeYzTWWGwwHmqWnjoh8RYnbtZAb3RlQefy4guagzIwcWtfftABIfm6JJTNQf4WPSKWZOpLmHXw==" + "resolved" "https://registry.npmjs.org/@electron/remote/-/remote-2.0.8.tgz" + "version" "2.0.8" "@electron/universal@1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@electron/universal/-/universal-1.2.1.tgz" - integrity sha512-7323HyMh7KBAl/nPDppdLsC87G6RwRU02dy5FPeGB1eS7rUePh55+WNWiDPLhFQqqVPHzh77M69uhmoT8XnwMQ== + "integrity" "sha512-7323HyMh7KBAl/nPDppdLsC87G6RwRU02dy5FPeGB1eS7rUePh55+WNWiDPLhFQqqVPHzh77M69uhmoT8XnwMQ==" + "resolved" "https://registry.npmjs.org/@electron/universal/-/universal-1.2.1.tgz" + "version" "1.2.1" dependencies: "@malept/cross-spawn-promise" "^1.1.0" - asar "^3.1.0" - debug "^4.3.1" - dir-compare "^2.4.0" - fs-extra "^9.0.1" - minimatch "^3.0.4" - plist "^3.0.4" + "asar" "^3.1.0" + "debug" "^4.3.1" + "dir-compare" "^2.4.0" + "fs-extra" "^9.0.1" + "minimatch" "^3.0.4" + "plist" "^3.0.4" "@malept/cross-spawn-promise@^1.1.0": - version "1.1.1" - resolved "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz" - integrity sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ== + "integrity" "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==" + "resolved" "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz" + "version" "1.1.1" dependencies: - cross-spawn "^7.0.1" + "cross-spawn" "^7.0.1" "@malept/flatpak-bundler@^0.4.0": - version "0.4.0" - resolved "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz" - integrity sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q== + "integrity" "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==" + "resolved" "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz" + "version" "0.4.0" dependencies: - debug "^4.1.1" - fs-extra "^9.0.0" - lodash "^4.17.15" - tmp-promise "^3.0.2" + "debug" "^4.1.1" + "fs-extra" "^9.0.0" + "lodash" "^4.17.15" + "tmp-promise" "^3.0.2" "@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + "integrity" "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" + "resolved" "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz" + "version" "0.14.0" "@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + "integrity" "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==" + "resolved" "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz" + "version" "1.1.2" dependencies: - defer-to-connect "^1.0.1" + "defer-to-connect" "^1.0.1" "@tootallnate/once@2": - version "2.0.0" - resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" - integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + "integrity" "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" + "resolved" "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" + "version" "2.0.0" "@types/debug@^4.1.6": - version "4.1.7" - resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== + "integrity" "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==" + "resolved" "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz" + "version" "4.1.7" dependencies: "@types/ms" "*" "@types/fs-extra@^9.0.11": - version "9.0.13" - resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz" - integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== + "integrity" "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==" + "resolved" "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz" + "version" "9.0.13" dependencies: "@types/node" "*" "@types/glob@^7.1.1": - version "7.2.0" - resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + "integrity" "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==" + "resolved" "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" + "version" "7.2.0" dependencies: "@types/minimatch" "*" "@types/node" "*" "@types/minimatch@*": - version "5.1.2" - resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== + "integrity" "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==" + "resolved" "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz" + "version" "5.1.2" "@types/ms@*": - version "0.7.31" - resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + "integrity" "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" + "resolved" "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" + "version" "0.7.31" "@types/node@*", "@types/node@^16.11.26": - version "16.11.33" - resolved "https://registry.npmjs.org/@types/node/-/node-16.11.33.tgz" - integrity sha512-0PJ0vg+JyU0MIan58IOIFRtSvsb7Ri+7Wltx2qAg94eMOrpg4+uuP3aUHCpxXc1i0jCXiC+zIamSZh3l9AbcQA== + "integrity" "sha512-0PJ0vg+JyU0MIan58IOIFRtSvsb7Ri+7Wltx2qAg94eMOrpg4+uuP3aUHCpxXc1i0jCXiC+zIamSZh3l9AbcQA==" + "resolved" "https://registry.npmjs.org/@types/node/-/node-16.11.33.tgz" + "version" "16.11.33" + +"@types/plist@^3.0.1": + "integrity" "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==" + "resolved" "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "@types/node" "*" + "xmlbuilder" ">=11.0.1" + +"@types/verror@^1.10.3": + "integrity" "sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==" + "resolved" "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz" + "version" "1.10.6" "@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + "integrity" "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" + "resolved" "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz" + "version" "21.0.0" "@types/yargs@^17.0.1": - version "17.0.10" - resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz" - integrity sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA== + "integrity" "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==" + "resolved" "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz" + "version" "17.0.10" dependencies: "@types/yargs-parser" "*" "7zip-bin@~5.1.1": - version "5.1.1" - resolved "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz" - integrity sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ== - -adm-zip@^0.5.10: - version "0.5.10" - resolved "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz" - integrity sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ== - -agent-base@6: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -ajv-keywords@^3.4.1: - version "3.5.2" - resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv@^6.12.0, ajv@^6.9.1: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -app-builder-bin@4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz" - integrity sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA== - -app-builder-lib@23.6.0: - version "23.6.0" - resolved "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.6.0.tgz" - integrity sha512-dQYDuqm/rmy8GSCE6Xl/3ShJg6Ab4bZJMT8KaTKGzT436gl1DN4REP3FCWfXoh75qGTJ+u+WsdnnpO9Jl8nyMA== + "integrity" "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==" + "resolved" "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz" + "version" "5.1.1" + +"adm-zip@^0.5.10": + "integrity" "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==" + "resolved" "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz" + "version" "0.5.10" + +"agent-base@6": + "integrity" "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==" + "resolved" "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + "version" "6.0.2" + dependencies: + "debug" "4" + +"ajv-keywords@^3.4.1": + "integrity" "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + "resolved" "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" + "version" "3.5.2" + +"ajv@^6.10.0", "ajv@^6.12.0", "ajv@^6.9.1": + "integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==" + "resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + "version" "6.12.6" + dependencies: + "fast-deep-equal" "^3.1.1" + "fast-json-stable-stringify" "^2.0.0" + "json-schema-traverse" "^0.4.1" + "uri-js" "^4.2.2" + +"ansi-regex@^5.0.1": + "integrity" "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + "version" "5.0.1" + +"ansi-styles@^4.0.0", "ansi-styles@^4.1.0": + "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + "version" "4.3.0" + dependencies: + "color-convert" "^2.0.1" + +"app-builder-bin@4.0.0": + "integrity" "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==" + "resolved" "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz" + "version" "4.0.0" + +"app-builder-lib@23.6.0": + "integrity" "sha512-dQYDuqm/rmy8GSCE6Xl/3ShJg6Ab4bZJMT8KaTKGzT436gl1DN4REP3FCWfXoh75qGTJ+u+WsdnnpO9Jl8nyMA==" + "resolved" "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.6.0.tgz" + "version" "23.6.0" dependencies: "@develar/schema-utils" "~2.6.5" "@electron/universal" "1.2.1" "@malept/flatpak-bundler" "^0.4.0" "7zip-bin" "~5.1.1" - async-exit-hook "^2.0.1" - bluebird-lst "^1.0.9" - builder-util "23.6.0" - builder-util-runtime "9.1.1" - chromium-pickle-js "^0.2.0" - debug "^4.3.4" - ejs "^3.1.7" - electron-osx-sign "^0.6.0" - electron-publish "23.6.0" - form-data "^4.0.0" - fs-extra "^10.1.0" - hosted-git-info "^4.1.0" - is-ci "^3.0.0" - isbinaryfile "^4.0.10" - js-yaml "^4.1.0" - lazy-val "^1.0.5" - minimatch "^3.1.2" - read-config-file "6.2.0" - sanitize-filename "^1.6.3" - semver "^7.3.7" - tar "^6.1.11" - temp-file "^3.4.0" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -asar@^3.1.0: - version "3.2.0" - resolved "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz" - integrity sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg== - dependencies: - chromium-pickle-js "^0.2.0" - commander "^5.0.0" - glob "^7.1.6" - minimatch "^3.0.4" + "async-exit-hook" "^2.0.1" + "bluebird-lst" "^1.0.9" + "builder-util" "23.6.0" + "builder-util-runtime" "9.1.1" + "chromium-pickle-js" "^0.2.0" + "debug" "^4.3.4" + "ejs" "^3.1.7" + "electron-osx-sign" "^0.6.0" + "electron-publish" "23.6.0" + "form-data" "^4.0.0" + "fs-extra" "^10.1.0" + "hosted-git-info" "^4.1.0" + "is-ci" "^3.0.0" + "isbinaryfile" "^4.0.10" + "js-yaml" "^4.1.0" + "lazy-val" "^1.0.5" + "minimatch" "^3.1.2" + "read-config-file" "6.2.0" + "sanitize-filename" "^1.6.3" + "semver" "^7.3.7" + "tar" "^6.1.11" + "temp-file" "^3.4.0" + +"argparse@^2.0.1": + "integrity" "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "resolved" "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + "version" "2.0.1" + +"asar@^3.1.0": + "integrity" "sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==" + "resolved" "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz" + "version" "3.2.0" + dependencies: + "chromium-pickle-js" "^0.2.0" + "commander" "^5.0.0" + "glob" "^7.1.6" + "minimatch" "^3.0.4" optionalDependencies: "@types/glob" "^7.1.1" -async-exit-hook@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz" - integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw== - -async@^3.2.3: - version "3.2.4" - resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.5.1: - version "1.5.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bluebird-lst@^1.0.9: - version "1.0.9" - resolved "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz" - integrity sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw== - dependencies: - bluebird "^3.5.5" - -bluebird@^3.5.0, bluebird@^3.5.5: - version "3.7.2" - resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -boolean@^3.0.1: - version "3.2.0" - resolved "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz" - integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - -buffer-crc32@~0.2.3: - version "0.2.13" - resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" - integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= - -buffer-equal@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz" - integrity sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ== - -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz" - integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -builder-util-runtime@9.1.1: - version "9.1.1" - resolved "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz" - integrity sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw== - dependencies: - debug "^4.3.4" - sax "^1.2.4" - -builder-util@23.6.0: - version "23.6.0" - resolved "https://registry.npmjs.org/builder-util/-/builder-util-23.6.0.tgz" - integrity sha512-QiQHweYsh8o+U/KNCZFSvISRnvRctb8m/2rB2I1JdByzvNKxPeFLlHFRPQRXab6aYeXc18j9LpsDLJ3sGQmWTQ== +"assert-plus@^1.0.0": + "integrity" "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "resolved" "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + "version" "1.0.0" + +"astral-regex@^2.0.0": + "integrity" "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + "resolved" "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" + "version" "2.0.0" + +"async-exit-hook@^2.0.1": + "integrity" "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==" + "resolved" "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz" + "version" "2.0.1" + +"async@^3.2.3": + "integrity" "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + "resolved" "https://registry.npmjs.org/async/-/async-3.2.4.tgz" + "version" "3.2.4" + +"asynckit@^0.4.0": + "integrity" "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "resolved" "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + "version" "0.4.0" + +"at-least-node@^1.0.0": + "integrity" "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + "resolved" "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" + "version" "1.0.0" + +"balanced-match@^1.0.0": + "integrity" "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" + "version" "1.0.0" + +"base64-js@^1.3.1", "base64-js@^1.5.1": + "integrity" "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "resolved" "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + "version" "1.5.1" + +"bluebird-lst@^1.0.9": + "integrity" "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==" + "resolved" "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz" + "version" "1.0.9" + dependencies: + "bluebird" "^3.5.5" + +"bluebird@^3.5.0", "bluebird@^3.5.5": + "integrity" "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + "resolved" "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" + "version" "3.7.2" + +"boolean@^3.0.1": + "integrity" "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==" + "resolved" "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz" + "version" "3.2.0" + +"brace-expansion@^1.1.7": + "integrity" "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==" + "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + "version" "1.1.11" + dependencies: + "balanced-match" "^1.0.0" + "concat-map" "0.0.1" + +"brace-expansion@^2.0.1": + "integrity" "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==" + "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "balanced-match" "^1.0.0" + +"buffer-alloc-unsafe@^1.1.0": + "integrity" "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + "resolved" "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz" + "version" "1.1.0" + +"buffer-alloc@^1.2.0": + "integrity" "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==" + "resolved" "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz" + "version" "1.2.0" + dependencies: + "buffer-alloc-unsafe" "^1.1.0" + "buffer-fill" "^1.0.0" + +"buffer-crc32@~0.2.3": + "integrity" "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + "resolved" "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" + "version" "0.2.13" + +"buffer-equal@1.0.0": + "integrity" "sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==" + "resolved" "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz" + "version" "1.0.0" + +"buffer-fill@^1.0.0": + "integrity" "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" + "resolved" "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz" + "version" "1.0.0" + +"buffer-from@^1.0.0": + "integrity" "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + "version" "1.1.2" + +"buffer@^5.1.0": + "integrity" "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==" + "resolved" "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" + "version" "5.7.1" + dependencies: + "base64-js" "^1.3.1" + "ieee754" "^1.1.13" + +"builder-util-runtime@9.1.1": + "integrity" "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==" + "resolved" "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz" + "version" "9.1.1" + dependencies: + "debug" "^4.3.4" + "sax" "^1.2.4" + +"builder-util@23.6.0": + "integrity" "sha512-QiQHweYsh8o+U/KNCZFSvISRnvRctb8m/2rB2I1JdByzvNKxPeFLlHFRPQRXab6aYeXc18j9LpsDLJ3sGQmWTQ==" + "resolved" "https://registry.npmjs.org/builder-util/-/builder-util-23.6.0.tgz" + "version" "23.6.0" dependencies: "@types/debug" "^4.1.6" "@types/fs-extra" "^9.0.11" "7zip-bin" "~5.1.1" - app-builder-bin "4.0.0" - bluebird-lst "^1.0.9" - builder-util-runtime "9.1.1" - chalk "^4.1.1" - cross-spawn "^7.0.3" - debug "^4.3.4" - fs-extra "^10.0.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-ci "^3.0.0" - js-yaml "^4.1.0" - source-map-support "^0.5.19" - stat-mode "^1.0.0" - temp-file "^3.4.0" - -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - -chalk@^4.0.2, chalk@^4.1.1: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - -chromium-pickle-js@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz" - integrity sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw== - -ci-info@^3.2.0: - version "3.8.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz" - integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - -clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colors@1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz" - integrity sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commander@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz" - integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== - -commander@2.9.0: - version "2.9.0" - resolved "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz" - integrity sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A== - dependencies: - graceful-readlink ">= 1.0.0" - -compare-version@^0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz" - integrity sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.6.2: - version "1.6.2" - resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -config-chain@^1.1.11: - version "1.1.13" - resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz" - integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cross-spawn@^7.0.1, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -debug@^2.6.8: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4, debug@4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== - -define-properties@^1.1.3: - version "1.1.4" - resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -dir-compare@^2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/dir-compare/-/dir-compare-2.4.0.tgz" - integrity sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA== - dependencies: - buffer-equal "1.0.0" - colors "1.0.3" - commander "2.9.0" - minimatch "3.0.4" - -dmg-builder@23.6.0: - version "23.6.0" - resolved "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.6.0.tgz" - integrity sha512-jFZvY1JohyHarIAlTbfQOk+HnceGjjAdFjVn3n8xlDWKsYNqbO4muca6qXEZTfGXeQMG7TYim6CeS5XKSfSsGA== - dependencies: - app-builder-lib "23.6.0" - builder-util "23.6.0" - builder-util-runtime "9.1.1" - fs-extra "^10.0.0" - iconv-lite "^0.6.2" - js-yaml "^4.1.0" + "app-builder-bin" "4.0.0" + "bluebird-lst" "^1.0.9" + "builder-util-runtime" "9.1.1" + "chalk" "^4.1.1" + "cross-spawn" "^7.0.3" + "debug" "^4.3.4" + "fs-extra" "^10.0.0" + "http-proxy-agent" "^5.0.0" + "https-proxy-agent" "^5.0.0" + "is-ci" "^3.0.0" + "js-yaml" "^4.1.0" + "source-map-support" "^0.5.19" + "stat-mode" "^1.0.0" + "temp-file" "^3.4.0" + +"cacheable-request@^6.0.0": + "integrity" "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==" + "resolved" "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz" + "version" "6.1.0" + dependencies: + "clone-response" "^1.0.2" + "get-stream" "^5.1.0" + "http-cache-semantics" "^4.0.0" + "keyv" "^3.0.0" + "lowercase-keys" "^2.0.0" + "normalize-url" "^4.1.0" + "responselike" "^1.0.2" + +"chalk@^4.0.2", "chalk@^4.1.1": + "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + "version" "4.1.2" + dependencies: + "ansi-styles" "^4.1.0" + "supports-color" "^7.1.0" + +"chownr@^2.0.0": + "integrity" "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + "resolved" "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" + "version" "2.0.0" + +"chromium-pickle-js@^0.2.0": + "integrity" "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==" + "resolved" "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz" + "version" "0.2.0" + +"ci-info@^3.2.0": + "integrity" "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==" + "resolved" "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz" + "version" "3.8.0" + +"cli-truncate@^2.1.0": + "integrity" "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==" + "resolved" "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "slice-ansi" "^3.0.0" + "string-width" "^4.2.0" + +"cliui@^8.0.1": + "integrity" "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==" + "resolved" "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + "version" "8.0.1" + dependencies: + "string-width" "^4.2.0" + "strip-ansi" "^6.0.1" + "wrap-ansi" "^7.0.0" + +"clone-response@^1.0.2": + "integrity" "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=" + "resolved" "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz" + "version" "1.0.2" + dependencies: + "mimic-response" "^1.0.0" + +"color-convert@^2.0.1": + "integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==" + "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "color-name" "~1.1.4" + +"color-name@~1.1.4": + "integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + "version" "1.1.4" + +"colors@1.0.3": + "integrity" "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==" + "resolved" "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz" + "version" "1.0.3" + +"combined-stream@^1.0.8": + "integrity" "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==" + "resolved" "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + "version" "1.0.8" + dependencies: + "delayed-stream" "~1.0.0" + +"commander@^5.0.0": + "integrity" "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" + "resolved" "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz" + "version" "5.1.0" + +"commander@2.9.0": + "integrity" "sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==" + "resolved" "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz" + "version" "2.9.0" + dependencies: + "graceful-readlink" ">= 1.0.0" + +"compare-version@^0.1.2": + "integrity" "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==" + "resolved" "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz" + "version" "0.1.2" + +"concat-map@0.0.1": + "integrity" "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + "version" "0.0.1" + +"concat-stream@^1.6.2": + "integrity" "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==" + "resolved" "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz" + "version" "1.6.2" + dependencies: + "buffer-from" "^1.0.0" + "inherits" "^2.0.3" + "readable-stream" "^2.2.2" + "typedarray" "^0.0.6" + +"config-chain@^1.1.11": + "integrity" "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==" + "resolved" "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz" + "version" "1.1.13" + dependencies: + "ini" "^1.3.4" + "proto-list" "~1.2.1" + +"core-util-is@~1.0.0", "core-util-is@1.0.2": + "integrity" "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "resolved" "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + "version" "1.0.2" + +"crc@^3.8.0": + "integrity" "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==" + "resolved" "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz" + "version" "3.8.0" + dependencies: + "buffer" "^5.1.0" + +"cross-spawn@^7.0.1", "cross-spawn@^7.0.3": + "integrity" "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==" + "resolved" "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + "version" "7.0.3" + dependencies: + "path-key" "^3.1.0" + "shebang-command" "^2.0.0" + "which" "^2.0.1" + +"debug@^2.6.8": + "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" + "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + "version" "2.6.9" + dependencies: + "ms" "2.0.0" + +"debug@^2.6.9": + "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" + "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + "version" "2.6.9" + dependencies: + "ms" "2.0.0" + +"debug@^4.1.0", "debug@^4.1.1", "debug@^4.3.1", "debug@^4.3.4", "debug@4": + "integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==" + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + "version" "4.3.4" + dependencies: + "ms" "2.1.2" + +"decompress-response@^3.3.0": + "integrity" "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=" + "resolved" "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz" + "version" "3.3.0" + dependencies: + "mimic-response" "^1.0.0" + +"defer-to-connect@^1.0.1": + "integrity" "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + "resolved" "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz" + "version" "1.1.3" + +"define-properties@^1.1.3": + "integrity" "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==" + "resolved" "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz" + "version" "1.1.4" + dependencies: + "has-property-descriptors" "^1.0.0" + "object-keys" "^1.1.1" + +"delayed-stream@~1.0.0": + "integrity" "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + "resolved" "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + "version" "1.0.0" + +"detect-node@^2.0.4": + "integrity" "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + "resolved" "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" + "version" "2.1.0" + +"dir-compare@^2.4.0": + "integrity" "sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA==" + "resolved" "https://registry.npmjs.org/dir-compare/-/dir-compare-2.4.0.tgz" + "version" "2.4.0" + dependencies: + "buffer-equal" "1.0.0" + "colors" "1.0.3" + "commander" "2.9.0" + "minimatch" "3.0.4" + +"dmg-builder@23.6.0": + "integrity" "sha512-jFZvY1JohyHarIAlTbfQOk+HnceGjjAdFjVn3n8xlDWKsYNqbO4muca6qXEZTfGXeQMG7TYim6CeS5XKSfSsGA==" + "resolved" "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.6.0.tgz" + "version" "23.6.0" + dependencies: + "app-builder-lib" "23.6.0" + "builder-util" "23.6.0" + "builder-util-runtime" "9.1.1" + "fs-extra" "^10.0.0" + "iconv-lite" "^0.6.2" + "js-yaml" "^4.1.0" optionalDependencies: - dmg-license "^1.0.11" - -dotenv-expand@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz" - integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== - -dotenv@^8.2.0: - version "8.2.0" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz" - integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== - -dotenv@^9.0.2: - version "9.0.2" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz" - integrity sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg== - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - -ejs@^3.1.7: - version "3.1.9" - resolved "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz" - integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== - dependencies: - jake "^10.8.5" - -electron-builder@^23.6.0: - version "23.6.0" - resolved "https://registry.npmjs.org/electron-builder/-/electron-builder-23.6.0.tgz" - integrity sha512-y8D4zO+HXGCNxFBV/JlyhFnoQ0Y0K7/sFH+XwIbj47pqaW8S6PGYQbjoObolKBR1ddQFPt4rwp4CnwMJrW3HAw== + "dmg-license" "^1.0.11" + +"dmg-license@^1.0.11": + "integrity" "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==" + "resolved" "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz" + "version" "1.0.11" + dependencies: + "@types/plist" "^3.0.1" + "@types/verror" "^1.10.3" + "ajv" "^6.10.0" + "crc" "^3.8.0" + "iconv-corefoundation" "^1.1.7" + "plist" "^3.0.4" + "smart-buffer" "^4.0.2" + "verror" "^1.10.0" + +"dotenv-expand@^5.1.0": + "integrity" "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" + "resolved" "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz" + "version" "5.1.0" + +"dotenv@^8.2.0": + "integrity" "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + "resolved" "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz" + "version" "8.2.0" + +"dotenv@^9.0.2": + "integrity" "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==" + "resolved" "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz" + "version" "9.0.2" + +"duplexer3@^0.1.4": + "integrity" "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + "resolved" "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz" + "version" "0.1.4" + +"ejs@^3.1.7": + "integrity" "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==" + "resolved" "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz" + "version" "3.1.9" + dependencies: + "jake" "^10.8.5" + +"electron-builder@^23.6.0": + "integrity" "sha512-y8D4zO+HXGCNxFBV/JlyhFnoQ0Y0K7/sFH+XwIbj47pqaW8S6PGYQbjoObolKBR1ddQFPt4rwp4CnwMJrW3HAw==" + "resolved" "https://registry.npmjs.org/electron-builder/-/electron-builder-23.6.0.tgz" + "version" "23.6.0" dependencies: "@types/yargs" "^17.0.1" - app-builder-lib "23.6.0" - builder-util "23.6.0" - builder-util-runtime "9.1.1" - chalk "^4.1.1" - dmg-builder "23.6.0" - fs-extra "^10.0.0" - is-ci "^3.0.0" - lazy-val "^1.0.5" - read-config-file "6.2.0" - simple-update-notifier "^1.0.7" - yargs "^17.5.1" - -electron-is-dev@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.3.0.tgz" - integrity sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4= - -electron-is@^2.4.0: - version "2.4.1" - resolved "https://registry.npmjs.org/electron-is/-/electron-is-2.4.1.tgz" - integrity sha512-cWPJVsyfU1lTbUCwOyEhTChl+dU5OTPgQ/qffX72aBaWE2YcgmUriRrDioBn5gnlMok/LctTzcnJSVSTUJJMjg== - dependencies: - electron-is-dev "^0.3.0" - semver "^5.3.0" - -electron-notarize@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.2.1.tgz" - integrity sha512-oZ6/NhKeXmEKNROiFmRNfytqu3cxqC95sjooG7kBXQVEUSQkZnbiAhxVh5jXngL881G197pbwpeVPJyM7Ikmxw== - dependencies: - debug "^4.1.1" - fs-extra "^8.1.0" - -electron-osx-sign@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.6.0.tgz" - integrity sha512-+hiIEb2Xxk6eDKJ2FFlpofCnemCbjbT5jz+BKGpVBrRNT3kWTGs4DfNX6IzGwgi33hUcXF+kFs9JW+r6Wc1LRg== - dependencies: - bluebird "^3.5.0" - compare-version "^0.1.2" - debug "^2.6.8" - isbinaryfile "^3.0.2" - minimist "^1.2.0" - plist "^3.0.1" - -electron-publish@23.6.0: - version "23.6.0" - resolved "https://registry.npmjs.org/electron-publish/-/electron-publish-23.6.0.tgz" - integrity sha512-jPj3y+eIZQJF/+t5SLvsI5eS4mazCbNYqatv5JihbqOstIM13k0d1Z3vAWntvtt13Itl61SO6seicWdioOU5dg== + "app-builder-lib" "23.6.0" + "builder-util" "23.6.0" + "builder-util-runtime" "9.1.1" + "chalk" "^4.1.1" + "dmg-builder" "23.6.0" + "fs-extra" "^10.0.0" + "is-ci" "^3.0.0" + "lazy-val" "^1.0.5" + "read-config-file" "6.2.0" + "simple-update-notifier" "^1.0.7" + "yargs" "^17.5.1" + +"electron-is-dev@^0.3.0": + "integrity" "sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4=" + "resolved" "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.3.0.tgz" + "version" "0.3.0" + +"electron-is@^2.4.0": + "integrity" "sha512-cWPJVsyfU1lTbUCwOyEhTChl+dU5OTPgQ/qffX72aBaWE2YcgmUriRrDioBn5gnlMok/LctTzcnJSVSTUJJMjg==" + "resolved" "https://registry.npmjs.org/electron-is/-/electron-is-2.4.1.tgz" + "version" "2.4.1" + dependencies: + "electron-is-dev" "^0.3.0" + "semver" "^5.3.0" + +"electron-notarize@^0.2.1": + "integrity" "sha512-oZ6/NhKeXmEKNROiFmRNfytqu3cxqC95sjooG7kBXQVEUSQkZnbiAhxVh5jXngL881G197pbwpeVPJyM7Ikmxw==" + "resolved" "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.2.1.tgz" + "version" "0.2.1" + dependencies: + "debug" "^4.1.1" + "fs-extra" "^8.1.0" + +"electron-osx-sign@^0.6.0": + "integrity" "sha512-+hiIEb2Xxk6eDKJ2FFlpofCnemCbjbT5jz+BKGpVBrRNT3kWTGs4DfNX6IzGwgi33hUcXF+kFs9JW+r6Wc1LRg==" + "resolved" "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.6.0.tgz" + "version" "0.6.0" + dependencies: + "bluebird" "^3.5.0" + "compare-version" "^0.1.2" + "debug" "^2.6.8" + "isbinaryfile" "^3.0.2" + "minimist" "^1.2.0" + "plist" "^3.0.1" + +"electron-publish@23.6.0": + "integrity" "sha512-jPj3y+eIZQJF/+t5SLvsI5eS4mazCbNYqatv5JihbqOstIM13k0d1Z3vAWntvtt13Itl61SO6seicWdioOU5dg==" + "resolved" "https://registry.npmjs.org/electron-publish/-/electron-publish-23.6.0.tgz" + "version" "23.6.0" dependencies: "@types/fs-extra" "^9.0.11" - builder-util "23.6.0" - builder-util-runtime "9.1.1" - chalk "^4.1.1" - fs-extra "^10.0.0" - lazy-val "^1.0.5" - mime "^2.5.2" - -"electron@>= 13.0.0", electron@18.2.2: - version "18.2.2" - resolved "https://registry.npmjs.org/electron/-/electron-18.2.2.tgz" - integrity sha512-o9/9+ntxZ0RoVtllH1e9FDLiCLVg00EO8AJZoCR1cVt7l7AVpRgynZdSczaUtTb9XJpWv7U02R6hoWALl55opQ== + "builder-util" "23.6.0" + "builder-util-runtime" "9.1.1" + "chalk" "^4.1.1" + "fs-extra" "^10.0.0" + "lazy-val" "^1.0.5" + "mime" "^2.5.2" + +"electron@>= 13.0.0", "electron@18.2.2": + "integrity" "sha512-o9/9+ntxZ0RoVtllH1e9FDLiCLVg00EO8AJZoCR1cVt7l7AVpRgynZdSczaUtTb9XJpWv7U02R6hoWALl55opQ==" + "resolved" "https://registry.npmjs.org/electron/-/electron-18.2.2.tgz" + "version" "18.2.2" dependencies: "@electron/get" "^1.13.0" "@types/node" "^16.11.26" - extract-zip "^1.0.3" - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -encodeurl@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -es6-error@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz" - integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -extract-zip@^1.0.3: - version "1.7.0" - resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz" - integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA== - dependencies: - concat-stream "^1.6.2" - debug "^2.6.9" - mkdirp "^0.5.4" - yauzl "^2.10.0" - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fd-slicer@~1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz" - integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= - dependencies: - pend "~1.2.0" - -filelist@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz" - integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== - dependencies: - minimatch "^5.0.1" - -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -fs-extra@^10.0.0: - version "10.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^10.1.0: - version "10.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^9.0.0: - version "9.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^9.0.1: - version "9.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -glob@^7.0.0, glob@^7.1.3, glob@^7.1.6: - version "7.1.6" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-agent@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz" - integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q== - dependencies: - boolean "^3.0.1" - es6-error "^4.1.1" - matcher "^3.0.0" - roarr "^2.15.3" - semver "^7.3.2" - serialize-error "^7.0.1" - -global-tunnel-ng@^2.7.1: - version "2.7.1" - resolved "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz" - integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg== - dependencies: - encodeurl "^1.0.2" - lodash "^4.17.10" - npm-conf "^1.1.3" - tunnel "^0.0.6" - -globalthis@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz" - integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ== - dependencies: - define-properties "^1.1.3" - -got@^9.6.0: - version "9.6.0" - resolved "https://registry.npmjs.org/got/-/got-9.6.0.tgz" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + "extract-zip" "^1.0.3" + +"emoji-regex@^8.0.0": + "integrity" "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + "version" "8.0.0" + +"encodeurl@^1.0.2": + "integrity" "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "resolved" "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + "version" "1.0.2" + +"end-of-stream@^1.1.0": + "integrity" "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==" + "resolved" "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" + "version" "1.4.4" + dependencies: + "once" "^1.4.0" + +"env-paths@^2.2.0": + "integrity" "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + "resolved" "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" + "version" "2.2.1" + +"es6-error@^4.1.1": + "integrity" "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" + "resolved" "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz" + "version" "4.1.1" + +"escalade@^3.1.1": + "integrity" "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "resolved" "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + "version" "3.1.1" + +"escape-string-regexp@^4.0.0": + "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + "version" "4.0.0" + +"extract-zip@^1.0.3": + "integrity" "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==" + "resolved" "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz" + "version" "1.7.0" + dependencies: + "concat-stream" "^1.6.2" + "debug" "^2.6.9" + "mkdirp" "^0.5.4" + "yauzl" "^2.10.0" + +"extsprintf@^1.2.0": + "integrity" "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==" + "resolved" "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz" + "version" "1.4.1" + +"fast-deep-equal@^3.1.1": + "integrity" "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "resolved" "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + "version" "3.1.3" + +"fast-json-stable-stringify@^2.0.0": + "integrity" "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "resolved" "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + "version" "2.1.0" + +"fd-slicer@~1.1.0": + "integrity" "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=" + "resolved" "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz" + "version" "1.1.0" + dependencies: + "pend" "~1.2.0" + +"filelist@^1.0.1": + "integrity" "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==" + "resolved" "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz" + "version" "1.0.4" + dependencies: + "minimatch" "^5.0.1" + +"form-data@^4.0.0": + "integrity" "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==" + "resolved" "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "asynckit" "^0.4.0" + "combined-stream" "^1.0.8" + "mime-types" "^2.1.12" + +"fs-extra@^10.0.0": + "integrity" "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==" + "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" + "version" "10.1.0" + dependencies: + "graceful-fs" "^4.2.0" + "jsonfile" "^6.0.1" + "universalify" "^2.0.0" + +"fs-extra@^10.1.0": + "integrity" "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==" + "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" + "version" "10.1.0" + dependencies: + "graceful-fs" "^4.2.0" + "jsonfile" "^6.0.1" + "universalify" "^2.0.0" + +"fs-extra@^8.1.0": + "integrity" "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==" + "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" + "version" "8.1.0" + dependencies: + "graceful-fs" "^4.2.0" + "jsonfile" "^4.0.0" + "universalify" "^0.1.0" + +"fs-extra@^9.0.0": + "integrity" "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==" + "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" + "version" "9.1.0" + dependencies: + "at-least-node" "^1.0.0" + "graceful-fs" "^4.2.0" + "jsonfile" "^6.0.1" + "universalify" "^2.0.0" + +"fs-extra@^9.0.1": + "integrity" "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==" + "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" + "version" "9.1.0" + dependencies: + "at-least-node" "^1.0.0" + "graceful-fs" "^4.2.0" + "jsonfile" "^6.0.1" + "universalify" "^2.0.0" + +"fs-minipass@^2.0.0": + "integrity" "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==" + "resolved" "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "minipass" "^3.0.0" + +"fs.realpath@^1.0.0": + "integrity" "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + "version" "1.0.0" + +"function-bind@^1.1.1": + "integrity" "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "resolved" "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + "version" "1.1.1" + +"get-caller-file@^2.0.5": + "integrity" "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "resolved" "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + "version" "2.0.5" + +"get-intrinsic@^1.1.1": + "integrity" "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==" + "resolved" "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" + "version" "1.1.1" + dependencies: + "function-bind" "^1.1.1" + "has" "^1.0.3" + "has-symbols" "^1.0.1" + +"get-stream@^4.1.0": + "integrity" "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==" + "resolved" "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "pump" "^3.0.0" + +"get-stream@^5.1.0": + "integrity" "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==" + "resolved" "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" + "version" "5.2.0" + dependencies: + "pump" "^3.0.0" + +"glob@^7.0.0", "glob@^7.1.3", "glob@^7.1.6": + "integrity" "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==" + "resolved" "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" + "version" "7.1.6" + dependencies: + "fs.realpath" "^1.0.0" + "inflight" "^1.0.4" + "inherits" "2" + "minimatch" "^3.0.4" + "once" "^1.3.0" + "path-is-absolute" "^1.0.0" + +"global-agent@^3.0.0": + "integrity" "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==" + "resolved" "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "boolean" "^3.0.1" + "es6-error" "^4.1.1" + "matcher" "^3.0.0" + "roarr" "^2.15.3" + "semver" "^7.3.2" + "serialize-error" "^7.0.1" + +"global-tunnel-ng@^2.7.1": + "integrity" "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==" + "resolved" "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz" + "version" "2.7.1" + dependencies: + "encodeurl" "^1.0.2" + "lodash" "^4.17.10" + "npm-conf" "^1.1.3" + "tunnel" "^0.0.6" + +"globalthis@^1.0.1": + "integrity" "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==" + "resolved" "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz" + "version" "1.0.2" + dependencies: + "define-properties" "^1.1.3" + +"got@^9.6.0": + "integrity" "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==" + "resolved" "https://registry.npmjs.org/got/-/got-9.6.0.tgz" + "version" "9.6.0" dependencies: "@sindresorhus/is" "^0.14.0" "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - -graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.4" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + "cacheable-request" "^6.0.0" + "decompress-response" "^3.3.0" + "duplexer3" "^0.1.4" + "get-stream" "^4.1.0" + "lowercase-keys" "^1.0.1" + "mimic-response" "^1.0.1" + "p-cancelable" "^1.0.0" + "to-readable-stream" "^1.0.0" + "url-parse-lax" "^3.0.0" + +"graceful-fs@^4.1.6", "graceful-fs@^4.2.0": + "integrity" "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + "resolved" "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz" + "version" "4.2.4" "graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" - integrity sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w== + "integrity" "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==" + "resolved" "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" + "version" "1.0.1" -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +"has-flag@^4.0.0": + "integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + "version" "4.0.0" -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== +"has-property-descriptors@^1.0.0": + "integrity" "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==" + "resolved" "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" + "version" "1.0.0" dependencies: - get-intrinsic "^1.1.1" + "get-intrinsic" "^1.1.1" -has-symbols@^1.0.1: - version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +"has-symbols@^1.0.1": + "integrity" "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + "resolved" "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + "version" "1.0.3" -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== +"has@^1.0.3": + "integrity" "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==" + "resolved" "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + "version" "1.0.3" dependencies: - function-bind "^1.1.1" + "function-bind" "^1.1.1" -hosted-git-info@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz" - integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== +"hosted-git-info@^4.1.0": + "integrity" "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==" + "resolved" "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz" + "version" "4.1.0" dependencies: - lru-cache "^6.0.0" + "lru-cache" "^6.0.0" -http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== +"http-cache-semantics@^4.0.0": + "integrity" "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + "resolved" "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" + "version" "4.1.0" -http-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" - integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== +"http-proxy-agent@^5.0.0": + "integrity" "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==" + "resolved" "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" + "version" "5.0.0" dependencies: "@tootallnate/once" "2" - agent-base "6" - debug "4" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@^2.0.3, inherits@~2.0.3, inherits@2: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@^1.3.4: - version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - -is-ci@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz" - integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== - dependencies: - ci-info "^3.2.0" - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isbinaryfile@^3.0.2: - version "3.0.3" - resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz" - integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== - dependencies: - buffer-alloc "^1.2.0" - -isbinaryfile@^4.0.10: - version "4.0.10" - resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz" - integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -jake@^10.8.5: - version "10.8.5" - resolved "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== - dependencies: - async "^3.2.3" - chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@^2.2.0: - version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + "agent-base" "6" + "debug" "4" + +"https-proxy-agent@^5.0.0": + "integrity" "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==" + "resolved" "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" + "version" "5.0.1" + dependencies: + "agent-base" "6" + "debug" "4" + +"iconv-corefoundation@^1.1.7": + "integrity" "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==" + "resolved" "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz" + "version" "1.1.7" + dependencies: + "cli-truncate" "^2.1.0" + "node-addon-api" "^1.6.3" + +"iconv-lite@^0.6.2": + "integrity" "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==" + "resolved" "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + "version" "0.6.3" + dependencies: + "safer-buffer" ">= 2.1.2 < 3.0.0" + +"ieee754@^1.1.13": + "integrity" "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "resolved" "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + "version" "1.2.1" + +"inflight@^1.0.4": + "integrity" "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=" + "resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + "version" "1.0.6" + dependencies: + "once" "^1.3.0" + "wrappy" "1" + +"inherits@^2.0.3", "inherits@~2.0.3", "inherits@2": + "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + "version" "2.0.4" + +"ini@^1.3.4": + "integrity" "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "resolved" "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + "version" "1.3.8" + +"interpret@^1.0.0": + "integrity" "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + "resolved" "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz" + "version" "1.4.0" + +"is-ci@^3.0.0": + "integrity" "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==" + "resolved" "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "ci-info" "^3.2.0" + +"is-fullwidth-code-point@^3.0.0": + "integrity" "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + "version" "3.0.0" + +"isarray@~1.0.0": + "integrity" "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "resolved" "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + "version" "1.0.0" + +"isbinaryfile@^3.0.2": + "integrity" "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==" + "resolved" "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz" + "version" "3.0.3" + dependencies: + "buffer-alloc" "^1.2.0" + +"isbinaryfile@^4.0.10": + "integrity" "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==" + "resolved" "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz" + "version" "4.0.10" + +"isexe@^2.0.0": + "integrity" "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "resolved" "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + "version" "2.0.0" + +"jake@^10.8.5": + "integrity" "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==" + "resolved" "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz" + "version" "10.8.5" + dependencies: + "async" "^3.2.3" + "chalk" "^4.0.2" + "filelist" "^1.0.1" + "minimatch" "^3.0.4" + +"js-yaml@^4.1.0": + "integrity" "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==" + "resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "argparse" "^2.0.1" + +"json-buffer@3.0.0": + "integrity" "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + "resolved" "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz" + "version" "3.0.0" + +"json-schema-traverse@^0.4.1": + "integrity" "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "resolved" "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + "version" "0.4.1" + +"json-stringify-safe@^5.0.1": + "integrity" "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "resolved" "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + "version" "5.0.1" + +"json5@^2.2.0": + "integrity" "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + "resolved" "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + "version" "2.2.3" + +"jsonfile@^4.0.0": + "integrity" "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=" + "resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" + "version" "4.0.0" optionalDependencies: - graceful-fs "^4.1.6" + "graceful-fs" "^4.1.6" -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== +"jsonfile@^6.0.1": + "integrity" "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==" + "resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" + "version" "6.1.0" dependencies: - universalify "^2.0.0" + "universalify" "^2.0.0" optionalDependencies: - graceful-fs "^4.1.6" + "graceful-fs" "^4.1.6" -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== +"keyv@^3.0.0": + "integrity" "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==" + "resolved" "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz" + "version" "3.1.0" dependencies: - json-buffer "3.0.0" + "json-buffer" "3.0.0" -lazy-val@^1.0.4, lazy-val@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz" - integrity sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q== +"lazy-val@^1.0.4", "lazy-val@^1.0.5": + "integrity" "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==" + "resolved" "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz" + "version" "1.0.5" -lodash@^4.17.10, lodash@^4.17.15: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +"lodash@^4.17.10", "lodash@^4.17.15": + "integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + "version" "4.17.21" -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== +"lowercase-keys@^1.0.0", "lowercase-keys@^1.0.1": + "integrity" "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + "resolved" "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz" + "version" "1.0.1" -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +"lowercase-keys@^2.0.0": + "integrity" "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + "resolved" "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" + "version" "2.0.0" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== +"lru-cache@^6.0.0": + "integrity" "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==" + "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + "version" "6.0.0" dependencies: - yallist "^4.0.0" - -matcher@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz" - integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng== - dependencies: - escape-string-regexp "^4.0.0" + "yallist" "^4.0.0" + +"matcher@^3.0.0": + "integrity" "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==" + "resolved" "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "escape-string-regexp" "^4.0.0" -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@^2.5.2: - version "2.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== - -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -minimatch@^3.0.4, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -minipass@^3.0.0: - version "3.3.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^4.0.0: - version "4.2.8" - resolved "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz" - integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== - -minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mkdirp@^0.5.4: - version "0.5.5" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mkdirp@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -normalize-url@^4.1.0: - version "4.5.1" - resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz" - integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== - -npm-conf@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz" - integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== - dependencies: - config-chain "^1.1.11" - pify "^3.0.0" - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -pend@~1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" - integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -plist@^3.0.1, plist@^3.0.4: - version "3.0.6" - resolved "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz" - integrity sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA== - dependencies: - base64-js "^1.5.1" - xmlbuilder "^15.1.1" - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - -prettier@1.15.3: - version "1.15.3" - resolved "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz" - integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -progress@^2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -read-config-file@6.2.0: - version "6.2.0" - resolved "https://registry.npmjs.org/read-config-file/-/read-config-file-6.2.0.tgz" - integrity sha512-gx7Pgr5I56JtYz+WuqEbQHj/xWo+5Vwua2jhb1VwM4Wid5PqYmZ4i00ZB0YEGIfkVBsCv9UrjgyqCiQfS/Oosg== - dependencies: - dotenv "^9.0.2" - dotenv-expand "^5.1.0" - js-yaml "^4.1.0" - json5 "^2.2.0" - lazy-val "^1.0.4" - -readable-stream@^2.2.2: - version "2.3.7" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - dependencies: - resolve "^1.1.6" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -resolve@^1.1.6: - version "1.17.0" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= - dependencies: - lowercase-keys "^1.0.0" - -rimraf@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -roarr@^2.15.3: - version "2.15.4" - resolved "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz" - integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A== - dependencies: - boolean "^3.0.1" - detect-node "^2.0.4" - globalthis "^1.0.1" - json-stringify-safe "^5.0.1" - semver-compare "^1.0.0" - sprintf-js "^1.1.2" - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +"mime-db@1.52.0": + "integrity" "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + "resolved" "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + "version" "1.52.0" + +"mime-types@^2.1.12": + "integrity" "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==" + "resolved" "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + "version" "2.1.35" + dependencies: + "mime-db" "1.52.0" + +"mime@^2.5.2": + "integrity" "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" + "resolved" "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" + "version" "2.6.0" + +"mimic-response@^1.0.0", "mimic-response@^1.0.1": + "integrity" "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + "resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" + "version" "1.0.1" + +"minimatch@^3.0.4", "minimatch@^3.1.2": + "integrity" "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + "version" "3.1.2" + dependencies: + "brace-expansion" "^1.1.7" + +"minimatch@^5.0.1": + "integrity" "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" + "version" "5.1.6" + dependencies: + "brace-expansion" "^2.0.1" + +"minimatch@3.0.4": + "integrity" "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" + "version" "3.0.4" + dependencies: + "brace-expansion" "^1.1.7" + +"minimist@^1.2.0", "minimist@^1.2.3", "minimist@^1.2.5": + "integrity" "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" + "version" "1.2.5" + +"minipass@^3.0.0": + "integrity" "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==" + "resolved" "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" + "version" "3.3.6" + dependencies: + "yallist" "^4.0.0" + +"minipass@^4.0.0": + "integrity" "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==" + "resolved" "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz" + "version" "4.2.8" + +"minizlib@^2.1.1": + "integrity" "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==" + "resolved" "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" + "version" "2.1.2" + dependencies: + "minipass" "^3.0.0" + "yallist" "^4.0.0" + +"mkdirp@^0.5.4": + "integrity" "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==" + "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" + "version" "0.5.5" + dependencies: + "minimist" "^1.2.5" + +"mkdirp@^1.0.3": + "integrity" "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + "version" "1.0.4" + +"ms@2.0.0": + "integrity" "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + "version" "2.0.0" + +"ms@2.1.2": + "integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + "version" "2.1.2" + +"node-addon-api@^1.6.3": + "integrity" "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==" + "resolved" "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz" + "version" "1.7.2" + +"normalize-url@^4.1.0": + "integrity" "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" + "resolved" "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz" + "version" "4.5.1" + +"npm-conf@^1.1.3": + "integrity" "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==" + "resolved" "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz" + "version" "1.1.3" + dependencies: + "config-chain" "^1.1.11" + "pify" "^3.0.0" + +"object-keys@^1.1.1": + "integrity" "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + "resolved" "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" + "version" "1.1.1" + +"once@^1.3.0", "once@^1.3.1", "once@^1.4.0": + "integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" + "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + "version" "1.4.0" + dependencies: + "wrappy" "1" + +"p-cancelable@^1.0.0": + "integrity" "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + "resolved" "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz" + "version" "1.1.0" + +"path-is-absolute@^1.0.0": + "integrity" "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + "version" "1.0.1" + +"path-key@^3.1.0": + "integrity" "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + "resolved" "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + "version" "3.1.1" + +"path-parse@^1.0.6": + "integrity" "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "resolved" "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz" + "version" "1.0.6" + +"pend@~1.2.0": + "integrity" "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + "resolved" "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" + "version" "1.2.0" + +"pify@^3.0.0": + "integrity" "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + "resolved" "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" + "version" "3.0.0" + +"plist@^3.0.1", "plist@^3.0.4": + "integrity" "sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==" + "resolved" "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz" + "version" "3.0.6" + dependencies: + "base64-js" "^1.5.1" + "xmlbuilder" "^15.1.1" + +"prepend-http@^2.0.0": + "integrity" "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + "resolved" "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz" + "version" "2.0.0" + +"prettier@1.15.3": + "integrity" "sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==" + "resolved" "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz" + "version" "1.15.3" + +"process-nextick-args@~2.0.0": + "integrity" "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "resolved" "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + "version" "2.0.1" + +"progress@^2.0.3": + "integrity" "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + "resolved" "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" + "version" "2.0.3" + +"proto-list@~1.2.1": + "integrity" "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" + "resolved" "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz" + "version" "1.2.4" + +"pump@^3.0.0": + "integrity" "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==" + "resolved" "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "end-of-stream" "^1.1.0" + "once" "^1.3.1" + +"punycode@^2.1.0": + "integrity" "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" + "resolved" "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" + "version" "2.3.0" + +"read-config-file@6.2.0": + "integrity" "sha512-gx7Pgr5I56JtYz+WuqEbQHj/xWo+5Vwua2jhb1VwM4Wid5PqYmZ4i00ZB0YEGIfkVBsCv9UrjgyqCiQfS/Oosg==" + "resolved" "https://registry.npmjs.org/read-config-file/-/read-config-file-6.2.0.tgz" + "version" "6.2.0" + dependencies: + "dotenv" "^9.0.2" + "dotenv-expand" "^5.1.0" + "js-yaml" "^4.1.0" + "json5" "^2.2.0" + "lazy-val" "^1.0.4" + +"readable-stream@^2.2.2": + "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==" + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" + "version" "2.3.7" + dependencies: + "core-util-is" "~1.0.0" + "inherits" "~2.0.3" + "isarray" "~1.0.0" + "process-nextick-args" "~2.0.0" + "safe-buffer" "~5.1.1" + "string_decoder" "~1.1.1" + "util-deprecate" "~1.0.1" + +"rechoir@^0.6.2": + "integrity" "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=" + "resolved" "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" + "version" "0.6.2" + dependencies: + "resolve" "^1.1.6" + +"require-directory@^2.1.1": + "integrity" "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + "resolved" "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + "version" "2.1.1" + +"resolve@^1.1.6": + "integrity" "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==" + "resolved" "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz" + "version" "1.17.0" + dependencies: + "path-parse" "^1.0.6" + +"responselike@^1.0.2": + "integrity" "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=" + "resolved" "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz" + "version" "1.0.2" + dependencies: + "lowercase-keys" "^1.0.0" + +"rimraf@^3.0.0": + "integrity" "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==" + "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "glob" "^7.1.3" + +"roarr@^2.15.3": + "integrity" "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==" + "resolved" "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz" + "version" "2.15.4" + dependencies: + "boolean" "^3.0.1" + "detect-node" "^2.0.4" + "globalthis" "^1.0.1" + "json-stringify-safe" "^5.0.1" + "semver-compare" "^1.0.0" + "sprintf-js" "^1.1.2" + +"safe-buffer@~5.1.0", "safe-buffer@~5.1.1": + "integrity" "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + "version" "5.1.2" "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sanitize-filename@^1.6.3: - version "1.6.3" - resolved "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz" - integrity sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg== - dependencies: - truncate-utf8-bytes "^1.0.0" - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -semver-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" - integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= - -semver@^5.3.0: - version "5.7.1" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.2.0: - version "6.3.0" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.3.2: - version "7.3.7" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.7: - version "7.5.0" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz" - integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== - dependencies: - lru-cache "^6.0.0" - -semver@~7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - -serialize-error@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz" - integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw== - dependencies: - type-fest "^0.13.1" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shelljs@0.8.4: - version "0.8.4" - resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz" - integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -simple-update-notifier@^1.0.7: - version "1.1.0" - resolved "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz" - integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== - dependencies: - semver "~7.0.0" - -source-map-support@^0.5.19: - version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -sprintf-js@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz" - integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== - -stat-mode@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz" - integrity sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg== - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -sumchecker@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz" - integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg== - dependencies: - debug "^4.1.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -tar@^6.1.11: - version "6.1.13" - resolved "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz" - integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^4.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -temp-file@^3.4.0: - version "3.4.0" - resolved "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz" - integrity sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg== - dependencies: - async-exit-hook "^2.0.1" - fs-extra "^10.0.0" - -tmp-promise@^3.0.2: - version "3.0.3" - resolved "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz" - integrity sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ== - dependencies: - tmp "^0.2.0" - -tmp@^0.2.0: - version "0.2.1" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - -truncate-utf8-bytes@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz" - integrity sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ== - dependencies: - utf8-byte-length "^1.0.1" - -tunnel@^0.0.6: - version "0.0.6" - resolved "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz" - integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== - -type-fest@^0.13.1: - version "0.13.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz" - integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= - dependencies: - prepend-http "^2.0.0" - -utf8-byte-length@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz" - integrity sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA== - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -xmlbuilder@^15.1.1: - version "15.1.1" - resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz" - integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - -yargs@^17.5.1: - version "17.7.2" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - -yauzl@^2.10.0: - version "2.10.0" - resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz" - integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= - dependencies: - buffer-crc32 "~0.2.3" - fd-slicer "~1.1.0" + "integrity" "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "resolved" "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + "version" "2.1.2" + +"sanitize-filename@^1.6.3": + "integrity" "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==" + "resolved" "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz" + "version" "1.6.3" + dependencies: + "truncate-utf8-bytes" "^1.0.0" + +"sax@^1.2.4": + "integrity" "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + "resolved" "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" + "version" "1.2.4" + +"semver-compare@^1.0.0": + "integrity" "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" + "resolved" "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" + "version" "1.0.0" + +"semver@^5.3.0": + "integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" + "version" "5.7.1" + +"semver@^6.2.0": + "integrity" "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "resolved" "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + "version" "6.3.0" + +"semver@^7.3.2": + "integrity" "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==" + "resolved" "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz" + "version" "7.3.7" + dependencies: + "lru-cache" "^6.0.0" + +"semver@^7.3.7": + "integrity" "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==" + "resolved" "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz" + "version" "7.5.0" + dependencies: + "lru-cache" "^6.0.0" + +"semver@~7.0.0": + "integrity" "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" + "resolved" "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz" + "version" "7.0.0" + +"serialize-error@^7.0.1": + "integrity" "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==" + "resolved" "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz" + "version" "7.0.1" + dependencies: + "type-fest" "^0.13.1" + +"shebang-command@^2.0.0": + "integrity" "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==" + "resolved" "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "shebang-regex" "^3.0.0" + +"shebang-regex@^3.0.0": + "integrity" "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + "resolved" "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + "version" "3.0.0" + +"shelljs@0.8.4": + "integrity" "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==" + "resolved" "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz" + "version" "0.8.4" + dependencies: + "glob" "^7.0.0" + "interpret" "^1.0.0" + "rechoir" "^0.6.2" + +"simple-update-notifier@^1.0.7": + "integrity" "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==" + "resolved" "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz" + "version" "1.1.0" + dependencies: + "semver" "~7.0.0" + +"slice-ansi@^3.0.0": + "integrity" "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==" + "resolved" "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "ansi-styles" "^4.0.0" + "astral-regex" "^2.0.0" + "is-fullwidth-code-point" "^3.0.0" + +"smart-buffer@^4.0.2": + "integrity" "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + "resolved" "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" + "version" "4.2.0" + +"source-map-support@^0.5.19": + "integrity" "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==" + "resolved" "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + "version" "0.5.21" + dependencies: + "buffer-from" "^1.0.0" + "source-map" "^0.6.0" + +"source-map@^0.6.0": + "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + "version" "0.6.1" + +"sprintf-js@^1.1.2": + "integrity" "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + "resolved" "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz" + "version" "1.1.2" + +"stat-mode@^1.0.0": + "integrity" "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==" + "resolved" "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz" + "version" "1.0.0" + +"string_decoder@~1.1.1": + "integrity" "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==" + "resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + "version" "1.1.1" + dependencies: + "safe-buffer" "~5.1.0" + +"string-width@^4.1.0", "string-width@^4.2.0", "string-width@^4.2.3": + "integrity" "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==" + "resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + "version" "4.2.3" + dependencies: + "emoji-regex" "^8.0.0" + "is-fullwidth-code-point" "^3.0.0" + "strip-ansi" "^6.0.1" + +"strip-ansi@^6.0.0", "strip-ansi@^6.0.1": + "integrity" "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==" + "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "ansi-regex" "^5.0.1" + +"sumchecker@^3.0.1": + "integrity" "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==" + "resolved" "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "debug" "^4.1.0" + +"supports-color@^7.1.0": + "integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + "version" "7.2.0" + dependencies: + "has-flag" "^4.0.0" + +"tar@^6.1.11": + "integrity" "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==" + "resolved" "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz" + "version" "6.1.13" + dependencies: + "chownr" "^2.0.0" + "fs-minipass" "^2.0.0" + "minipass" "^4.0.0" + "minizlib" "^2.1.1" + "mkdirp" "^1.0.3" + "yallist" "^4.0.0" + +"temp-file@^3.4.0": + "integrity" "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==" + "resolved" "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz" + "version" "3.4.0" + dependencies: + "async-exit-hook" "^2.0.1" + "fs-extra" "^10.0.0" + +"tmp-promise@^3.0.2": + "integrity" "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==" + "resolved" "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz" + "version" "3.0.3" + dependencies: + "tmp" "^0.2.0" + +"tmp@^0.2.0": + "integrity" "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==" + "resolved" "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" + "version" "0.2.1" + dependencies: + "rimraf" "^3.0.0" + +"to-readable-stream@^1.0.0": + "integrity" "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" + "resolved" "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz" + "version" "1.0.0" + +"truncate-utf8-bytes@^1.0.0": + "integrity" "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==" + "resolved" "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz" + "version" "1.0.2" + dependencies: + "utf8-byte-length" "^1.0.1" + +"tunnel@^0.0.6": + "integrity" "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + "resolved" "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz" + "version" "0.0.6" + +"type-fest@^0.13.1": + "integrity" "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==" + "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz" + "version" "0.13.1" + +"typedarray@^0.0.6": + "integrity" "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + "resolved" "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" + "version" "0.0.6" + +"universalify@^0.1.0": + "integrity" "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "resolved" "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" + "version" "0.1.2" + +"universalify@^2.0.0": + "integrity" "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + "resolved" "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" + "version" "2.0.0" + +"uri-js@^4.2.2": + "integrity" "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==" + "resolved" "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + "version" "4.4.1" + dependencies: + "punycode" "^2.1.0" + +"url-parse-lax@^3.0.0": + "integrity" "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=" + "resolved" "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "prepend-http" "^2.0.0" + +"utf8-byte-length@^1.0.1": + "integrity" "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==" + "resolved" "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz" + "version" "1.0.4" + +"util-deprecate@~1.0.1": + "integrity" "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "resolved" "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + "version" "1.0.2" + +"verror@^1.10.0": + "integrity" "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==" + "resolved" "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz" + "version" "1.10.1" + dependencies: + "assert-plus" "^1.0.0" + "core-util-is" "1.0.2" + "extsprintf" "^1.2.0" + +"which@^2.0.1": + "integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==" + "resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "isexe" "^2.0.0" + +"wrap-ansi@^7.0.0": + "integrity" "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==" + "resolved" "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + "version" "7.0.0" + dependencies: + "ansi-styles" "^4.0.0" + "string-width" "^4.1.0" + "strip-ansi" "^6.0.0" + +"wrappy@1": + "integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + "version" "1.0.2" + +"xmlbuilder@^15.1.1", "xmlbuilder@>=11.0.1": + "integrity" "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==" + "resolved" "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz" + "version" "15.1.1" + +"y18n@^5.0.5": + "integrity" "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + "resolved" "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + "version" "5.0.8" + +"yallist@^4.0.0": + "integrity" "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "resolved" "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + "version" "4.0.0" + +"yargs-parser@^21.1.1": + "integrity" "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + "version" "21.1.1" + +"yargs@^17.5.1": + "integrity" "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==" + "resolved" "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" + "version" "17.7.2" + dependencies: + "cliui" "^8.0.1" + "escalade" "^3.1.1" + "get-caller-file" "^2.0.5" + "require-directory" "^2.1.1" + "string-width" "^4.2.3" + "y18n" "^5.0.5" + "yargs-parser" "^21.1.1" + +"yauzl@^2.10.0": + "integrity" "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=" + "resolved" "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz" + "version" "2.10.0" + dependencies: + "buffer-crc32" "~0.2.3" + "fd-slicer" "~1.1.0" From 65f370f9dd8acdc8e5bff14dca8ee6fd5d75673c Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Fri, 11 Aug 2023 16:54:57 +0300 Subject: [PATCH 02/80] implement base spine functionality, properties panel and object editor --- Extensions/CMakeLists.txt | 1 + Extensions/Spine/CMakeLists.txt | 20 + Extensions/Spine/GDevelop.code-workspace | 125 + Extensions/Spine/JsExtension.js | 590 +- Extensions/Spine/SpineObjectConfiguration.cpp | 220 + Extensions/Spine/SpineObjectConfiguration.h | 165 + .../Spine/spineruntimeobject-pixi-renderer.ts | 186 +- Extensions/Spine/spineruntimeobject.ts | 167 +- GDJS/GDJS/IDE/ExporterHelper.cpp | 2 + GDJS/Runtime/pixi-renderers/pixi-spine.umd.js | 24220 ++++++++++++++++ GDJS/Runtime/runtimegame.ts | 76 +- GDJS/Runtime/textmanager.ts | 169 + GDJS/Runtime/types/global-pixi.d.ts | 2 + GDJS/package-lock.json | 142 + GDJS/scripts/lib/runtime-files-list.js | 1 + GDJS/tests/karma.conf.js | 2 + GDevelop.js/Bindings/Bindings.idl | 29 + GDevelop.js/Bindings/Wrapper.cpp | 1 + GDevelop.js/Bindings/postjs.js | 3 + GDevelop.js/CMakeLists.txt | 1 + GDevelop.js/scripts/generate-types.js | 1 + GDevelop.js/types/gdspineanimation.js | 12 + .../types/gdspineobjectconfiguration.js | 15 + GDevelop.js/types/libgdevelop.js | 3 + newIDE/app/package-lock.json | 775 +- newIDE/app/package.json | 6 +- .../ObjectAnimationNameField.js | 14 + .../BrowserJsExtensionsLoader.js | 2 +- .../src/ObjectEditor/Editors/Model3DEditor.js | 9 +- .../src/ObjectEditor/Editors/SpineEditor.js | 511 + .../src/ObjectEditor/ObjectsEditorService.js | 16 + newIDE/app/src/ObjectsList/index.js | 1 + .../ObjectsRenderingService.js | 5 +- .../ObjectsRendering/PixiResourcesLoader.js | 96 +- .../ResourcesList/BrowserResourceSources.js | 6 +- .../src/ResourcesList/LocalResourceSources.js | 6 +- .../app/src/ResourcesList/ResourceSelector.js | 5 +- .../app/src/ResourcesList/ResourceSource.js | 2 +- 38 files changed, 26385 insertions(+), 1222 deletions(-) create mode 100644 Extensions/Spine/CMakeLists.txt create mode 100644 Extensions/Spine/GDevelop.code-workspace create mode 100644 Extensions/Spine/SpineObjectConfiguration.cpp create mode 100644 Extensions/Spine/SpineObjectConfiguration.h create mode 100644 GDJS/Runtime/pixi-renderers/pixi-spine.umd.js create mode 100644 GDJS/Runtime/textmanager.ts create mode 100644 GDevelop.js/types/gdspineanimation.js create mode 100644 GDevelop.js/types/gdspineobjectconfiguration.js create mode 100644 newIDE/app/src/ObjectEditor/Editors/SpineEditor.js diff --git a/Extensions/CMakeLists.txt b/Extensions/CMakeLists.txt index 1c9ad2510e25..8d531372e50f 100644 --- a/Extensions/CMakeLists.txt +++ b/Extensions/CMakeLists.txt @@ -26,6 +26,7 @@ set( TextEntryObject TextObject TiledSpriteObject + Spine TopDownMovementBehavior) # Automatically add all listed extensions diff --git a/Extensions/Spine/CMakeLists.txt b/Extensions/Spine/CMakeLists.txt new file mode 100644 index 000000000000..0c89c6faf7b9 --- /dev/null +++ b/Extensions/Spine/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.6) +cmake_policy(SET CMP0015 NEW) + +project(SpineObject) +gd_add_extension_includes() + +#Defines +### +gd_add_extension_definitions(SpineObject) + +#The targets +### +include_directories(.) +file(GLOB source_files *.cpp *.h) +gd_add_clang_utils(SpineObject "${source_files}") +gd_add_extension_target(SpineObject "${source_files}") + +#Linker files for the IDE extension +### +gd_extension_link_libraries(SpineObject) diff --git a/Extensions/Spine/GDevelop.code-workspace b/Extensions/Spine/GDevelop.code-workspace new file mode 100644 index 000000000000..c3986797c37a --- /dev/null +++ b/Extensions/Spine/GDevelop.code-workspace @@ -0,0 +1,125 @@ +{ + "folders": [ + { + "path": "../.." + } + ], + "settings": { + "files.associations": { + "*.idl": "java", + "Fastfile": "ruby", + "iosfwd": "cpp", + "functional": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "algorithm": "cpp", + "random": "cpp", + "__config": "cpp", + "cstddef": "cpp", + "exception": "cpp", + "initializer_list": "cpp", + "new": "cpp", + "stdexcept": "cpp", + "typeinfo": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "complex": "cpp", + "cstdarg": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "istream": "cpp", + "limits": "cpp", + "memory": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "streambuf": "cpp", + "hashtable": "cpp", + "tuple": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "__split_buffer": "cpp", + "deque": "cpp", + "iterator": "cpp", + "list": "cpp", + "map": "cpp", + "queue": "cpp", + "regex": "cpp", + "set": "cpp", + "stack": "cpp", + "string": "cpp", + "vector": "cpp", + "iostream": "cpp", + "__functional_03": "cpp", + "__hash_table": "cpp", + "__tree": "cpp", + "bitset": "cpp", + "__bit_reference": "cpp", + "__mutex_base": "cpp", + "fstream": "cpp", + "ios": "cpp", + "__locale": "cpp", + "valarray": "cpp", + "freeglut_spaceball.c": "cpp", + "__tuple": "cpp", + "hash_map": "cpp", + "hash_set": "cpp", + "system_error": "cpp", + "__nullptr": "cpp", + "__functional_base": "cpp", + "__functional_base_03": "cpp", + "chrono": "cpp", + "ratio": "cpp", + "atomic": "cpp", + "locale": "cpp", + "string_view": "cpp", + "__string": "cpp", + "cstring": "cpp", + "iomanip": "cpp", + "cstdint": "cpp", + "forward_list": "cpp", + "mutex": "cpp", + "__hash": "cpp", + "__debug": "cpp", + "__threading_support": "cpp", + "any": "cpp", + "array": "cpp", + "cinttypes": "cpp", + "numeric": "cpp", + "__memory": "cpp", + "__errc": "cpp", + "__node_handle": "cpp", + "bit": "cpp", + "optional": "cpp", + "filesystem": "cpp", + "compare": "cpp", + "concepts": "cpp", + "xfacet": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocinfo": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xstddef": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp", + "xlocbuf": "cpp", + "xlocmes": "cpp", + "xmemory0": "cpp", + "memory_resource": "cpp", + "__bits": "cpp", + "__verbose_abort": "cpp", + "variant": "cpp" + }, + "javascript.validate.enable": false + } +} \ No newline at end of file diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 638049c3ea21..336c4a00ae18 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -25,131 +25,33 @@ module.exports = { gd /*: libGDevelop */ ) { const extension = new gd.PlatformExtension(); + extension .setExtensionInformation( - 'Spine', + 'SpineObject', _('Spine'), - _( - 'Displays a text using a "Bitmap Font" (an image representing characters). This is more performant than a traditional Text object and it allows for complete control on the characters aesthetic.' - ), + _('Displays a Spine animation.'), 'Aurélien Vivet', 'Open source (MIT License)' ) - .setExtensionHelpPath('/objects/bitmap_text') - .setCategory('Text'); + .setExtensionHelpPath('/objects/spine') + .setCategory('General'); + extension .addInstructionOrExpressionGroupMetadata(_('Spine')) - .setIcon('JsPlatform/Extensions/bitmapfont32.png'); - - const bitmapTextObject = new gd.ObjectJsImplementation(); - // $FlowExpectedError - bitmapTextObject.updateProperty = function ( - objectContent, - propertyName, - newValue - ) { - if (propertyName in objectContent) { - if (typeof objectContent[propertyName] === 'boolean') - objectContent[propertyName] = newValue === '1'; - else if (typeof objectContent[propertyName] === 'number') - objectContent[propertyName] = parseFloat(newValue); - else objectContent[propertyName] = newValue; - return true; - } - - return false; - }; - // $FlowExpectedError - bitmapTextObject.getProperties = function (objectContent) { - const objectProperties = new gd.MapStringPropertyDescriptor(); - - objectProperties - .getOrCreate('jsonResourceName') - .setValue(objectContent.jsonResourceName) - .setType('resource') - .addExtraInfo('json') - .setLabel(_('Spine JSON')) - .setGroup(_('Spine Files')); - - objectProperties - .getOrCreate('atlasResourceName') - .setValue(objectContent.atlasResourceName) - .setType('resource') - .addExtraInfo('atlas') - .setLabel(_('Atlas file')) - .setGroup(_('Spine Files')); - - objectProperties - .getOrCreate('imageResourceName') - .setValue(objectContent.textureAtlasResourceName) - .setType('resource') - .addExtraInfo('image') - .setLabel(_('Spine atlas image')) - .setGroup(_('Spine Files')); - - objectProperties - .getOrCreate('opacity') - .setValue(objectContent.opacity.toString()) - .setType('number') - .setLabel(_('Opacity (0-255)')) - .setGroup(_('Appearance')); - - objectProperties - .getOrCreate('scale') - .setValue(objectContent.scale.toString()) - .setType('number') - .setLabel(_('Text scale')) - .setGroup(_('Appearance')); - - return objectProperties; - }; - bitmapTextObject.setRawJSONContent( - JSON.stringify({ - opacity: 255, - scale: 1, - jsonResourceName: '', - atlasResourceName: '', - imageResourceName: '', - }) - ); - - // $FlowExpectedError - bitmapTextObject.updateInitialInstanceProperty = function ( - objectContent, - instance, - propertyName, - newValue, - project, - layout - ) { - return false; - }; - // $FlowExpectedError - bitmapTextObject.getInitialInstanceProperties = function ( - content, - instance, - project, - layout - ) { - var instanceProperties = new gd.MapStringPropertyDescriptor(); - return instanceProperties; - }; + .setIcon('CppPlatform/Extensions/spriteicon.png'); const object = extension .addObject( 'SpineObject', _('Spine'), - _( - 'Display and animate Spine skeleton. Select Spine files (json, atlas, image).' - ), - 'JsPlatform/Extensions/bitmapfont32.png', - bitmapTextObject + _('Display and animate Spine skeleton. Select Spine files (json, atlas, image).'), + 'CppPlatform/Extensions/spriteicon.png', + new gd.SpineObjectConfiguration() ) .setIncludeFile('Extensions/Spine/spineruntimeobject.js') - .addIncludeFile( - 'Extensions/Spine/spineruntimeobject-pixi-renderer.js' - ) - .setCategoryFullName(_('Text')); + .addIncludeFile('Extensions/Spine/spineruntimeobject-pixi-renderer.js') + .setCategoryFullName(_('General')); object .addExpressionAndConditionAndAction( @@ -161,7 +63,7 @@ module.exports = { '', 'res/conditions/opacity24.png' ) - .addParameter('object', _('Bitmap text'), 'SpineObject', false) + .addParameter('object', _('Spine'), 'SpineObject', false) .useStandardParameters( 'number', gd.ParameterOptions.makeNewOptions().setDescription( @@ -181,7 +83,7 @@ module.exports = { '', 'res/actions/scale24_black.png' ) - .addParameter('object', _('Bitmap text'), 'SpineObject', false) + .addParameter('object', _('Spine'), 'SpineObject', false) .useStandardParameters( 'number', gd.ParameterOptions.makeNewOptions().setDescription( @@ -190,6 +92,47 @@ module.exports = { ) .setFunctionName('setScale') .setGetter('getScale'); + + + object + .addExpressionAndConditionAndAction( + 'number', + 'Animation', + _('Animation (by number)'), + _( + 'the number of the animation played by the object (the number from the animations list)' + ), + _('the number of the animation'), + _('Animations and images'), + 'res/actions/animation24.png' + ) + .addParameter('object', _('Spine'), 'SpineObject') + .useStandardParameters('number', gd.ParameterOptions.makeNewOptions()) + .markAsSimple() + .setFunctionName('setAnimationIndex') + .setGetter('getAnimationIndex'); + + object + .addExpressionAndConditionAndAction( + 'string', + 'AnimationName', + _('Animation (by name)'), + _('the animation played by the object'), + _('the animation'), + _('Animations and images'), + 'res/actions/animation24.png' + ) + .addParameter('object', _('Spine'), 'SpineObject') + .useStandardParameters( + 'objectAnimationName', + gd.ParameterOptions.makeNewOptions().setDescription( + _('Animation name') + ) + ) + .markAsAdvanced() + .setFunctionName('setAnimationName') + .setGetter('getAnimationName'); + return extension; }, @@ -219,9 +162,9 @@ module.exports = { objectsEditorService /*: ObjectsEditorService */ ) { objectsEditorService.registerEditorConfiguration( - 'Spine::SpineObject', + 'SpineObject::SpineObject', objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({ - helpPagePath: '/objects/bitmap_text', + helpPagePath: '/objects/spine', }) ); }, @@ -233,327 +176,144 @@ module.exports = { registerInstanceRenderers: function ( objectsRenderingService /*: ObjectsRenderingService */ ) { - const RenderedInstance = objectsRenderingService.RenderedInstance; - const PIXI = objectsRenderingService.PIXI; - - /** The bitmap font used in case another font can't be loaded. */ - let defaultBitmapFont = null; - - const defaultBitmapFontInstallKey = 'GD-DEFAULT-BITMAP-FONT'; - - /** - * Map counting the number of "reference" to a bitmap font. This is useful - * to uninstall a bitmap font when not used anymore. - */ - const bitmapFontUsageCount = {}; - - /** - * We patch the installed font to use a name that is unique for each font data and texture, - * to avoid conflicts between different font files using the same font name (by default, the - * font name used by Pixi is the one inside the font data, but this name is not necessarily unique. - * For example, 2 resources can use the same font, or we can have multiple objects with the same - * font data and different textures). - */ - const patchBitmapFont = (bitmapFont, bitmapFontInstallKey) => { - const defaultName = bitmapFont.font; - bitmapFont.font = bitmapFontInstallKey; - PIXI.BitmapFont.available[bitmapFontInstallKey] = bitmapFont; - - delete PIXI.BitmapFont.available[defaultName]; - return PIXI.BitmapFont.available[bitmapFontInstallKey]; - }; - - /** - * Return a default bitmap font to be used in case another font can't be loaded. - */ - const getDefaultBitmapFont = () => { - if (defaultBitmapFont) return defaultBitmapFont; - - const defaultBitmapFontStyle = new PIXI.TextStyle({ - fontFamily: 'Arial', - fontSize: 20, - padding: 5, - align: 'left', - fill: '#ffffff', - wordWrap: true, - lineHeight: 20, - }); - - defaultBitmapFont = patchBitmapFont( - PIXI.BitmapFont.from( - defaultBitmapFontStyle.fontFamily, - defaultBitmapFontStyle, - { - chars: [ - [' ', '~'], // All the printable ASCII characters - ], - } - ), - defaultBitmapFontInstallKey - ); - return defaultBitmapFont; - }; - - /** - * Given a bitmap font resource name and a texture atlas resource name, returns the PIXI.BitmapFont - * for it. - * The font must be released with `releaseBitmapFont` when not used anymore - so that it can be removed - * from memory when not used by any instance. - * - * @param pixiResourcesLoader - * @param project - * @param bitmapFontResourceName - * @param textureAtlasResourceName - */ - const obtainBitmapFont = ( - pixiResourcesLoader, - project, - bitmapFontResourceName, - textureAtlasResourceName - ) => { - const bitmapFontInstallKey = - bitmapFontResourceName + '@' + textureAtlasResourceName; - - if (PIXI.BitmapFont.available[bitmapFontInstallKey]) { - // Return the existing BitmapFont that is already in memory and already installed. - bitmapFontUsageCount[bitmapFontInstallKey] = - (bitmapFontUsageCount[bitmapFontInstallKey] || 0) + 1; - return Promise.resolve(PIXI.BitmapFont.available[bitmapFontInstallKey]); - } + const { PIXI, RenderedInstance } = objectsRenderingService; - // Get the atlas texture, the bitmap font data and install the font: - const texture = pixiResourcesLoader.getPIXITexture( - project, - textureAtlasResourceName - ); + class RenderedSpineInstance extends RenderedInstance { + _spine; + _rect = new PIXI.Graphics(); + _initialWidth; + _initialHeight; + _animationIndex; - const loadBitmapFont = () => + constructor( + project, + layout, + instance, + associatedObjectConfiguration, + pixiContainer, pixiResourcesLoader - .getBitmapFontData(project, bitmapFontResourceName) - .then((fontData) => { - if (!texture.valid) - throw new Error( - 'Tried to install a BitmapFont with an invalid texture.' - ); - - const bitmapFont = patchBitmapFont( - PIXI.BitmapFont.install(fontData, texture), - bitmapFontInstallKey - ); - bitmapFontUsageCount[bitmapFontInstallKey] = - (bitmapFontUsageCount[bitmapFontInstallKey] || 0) + 1; - - return bitmapFont; - }) - .catch((err) => { - console.warn('Unable to load font data:', err); - console.info( - 'Is the texture atlas properly set for the Spine object? The default font will be used instead.' - ); - - const bitmapFont = getDefaultBitmapFont(); - return bitmapFont; - }); + ) { + super( + project, + layout, + instance, + associatedObjectConfiguration, + pixiContainer, + pixiResourcesLoader + ); - if (!texture.valid) { - // Post pone texture update if texture is not loaded. - // (otherwise, the bitmap font would not get updated when the - // texture is loaded and updated). - return new Promise((resolve) => { - texture.once('update', () => { - resolve(loadBitmapFont()); - }); - }); - } else { - // We're ready to load the bitmap font now, as the texture - // is already loaded. - return loadBitmapFont(); + // there is issue with spine selection. mouse events are not triggering during interaction. + // create the invisible background rectangle to fill spine range. + this._rect.alpha = 0; + this._pixiObject = new PIXI.Container(); + this._pixiObject.addChild(this._rect); + this._pixiContainer.addChild(this._pixiObject); + + this.loadSpine(); + this.update(); } - }; - - /** - * When a font is not used by an object anymore (object destroyed or font changed), - * call this function to decrease the internal count of objects using the font. - * - * Fonts are unloaded when not used anymore. - */ - const releaseBitmapFont = (bitmapFontInstallKey) => { - if (bitmapFontInstallKey === defaultBitmapFontInstallKey) { - // Never uninstall the default bitmap font. - return; + + // use smth better. can I create texture of default spine stage ? + static getThumbnail(project, resourcesLoader, objectConfiguration) { + return 'JsPlatform/Extensions/3d_box.svg'; } - if (!bitmapFontUsageCount[bitmapFontInstallKey]) { - console.error( - 'BitmapFont with name ' + - bitmapFontInstallKey + - ' was tried to be released but was never marked as used.' - ); - return; + loadSpine() { + const jsonResourceName = this.properties.get('jsonResourceName').getValue(); + const imageResourceName = this.properties.get('imageResourceName').getValue(); + const atlasResourceName = this.properties.get('atlasResourceName').getValue(); + + this._pixiResourcesLoader + .getSpineData(this._project, jsonResourceName, imageResourceName, atlasResourceName) + .then((spineData) => {; + this._spine = new PIXI.Spine(spineData); + this._pixiObject.addChild(this._spine); + this.update(); + }); } - bitmapFontUsageCount[bitmapFontInstallKey]--; - if (bitmapFontUsageCount[bitmapFontInstallKey] === 0) { - PIXI.BitmapFont.uninstall(bitmapFontInstallKey); - console.info( - 'Uninstalled BitmapFont "' + bitmapFontInstallKey + '" from memory.' - ); + update() { + // instance settings + this._pixiObject.position.set(this._instance.getX(), this._instance.getY()); + + // object settings + this.setAnimation(this._instance.getRawDoubleProperty('animation')); + + const width = this.getWidth(); + const height = this.getHeight(); + + this._rect.clear(); + this._rect.beginFill(0xFFFFFF); + this._rect.lineStyle(0, 0xFFFFFF); + this._rect.drawRect(0, 0, width, height); + + if (this._spine) { + const s = this._spine; + s.width = width; + s.height = height; + s.alpha = this.properties.get('opacity').getValue() / 255; + const localBounds = s.getLocalBounds(undefined, true); + s.position.set(-localBounds.x * s.scale.x, -localBounds.y * s.scale.y); + } + + this._pixiObject.calculateBounds(); } - }; - - /** - * Renderer for instances of Spine inside the IDE. - * - * @extends RenderedSpineInstance - * @class RenderedSpineInstance - * @constructor - */ - function RenderedSpineInstance( - project, - layout, - instance, - associatedObjectConfiguration, - pixiContainer, - pixiResourcesLoader - ) { - RenderedInstance.call( - this, - project, - layout, - instance, - associatedObjectConfiguration, - pixiContainer, - pixiResourcesLoader - ); - // We'll track changes of the font to trigger the loading of the new font. - this._currentBitmapFontResourceName = ''; - this._currentTextureAtlasResourceName = ''; + setAnimation(index) { + const s = this._spine; + const {configuration} = this; + + if (!s || configuration.hasNoAnimations() || index === this._animationIndex) { + return; + } + + // should I do that ? maybe just { return; } ? + if (!Number.isInteger(index) || index < 0) { + index = 0; + } else if (configuration.getAnimationsCount() <= index) { + index = configuration.getAnimationsCount() - 1; + } + + this._animationIndex = index; + const animation = configuration.getAnimation(index); + const name = animation.getName?.(); + const source = animation.getSource?.(); + const shouldLoop = animation.shouldLoop?.(); + + // reset scale to track new animation range + // if custome size is set it will be reinitialized in update method + s.scale.set(1, 1); + s.state.setAnimation(0, source, shouldLoop); + s.state.tracks[0].trackTime = 0; + s.update(0); + s.autoUpdate = false; + this._initialWidth = s.width; + this._initialHeight = s.height; + } - this._pixiObject = new PIXI.Spine('', { - // Use a default font. The proper font will be loaded in `update` method. - fontName: getDefaultBitmapFont().font, - }); + getDefaultWidth() { + const scale = +this.properties.get('scale').getValue() || 1; - this._pixiObject.anchor.x = 0.5; - this._pixiObject.anchor.y = 0.5; - this._pixiContainer.addChild(this._pixiObject); - this.update(); - } - RenderedSpineInstance.prototype = Object.create( - RenderedInstance.prototype - ); + return typeof this._initialWidth === 'number' ? this._initialWidth * scale : 256; + } - /** - * Return the path to the thumbnail of the specified object. - */ - RenderedSpineInstance.getThumbnail = function ( - project, - resourcesLoader, - objectConfiguration - ) { - return 'JsPlatform/Extensions/bitmapfont24.png'; - }; - - // This is called to update the PIXI object on the scene editor - RenderedSpineInstance.prototype.update = function () { - const properties = this._associatedObjectConfiguration.getProperties(); - - // Update the rendered text properties (note: Pixi is only - // applying changes if there were changed). - const rawText = properties.get('text').getValue(); - this._pixiObject.text = rawText; - - const opacity = properties.get('opacity').getValue(); - this._pixiObject.alpha = opacity / 255; - - const align = properties.get('align').getValue(); - this._pixiObject.align = align; - - const color = properties.get('tint').getValue(); - this._pixiObject.tint = - objectsRenderingService.rgbOrHexToHexNumber(color); - - const scale = properties.get('scale').getValue() || 1; - this._pixiObject.scale.set(scale); - - // Track the changes in font to load the new requested font. - const bitmapFontResourceName = properties - .get('bitmapFontResourceName') - .getValue(); - const textureAtlasResourceName = properties - .get('textureAtlasResourceName') - .getValue(); - - if ( - this._currentBitmapFontResourceName !== bitmapFontResourceName || - this._currentTextureAtlasResourceName !== textureAtlasResourceName - ) { - // Release the old font (if it was installed). - releaseBitmapFont(this._pixiObject.fontName); - - // Temporarily go back to the default font, as the PIXI.Spine - // object does not support being displayed with a font not installed at all. - // It will be replaced as soon as the proper font is loaded. - this._pixiObject.fontName = getDefaultBitmapFont().font; - - this._currentBitmapFontResourceName = bitmapFontResourceName; - this._currentTextureAtlasResourceName = textureAtlasResourceName; - obtainBitmapFont( - this._pixiResourcesLoader, - this._project, - this._currentBitmapFontResourceName, - this._currentTextureAtlasResourceName - ).then((bitmapFont) => { - this._pixiObject.fontName = bitmapFont.font; - this._pixiObject.fontSize = bitmapFont.size; - this._pixiObject.dirty = true; - }); + getDefaultHeight() { + const scale = +this.properties.get('scale').getValue() || 1; + + return typeof this._initialHeight === 'number' ? this._initialHeight * scale : 256; } - // Set up the wrapping width if enabled. - const wordWrap = properties.get('wordWrap').getValue() === 'true'; - if (wordWrap && this._instance.hasCustomSize()) { - this._pixiObject.maxWidth = - this.getCustomWidth() / this._pixiObject.scale.x; - this._pixiObject.dirty = true; - } else { - this._pixiObject.maxWidth = 0; - this._pixiObject.dirty = true; + get configuration() { + return gd.asSpineConfiguration(this._associatedObjectConfiguration); } - this._pixiObject.position.x = - this._instance.getX() + (this._pixiObject.textWidth * scale) / 2; - this._pixiObject.position.y = - this._instance.getY() + (this._pixiObject.textHeight * scale) / 2; - this._pixiObject.rotation = RenderedInstance.toRad( - this._instance.getAngle() - ); - }; - - RenderedSpineInstance.prototype.onRemovedFromScene = function () { - RenderedInstance.prototype.onRemovedFromScene.call(this); - - releaseBitmapFont(this._pixiObject.fontName); - this._pixiObject.destroy(); - }; - - /** - * Return the width of the instance, when it's not resized. - */ - RenderedSpineInstance.prototype.getDefaultWidth = function () { - return this._pixiObject.width; - }; - - /** - * Return the height of the instance, when it's not resized. - */ - RenderedSpineInstance.prototype.getDefaultHeight = function () { - return this._pixiObject.height; - }; + get properties() { + return this._associatedObjectConfiguration.getProperties(); + } + } objectsRenderingService.registerInstanceRenderer( - 'Spine::SpineObject', + 'SpineObject::SpineObject', RenderedSpineInstance ); }, diff --git a/Extensions/Spine/SpineObjectConfiguration.cpp b/Extensions/Spine/SpineObjectConfiguration.cpp new file mode 100644 index 000000000000..cb45bf190c3e --- /dev/null +++ b/Extensions/Spine/SpineObjectConfiguration.cpp @@ -0,0 +1,220 @@ +/** + +GDevelop - Particle System Extension +Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com) +This project is released under the MIT License. +*/ + +#include "SpineObjectConfiguration.h" + +#include "GDCore/CommonTools.h" +#include "GDCore/IDE/Project/ArbitraryResourceWorker.h" +#include "GDCore/Project/InitialInstance.h" +#include "GDCore/Project/MeasurementUnit.h" +#include "GDCore/Project/Object.h" +#include "GDCore/Project/Project.h" +#include "GDCore/Project/PropertyDescriptor.h" +#include "GDCore/Serialization/SerializerElement.h" +#include "GDCore/Tools/Localization.h" + +using namespace std; + +SpineObjectConfiguration::SpineObjectConfiguration() + : scale(1), opacity(255), timeScale(1), + jsonResourceName(""), imageResourceName(""), atlasResourceName("") {}; + +bool SpineObjectConfiguration::UpdateProperty(const gd::String &propertyName, const gd::String &newValue) { + if (propertyName == "scale") { + scale = newValue.To(); + return true; + } + if (propertyName == "opacity") { + opacity = newValue.To(); + return true; + } + if (propertyName == "timeScale") { + timeScale = newValue.To(); + return true; + } + if (propertyName == "jsonResourceName") { + jsonResourceName = newValue; + return true; + } + if (propertyName == "imageResourceName") { + imageResourceName = newValue; + return true; + } + if (propertyName == "atlasResourceName") { + atlasResourceName = newValue; + return true; + } + + return false; +} + +std::map +SpineObjectConfiguration::GetProperties() const { + std::map objectProperties; + + objectProperties["scale"] + .SetValue(gd::String::From(scale)) + .SetType("number") + .SetLabel(_("Scale")) + .SetGroup(_("Appearance")); + + objectProperties["opacity"] + .SetValue(gd::String::From(opacity)) + .SetType("number") + .SetLabel(_("Opacity")) + .SetGroup(_("Appearance")); + + objectProperties["timeScale"] + .SetValue(gd::String::From(timeScale)) + .SetType("number") + .SetLabel(_("Time Scale")) + .SetGroup(_("Play")); + + objectProperties["jsonResourceName"] + .SetValue(jsonResourceName) + .SetType("resource") + .AddExtraInfo("json") + .SetLabel(_("Json")); + + objectProperties["imageResourceName"] + .SetValue(imageResourceName) + .SetType("resource") + .AddExtraInfo("image") + .SetLabel(_("Atlas image")); + + objectProperties["atlasResourceName"] + .SetValue(atlasResourceName) + .SetType("resource") + .AddExtraInfo("atlas") + .SetLabel(_("Atlas text")); + + return objectProperties; +} + +bool SpineObjectConfiguration::UpdateInitialInstanceProperty( + gd::InitialInstance &instance, const gd::String &propertyName, + const gd::String &newValue, gd::Project &project, gd::Layout &layout) { + if (propertyName == "animation") { + instance.SetRawDoubleProperty( + "animation", std::max(0, newValue.empty() ? 0 : newValue.To())); + } + + return true; +} + +std::map +SpineObjectConfiguration::GetInitialInstanceProperties(const gd::InitialInstance &instance, gd::Project &project, gd::Layout &layout) { + std::map properties; + properties["animation"] = + gd::PropertyDescriptor( + gd::String::From(instance.GetRawDoubleProperty("animation"))) + .SetLabel(_("Animation")) + .SetType("number"); + + return properties; +} + +void SpineObjectConfiguration::DoUnserializeFrom(gd::Project &project, const gd::SerializerElement &element) { + auto &content = element.GetChild("content"); + + scale = content.GetDoubleAttribute("scale"); + opacity = content.GetDoubleAttribute("opacity"); + timeScale = content.GetDoubleAttribute("timeScale"); + jsonResourceName = content.GetStringAttribute("jsonResourceName"); + imageResourceName = content.GetStringAttribute("imageResourceName"); + atlasResourceName = content.GetStringAttribute("atlasResourceName"); + + RemoveAllAnimations(); + auto &animationsElement = content.GetChild("animations"); + animationsElement.ConsiderAsArrayOf("animation"); + for (std::size_t i = 0; i < animationsElement.GetChildrenCount(); ++i) { + auto &animationElement = animationsElement.GetChild(i); + SpineAnimation animation; + animation.SetName(animationElement.GetStringAttribute("name", "")); + animation.SetSource(animationElement.GetStringAttribute("source", "")); + animation.SetShouldLoop(animationElement.GetBoolAttribute("loop", false)); + AddAnimation(animation); + } +} + +void SpineObjectConfiguration::DoSerializeTo( + gd::SerializerElement &element) const { + auto &content = element.AddChild("content"); + content.SetAttribute("scale", scale); + content.SetAttribute("opacity", opacity); + content.SetAttribute("timeScale", timeScale); + content.SetAttribute("jsonResourceName", jsonResourceName); + content.SetAttribute("imageResourceName", imageResourceName); + content.SetAttribute("atlasResourceName", atlasResourceName); + + auto &animationsElement = content.AddChild("animations"); + animationsElement.ConsiderAsArrayOf("animation"); + for (auto &animation : animations) { + auto &animationElement = animationsElement.AddChild("animation"); + animationElement.SetAttribute("name", animation.GetName()); + animationElement.SetAttribute("source", animation.GetSource()); + animationElement.SetAttribute("loop", animation.ShouldLoop()); + } +} + +void SpineObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker &worker) { + worker.ExposeJson(jsonResourceName); + worker.ExposeImage(imageResourceName); + worker.ExposeAtlas(atlasResourceName); +} + +const SpineAnimation & +SpineObjectConfiguration::GetAnimation(std::size_t nb) const { + if (nb >= animations.size()) { + nb = nb % animations.size(); + } + + return animations[nb]; +} + +SpineAnimation &SpineObjectConfiguration::GetAnimation(std::size_t nb) { + if (nb >= animations.size()) { + nb = nb % animations.size(); + } + + return animations[nb]; +} + +bool SpineObjectConfiguration::HasAnimationNamed(const gd::String &name) const { + return !name.empty() && (find_if(animations.begin(), animations.end(), + [&name](const SpineAnimation &animation) { + return animation.GetName() == name; + }) != animations.end()); +} + +void SpineObjectConfiguration::AddAnimation(const SpineAnimation &animation) { + animations.push_back(animation); +} + +bool SpineObjectConfiguration::RemoveAnimation(std::size_t nb) { + if (nb >= GetAnimationsCount()) + return false; + + animations.erase(animations.begin() + nb); + return true; +} + +void SpineObjectConfiguration::SwapAnimations(std::size_t firstIndex, std::size_t secondIndex) { + if (firstIndex < animations.size() && secondIndex < animations.size() && firstIndex != secondIndex) { + std::swap(animations[firstIndex], animations[secondIndex]); + } +} + +void SpineObjectConfiguration::MoveAnimation(std::size_t oldIndex, std::size_t newIndex) { + if (oldIndex >= animations.size() || newIndex >= animations.size()) { + return; + } + + auto animation = animations[oldIndex]; + animations.erase(animations.begin() + oldIndex); + animations.insert(animations.begin() + newIndex, animation); +} diff --git a/Extensions/Spine/SpineObjectConfiguration.h b/Extensions/Spine/SpineObjectConfiguration.h new file mode 100644 index 000000000000..4462d582dc75 --- /dev/null +++ b/Extensions/Spine/SpineObjectConfiguration.h @@ -0,0 +1,165 @@ +/** + +GDevelop - Particle System Extension +Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com) +This project is released under the MIT License. +*/ + +#pragma once + +#include "GDCore/Project/ObjectConfiguration.h" +namespace gd { +class InitialInstance; +class Project; +} // namespace gd + +class GD_EXTENSION_API SpineAnimation { +public: + SpineAnimation() : shouldLoop(false) {}; + virtual ~SpineAnimation(){}; + + /** + * \brief Return the name of the animation + */ + const gd::String &GetName() const { return name; } + + /** + * \brief Change the name of the animation + */ + void SetName(const gd::String &name_) { name = name_; } + + /** + * \brief Return the name of the animation from the GLB file. + */ + const gd::String &GetSource() const { return source; } + + /** + * \brief Change the name of the animation from the GLB file. + */ + void SetSource(const gd::String &source_) { source = source_; } + + /** + * \brief Return true if the animation should loop. + */ + const bool ShouldLoop() const { return shouldLoop; } + + /** + * \brief Change whether the animation should loop or not. + */ + void SetShouldLoop(bool shouldLoop_) { shouldLoop = shouldLoop_; } + +private: + gd::String name; + gd::String source; + bool shouldLoop; +}; + +/** + * \brief Particle Emitter object used for storage and for the IDE. + */ +class GD_EXTENSION_API SpineObjectConfiguration : public gd::ObjectConfiguration { +public: + SpineObjectConfiguration(); + virtual ~SpineObjectConfiguration(){}; + virtual std::unique_ptr Clone() const override { + return gd::make_unique(*this); + } + + virtual void ExposeResources(gd::ArbitraryResourceWorker &worker) override; + + virtual std::mapGetProperties() const override; + + virtual bool UpdateProperty(const gd::String &name, const gd::String &value) override; + + virtual std::map + GetInitialInstanceProperties(const gd::InitialInstance &instance, + gd::Project &project, + gd::Layout &layout) override; + + virtual bool UpdateInitialInstanceProperty(gd::InitialInstance &instance, + const gd::String &name, + const gd::String &value, + gd::Project &project, + gd::Layout &layout) override; + + /** \name Animations + * Methods related to animations management + */ + ///@{ + /** + * \brief Return the animation at the specified index. + * If the index is out of bound, a "bad animation" object is returned. + */ + const SpineAnimation &GetAnimation(std::size_t nb) const; + + /** + * \brief Return the animation at the specified index. + * If the index is out of bound, a "bad animation" object is returned. + */ + SpineAnimation &GetAnimation(std::size_t nb); + + /** + * \brief Return the number of animations this object has. + */ + std::size_t GetAnimationsCount() const { return animations.size(); }; + + /** + * \brief Return true if the animation called "name" exists. + */ + bool HasAnimationNamed(const gd::String& name) const; + + /** + * \brief Add an animation at the end of the existing ones. + */ + void AddAnimation(const SpineAnimation &animation); + + /** + * \brief Remove an animation. + */ + bool RemoveAnimation(std::size_t nb); + + /** + * \brief Remove all animations. + */ + void RemoveAllAnimations() { animations.clear(); } + + /** + * \brief Return true if the object hasn't any animation. + */ + bool HasNoAnimations() const { return animations.empty(); } + + /** + * \brief Swap the position of two animations + */ + void SwapAnimations(std::size_t firstIndex, std::size_t secondIndex); + + /** + * \brief Change the position of the specified animation + */ + void MoveAnimation(std::size_t oldIndex, std::size_t newIndex); + + /** + * \brief Return a read-only reference to the vector containing all the + * animation of the object. + */ + const std::vector &GetAllAnimations() const { + return animations; + } + + ///@} + +protected: + virtual void DoUnserializeFrom(gd::Project &project, const gd::SerializerElement &element) override; + virtual void DoSerializeTo(gd::SerializerElement &element) const override; + +private: + double scale; + double opacity; + double timeScale; + + gd::String jsonResourceName; + gd::String imageResourceName; + gd::String atlasResourceName; + + std::vector animations; +}; diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index b99b4e19513d..f7b2d5a0f7cb 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -1,12 +1,14 @@ namespace gdjs { import PIXI = GlobalPIXIModule.PIXI; + import PIXI_SPINE = GlobalPIXIModule.PIXI_SPINE; /** * The PIXI.js renderer for the Bitmap Text runtime object. */ export class SpineRuntimeObjectPixiRenderer { _object: gdjs.SpineRuntimeObject; - _pixiObject: PIXI.BitmapText; + _pixiObject: PIXI.Container; + _spine!: Promise; /** * @param runtimeObject The object to render @@ -14,22 +16,11 @@ namespace gdjs { */ constructor( runtimeObject: gdjs.SpineRuntimeObject, - instanceContainer: gdjs.RuntimeInstanceContainer + private instanceContainer: gdjs.RuntimeInstanceContainer ) { this._object = runtimeObject; - - // Obtain the bitmap font to use in the object. - const bitmapFont = instanceContainer - .getGame() - .getBitmapFontManager() - .obtainBitmapFont( - runtimeObject._bitmapFontResourceName, - runtimeObject._textureAtlasResourceName - ); - this._pixiObject = new PIXI.BitmapText(runtimeObject._text, { - fontName: bitmapFont.font, - fontSize: bitmapFont.size, - }); + this._pixiObject = new PIXI.Container(); + this.constructSpine(); // Set the object on the scene instanceContainer @@ -37,20 +28,11 @@ namespace gdjs { .getRenderer() .addRendererObject(this._pixiObject, runtimeObject.getZOrder()); - // Set the anchor in the center, so that the object rotates around - // its center. - // @ts-ignore - this._pixiObject.anchor.x = 0.5; - // @ts-ignore - this._pixiObject.anchor.y = 0.5; - - this.updateAlignment(); - this.updateTextContent(); + this.updateTimeScale(); + this.updatePosition(); this.updateAngle(); this.updateOpacity(); this.updateScale(); - this.updateWrappingWidth(); - this.updateTint(); } getRendererObject() { @@ -58,118 +40,106 @@ namespace gdjs { } onDestroy() { - // Mark the font from the object as not used anymore. - this._object - .getInstanceContainer() - .getGame() - .getBitmapFontManager() - .releaseBitmapFont(this._pixiObject.fontName); - this._pixiObject.destroy(); } - getFontSize() { - return this._pixiObject.fontSize; + updateTimeScale() { + this._spine.then(spine => spine.state.timeScale = this._object.getTimeScale()); } - updateFont(): void { - // Get the new bitmap font to use - const bitmapFont = this._object - .getInstanceContainer() - .getGame() - .getBitmapFontManager() - .obtainBitmapFont( - this._object._bitmapFontResourceName, - this._object._textureAtlasResourceName - ); - - // Mark the old font as not used anymore - this._object - .getInstanceContainer() - .getGame() - .getBitmapFontManager() - .releaseBitmapFont(this._pixiObject.fontName); + updateScale(): void { + this._pixiObject.scale.set(Math.max(this._object.getScale(), 0)); + } - // Update the font used by the object: - this._pixiObject.fontName = bitmapFont.font; - this._pixiObject.fontSize = bitmapFont.size; - this.updatePosition(); + getScale() { + // is it ok ? see it as a pattern + return Math.max(this._pixiObject.scale.x, this._pixiObject.scale.y); } - updateTint(): void { - this._pixiObject.tint = gdjs.rgbToHexNumber( - this._object._tint[0], - this._object._tint[1], - this._object._tint[2] - ); - this._pixiObject.dirty = true; + updatePosition(): void { + this._pixiObject.position.x = this._object.x; + this._pixiObject.position.y = this._object.y; } - /** - * Get the tint of the bitmap object as a "R;G;B" string. - * @returns the tint of bitmap object in "R;G;B" format. - */ - getTint(): string { - return ( - this._object._tint[0] + - ';' + - this._object._tint[1] + - ';' + - this._object._tint[2] - ); + updateAngle(): void { + this._pixiObject.rotation = gdjs.toRad(this._object.angle); } - updateScale(): void { - this._pixiObject.scale.set(Math.max(this._object._scale, 0)); - this.updatePosition(); + updateOpacity(): void { + this._pixiObject.alpha = this._object.getOpacity() / 255; } - getScale() { - return Math.max(this._pixiObject.scale.x, this._pixiObject.scale.y); + getWidth(): float { + return this._pixiObject.width; } - updateWrappingWidth(): void { - if (this._object._wordWrap) { - this._pixiObject.maxWidth = - this._object._wrappingWidth / this._object._scale; - this._pixiObject.dirty = true; - } else { - this._pixiObject.maxWidth = 0; - this._pixiObject.dirty = true; - } - this.updatePosition(); + getHeight(): float { + return this._pixiObject.height; } - updateTextContent(): void { - this._pixiObject.text = this._object._text; - this.updatePosition(); + setWidth(width: float): void { + this._spine.then(spine => { + spine.width = width; + this.updateBounds(spine); + }); } - updateAlignment(): void { - // @ts-ignore - assume align is always a valid value. - this._pixiObject.align = this._object._align; - this.updatePosition(); + setHeight(height: float): void { + this._spine.then(spine => { + spine.height = height; + this.updateBounds(spine); + }); } - updatePosition(): void { - this._pixiObject.position.x = this._object.x + this.getWidth() / 2; - this._pixiObject.position.y = this._object.y + this.getHeight() / 2; + setSize(width: float, height: float): void { + this._spine?.then(spine => { + spine.width = width; + spine.height = height; + this.updateBounds(spine); + }); } - updateAngle(): void { - this._pixiObject.rotation = gdjs.toRad(this._object.angle); + setAnimation(animation: string, loop: boolean) { + this._spine?.then(s => { + s.state.setAnimation(0, animation, loop); + this.updateBounds(s); + }); } - updateOpacity(): void { - this._pixiObject.alpha = this._object._opacity / 255; + private constructSpine() { + const game = this.instanceContainer.getGame(); + const spineJson = game.getJsonManager().getLoadedJson(this._object.jsonResourceName)!; + const atlasText = game.getTextManager().get(this._object.atlasResourceName)!; + const atlasImage = game.getImageManager().getPIXITexture(this._object.imageResourceName)!; + + this._spine = this.getSpineSkeleton(spineJson, atlasText, atlasImage) + .then(skeleton => { + const s = new PIXI_SPINE.Spine(skeleton); + this._pixiObject.addChild(s); + this.updateBounds(s); + + return s; + }); } - getWidth(): float { - return this._pixiObject.textWidth * this.getScale(); + private updateBounds(s: PIXI_SPINE.Spine) { + const localBounds = s.getLocalBounds(undefined, true); + s.position.set(-localBounds.x * s.scale.x, -localBounds.y * s.scale.y); } - getHeight(): float { - return this._pixiObject.textHeight * this.getScale(); + private getSpineSkeleton(spineJson: Object, atlasText: string, atlasImage: PIXI.Texture) { + return new Promise((resolve) => { + new PIXI_SPINE.TextureAtlas( + atlasText, + (_, textureCb) => textureCb(atlasImage.baseTexture), + (atlas) => { + const resourceMoc = {}; + const spineParser = new PIXI_SPINE.SpineParser(); + spineParser.parseData(resourceMoc as any, spineParser.createJsonParser(), atlas, spineJson); + + resolve((resourceMoc as unknown as { spineData: PIXI_SPINE.ISkeletonData }).spineData); + }); + }); } } export const SpineRuntimeObjectRenderer = SpineRuntimeObjectPixiRenderer; diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 0c9d3c3cdb1f..47d748bc4d7c 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -1,38 +1,30 @@ namespace gdjs { - /** Base parameters for {@link gdjs.SpineRuntimeObject} */ + type SpineAnimation = { name: string; source: string; loop: boolean }; + export type SpineObjectDataType = { - /** The base parameters of the Bitmap Text */ content: { - /** The opacity of the text. */ opacity: float; - /** The scale of the spine. */ scale: float; + timeScale: float; jsonResourceName: string; atlasResourceName: string; imageResourceName: string; + animations: SpineAnimation[]; }; }; export type SpineObjectData = ObjectData & SpineObjectDataType; - /** - * Displays a text using a "Bitmap Font", generated in a external editor like bmFont. - * This is more efficient/faster to render than a traditional text (which needs - * to have its whole texture re-rendered anytime it changes). - * - * Bitmap Font can be created with softwares like: - * * BMFont (Windows, free): http://www.angelcode.com/products/bmfont/|http://www.angelcode.com/products/bmfont/ - * * Glyph Designer (OS X, commercial): http://www.71squared.com/en/glyphdesigner|http://www.71squared.com/en/glyphdesigner - * * Littera (Web-based, free): http://kvazars.com/littera/|http://kvazars.com/littera/ - */ export class SpineRuntimeObject extends gdjs.RuntimeObject { - _opacity: float; - _scale: number; - - _renderer: gdjs.SpineRuntimeObjectPixiRenderer; + private _opacity: float; + private _scale: number; + private _timeScale: number; + private _animations: SpineAnimation[]; + private _currentAnimationIndex!: number; + private _renderer: gdjs.SpineRuntimeObjectPixiRenderer; - jsonResourceName: string; - atlasResourceName: string; - imageResourceName: string; + readonly jsonResourceName: string; + readonly atlasResourceName: string; + readonly imageResourceName: string; /** * @param instanceContainer The container the object belongs to. @@ -44,17 +36,14 @@ namespace gdjs { ) { super(instanceContainer, objectData); + this._animations = objectData.content.animations; + this._timeScale = objectData.content.timeScale; this._opacity = objectData.content.opacity; this._scale = objectData.content.scale; this.jsonResourceName = objectData.content.jsonResourceName; this.atlasResourceName = objectData.content.atlasResourceName; this.imageResourceName = objectData.content.imageResourceName; - - this._renderer = new gdjs.SpineRuntimeObjectRenderer( - this, - instanceContainer - ); - + this._renderer = new gdjs.SpineRuntimeObjectRenderer(this, instanceContainer); // *ALWAYS* call `this.onCreated()` at the very end of your object constructor. this.onCreated(); @@ -64,26 +53,54 @@ namespace gdjs { return this._renderer.getRendererObject(); } - // @ts-ignore updateFromObjectData( - oldObjectData: SpineObjectDataType, - newObjectData: SpineObjectDataType + oldObjectData: SpineObjectData, + newObjectData: SpineObjectData ): boolean { + super.updateFromObjectData if (oldObjectData.content.opacity !== newObjectData.content.opacity) { this.setOpacity(newObjectData.content.opacity); } if (oldObjectData.content.scale !== newObjectData.content.scale) { + // should I prioritize custom size here ? + // is there a same cb if instance properties have been changed ? this.setScale(newObjectData.content.scale); } + if (oldObjectData.content.timeScale !== newObjectData.content.timeScale) { + this.setTimeScale(newObjectData.content.timeScale); + } return true; } + extraInitializationFromInitialInstance(initialInstanceData: InstanceData) { + for (const extraData of initialInstanceData.numberProperties || []) { + if (extraData.name === 'animation') { + this.setAnimationIndex(extraData.value); + } + } + if (initialInstanceData.customSize) { + // prioritize custom size + this.setScale(1); + this._renderer.setSize(initialInstanceData.width, initialInstanceData.height); + this.invalidateHitboxes(); + } + } + onDestroyFromScene(instanceContainer: gdjs.RuntimeInstanceContainer): void { super.onDestroyFromScene(instanceContainer); this._renderer.onDestroy(); } + setTimeScale(timeScale: float): void { + this._timeScale = timeScale; + this._renderer.updateTimeScale(); + } + + getTimeScale(): float { + return this._timeScale; + } + setScale(scale: float): void { this._scale = scale; this._renderer.updateScale(); @@ -94,75 +111,91 @@ namespace gdjs { return this._scale; } - getFontSize(): float { - return this._renderer.getFontSize(); - } - - /** - * Set object position on X axis. - * @param x The new position X of the object. - */ setX(x: float): void { super.setX(x); this._renderer.updatePosition(); } - /** - * Set object position on Y axis. - * @param y The new position Y of the object. - */ setY(y: float): void { super.setY(y); this._renderer.updatePosition(); } - /** - * Set the angle of the object. - * @param angle The new angle of the object. - */ setAngle(angle: float): void { super.setAngle(angle); this._renderer.updateAngle(); } - /** - * Set object opacity. - * @param opacity The new opacity of the object (0-255). - */ setOpacity(opacity: float): void { - if (opacity < 0) { - opacity = 0; - } - if (opacity > 255) { - opacity = 255; - } - this._opacity = opacity; + this._opacity = + opacity < 0 ? 0 : + opacity > 255 ? 255 : + opacity; this._renderer.updateOpacity(); } - /** - * Get object opacity. - */ getOpacity(): float { return this._opacity; } - /** - * Get the width of the object. - */ getWidth(): float { return this._renderer.getWidth(); } - /** - * Get the height of the object. - */ getHeight(): float { return this._renderer.getHeight(); } + + setWidth(width: float): void { + this._renderer.setWidth(width); + this.invalidateHitboxes(); + } + + setHeight(height: float): void { + this._renderer.setHeight(height); + this.invalidateHitboxes(); + } + + setAnimationIndex(animationIndex: number) { + if (!this.isAnimationIndex(animationIndex)) { return; } + + const animation = this._animations[animationIndex]; + this._currentAnimationIndex = animationIndex; + this._renderer.setAnimation(animation.source, animation.loop); + } + + setAnimationName(animationName: string) { + this.setAnimationIndex(this.getAnimationIndex(animationName)); + } + + getCurrentAnimationIndex(): number { + return this._currentAnimationIndex; + } + + getAnimationName(): string { + return this.isAnimationIndex(this._currentAnimationIndex) ? + '' : this._animations[this._currentAnimationIndex].name; + } + + getAnimationIndex(animationName: string) { + return this._animations.findIndex(animation => animation.name === animationName); + } + + isAnimationIndex(animationIndex: number) { + return ( + Number.isInteger(animationIndex) + && animationIndex >= 0 + && animationIndex < this._animations.length + ); + } + + isCurrentAnimationName(name): boolean { + return this.getAnimationName() === name; + } } + gdjs.registerObject( - 'Spine::SpineObject', + 'SpineObject::SpineObject', // @ts-ignore gdjs.SpineRuntimeObject ); diff --git a/GDJS/GDJS/IDE/ExporterHelper.cpp b/GDJS/GDJS/IDE/ExporterHelper.cpp index 917dd4a2caaa..33556c257e69 100644 --- a/GDJS/GDJS/IDE/ExporterHelper.cpp +++ b/GDJS/GDJS/IDE/ExporterHelper.cpp @@ -624,6 +624,7 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers, InsertUnique(includesFiles, "AsyncTasksManager.js"); InsertUnique(includesFiles, "inputmanager.js"); InsertUnique(includesFiles, "jsonmanager.js"); + InsertUnique(includesFiles, "textmanager.js"); InsertUnique(includesFiles, "Model3DManager.js"); InsertUnique(includesFiles, "timemanager.js"); InsertUnique(includesFiles, "polygon.js"); @@ -691,6 +692,7 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers, } if (pixiRenderers) { InsertUnique(includesFiles, "pixi-renderers/pixi.js"); + InsertUnique(includesFiles, "pixi-renderers/pixi-spine.umd.js"); InsertUnique(includesFiles, "pixi-renderers/pixi-filters-tools.js"); InsertUnique(includesFiles, "pixi-renderers/runtimegame-pixi-renderer.js"); InsertUnique(includesFiles, "pixi-renderers/runtimescene-pixi-renderer.js"); diff --git a/GDJS/Runtime/pixi-renderers/pixi-spine.umd.js b/GDJS/Runtime/pixi-renderers/pixi-spine.umd.js new file mode 100644 index 000000000000..4a4f5380493d --- /dev/null +++ b/GDJS/Runtime/pixi-renderers/pixi-spine.umd.js @@ -0,0 +1,24220 @@ +/* eslint-disable */ + +/*! + * pixi-spine - v3.1.2 + * Compiled Tue, 01 Aug 2023 11:10:46 UTC + * + * pixi-spine is licensed under SPINE-LICENSE + * http://esotericsoftware.com/spine-runtimes-license + * + * Copyright 2019-2020, Ivan Igorevich Popelyshev , All Rights Reserved + */ +this.PIXI = this.PIXI || {}; +this.PIXI.spine = this.PIXI.spine || {}; +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@pixi/loaders'), require('@pixi/core'), require('@pixi/constants'), require('@pixi/math'), require('@pixi/display'), require('@pixi/sprite'), require('@pixi/mesh-extras'), require('@pixi/graphics'), require('@pixi/utils')) : + typeof define === 'function' && define.amd ? define(['exports', '@pixi/loaders', '@pixi/core', '@pixi/constants', '@pixi/math', '@pixi/display', '@pixi/sprite', '@pixi/mesh-extras', '@pixi/graphics', '@pixi/utils'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pixi_spine = {}, global.PIXI, global.PIXI, global.PIXI, global.PIXI, global.PIXI, global.PIXI, global.PIXI, global.PIXI, global.PIXI.utils)); +})(this, (function (exports, loaders, core, constants, math, display, sprite, meshExtras, graphics, utils) { 'use strict'; + + /* eslint-disable */ + + /** + * @public + */ + exports.AttachmentType = void 0; + (function (AttachmentType) { + AttachmentType[AttachmentType["Region"] = 0] = "Region"; + AttachmentType[AttachmentType["BoundingBox"] = 1] = "BoundingBox"; + AttachmentType[AttachmentType["Mesh"] = 2] = "Mesh"; + AttachmentType[AttachmentType["LinkedMesh"] = 3] = "LinkedMesh"; + AttachmentType[AttachmentType["Path"] = 4] = "Path"; + AttachmentType[AttachmentType["Point"] = 5] = "Point"; + AttachmentType[AttachmentType["Clipping"] = 6] = "Clipping"; + })(exports.AttachmentType || (exports.AttachmentType = {})); + + /** + * @public + */ + var BinaryInput = /** @class */ (function () { + function BinaryInput(data, strings, index, buffer) { + if (strings === void 0) { strings = new Array(); } + if (index === void 0) { index = 0; } + if (buffer === void 0) { buffer = new DataView(data.buffer); } + this.strings = strings; + this.index = index; + this.buffer = buffer; + } + BinaryInput.prototype.readByte = function () { + return this.buffer.getInt8(this.index++); + }; + BinaryInput.prototype.readUnsignedByte = function () { + return this.buffer.getUint8(this.index++); + }; + BinaryInput.prototype.readShort = function () { + var value = this.buffer.getInt16(this.index); + this.index += 2; + return value; + }; + BinaryInput.prototype.readInt32 = function () { + var value = this.buffer.getInt32(this.index); + this.index += 4; + return value; + }; + BinaryInput.prototype.readInt = function (optimizePositive) { + var b = this.readByte(); + var result = b & 0x7F; + if ((b & 0x80) != 0) { + b = this.readByte(); + result |= (b & 0x7F) << 7; + if ((b & 0x80) != 0) { + b = this.readByte(); + result |= (b & 0x7F) << 14; + if ((b & 0x80) != 0) { + b = this.readByte(); + result |= (b & 0x7F) << 21; + if ((b & 0x80) != 0) { + b = this.readByte(); + result |= (b & 0x7F) << 28; + } + } + } + } + return optimizePositive ? result : ((result >>> 1) ^ -(result & 1)); + }; + BinaryInput.prototype.readStringRef = function () { + var index = this.readInt(true); + return index == 0 ? null : this.strings[index - 1]; + }; + BinaryInput.prototype.readString = function () { + var byteCount = this.readInt(true); + switch (byteCount) { + case 0: + return null; + case 1: + return ""; + } + byteCount--; + var chars = ""; + for (var i = 0; i < byteCount;) { + var b = this.readUnsignedByte(); + switch (b >> 4) { + case 12: + case 13: + chars += String.fromCharCode(((b & 0x1F) << 6 | this.readByte() & 0x3F)); + i += 2; + break; + case 14: + chars += String.fromCharCode(((b & 0x0F) << 12 | (this.readByte() & 0x3F) << 6 | this.readByte() & 0x3F)); + i += 3; + break; + default: + chars += String.fromCharCode(b); + i++; + } + } + return chars; + }; + BinaryInput.prototype.readFloat = function () { + var value = this.buffer.getFloat32(this.index); + this.index += 4; + return value; + }; + BinaryInput.prototype.readBoolean = function () { + return this.readByte() != 0; + }; + return BinaryInput; + }()); + + // Those enums were moved from Animation.ts of spine 3.8 and 4.0 + /** Controls how a timeline value is mixed with the setup pose value or current pose value when a timeline's `alpha` + * < 1. + * + * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. + * @public + * */ + exports.MixBlend = void 0; + (function (MixBlend) { + /** Transitions from the setup value to the timeline value (the current value is not used). Before the first key, the setup + * value is set. */ + MixBlend[MixBlend["setup"] = 0] = "setup"; + /** Transitions from the current value to the timeline value. Before the first key, transitions from the current value to + * the setup value. Timelines which perform instant transitions, such as DrawOrderTimeline or + * AttachmentTimeline, use the setup value before the first key. + * + * `first` is intended for the first animations applied, not for animations layered on top of those. */ + MixBlend[MixBlend["first"] = 1] = "first"; + /** Transitions from the current value to the timeline value. No change is made before the first key (the current value is + * kept until the first key). + * + * `replace` is intended for animations layered on top of others, not for the first animations applied. */ + MixBlend[MixBlend["replace"] = 2] = "replace"; + /** Transitions from the current value to the current value plus the timeline value. No change is made before the first key + * (the current value is kept until the first key). + * + * `add` is intended for animations layered on top of others, not for the first animations applied. Properties + * keyed by additive animations must be set manually or by another animation before applying the additive animations, else + * the property values will increase continually. */ + MixBlend[MixBlend["add"] = 3] = "add"; + })(exports.MixBlend || (exports.MixBlend = {})); + /** Indicates whether a timeline's `alpha` is mixing out over time toward 0 (the setup or current pose value) or + * mixing in toward 1 (the timeline's value). + * + * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. + * @public + * */ + exports.MixDirection = void 0; + (function (MixDirection) { + MixDirection[MixDirection["mixIn"] = 0] = "mixIn"; + MixDirection[MixDirection["mixOut"] = 1] = "mixOut"; + })(exports.MixDirection || (exports.MixDirection = {})); + + // These enums were moved from PathConstraintData.ts of spine 3.7, 3.8 and 4.0 + /** 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. + * @public + * */ + exports.PositionMode = void 0; + (function (PositionMode) { + PositionMode[PositionMode["Fixed"] = 0] = "Fixed"; + PositionMode[PositionMode["Percent"] = 1] = "Percent"; + })(exports.PositionMode || (exports.PositionMode = {})); + /** Controls how bones are rotated, translated, and scaled to match the path. + * + * [Rotate mode](http://esotericsoftware.com/spine-path-constraints#Rotate-mod) in the Spine User Guide. + * @public + * */ + exports.RotateMode = void 0; + (function (RotateMode) { + RotateMode[RotateMode["Tangent"] = 0] = "Tangent"; + RotateMode[RotateMode["Chain"] = 1] = "Chain"; + RotateMode[RotateMode["ChainScale"] = 2] = "ChainScale"; + })(exports.RotateMode || (exports.RotateMode = {})); + + // This enum was moved from BoneData.ts of spine 3.7, 3.8 and 4.0 + /** Determines how a bone inherits world transforms from parent bones. + * @public + * */ + exports.TransformMode = void 0; + (function (TransformMode) { + TransformMode[TransformMode["Normal"] = 0] = "Normal"; + TransformMode[TransformMode["OnlyTranslation"] = 1] = "OnlyTranslation"; + TransformMode[TransformMode["NoRotationOrReflection"] = 2] = "NoRotationOrReflection"; + TransformMode[TransformMode["NoScale"] = 3] = "NoScale"; + TransformMode[TransformMode["NoScaleOrReflection"] = 4] = "NoScaleOrReflection"; + })(exports.TransformMode || (exports.TransformMode = {})); + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + var extendStatics$4 = function(d, b) { + extendStatics$4 = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics$4(d, b); + }; + + function __extends$4(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics$4(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + + /** + * @public + */ + function filterFromString(text) { + switch (text.toLowerCase()) { + case "nearest": return exports.TextureFilter.Nearest; + case "linear": return exports.TextureFilter.Linear; + case "mipmap": return exports.TextureFilter.MipMap; + case "mipmapnearestnearest": return exports.TextureFilter.MipMapNearestNearest; + case "mipmaplinearnearest": return exports.TextureFilter.MipMapLinearNearest; + case "mipmapnearestlinear": return exports.TextureFilter.MipMapNearestLinear; + case "mipmaplinearlinear": return exports.TextureFilter.MipMapLinearLinear; + default: throw new Error("Unknown texture filter " + text); + } + } + /** + * @public + */ + function wrapFromString(text) { + switch (text.toLowerCase()) { + case "mirroredtepeat": return exports.TextureWrap.MirroredRepeat; + case "clamptoedge": return exports.TextureWrap.ClampToEdge; + case "repeat": return exports.TextureWrap.Repeat; + default: throw new Error("Unknown texture wrap " + text); + } + } + /** + * @public + */ + exports.TextureFilter = void 0; + (function (TextureFilter) { + TextureFilter[TextureFilter["Nearest"] = 9728] = "Nearest"; + TextureFilter[TextureFilter["Linear"] = 9729] = "Linear"; + TextureFilter[TextureFilter["MipMap"] = 9987] = "MipMap"; + TextureFilter[TextureFilter["MipMapNearestNearest"] = 9984] = "MipMapNearestNearest"; + TextureFilter[TextureFilter["MipMapLinearNearest"] = 9985] = "MipMapLinearNearest"; + TextureFilter[TextureFilter["MipMapNearestLinear"] = 9986] = "MipMapNearestLinear"; + TextureFilter[TextureFilter["MipMapLinearLinear"] = 9987] = "MipMapLinearLinear"; // WebGLRenderingContext.LINEAR_MIPMAP_LINEAR + })(exports.TextureFilter || (exports.TextureFilter = {})); + /** + * @public + */ + exports.TextureWrap = void 0; + (function (TextureWrap) { + TextureWrap[TextureWrap["MirroredRepeat"] = 33648] = "MirroredRepeat"; + TextureWrap[TextureWrap["ClampToEdge"] = 33071] = "ClampToEdge"; + TextureWrap[TextureWrap["Repeat"] = 10497] = "Repeat"; // WebGLRenderingContext.REPEAT + })(exports.TextureWrap || (exports.TextureWrap = {})); + /** + * @public + */ + var TextureRegion = /** @class */ (function () { + function TextureRegion() { + //thats for overrides + this.size = null; + this.names = null; + this.values = null; + this.renderObject = null; + } + Object.defineProperty(TextureRegion.prototype, "width", { + get: function () { + var tex = this.texture; + if (tex.trim) { + return tex.trim.width; + } + return tex.orig.width; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "height", { + get: function () { + var tex = this.texture; + if (tex.trim) { + return tex.trim.height; + } + return tex.orig.height; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "u", { + get: function () { + return this.texture._uvs.x0; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "v", { + get: function () { + return this.texture._uvs.y0; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "u2", { + get: function () { + return this.texture._uvs.x2; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "v2", { + get: function () { + return this.texture._uvs.y2; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "offsetX", { + get: function () { + var tex = this.texture; + return tex.trim ? tex.trim.x : 0; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "offsetY", { + get: function () { + // console.warn("Deprecation Warning: @Hackerham: I guess, if you are using PIXI-SPINE ATLAS region.offsetY, you want a texture, right? Use region.texture from now on."); + return this.spineOffsetY; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "pixiOffsetY", { + get: function () { + var tex = this.texture; + return tex.trim ? tex.trim.y : 0; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "spineOffsetY", { + get: function () { + var tex = this.texture; + return this.originalHeight - this.height - (tex.trim ? tex.trim.y : 0); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "originalWidth", { + get: function () { + return this.texture.orig.width; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "originalHeight", { + get: function () { + return this.texture.orig.height; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "x", { + get: function () { + return this.texture.frame.x; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "y", { + get: function () { + return this.texture.frame.y; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "rotate", { + get: function () { + return this.texture.rotate !== 0; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TextureRegion.prototype, "degrees", { + get: function () { + return (360 - this.texture.rotate * 45) % 360; + }, + enumerable: false, + configurable: true + }); + return TextureRegion; + }()); + + var RegionFields = /** @class */ (function () { + function RegionFields() { + this.x = 0; + this.y = 0; + this.width = 0; + this.height = 0; + this.offsetX = 0; + this.offsetY = 0; + this.originalWidth = 0; + this.originalHeight = 0; + this.rotate = 0; + this.index = 0; + } + return RegionFields; + }()); + /** + * @public + */ + var TextureAtlas = /** @class */ (function () { + function TextureAtlas(atlasText, textureLoader, callback) { + this.pages = new Array(); + this.regions = new Array(); + if (atlasText) { + this.addSpineAtlas(atlasText, textureLoader, callback); + } + } + TextureAtlas.prototype.addTexture = function (name, texture) { + var pages = this.pages; + var page = null; + for (var i = 0; i < pages.length; i++) { + if (pages[i].baseTexture === texture.baseTexture) { + page = pages[i]; + break; + } + } + if (page === null) { + page = new TextureAtlasPage(); + page.name = 'texturePage'; + var baseTexture = texture.baseTexture; + page.width = baseTexture.realWidth; + page.height = baseTexture.realHeight; + page.baseTexture = baseTexture; + //those fields are not relevant in Pixi + page.minFilter = page.magFilter = exports.TextureFilter.Nearest; + page.uWrap = exports.TextureWrap.ClampToEdge; + page.vWrap = exports.TextureWrap.ClampToEdge; + pages.push(page); + } + var region = new TextureAtlasRegion(); + region.name = name; + region.page = page; + region.texture = texture; + region.index = -1; + this.regions.push(region); + return region; + }; + TextureAtlas.prototype.addTextureHash = function (textures, stripExtension) { + for (var key in textures) { + if (textures.hasOwnProperty(key)) { + this.addTexture(stripExtension && key.indexOf('.') !== -1 ? key.substr(0, key.lastIndexOf('.')) : key, textures[key]); + } + } + }; + TextureAtlas.prototype.addSpineAtlas = function (atlasText, textureLoader, callback) { + return this.load(atlasText, textureLoader, callback); + }; + TextureAtlas.prototype.load = function (atlasText, textureLoader, callback) { + var _this = this; + if (textureLoader == null) + throw new Error("textureLoader cannot be null."); + var reader = new TextureAtlasReader(atlasText); + var entry = new Array(4); + var page = null; + var pageFields = {}; + var region = null; + pageFields["size"] = function () { + page.width = parseInt(entry[1]); + page.height = parseInt(entry[2]); + }; + pageFields["format"] = function () { + // page.format = Format[tuple[0]]; we don't need format in WebGL + }; + pageFields["filter"] = function () { + page.minFilter = filterFromString(entry[1]); + page.magFilter = filterFromString(entry[2]); + }; + pageFields["repeat"] = function () { + if (entry[1].indexOf('x') != -1) + page.uWrap = exports.TextureWrap.Repeat; + if (entry[1].indexOf('y') != -1) + page.vWrap = exports.TextureWrap.Repeat; + }; + pageFields["pma"] = function () { + page.pma = entry[1] == "true"; + }; + var regionFields = {}; + regionFields["xy"] = function () { + region.x = parseInt(entry[1]); + region.y = parseInt(entry[2]); + }; + regionFields["size"] = function () { + region.width = parseInt(entry[1]); + region.height = parseInt(entry[2]); + }; + regionFields["bounds"] = function () { + region.x = parseInt(entry[1]); + region.y = parseInt(entry[2]); + region.width = parseInt(entry[3]); + region.height = parseInt(entry[4]); + }; + regionFields["offset"] = function () { + region.offsetX = parseInt(entry[1]); + region.offsetY = parseInt(entry[2]); + }; + regionFields["orig"] = function () { + region.originalWidth = parseInt(entry[1]); + region.originalHeight = parseInt(entry[2]); + }; + regionFields["offsets"] = function () { + region.offsetX = parseInt(entry[1]); + region.offsetY = parseInt(entry[2]); + region.originalWidth = parseInt(entry[3]); + region.originalHeight = parseInt(entry[4]); + }; + regionFields["rotate"] = function () { + var rotateValue = entry[1]; + var rotate = 0; + if (rotateValue.toLocaleLowerCase() == "true") { + rotate = 6; + } + else if (rotateValue.toLocaleLowerCase() == "false") { + rotate = 0; + } + else { + rotate = ((720 - parseFloat(rotateValue)) % 360) / 45; + } + region.rotate = rotate; + }; + regionFields["index"] = function () { + region.index = parseInt(entry[1]); + }; + var line = reader.readLine(); + // Ignore empty lines before first entry. + while (line != null && line.trim().length == 0) + line = reader.readLine(); + // Header entries. + while (true) { + if (line == null || line.trim().length == 0) + break; + if (reader.readEntry(entry, line) == 0) + break; // Silently ignore all header fields. + line = reader.readLine(); + } + var iterateParser = function () { + while (true) { + if (line == null) { + return callback && callback(_this); + } + if (line.trim().length == 0) { + page = null; + line = reader.readLine(); + } + else if (page === null) { + page = new TextureAtlasPage(); + page.name = line.trim(); + while (true) { + if (reader.readEntry(entry, line = reader.readLine()) == 0) + break; + var field = pageFields[entry[0]]; + if (field) + field(); + } + _this.pages.push(page); + textureLoader(page.name, function (texture) { + if (texture === null) { + _this.pages.splice(_this.pages.indexOf(page), 1); + return callback && callback(null); + } + page.baseTexture = texture; + //TODO: set scaleMode and mipmapMode from spine + if (page.pma) { + texture.alphaMode = constants.ALPHA_MODES.PMA; + } + if (!texture.valid) { + texture.setSize(page.width, page.height); + } + page.setFilters(); + if (!page.width || !page.height) { + page.width = texture.realWidth; + page.height = texture.realHeight; + if (!page.width || !page.height) { + console.log("ERROR spine atlas page " + page.name + ": meshes wont work if you dont specify size in atlas (http://www.html5gamedevs.com/topic/18888-pixi-spines-and-meshes/?p=107121)"); + } + } + iterateParser(); + }); + break; + } + else { + region = new RegionFields(); + var atlasRegion = new TextureAtlasRegion(); + atlasRegion.name = line; + atlasRegion.page = page; + var names = null; + var values = null; + while (true) { + var count = reader.readEntry(entry, line = reader.readLine()); + if (count == 0) + break; + var field = regionFields[entry[0]]; + if (field) + field(); + else { + if (names == null) { + names = []; + values = []; + } + names.push(entry[0]); + var entryValues = []; + for (var i = 0; i < count; i++) + entryValues.push(parseInt(entry[i + 1])); + values.push(entryValues); + } + } + if (region.originalWidth == 0 && region.originalHeight == 0) { + region.originalWidth = region.width; + region.originalHeight = region.height; + } + var resolution = page.baseTexture.resolution; + region.x /= resolution; + region.y /= resolution; + region.width /= resolution; + region.height /= resolution; + region.originalWidth /= resolution; + region.originalHeight /= resolution; + region.offsetX /= resolution; + region.offsetY /= resolution; + var swapWH = region.rotate % 4 !== 0; + var frame = new math.Rectangle(region.x, region.y, swapWH ? region.height : region.width, swapWH ? region.width : region.height); + var orig = new math.Rectangle(0, 0, region.originalWidth, region.originalHeight); + var trim = new math.Rectangle(region.offsetX, region.originalHeight - region.height - region.offsetY, region.width, region.height); + atlasRegion.texture = new core.Texture(atlasRegion.page.baseTexture, frame, orig, trim, region.rotate); + atlasRegion.index = region.index; + atlasRegion.texture.updateUvs(); + _this.regions.push(atlasRegion); + } + } + }; + iterateParser(); + }; + TextureAtlas.prototype.findRegion = function (name) { + for (var i = 0; i < this.regions.length; i++) { + if (this.regions[i].name == name) { + return this.regions[i]; + } + } + return null; + }; + TextureAtlas.prototype.dispose = function () { + for (var i = 0; i < this.pages.length; i++) { + this.pages[i].baseTexture.dispose(); + } + }; + return TextureAtlas; + }()); + /** + * @public + */ + var TextureAtlasReader = /** @class */ (function () { + function TextureAtlasReader(text) { + this.index = 0; + this.lines = text.split(/\r\n|\r|\n/); + } + TextureAtlasReader.prototype.readLine = function () { + if (this.index >= this.lines.length) + return null; + return this.lines[this.index++]; + }; + TextureAtlasReader.prototype.readEntry = function (entry, line) { + if (line == null) + return 0; + line = line.trim(); + if (line.length == 0) + return 0; + var colon = line.indexOf(':'); + if (colon == -1) + return 0; + entry[0] = line.substr(0, colon).trim(); + for (var i = 1, lastMatch = colon + 1;; i++) { + var comma = line.indexOf(',', lastMatch); + if (comma == -1) { + entry[i] = line.substr(lastMatch).trim(); + return i; + } + entry[i] = line.substr(lastMatch, comma - lastMatch).trim(); + lastMatch = comma + 1; + if (i == 4) + return 4; + } + }; + return TextureAtlasReader; + }()); + /** + * @public + */ + var TextureAtlasPage = /** @class */ (function () { + function TextureAtlasPage() { + this.minFilter = exports.TextureFilter.Nearest; + this.magFilter = exports.TextureFilter.Nearest; + this.uWrap = exports.TextureWrap.ClampToEdge; + this.vWrap = exports.TextureWrap.ClampToEdge; + } + TextureAtlasPage.prototype.setFilters = function () { + var tex = this.baseTexture; + var filter = this.minFilter; + if (filter == exports.TextureFilter.Linear) { + tex.scaleMode = constants.SCALE_MODES.LINEAR; + } + else if (this.minFilter == exports.TextureFilter.Nearest) { + tex.scaleMode = constants.SCALE_MODES.NEAREST; + } + else { + tex.mipmap = constants.MIPMAP_MODES.POW2; + if (filter == exports.TextureFilter.MipMapNearestNearest) { + tex.scaleMode = constants.SCALE_MODES.NEAREST; + } + else { + tex.scaleMode = constants.SCALE_MODES.LINEAR; + } + } + }; + return TextureAtlasPage; + }()); + /** + * @public + */ + var TextureAtlasRegion = /** @class */ (function (_super) { + __extends$4(TextureAtlasRegion, _super); + function TextureAtlasRegion() { + return _super !== null && _super.apply(this, arguments) || this; + } + return TextureAtlasRegion; + }(TextureRegion)); + + var fround_polyfill = (function (array) { + return function (x) { + return array[0] = x, array[0]; + }; + })(new Float32Array(1)); + var fround = Math.fround || fround_polyfill; + /** + * @public + */ + var IntSet = /** @class */ (function () { + function IntSet() { + this.array = new Array(); + } + IntSet.prototype.add = function (value) { + var contains = this.contains(value); + this.array[value | 0] = value | 0; + return !contains; + }; + IntSet.prototype.contains = function (value) { + return this.array[value | 0] != undefined; + }; + IntSet.prototype.remove = function (value) { + this.array[value | 0] = undefined; + }; + IntSet.prototype.clear = function () { + this.array.length = 0; + }; + return IntSet; + }()); + /** + * @public + */ + var StringSet = /** @class */ (function () { + function StringSet() { + this.entries = {}; + this.size = 0; + } + StringSet.prototype.add = function (value) { + var contains = this.entries[value]; + this.entries[value] = true; + if (!contains) { + this.size++; + return true; + } + return false; + }; + StringSet.prototype.addAll = function (values) { + var oldSize = this.size; + for (var i = 0, n = values.length; i < n; i++) + this.add(values[i]); + return oldSize != this.size; + }; + StringSet.prototype.contains = function (value) { + return this.entries[value]; + }; + StringSet.prototype.clear = function () { + this.entries = {}; + this.size = 0; + }; + return StringSet; + }()); + /** + * @public + */ + var Color = /** @class */ (function () { + function Color(r, g, b, a) { + if (r === void 0) { r = 0; } + if (g === void 0) { g = 0; } + if (b === void 0) { b = 0; } + if (a === void 0) { a = 0; } + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + Color.prototype.set = function (r, g, b, a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + return this.clamp(); + }; + Color.prototype.setFromColor = function (c) { + this.r = c.r; + this.g = c.g; + this.b = c.b; + this.a = c.a; + return this; + }; + Color.prototype.setFromString = function (hex) { + hex = hex.charAt(0) == '#' ? hex.substr(1) : hex; + this.r = parseInt(hex.substr(0, 2), 16) / 255; + this.g = parseInt(hex.substr(2, 2), 16) / 255; + this.b = parseInt(hex.substr(4, 2), 16) / 255; + this.a = hex.length != 8 ? 1 : parseInt(hex.substr(6, 2), 16) / 255; + return this; + }; + Color.prototype.add = function (r, g, b, a) { + this.r += r; + this.g += g; + this.b += b; + this.a += a; + return this.clamp(); + }; + Color.prototype.clamp = function () { + if (this.r < 0) + this.r = 0; + else if (this.r > 1) + this.r = 1; + if (this.g < 0) + this.g = 0; + else if (this.g > 1) + this.g = 1; + if (this.b < 0) + this.b = 0; + else if (this.b > 1) + this.b = 1; + if (this.a < 0) + this.a = 0; + else if (this.a > 1) + this.a = 1; + return this; + }; + Color.rgba8888ToColor = function (color, value) { + color.r = ((value & 0xff000000) >>> 24) / 255; + color.g = ((value & 0x00ff0000) >>> 16) / 255; + color.b = ((value & 0x0000ff00) >>> 8) / 255; + color.a = ((value & 0x000000ff)) / 255; + }; + Color.rgb888ToColor = function (color, value) { + color.r = ((value & 0x00ff0000) >>> 16) / 255; + color.g = ((value & 0x0000ff00) >>> 8) / 255; + color.b = ((value & 0x000000ff)) / 255; + }; + Color.fromString = function (hex) { + return new Color().setFromString(hex); + }; + Color.WHITE = new Color(1, 1, 1, 1); + Color.RED = new Color(1, 0, 0, 1); + Color.GREEN = new Color(0, 1, 0, 1); + Color.BLUE = new Color(0, 0, 1, 1); + Color.MAGENTA = new Color(1, 0, 1, 1); + return Color; + }()); + /** + * @public + */ + var MathUtils = /** @class */ (function () { + function MathUtils() { + } + MathUtils.clamp = function (value, min, max) { + if (value < min) + return min; + if (value > max) + return max; + return value; + }; + MathUtils.cosDeg = function (degrees) { + return Math.cos(degrees * MathUtils.degRad); + }; + MathUtils.sinDeg = function (degrees) { + return Math.sin(degrees * MathUtils.degRad); + }; + MathUtils.signum = function (value) { + return value > 0 ? 1 : value < 0 ? -1 : 0; + }; + MathUtils.toInt = function (x) { + return x > 0 ? Math.floor(x) : Math.ceil(x); + }; + MathUtils.cbrt = function (x) { + var y = Math.pow(Math.abs(x), 1 / 3); + return x < 0 ? -y : y; + }; + MathUtils.randomTriangular = function (min, max) { + return MathUtils.randomTriangularWith(min, max, (min + max) * 0.5); + }; + MathUtils.randomTriangularWith = function (min, max, mode) { + var u = Math.random(); + var d = max - min; + if (u <= (mode - min) / d) + return min + Math.sqrt(u * d * (mode - min)); + return max - Math.sqrt((1 - u) * d * (max - mode)); + }; + MathUtils.isPowerOfTwo = function (value) { + return value && (value & (value - 1)) === 0; + }; + MathUtils.PI = 3.1415927; + MathUtils.PI2 = MathUtils.PI * 2; + MathUtils.radiansToDegrees = 180 / MathUtils.PI; + MathUtils.radDeg = MathUtils.radiansToDegrees; + MathUtils.degreesToRadians = MathUtils.PI / 180; + MathUtils.degRad = MathUtils.degreesToRadians; + return MathUtils; + }()); + /** + * @public + */ + var Interpolation = /** @class */ (function () { + function Interpolation() { + } + Interpolation.prototype.apply = function (start, end, a) { + return start + (end - start) * this.applyInternal(a); + }; + return Interpolation; + }()); + /** + * @public + */ + var Pow = /** @class */ (function (_super) { + __extends$4(Pow, _super); + function Pow(power) { + var _this = _super.call(this) || this; + _this.power = 2; + _this.power = power; + return _this; + } + Pow.prototype.applyInternal = function (a) { + if (a <= 0.5) + return Math.pow(a * 2, this.power) / 2; + return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1; + }; + return Pow; + }(Interpolation)); + /** + * @public + */ + var PowOut = /** @class */ (function (_super) { + __extends$4(PowOut, _super); + function PowOut(power) { + return _super.call(this, power) || this; + } + PowOut.prototype.applyInternal = function (a) { + return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1; + }; + return PowOut; + }(Pow)); + /** + * @public + */ + var Utils = /** @class */ (function () { + function Utils() { + } + Utils.arrayCopy = function (source, sourceStart, dest, destStart, numElements) { + for (var i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) { + dest[j] = source[i]; + } + }; + Utils.arrayFill = function (array, fromIndex, toIndex, value) { + for (var i = fromIndex; i < toIndex; i++) + array[i] = value; + }; + Utils.setArraySize = function (array, size, value) { + if (value === void 0) { value = 0; } + var oldSize = array.length; + if (oldSize == size) + return array; + array.length = size; + if (oldSize < size) { + for (var i = oldSize; i < size; i++) + array[i] = value; + } + return array; + }; + Utils.ensureArrayCapacity = function (array, size, value) { + if (value === void 0) { value = 0; } + if (array.length >= size) + return array; + return Utils.setArraySize(array, size, value); + }; + Utils.newArray = function (size, defaultValue) { + var array = new Array(size); + for (var i = 0; i < size; i++) + array[i] = defaultValue; + return array; + }; + Utils.newFloatArray = function (size) { + if (Utils.SUPPORTS_TYPED_ARRAYS) + return new Float32Array(size); + else { + var array = new Array(size); + for (var i = 0; i < array.length; i++) + array[i] = 0; + return array; + } + }; + Utils.newShortArray = function (size) { + if (Utils.SUPPORTS_TYPED_ARRAYS) + return new Int16Array(size); + else { + var array = new Array(size); + for (var i = 0; i < array.length; i++) + array[i] = 0; + return array; + } + }; + Utils.toFloatArray = function (array) { + return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array; + }; + Utils.toSinglePrecision = function (value) { + return Utils.SUPPORTS_TYPED_ARRAYS ? fround(value) : value; + }; + // This function is used to fix WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 + Utils.webkit602BugfixHelper = function (alpha, blend) { + }; + Utils.contains = function (array, element, identity) { + for (var i = 0; i < array.length; i++) + if (array[i] == element) + return true; + return false; + }; + Utils.enumValue = function (type, name) { + return type[name[0].toUpperCase() + name.slice(1)]; + }; + Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined"; + return Utils; + }()); + /** + * @public + */ + var DebugUtils = /** @class */ (function () { + function DebugUtils() { + } + DebugUtils.logBones = function (skeleton) { + for (var i = 0; i < skeleton.bones.length; i++) { + var bone = skeleton.bones[i]; + var mat = bone.matrix; + console.log(bone.data.name + ", " + mat.a + ", " + mat.b + ", " + mat.c + ", " + mat.d + ", " + mat.tx + ", " + mat.ty); + } + }; + return DebugUtils; + }()); + /** + * @public + */ + var Pool = /** @class */ (function () { + function Pool(instantiator) { + this.items = new Array(); + this.instantiator = instantiator; + } + Pool.prototype.obtain = function () { + return this.items.length > 0 ? this.items.pop() : this.instantiator(); + }; + Pool.prototype.free = function (item) { + if (item.reset) + item.reset(); + this.items.push(item); + }; + Pool.prototype.freeAll = function (items) { + for (var i = 0; i < items.length; i++) + this.free(items[i]); + }; + Pool.prototype.clear = function () { + this.items.length = 0; + }; + return Pool; + }()); + /** + * @public + */ + var Vector2 = /** @class */ (function () { + function Vector2(x, y) { + if (x === void 0) { x = 0; } + if (y === void 0) { y = 0; } + this.x = x; + this.y = y; + } + Vector2.prototype.set = function (x, y) { + this.x = x; + this.y = y; + return this; + }; + Vector2.prototype.length = function () { + var x = this.x; + var y = this.y; + return Math.sqrt(x * x + y * y); + }; + Vector2.prototype.normalize = function () { + var len = this.length(); + if (len != 0) { + this.x /= len; + this.y /= len; + } + return this; + }; + return Vector2; + }()); + /** + * @public + */ + var TimeKeeper = /** @class */ (function () { + function TimeKeeper() { + this.maxDelta = 0.064; + this.framesPerSecond = 0; + this.delta = 0; + this.totalTime = 0; + this.lastTime = Date.now() / 1000; + this.frameCount = 0; + this.frameTime = 0; + } + TimeKeeper.prototype.update = function () { + var now = Date.now() / 1000; + this.delta = now - this.lastTime; + this.frameTime += this.delta; + this.totalTime += this.delta; + if (this.delta > this.maxDelta) + this.delta = this.maxDelta; + this.lastTime = now; + this.frameCount++; + if (this.frameTime > 1) { + this.framesPerSecond = this.frameCount / this.frameTime; + this.frameTime = 0; + this.frameCount = 0; + } + }; + return TimeKeeper; + }()); + /** + * @public + */ + var WindowedMean = /** @class */ (function () { + function WindowedMean(windowSize) { + if (windowSize === void 0) { windowSize = 32; } + this.addedValues = 0; + this.lastValue = 0; + this.mean = 0; + this.dirty = true; + this.values = new Array(windowSize); + } + WindowedMean.prototype.hasEnoughData = function () { + return this.addedValues >= this.values.length; + }; + WindowedMean.prototype.addValue = function (value) { + if (this.addedValues < this.values.length) + this.addedValues++; + this.values[this.lastValue++] = value; + if (this.lastValue > this.values.length - 1) + this.lastValue = 0; + this.dirty = true; + }; + WindowedMean.prototype.getMean = function () { + if (this.hasEnoughData()) { + if (this.dirty) { + var mean = 0; + for (var i = 0; i < this.values.length; i++) + mean += this.values[i]; + this.mean = mean / this.values.length; + this.dirty = false; + } + return this.mean; + } + return 0; + }; + return WindowedMean; + }()); + + /** Collects each visible BoundingBoxAttachment and computes the world vertices for its polygon. The polygon vertices are + * provided along with convenience methods for doing hit detection. + * @public + * */ + var SkeletonBoundsBase = /** @class */ (function () { + function SkeletonBoundsBase() { + /** The left edge of the axis aligned bounding box. */ + this.minX = 0; + /** The bottom edge of the axis aligned bounding box. */ + this.minY = 0; + /** The right edge of the axis aligned bounding box. */ + this.maxX = 0; + /** The top edge of the axis aligned bounding box. */ + this.maxY = 0; + /** The visible bounding boxes. */ + this.boundingBoxes = new Array(); + /** The world vertices for the bounding box polygons. */ + this.polygons = new Array(); + this.polygonPool = new Pool(function () { + return Utils.newFloatArray(16); + }); + } + /** Clears any previous polygons, finds all visible bounding box attachments, and computes the world vertices for each bounding + * box's polygon. + * @param updateAabb If true, the axis aligned bounding box containing all the polygons is computed. If false, the + * SkeletonBounds AABB methods will always return true. */ + SkeletonBoundsBase.prototype.update = function (skeleton, updateAabb) { + if (!skeleton) + throw new Error("skeleton cannot be null."); + var boundingBoxes = this.boundingBoxes; + var polygons = this.polygons; + var polygonPool = this.polygonPool; + var slots = skeleton.slots; + var slotCount = slots.length; + boundingBoxes.length = 0; + polygonPool.freeAll(polygons); + polygons.length = 0; + for (var i = 0; i < slotCount; i++) { + var slot = slots[i]; + if (!slot.bone.active) + continue; + var attachment = slot.getAttachment(); + if (attachment != null && attachment.type === exports.AttachmentType.BoundingBox) { + var boundingBox = attachment; + boundingBoxes.push(boundingBox); + var polygon = polygonPool.obtain(); + if (polygon.length != boundingBox.worldVerticesLength) { + polygon = Utils.newFloatArray(boundingBox.worldVerticesLength); + } + polygons.push(polygon); + boundingBox.computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2); + } + } + if (updateAabb) { + this.aabbCompute(); + } + else { + this.minX = Number.POSITIVE_INFINITY; + this.minY = Number.POSITIVE_INFINITY; + this.maxX = Number.NEGATIVE_INFINITY; + this.maxY = Number.NEGATIVE_INFINITY; + } + }; + SkeletonBoundsBase.prototype.aabbCompute = function () { + var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + var polygons = this.polygons; + for (var i = 0, n = polygons.length; i < n; i++) { + var polygon = polygons[i]; + var vertices = polygon; + for (var ii = 0, nn = polygon.length; ii < nn; ii += 2) { + var x = vertices[ii]; + var y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + }; + /** Returns true if the axis aligned bounding box contains the point. */ + SkeletonBoundsBase.prototype.aabbContainsPoint = function (x, y) { + return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY; + }; + /** Returns true if the axis aligned bounding box intersects the line segment. */ + SkeletonBoundsBase.prototype.aabbIntersectsSegment = function (x1, y1, x2, y2) { + var minX = this.minX; + var minY = this.minY; + var maxX = this.maxX; + var maxY = this.maxY; + if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY)) + return false; + var m = (y2 - y1) / (x2 - x1); + var y = m * (minX - x1) + y1; + if (y > minY && y < maxY) + return true; + y = m * (maxX - x1) + y1; + if (y > minY && y < maxY) + return true; + var x = (minY - y1) / m + x1; + if (x > minX && x < maxX) + return true; + x = (maxY - y1) / m + x1; + if (x > minX && x < maxX) + return true; + return false; + }; + /** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */ + SkeletonBoundsBase.prototype.aabbIntersectsSkeleton = function (bounds) { + return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY; + }; + /** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more + * efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. + * Cannot be done here because BoundingBoxAttachment is not a thing yet*/ + SkeletonBoundsBase.prototype.containsPoint = function (x, y) { + var polygons = this.polygons; + for (var i = 0, n = polygons.length; i < n; i++) + if (this.containsPointPolygon(polygons[i], x, y)) + return this.boundingBoxes[i]; + return null; + }; + /** Returns true if the polygon contains the point. */ + SkeletonBoundsBase.prototype.containsPointPolygon = function (polygon, x, y) { + var vertices = polygon; + var nn = polygon.length; + var prevIndex = nn - 2; + var inside = false; + for (var ii = 0; ii < nn; ii += 2) { + var vertexY = vertices[ii + 1]; + var prevY = vertices[prevIndex + 1]; + if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) { + var vertexX = vertices[ii]; + if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x) + inside = !inside; + } + prevIndex = ii; + } + return inside; + }; + /** Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it + * is usually more efficient to only call this method if {@link #aabbIntersectsSegment()} returns + * true. */ + SkeletonBoundsBase.prototype.intersectsSegment = function (x1, y1, x2, y2) { + var polygons = this.polygons; + for (var i = 0, n = polygons.length; i < n; i++) + if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2)) + return this.boundingBoxes[i]; + return null; + }; + /** Returns true if the polygon contains any part of the line segment. */ + SkeletonBoundsBase.prototype.intersectsSegmentPolygon = function (polygon, x1, y1, x2, y2) { + var vertices = polygon; + var nn = polygon.length; + var width12 = x1 - x2, height12 = y1 - y2; + var det1 = x1 * y2 - y1 * x2; + var x3 = vertices[nn - 2], y3 = vertices[nn - 1]; + for (var ii = 0; ii < nn; ii += 2) { + var x4 = vertices[ii], y4 = vertices[ii + 1]; + var det2 = x3 * y4 - y3 * x4; + var width34 = x3 - x4, height34 = y3 - y4; + var det3 = width12 * height34 - height12 * width34; + var x = (det1 * width34 - width12 * det2) / det3; + if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) { + var y = (det1 * height34 - height12 * det2) / det3; + if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) + return true; + } + x3 = x4; + y3 = y4; + } + return false; + }; + /** Returns the polygon for the specified bounding box, or null. */ + SkeletonBoundsBase.prototype.getPolygon = function (boundingBox) { + if (!boundingBox) + throw new Error("boundingBox cannot be null."); + var index = this.boundingBoxes.indexOf(boundingBox); + return index == -1 ? null : this.polygons[index]; + }; + /** The width of the axis aligned bounding box. */ + SkeletonBoundsBase.prototype.getWidth = function () { + return this.maxX - this.minX; + }; + /** The height of the axis aligned bounding box. */ + SkeletonBoundsBase.prototype.getHeight = function () { + return this.maxY - this.minY; + }; + return SkeletonBoundsBase; + }()); + + /** + * @public + */ + var settings = { + yDown: true, + /** + * pixi-spine gives option to not fail at certain parsing errors + * spine-ts fails here + */ + FAIL_ON_NON_EXISTING_SKIN: false, + /** + * past Spine.globalAutoUpdate + */ + GLOBAL_AUTO_UPDATE: true, + /** + * past Spine.globalDelayLimit + */ + GLOBAL_DELAY_LIMIT: 0, + }; + + var tempRgb = [0, 0, 0]; + /** + * @public + */ + var SpineSprite = /** @class */ (function (_super) { + __extends$4(SpineSprite, _super); + function SpineSprite() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.region = null; + _this.attachment = null; + return _this; + } + return SpineSprite; + }(sprite.Sprite)); + /** + * @public + */ + var SpineMesh = /** @class */ (function (_super) { + __extends$4(SpineMesh, _super); + function SpineMesh(texture, vertices, uvs, indices, drawMode) { + var _this = _super.call(this, texture, vertices, uvs, indices, drawMode) || this; + _this.region = null; + _this.attachment = null; + return _this; + } + return SpineMesh; + }(meshExtras.SimpleMesh)); + /** + * A class that enables the you to import and run your spine animations in pixi. + * The Spine animation data needs to be loaded using either the Loader or a SpineLoader before it can be used by this class + * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source + * + * ```js + * let spineAnimation = new spine(spineData); + * ``` + * + * @public + * @class + * @extends Container + * @memberof spine + * @param spineData {object} The spine data loaded from a spine atlas. + */ + var SpineBase = /** @class */ (function (_super) { + __extends$4(SpineBase, _super); + function SpineBase(spineData) { + var _this = _super.call(this) || this; + if (!spineData) { + throw new Error('The spineData param is required.'); + } + if ((typeof spineData) === "string") { + throw new Error('spineData param cant be string. Please use spine.Spine.fromAtlas("YOUR_RESOURCE_NAME") from now on.'); + } + /** + * The spineData object + * + * @member {object} + */ + _this.spineData = spineData; + /** + * A spine Skeleton object + * + * @member {object} + */ + _this.createSkeleton(spineData); + /** + * An array of containers + * + * @member {Container[]} + */ + _this.slotContainers = []; + _this.tempClipContainers = []; + for (var i = 0, n = _this.skeleton.slots.length; i < n; i++) { + var slot = _this.skeleton.slots[i]; + var attachment = slot.getAttachment(); + var slotContainer = _this.newContainer(); + _this.slotContainers.push(slotContainer); + _this.addChild(slotContainer); + _this.tempClipContainers.push(null); + if (!attachment) { + continue; + } + if (attachment.type === exports.AttachmentType.Region) { + var spriteName = attachment.name; + var sprite = _this.createSprite(slot, attachment, spriteName); + slot.currentSprite = sprite; + slot.currentSpriteName = spriteName; + slotContainer.addChild(sprite); + } + else if (attachment.type === exports.AttachmentType.Mesh) { + var mesh = _this.createMesh(slot, attachment); + slot.currentMesh = mesh; + slot.currentMeshId = attachment.id; + slot.currentMeshName = attachment.name; + slotContainer.addChild(mesh); + } + else if (attachment.type === exports.AttachmentType.Clipping) { + _this.createGraphics(slot, attachment); + slotContainer.addChild(slot.clippingContainer); + slotContainer.addChild(slot.currentGraphics); + } + } + /** + * The tint applied to all spine slots. This is a [r,g,b] value. A value of [1,1,1] will remove any tint effect. + * + * @member {number} + * @memberof spine.Spine# + */ + _this.tintRgb = new Float32Array([1, 1, 1]); + _this.autoUpdate = true; + _this.visible = true; + return _this; + } + Object.defineProperty(SpineBase.prototype, "debug", { + get: function () { + return this._debug; + }, + set: function (value) { + var _a; + if (value == this._debug) { // soft equality allows null == undefined + return; + } + (_a = this._debug) === null || _a === void 0 ? void 0 : _a.unregisterSpine(this); + value === null || value === void 0 ? void 0 : value.registerSpine(this); + this._debug = value; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(SpineBase.prototype, "autoUpdate", { + /** + * If this flag is set to true, the spine animation will be automatically updated every + * time the object id drawn. The down side of this approach is that the delta time is + * automatically calculated and you could miss out on cool effects like slow motion, + * pause, skip ahead and the sorts. Most of these effects can be achieved even with + * autoUpdate enabled but are harder to achieve. + * + * @member {boolean} + * @memberof spine.Spine# + * @default true + */ + get: function () { + return this._autoUpdate; + }, + set: function (value) { + if (value !== this._autoUpdate) { + this._autoUpdate = value; + this.updateTransform = value ? SpineBase.prototype.autoUpdateTransform : display.Container.prototype.updateTransform; + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(SpineBase.prototype, "tint", { + /** + * The tint applied to the spine object. This is a hex value. A value of 0xFFFFFF will remove any tint effect. + * + * @member {number} + * @memberof spine.Spine# + * @default 0xFFFFFF + */ + get: function () { + return utils.rgb2hex(this.tintRgb); + }, + set: function (value) { + this.tintRgb = utils.hex2rgb(value, this.tintRgb); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(SpineBase.prototype, "delayLimit", { + /** + * Limit value for the update dt with Spine.globalDelayLimit + * that can be overridden with localDelayLimit + * @return {number} - Maximum processed dt value for the update + */ + get: function () { + var limit = typeof this.localDelayLimit !== "undefined" ? + this.localDelayLimit : settings.GLOBAL_DELAY_LIMIT; + // If limit is 0, this means there is no limit for the delay + return limit || Number.MAX_VALUE; + }, + enumerable: false, + configurable: true + }); + /** + * Update the spine skeleton and its animations by delta time (dt) + * + * @param dt {number} Delta time. Time by which the animation should be updated + */ + SpineBase.prototype.update = function (dt) { + var _a; + // Limit delta value to avoid animation jumps + var delayLimit = this.delayLimit; + if (dt > delayLimit) + dt = delayLimit; + this.state.update(dt); + this.state.apply(this.skeleton); + //check we haven't been destroyed via a spine event callback in state update + if (!this.skeleton) + return; + this.skeleton.updateWorldTransform(); + var slots = this.skeleton.slots; + // in case pixi has double tint + var globalClr = this.color; + var light = null, dark = null; + if (globalClr) { + light = globalClr.light; + dark = globalClr.dark; + } + else { + light = this.tintRgb; + } + // let thack = false; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + var attachment = slot.getAttachment(); + var slotContainer = this.slotContainers[i]; + if (!attachment) { + slotContainer.visible = false; + continue; + } + var spriteColor = null; + if (attachment.sequence) { + attachment.sequence.apply(slot, attachment); + } + var region = attachment.region; + var attColor = attachment.color; + switch (attachment != null && attachment.type) { + case exports.AttachmentType.Region: + var transform = slotContainer.transform; + transform.setFromMatrix(slot.bone.matrix); + region = attachment.region; + if (slot.currentMesh) { + slot.currentMesh.visible = false; + slot.currentMesh = null; + slot.currentMeshId = undefined; + slot.currentMeshName = undefined; + } + if (!region) { + if (slot.currentSprite) { + slot.currentSprite.renderable = false; + } + break; + } + if (!slot.currentSpriteName || slot.currentSpriteName !== attachment.name) { + var spriteName = attachment.name; + if (slot.currentSprite) { + slot.currentSprite.visible = false; + } + slot.sprites = slot.sprites || {}; + if (slot.sprites[spriteName] !== undefined) { + slot.sprites[spriteName].visible = true; + } + else { + var sprite = this.createSprite(slot, attachment, spriteName); + slotContainer.addChild(sprite); + } + slot.currentSprite = slot.sprites[spriteName]; + slot.currentSpriteName = spriteName; + // force sprite update when attachment name is same. + // issues https://github.com/pixijs/pixi-spine/issues/318 + } + slot.currentSprite.renderable = true; + if (!slot.hackRegion) { + this.setSpriteRegion(attachment, slot.currentSprite, region); + } + if (slot.currentSprite.color) { + //YAY! double - tint! + spriteColor = slot.currentSprite.color; + } + else { + tempRgb[0] = light[0] * slot.color.r * attColor.r; + tempRgb[1] = light[1] * slot.color.g * attColor.g; + tempRgb[2] = light[2] * slot.color.b * attColor.b; + slot.currentSprite.tint = utils.rgb2hex(tempRgb); + } + slot.currentSprite.blendMode = slot.blendMode; + break; + case exports.AttachmentType.Mesh: + if (slot.currentSprite) { + //TODO: refactor this thing, switch it on and off for container + slot.currentSprite.visible = false; + slot.currentSprite = null; + slot.currentSpriteName = undefined; + //TODO: refactor this shit + var transform_1 = new math.Transform(); + transform_1._parentID = -1; + transform_1._worldID = slotContainer.transform._worldID; + slotContainer.transform = transform_1; + } + if (!region) { + if (slot.currentMesh) { + slot.currentMesh.renderable = false; + } + break; + } + var id = attachment.id; + if (slot.currentMeshId === undefined || slot.currentMeshId !== id) { + var meshId = id; + if (slot.currentMesh) { + slot.currentMesh.visible = false; + } + slot.meshes = slot.meshes || {}; + if (slot.meshes[meshId] !== undefined) { + slot.meshes[meshId].visible = true; + } + else { + var mesh = this.createMesh(slot, attachment); + slotContainer.addChild(mesh); + } + slot.currentMesh = slot.meshes[meshId]; + slot.currentMeshName = attachment.name; + slot.currentMeshId = meshId; + } + slot.currentMesh.renderable = true; + attachment.computeWorldVerticesOld(slot, slot.currentMesh.vertices); + if (slot.currentMesh.color) { + // pixi-heaven + spriteColor = slot.currentMesh.color; + } + else { + tempRgb[0] = light[0] * slot.color.r * attColor.r; + tempRgb[1] = light[1] * slot.color.g * attColor.g; + tempRgb[2] = light[2] * slot.color.b * attColor.b; + slot.currentMesh.tint = utils.rgb2hex(tempRgb); + } + slot.currentMesh.blendMode = slot.blendMode; + if (!slot.hackRegion) { + this.setMeshRegion(attachment, slot.currentMesh, region); + } + break; + case exports.AttachmentType.Clipping: + if (!slot.currentGraphics) { + this.createGraphics(slot, attachment); + slotContainer.addChild(slot.clippingContainer); + slotContainer.addChild(slot.currentGraphics); + } + this.updateGraphics(slot, attachment); + slotContainer.alpha = 1.0; + slotContainer.visible = true; + continue; + default: + slotContainer.visible = false; + continue; + } + slotContainer.visible = true; + // pixi has double tint + if (spriteColor) { + var r0 = slot.color.r * attColor.r; + var g0 = slot.color.g * attColor.g; + var b0 = slot.color.b * attColor.b; + //YAY! double-tint! + spriteColor.setLight(light[0] * r0 + dark[0] * (1.0 - r0), light[1] * g0 + dark[1] * (1.0 - g0), light[2] * b0 + dark[2] * (1.0 - b0)); + if (slot.darkColor) { + r0 = slot.darkColor.r; + g0 = slot.darkColor.g; + b0 = slot.darkColor.b; + } + else { + r0 = 0.0; + g0 = 0.0; + b0 = 0.0; + } + spriteColor.setDark(light[0] * r0 + dark[0] * (1 - r0), light[1] * g0 + dark[1] * (1 - g0), light[2] * b0 + dark[2] * (1 - b0)); + } + slotContainer.alpha = slot.color.a; + } + //== this is clipping implementation === + //TODO: remove parent hacks when pixi masks allow it + var drawOrder = this.skeleton.drawOrder; + var clippingAttachment = null; + var clippingContainer = null; + for (var i = 0, n = drawOrder.length; i < n; i++) { + var slot = slots[drawOrder[i].data.index]; + var slotContainer = this.slotContainers[drawOrder[i].data.index]; + if (!clippingContainer) { + //Adding null check as it is possible for slotContainer.parent to be null in the event of a spine being disposed off in its loop callback + if (slotContainer.parent !== null && slotContainer.parent !== this) { + slotContainer.parent.removeChild(slotContainer); + //silend add hack + slotContainer.parent = this; + } + } + if (slot.currentGraphics && slot.getAttachment()) { + clippingContainer = slot.clippingContainer; + clippingAttachment = slot.getAttachment(); + clippingContainer.children.length = 0; + this.children[i] = slotContainer; + if (clippingAttachment.endSlot === slot.data) { + clippingAttachment.endSlot = null; + } + } + else { + if (clippingContainer) { + var c = this.tempClipContainers[i]; + if (!c) { + c = this.tempClipContainers[i] = this.newContainer(); + c.visible = false; + } + this.children[i] = c; + //silent remove hack + slotContainer.parent = null; + clippingContainer.addChild(slotContainer); + if (clippingAttachment.endSlot == slot.data) { + clippingContainer.renderable = true; + clippingContainer = null; + clippingAttachment = null; + } + } + else { + this.children[i] = slotContainer; + } + } + } + // if you can debug, then debug! + (_a = this._debug) === null || _a === void 0 ? void 0 : _a.renderDebug(this); + }; + SpineBase.prototype.setSpriteRegion = function (attachment, sprite, region) { + // prevent setters calling when attachment and region is same + if (sprite.attachment === attachment && sprite.region === region) { + return; + } + sprite.region = region; + sprite.attachment = attachment; + sprite.texture = region.texture; + sprite.rotation = attachment.rotation * MathUtils.degRad; + sprite.position.x = attachment.x; + sprite.position.y = attachment.y; + sprite.alpha = attachment.color.a; + if (!region.size) { + sprite.scale.x = attachment.scaleX * attachment.width / region.originalWidth; + sprite.scale.y = -attachment.scaleY * attachment.height / region.originalHeight; + } + else { + //hacked! + sprite.scale.x = region.size.width / region.originalWidth; + sprite.scale.y = -region.size.height / region.originalHeight; + } + }; + SpineBase.prototype.setMeshRegion = function (attachment, mesh, region) { + if (mesh.attachment === attachment && mesh.region === region) { + return; + } + mesh.region = region; + mesh.attachment = attachment; + mesh.texture = region.texture; + region.texture.updateUvs(); + mesh.uvBuffer.update(attachment.regionUVs); + }; + /** + * When autoupdate is set to yes this function is used as pixi's updateTransform function + * + * @private + */ + SpineBase.prototype.autoUpdateTransform = function () { + if (settings.GLOBAL_AUTO_UPDATE) { + this.lastTime = this.lastTime || Date.now(); + var timeDelta = (Date.now() - this.lastTime) * 0.001; + this.lastTime = Date.now(); + this.update(timeDelta); + } + else { + this.lastTime = 0; + } + display.Container.prototype.updateTransform.call(this); + }; + /** + * Create a new sprite to be used with core.RegionAttachment + * + * @param slot {spine.Slot} The slot to which the attachment is parented + * @param attachment {spine.RegionAttachment} The attachment that the sprite will represent + * @private + */ + SpineBase.prototype.createSprite = function (slot, attachment, defName) { + var region = attachment.region; + if (slot.hackAttachment === attachment) { + region = slot.hackRegion; + } + var texture = region ? region.texture : null; + var sprite = this.newSprite(texture); + sprite.anchor.set(0.5); + if (region) { + this.setSpriteRegion(attachment, sprite, attachment.region); + } + slot.sprites = slot.sprites || {}; + slot.sprites[defName] = sprite; + return sprite; + }; + /** + * Creates a Strip from the spine data + * @param slot {spine.Slot} The slot to which the attachment is parented + * @param attachment {spine.RegionAttachment} The attachment that the sprite will represent + * @private + */ + SpineBase.prototype.createMesh = function (slot, attachment) { + var region = attachment.region; + if (slot.hackAttachment === attachment) { + region = slot.hackRegion; + slot.hackAttachment = null; + slot.hackRegion = null; + } + var strip = this.newMesh(region ? region.texture : null, new Float32Array(attachment.regionUVs.length), attachment.regionUVs, new Uint16Array(attachment.triangles), constants.DRAW_MODES.TRIANGLES); + if (typeof strip._canvasPadding !== "undefined") { + strip._canvasPadding = 1.5; + } + strip.alpha = attachment.color.a; + strip.region = attachment.region; + if (region) { + this.setMeshRegion(attachment, strip, region); + } + slot.meshes = slot.meshes || {}; + slot.meshes[attachment.id] = strip; + return strip; + }; + //@ts-ignore + SpineBase.prototype.createGraphics = function (slot, clip) { + var graphics = this.newGraphics(); + var poly = new math.Polygon([]); + graphics.clear(); + graphics.beginFill(0xffffff, 1); + graphics.drawPolygon(poly); + graphics.renderable = false; + slot.currentGraphics = graphics; + slot.clippingContainer = this.newContainer(); + slot.clippingContainer.mask = slot.currentGraphics; + return graphics; + }; + SpineBase.prototype.updateGraphics = function (slot, clip) { + var geom = slot.currentGraphics.geometry; + var vertices = geom.graphicsData[0].shape.points; + var n = clip.worldVerticesLength; + vertices.length = n; + clip.computeWorldVertices(slot, 0, n, vertices, 0, 2); + geom.invalidate(); + }; + /** + * Changes texture in attachment in specific slot. + * + * PIXI runtime feature, it was made to satisfy our users. + * + * @param slotIndex {number} + * @param [texture = null] {PIXI.Texture} If null, take default (original) texture + * @param [size = null] {PIXI.Point} sometimes we need new size for region attachment, you can pass 'texture.orig' there + * @returns {boolean} Success flag + */ + SpineBase.prototype.hackTextureBySlotIndex = function (slotIndex, texture, size) { + if (texture === void 0) { texture = null; } + if (size === void 0) { size = null; } + var slot = this.skeleton.slots[slotIndex]; + if (!slot) { + return false; + } + var attachment = slot.getAttachment(); + var region = attachment.region; + if (texture) { + region = new TextureRegion(); + region.texture = texture; + region.size = size; + slot.hackRegion = region; + slot.hackAttachment = attachment; + } + else { + slot.hackRegion = null; + slot.hackAttachment = null; + } + if (slot.currentSprite) { + this.setSpriteRegion(attachment, slot.currentSprite, region); + } + else if (slot.currentMesh) { + this.setMeshRegion(attachment, slot.currentMesh, region); + } + return true; + }; + /** + * Changes texture in attachment in specific slot. + * + * PIXI runtime feature, it was made to satisfy our users. + * + * @param slotName {string} + * @param [texture = null] {PIXI.Texture} If null, take default (original) texture + * @param [size = null] {PIXI.Point} sometimes we need new size for region attachment, you can pass 'texture.orig' there + * @returns {boolean} Success flag + */ + SpineBase.prototype.hackTextureBySlotName = function (slotName, texture, size) { + if (texture === void 0) { texture = null; } + if (size === void 0) { size = null; } + var index = this.skeleton.findSlotIndex(slotName); + if (index == -1) { + return false; + } + return this.hackTextureBySlotIndex(index, texture, size); + }; + /** + * Changes texture of an attachment + * + * PIXI runtime feature, it was made to satisfy our users. + * + * @param slotName {string} + * @param attachmentName {string} + * @param [texture = null] {PIXI.Texture} If null, take default (original) texture + * @param [size = null] {PIXI.Point} sometimes we need new size for region attachment, you can pass 'texture.orig' there + * @returns {boolean} Success flag + */ + SpineBase.prototype.hackTextureAttachment = function (slotName, attachmentName, texture, size) { + if (size === void 0) { size = null; } + // changes the texture of an attachment at the skeleton level + var slotIndex = this.skeleton.findSlotIndex(slotName); + var attachment = this.skeleton.getAttachmentByName(slotName, attachmentName); + attachment.region.texture = texture; + var slot = this.skeleton.slots[slotIndex]; + if (!slot) { + return false; + } + // gets the currently active attachment in this slot + var currentAttachment = slot.getAttachment(); + if (attachmentName === currentAttachment.name) { + // if the attachment we are changing is currently active, change the the live texture + var region = attachment.region; + if (texture) { + region = new TextureRegion(); + region.texture = texture; + region.size = size; + slot.hackRegion = region; + slot.hackAttachment = currentAttachment; + } + else { + slot.hackRegion = null; + slot.hackAttachment = null; + } + if (slot.currentSprite && slot.currentSprite.region != region) { + this.setSpriteRegion(currentAttachment, slot.currentSprite, region); + slot.currentSprite.region = region; + } + else if (slot.currentMesh && slot.currentMesh.region != region) { + this.setMeshRegion(currentAttachment, slot.currentMesh, region); + } + return true; + } + return false; + }; + //those methods can be overriden to spawn different classes + SpineBase.prototype.newContainer = function () { + return new display.Container(); + }; + SpineBase.prototype.newSprite = function (tex) { + return new SpineSprite(tex); + }; + SpineBase.prototype.newGraphics = function () { + return new graphics.Graphics(); + }; + SpineBase.prototype.newMesh = function (texture, vertices, uvs, indices, drawMode) { + return new SpineMesh(texture, vertices, uvs, indices, drawMode); + }; + SpineBase.prototype.transformHack = function () { + return 1; + }; + /** + * Hack for pixi-display and pixi-lights. Every attachment name ending with a suffix will be added to different layer + * @param nameSuffix + * @param group + * @param outGroup + */ + SpineBase.prototype.hackAttachmentGroups = function (nameSuffix, group, outGroup) { + if (!nameSuffix) { + return undefined; + } + var list_d = [], list_n = []; + for (var i = 0, len = this.skeleton.slots.length; i < len; i++) { + var slot = this.skeleton.slots[i]; + var name_1 = slot.currentSpriteName || slot.currentMeshName || ""; + var target = slot.currentSprite || slot.currentMesh; + if (name_1.endsWith(nameSuffix)) { + target.parentGroup = group; + list_n.push(target); + } + else if (outGroup && target) { + target.parentGroup = outGroup; + list_d.push(target); + } + } + return [list_d, list_n]; + }; + SpineBase.prototype.destroy = function (options) { + this.debug = null; // setter will do the cleanup + for (var i = 0, n = this.skeleton.slots.length; i < n; i++) { + var slot = this.skeleton.slots[i]; + for (var name_2 in slot.meshes) { + slot.meshes[name_2].destroy(options); + } + slot.meshes = null; + for (var name_3 in slot.sprites) { + slot.sprites[name_3].destroy(options); + } + slot.sprites = null; + } + for (var i = 0, n = this.slotContainers.length; i < n; i++) { + this.slotContainers[i].destroy(options); + } + this.spineData = null; + this.skeleton = null; + this.slotContainers = null; + this.stateData = null; + this.state = null; + this.tempClipContainers = null; + _super.prototype.destroy.call(this, options); + }; + SpineBase.clippingPolygon = []; + return SpineBase; + }(display.Container)); + /** + * The visibility of the spine object. If false the object will not be drawn, + * the updateTransform function will not be called, and the spine will not be automatically updated. + * + * @member {boolean} + * @memberof spine.Spine# + * @default true + */ + Object.defineProperty(SpineBase.prototype, 'visible', { + get: function () { + return this._visible; + }, + set: function (value) { + if (value !== this._visible) { + this._visible = value; + if (value) { + this.lastTime = 0; + } + } + } + }); + + /** + * This is a debug renderer that uses PixiJS Graphics under the hood. + * @public + */ + var SpineDebugRenderer = /** @class */ (function () { + function SpineDebugRenderer() { + this.registeredSpines = new Map(); + this.drawDebug = true; + this.drawMeshHull = true; + this.drawMeshTriangles = true; + this.drawBones = true; + this.drawPaths = true; + this.drawBoundingBoxes = true; + this.drawClipping = true; + this.drawRegionAttachments = true; + this.lineWidth = 1; + this.regionAttachmentsColor = 0x0078ff; + this.meshHullColor = 0x0078ff; + this.meshTrianglesColor = 0xffcc00; + this.clippingPolygonColor = 0xff00ff; + this.boundingBoxesRectColor = 0x00ff00; + this.boundingBoxesPolygonColor = 0x00ff00; + this.boundingBoxesCircleColor = 0x00ff00; + this.pathsCurveColor = 0xff0000; + this.pathsLineColor = 0xff00ff; + this.skeletonXYColor = 0xff0000; + this.bonesColor = 0x00eecc; + } + /** + * The debug is attached by force to each spine object. So we need to create it inside the spine when we get the first update + */ + SpineDebugRenderer.prototype.registerSpine = function (spine) { + if (this.registeredSpines.has(spine)) { + console.warn("SpineDebugRenderer.registerSpine() - this spine is already registered!", spine); + } + var debugDisplayObjects = { + parentDebugContainer: new display.Container(), + bones: new display.Container(), + skeletonXY: new graphics.Graphics(), + regionAttachmentsShape: new graphics.Graphics(), + meshTrianglesLine: new graphics.Graphics(), + meshHullLine: new graphics.Graphics(), + clippingPolygon: new graphics.Graphics(), + boundingBoxesRect: new graphics.Graphics(), + boundingBoxesCircle: new graphics.Graphics(), + boundingBoxesPolygon: new graphics.Graphics(), + pathsCurve: new graphics.Graphics(), + pathsLine: new graphics.Graphics(), + }; + debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.bones); + debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.skeletonXY); + debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.regionAttachmentsShape); + debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.meshTrianglesLine); + debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.meshHullLine); + debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.clippingPolygon); + debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.boundingBoxesRect); + debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.boundingBoxesCircle); + debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.boundingBoxesPolygon); + debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.pathsCurve); + debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.pathsLine); + spine.addChild(debugDisplayObjects.parentDebugContainer); + this.registeredSpines.set(spine, debugDisplayObjects); + }; + SpineDebugRenderer.prototype.renderDebug = function (spine) { + if (!this.registeredSpines.has(spine)) { + // This should never happen. Spines are registered when you assign spine.debug + this.registerSpine(spine); + } + var debugDisplayObjects = this.registeredSpines.get(spine); + debugDisplayObjects.skeletonXY.clear(); + debugDisplayObjects.regionAttachmentsShape.clear(); + debugDisplayObjects.meshTrianglesLine.clear(); + debugDisplayObjects.meshHullLine.clear(); + debugDisplayObjects.clippingPolygon.clear(); + debugDisplayObjects.boundingBoxesRect.clear(); + debugDisplayObjects.boundingBoxesCircle.clear(); + debugDisplayObjects.boundingBoxesPolygon.clear(); + debugDisplayObjects.pathsCurve.clear(); + debugDisplayObjects.pathsLine.clear(); + for (var len = debugDisplayObjects.bones.children.length; len > 0; len--) { + debugDisplayObjects.bones.children[len - 1].destroy({ children: true, texture: true, baseTexture: true }); + } + var scale = spine.scale.x || spine.scale.y || 1; + var lineWidth = this.lineWidth / scale; + if (this.drawBones) { + this.drawBonesFunc(spine, debugDisplayObjects, lineWidth, scale); + } + if (this.drawPaths) { + this.drawPathsFunc(spine, debugDisplayObjects, lineWidth); + } + if (this.drawBoundingBoxes) { + this.drawBoundingBoxesFunc(spine, debugDisplayObjects, lineWidth); + } + if (this.drawClipping) { + this.drawClippingFunc(spine, debugDisplayObjects, lineWidth); + } + if (this.drawMeshHull || this.drawMeshTriangles) { + this.drawMeshHullAndMeshTriangles(spine, debugDisplayObjects, lineWidth); + } + if (this.drawRegionAttachments) { + this.drawRegionAttachmentsFunc(spine, debugDisplayObjects, lineWidth); + } + }; + SpineDebugRenderer.prototype.drawBonesFunc = function (spine, debugDisplayObjects, lineWidth, scale) { + var skeleton = spine.skeleton; + var skeletonX = skeleton.x; + var skeletonY = skeleton.y; + var bones = skeleton.bones; + debugDisplayObjects.skeletonXY.lineStyle(lineWidth, this.skeletonXYColor, 1); + for (var i = 0, len = bones.length; i < len; i++) { + var bone = bones[i], boneLen = bone.data.length, starX = skeletonX + bone.matrix.tx, starY = skeletonY + bone.matrix.ty, endX = skeletonX + boneLen * bone.matrix.a + bone.matrix.tx, endY = skeletonY + boneLen * bone.matrix.b + bone.matrix.ty; + if (bone.data.name === "root" || bone.data.parent === null) { + continue; + } + // Triangle calculation formula + // area: A=sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))/4 + // alpha: alpha=acos((pow(b, 2)+pow(c, 2)-pow(a, 2))/(2*b*c)) + // beta: beta=acos((pow(a, 2)+pow(c, 2)-pow(b, 2))/(2*a*c)) + // gamma: gamma=acos((pow(a, 2)+pow(b, 2)-pow(c, 2))/(2*a*b)) + var w = Math.abs(starX - endX), h = Math.abs(starY - endY), + // a = w, // side length a + a2 = Math.pow(w, 2), // square root of side length a + b = h, // side length b + b2 = Math.pow(h, 2), // square root of side length b + c = Math.sqrt(a2 + b2), // side length c + c2 = Math.pow(c, 2), // square root of side length c + rad = Math.PI / 180, + // A = Math.acos([a2 + c2 - b2] / [2 * a * c]) || 0, // Angle A + // C = Math.acos([a2 + b2 - c2] / [2 * a * b]) || 0, // C angle + B = Math.acos((c2 + b2 - a2) / (2 * b * c)) || 0; // angle of corner B + if (c === 0) { + continue; + } + var gp = new graphics.Graphics(); + debugDisplayObjects.bones.addChild(gp); + // draw bone + var refRation = c / 50 / scale; + gp.beginFill(this.bonesColor, 1); + gp.drawPolygon(0, 0, 0 - refRation, c - refRation * 3, 0, c - refRation, 0 + refRation, c - refRation * 3); + gp.endFill(); + gp.x = starX; + gp.y = starY; + gp.pivot.y = c; + // Calculate bone rotation angle + var rotation = 0; + if (starX < endX && starY < endY) { + // bottom right + rotation = -B + 180 * rad; + } + else if (starX > endX && starY < endY) { + // bottom left + rotation = 180 * rad + B; + } + else if (starX > endX && starY > endY) { + // top left + rotation = -B; + } + else if (starX < endX && starY > endY) { + // bottom left + rotation = B; + } + else if (starY === endY && starX < endX) { + // To the right + rotation = 90 * rad; + } + else if (starY === endY && starX > endX) { + // go left + rotation = -90 * rad; + } + else if (starX === endX && starY < endY) { + // down + rotation = 180 * rad; + } + else if (starX === endX && starY > endY) { + // up + rotation = 0; + } + gp.rotation = rotation; + // Draw the starting rotation point of the bone + gp.lineStyle(lineWidth + refRation / 2.4, this.bonesColor, 1); + gp.beginFill(0x000000, 0.6); + gp.drawCircle(0, c, refRation * 1.2); + gp.endFill(); + } + // Draw the skeleton starting point "X" form + var startDotSize = lineWidth * 3; + debugDisplayObjects.skeletonXY.moveTo(skeletonX - startDotSize, skeletonY - startDotSize); + debugDisplayObjects.skeletonXY.lineTo(skeletonX + startDotSize, skeletonY + startDotSize); + debugDisplayObjects.skeletonXY.moveTo(skeletonX + startDotSize, skeletonY - startDotSize); + debugDisplayObjects.skeletonXY.lineTo(skeletonX - startDotSize, skeletonY + startDotSize); + }; + SpineDebugRenderer.prototype.drawRegionAttachmentsFunc = function (spine, debugDisplayObjects, lineWidth) { + var skeleton = spine.skeleton; + var slots = skeleton.slots; + debugDisplayObjects.regionAttachmentsShape.lineStyle(lineWidth, this.regionAttachmentsColor, 1); + for (var i = 0, len = slots.length; i < len; i++) { + var slot = slots[i], attachment = slot.getAttachment(); + if (attachment == null || attachment.type !== exports.AttachmentType.Region) { + continue; + } + var regionAttachment = attachment; + var vertices = new Float32Array(8); + regionAttachment === null || regionAttachment === void 0 ? void 0 : regionAttachment.updateOffset(); // We don't need this on all versions + regionAttachment.computeWorldVertices(slot, vertices, 0, 2); + debugDisplayObjects.regionAttachmentsShape.drawPolygon(Array.from(vertices.slice(0, 8))); + } + }; + SpineDebugRenderer.prototype.drawMeshHullAndMeshTriangles = function (spine, debugDisplayObjects, lineWidth) { + var skeleton = spine.skeleton; + var slots = skeleton.slots; + debugDisplayObjects.meshHullLine.lineStyle(lineWidth, this.meshHullColor, 1); + debugDisplayObjects.meshTrianglesLine.lineStyle(lineWidth, this.meshTrianglesColor, 1); + for (var i = 0, len = slots.length; i < len; i++) { + var slot = slots[i]; + if (!slot.bone.active) { + continue; + } + var attachment = slot.getAttachment(); + if (attachment == null || attachment.type !== exports.AttachmentType.Mesh) { + continue; + } + var meshAttachment = attachment; + var vertices = new Float32Array(meshAttachment.worldVerticesLength), triangles = meshAttachment.triangles; + var hullLength = meshAttachment.hullLength; + meshAttachment.computeWorldVertices(slot, 0, meshAttachment.worldVerticesLength, vertices, 0, 2); + // draw the skinned mesh (triangle) + if (this.drawMeshTriangles) { + for (var i_1 = 0, len_1 = triangles.length; i_1 < len_1; i_1 += 3) { + var v1 = triangles[i_1] * 2, v2 = triangles[i_1 + 1] * 2, v3 = triangles[i_1 + 2] * 2; + debugDisplayObjects.meshTrianglesLine.moveTo(vertices[v1], vertices[v1 + 1]); + debugDisplayObjects.meshTrianglesLine.lineTo(vertices[v2], vertices[v2 + 1]); + debugDisplayObjects.meshTrianglesLine.lineTo(vertices[v3], vertices[v3 + 1]); + } + } + // draw skin border + if (this.drawMeshHull && hullLength > 0) { + hullLength = (hullLength >> 1) * 2; + var lastX = vertices[hullLength - 2], lastY = vertices[hullLength - 1]; + for (var i_2 = 0, len_2 = hullLength; i_2 < len_2; i_2 += 2) { + var x = vertices[i_2], y = vertices[i_2 + 1]; + debugDisplayObjects.meshHullLine.moveTo(x, y); + debugDisplayObjects.meshHullLine.lineTo(lastX, lastY); + lastX = x; + lastY = y; + } + } + } + }; + SpineDebugRenderer.prototype.drawClippingFunc = function (spine, debugDisplayObjects, lineWidth) { + var skeleton = spine.skeleton; + var slots = skeleton.slots; + debugDisplayObjects.clippingPolygon.lineStyle(lineWidth, this.clippingPolygonColor, 1); + for (var i = 0, len = slots.length; i < len; i++) { + var slot = slots[i]; + if (!slot.bone.active) { + continue; + } + var attachment = slot.getAttachment(); + if (attachment == null || attachment.type !== exports.AttachmentType.Clipping) { + continue; + } + var clippingAttachment = attachment; + var nn = clippingAttachment.worldVerticesLength, world = new Float32Array(nn); + clippingAttachment.computeWorldVertices(slot, 0, nn, world, 0, 2); + debugDisplayObjects.clippingPolygon.drawPolygon(Array.from(world)); + } + }; + SpineDebugRenderer.prototype.drawBoundingBoxesFunc = function (spine, debugDisplayObjects, lineWidth) { + var _this = this; + // draw the total outline of the bounding box + debugDisplayObjects.boundingBoxesRect.lineStyle(lineWidth, this.boundingBoxesRectColor, 5); + var bounds = new SkeletonBoundsBase(); + bounds.update(spine.skeleton, true); + debugDisplayObjects.boundingBoxesRect.drawRect(bounds.minX, bounds.minY, bounds.getWidth(), bounds.getHeight()); + var polygons = bounds.polygons, drawPolygon = function (polygonVertices, _offset, count) { + debugDisplayObjects.boundingBoxesPolygon.lineStyle(lineWidth, _this.boundingBoxesPolygonColor, 1); + debugDisplayObjects.boundingBoxesPolygon.beginFill(_this.boundingBoxesPolygonColor, 0.1); + if (count < 3) { + throw new Error("Polygon must contain at least 3 vertices"); + } + var paths = [], dotSize = lineWidth * 2; + for (var i = 0, len = polygonVertices.length; i < len; i += 2) { + var x1 = polygonVertices[i], y1 = polygonVertices[i + 1]; + // draw the bounding box node + debugDisplayObjects.boundingBoxesCircle.lineStyle(0); + debugDisplayObjects.boundingBoxesCircle.beginFill(_this.boundingBoxesCircleColor); + debugDisplayObjects.boundingBoxesCircle.drawCircle(x1, y1, dotSize); + debugDisplayObjects.boundingBoxesCircle.endFill(); + paths.push(x1, y1); + } + // draw the bounding box area + debugDisplayObjects.boundingBoxesPolygon.drawPolygon(paths); + debugDisplayObjects.boundingBoxesPolygon.endFill(); + }; + for (var i = 0, len = polygons.length; i < len; i++) { + var polygon = polygons[i]; + drawPolygon(polygon, 0, polygon.length); + } + }; + SpineDebugRenderer.prototype.drawPathsFunc = function (spine, debugDisplayObjects, lineWidth) { + var skeleton = spine.skeleton; + var slots = skeleton.slots; + debugDisplayObjects.pathsCurve.lineStyle(lineWidth, this.pathsCurveColor, 1); + debugDisplayObjects.pathsLine.lineStyle(lineWidth, this.pathsLineColor, 1); + for (var i = 0, len = slots.length; i < len; i++) { + var slot = slots[i]; + if (!slot.bone.active) { + continue; + } + var attachment = slot.getAttachment(); + if (attachment == null || attachment.type !== exports.AttachmentType.Path) { + continue; + } + var pathAttachment = attachment; + var nn = pathAttachment.worldVerticesLength; + var world = new Float32Array(nn); + pathAttachment.computeWorldVertices(slot, 0, nn, world, 0, 2); + var x1 = world[2], y1 = world[3], x2 = 0, y2 = 0; + if (pathAttachment.closed) { + var cx1 = world[0], cy1 = world[1], cx2 = world[nn - 2], cy2 = world[nn - 1]; + x2 = world[nn - 4]; + y2 = world[nn - 3]; + // curve + debugDisplayObjects.pathsCurve.moveTo(x1, y1); + debugDisplayObjects.pathsCurve.bezierCurveTo(cx1, cy1, cx2, cy2, x2, y2); + // handle + debugDisplayObjects.pathsLine.moveTo(x1, y1); + debugDisplayObjects.pathsLine.lineTo(cx1, cy1); + debugDisplayObjects.pathsLine.moveTo(x2, y2); + debugDisplayObjects.pathsLine.lineTo(cx2, cy2); + } + nn -= 4; + for (var ii = 4; ii < nn; ii += 6) { + var cx1 = world[ii], cy1 = world[ii + 1], cx2 = world[ii + 2], cy2 = world[ii + 3]; + x2 = world[ii + 4]; + y2 = world[ii + 5]; + // curve + debugDisplayObjects.pathsCurve.moveTo(x1, y1); + debugDisplayObjects.pathsCurve.bezierCurveTo(cx1, cy1, cx2, cy2, x2, y2); + // handle + debugDisplayObjects.pathsLine.moveTo(x1, y1); + debugDisplayObjects.pathsLine.lineTo(cx1, cy1); + debugDisplayObjects.pathsLine.moveTo(x2, y2); + debugDisplayObjects.pathsLine.lineTo(cx2, cy2); + x1 = x2; + y1 = y2; + } + } + }; + SpineDebugRenderer.prototype.unregisterSpine = function (spine) { + if (!this.registeredSpines.has(spine)) { + console.warn("SpineDebugRenderer.unregisterSpine() - spine is not registered, can't unregister!", spine); + } + var debugDisplayObjects = this.registeredSpines.get(spine); + debugDisplayObjects.parentDebugContainer.destroy({ baseTexture: true, children: true, texture: true }); + this.registeredSpines.delete(spine); + }; + return SpineDebugRenderer; + }()); + + /* eslint-disable */ + + function isJson(resource) { + return resource.type === loaders.LoaderResource.TYPE.JSON; + } + function isBuffer(resource) { + return resource.xhrType === loaders.LoaderResource.XHR_RESPONSE_TYPE.BUFFER; + } + loaders.LoaderResource.setExtensionXhrType('skel', loaders.LoaderResource.XHR_RESPONSE_TYPE.BUFFER); + /** + * @public + */ + var AbstractSpineParser = /** @class */ (function () { + function AbstractSpineParser() { + } + AbstractSpineParser.prototype.genMiddleware = function () { + var self = this; + return { + use: function (resource, next) { + // skip if no data, its not json, or it isn't atlas data + if (!resource.data) { + return next(); + } + var isJsonSpineModel = isJson(resource) && resource.data.bones; + var isBinarySpineModel = isBuffer(resource) && (resource.extension === 'skel' || resource.metadata + && resource.metadata.spineMetadata); + if (!isJsonSpineModel && !isBinarySpineModel) { + return next(); + } + var parser = null; + var dataToParse = resource.data; + if (isJsonSpineModel) { + parser = self.createJsonParser(); + } + else { + parser = self.createBinaryParser(); + if (resource.data instanceof ArrayBuffer) { + dataToParse = new Uint8Array(resource.data); + } + } + var metadata = (resource.metadata || {}); + var metadataSkeletonScale = metadata ? metadata.spineSkeletonScale : null; + if (metadataSkeletonScale) { + parser.scale = metadataSkeletonScale; + } + var metadataAtlas = metadata.spineAtlas; + if (metadataAtlas === false) { + return next(); + } + if (metadataAtlas && metadataAtlas.pages) { + self.parseData(resource, parser, metadataAtlas, dataToParse); + return next(); + } + var metadataAtlasSuffix = metadata.spineAtlasSuffix || '.atlas'; + /** + * use a bit of hackery to load the atlas file, here we assume that the .json, .atlas and .png files + * that correspond to the spine file are in the same base URL and that the .json and .atlas files + * have the same name + */ + var atlasPath = resource.url; + var queryStringPos = atlasPath.indexOf('?'); + if (queryStringPos > 0) { + //remove querystring + atlasPath = atlasPath.substr(0, queryStringPos); + } + atlasPath = atlasPath.substr(0, atlasPath.lastIndexOf('.')) + metadataAtlasSuffix; + // use atlas path as a params. (no need to use same atlas file name with json file name) + if (metadata.spineAtlasFile) { + atlasPath = metadata.spineAtlasFile; + } + //remove the baseUrl + atlasPath = atlasPath.replace(this.baseUrl, ''); + var atlasOptions = { + crossOrigin: resource.crossOrigin, + xhrType: loaders.LoaderResource.XHR_RESPONSE_TYPE.TEXT, + metadata: metadata.spineMetadata || null, + parentResource: resource + }; + var imageOptions = { + crossOrigin: resource.crossOrigin, + metadata: metadata.imageMetadata || null, + parentResource: resource + }; + var baseUrl = resource.url.substr(0, resource.url.lastIndexOf('/') + 1); + //remove the baseUrl + baseUrl = baseUrl.replace(this.baseUrl, ''); + var namePrefix = metadata.imageNamePrefix || (resource.name + '_atlas_page_'); + var adapter = metadata.images ? staticImageLoader(metadata.images) + : metadata.image ? staticImageLoader({ 'default': metadata.image }) + : metadata.imageLoader ? metadata.imageLoader(this, namePrefix, baseUrl, imageOptions) + : imageLoaderAdapter(this, namePrefix, baseUrl, imageOptions); + function createSkeletonWithRawAtlas(rawData) { + new TextureAtlas(rawData, adapter, function (spineAtlas) { + if (spineAtlas) { + self.parseData(resource, parser, spineAtlas, dataToParse); + } + next(); + }); + } + if (metadata.atlasRawData) { + createSkeletonWithRawAtlas(metadata.atlasRawData); + } + else { + this.add(resource.name + '_atlas', atlasPath, atlasOptions, function (atlasResource) { + if (!atlasResource.error) { + createSkeletonWithRawAtlas(atlasResource.data); + } + else { + next(); + } + }); + } + } + }; + }; + return AbstractSpineParser; + }()); + /** + * @public + */ + function imageLoaderAdapter(loader, namePrefix, baseUrl, imageOptions) { + if (baseUrl && baseUrl.lastIndexOf('/') !== (baseUrl.length - 1)) { + baseUrl += '/'; + } + return function (line, callback) { + var name = namePrefix + line; + var url = baseUrl + line; + var cachedResource = loader.resources[name]; + if (cachedResource) { + var done = function () { + callback(cachedResource.texture.baseTexture); + }; + if (cachedResource.texture) { + done(); + } + else { + cachedResource.onAfterMiddleware.add(done); + } + } + else { + loader.add(name, url, imageOptions, function (resource) { + if (!resource.error) { + if (line.indexOf('-pma.') >= 0) { + resource.texture.baseTexture.alphaMode = constants.ALPHA_MODES.PMA; + } + callback(resource.texture.baseTexture); + } + else { + callback(null); + } + }); + } + }; + } + /** + * @public + */ + function syncImageLoaderAdapter(baseUrl, crossOrigin) { + if (baseUrl && baseUrl.lastIndexOf('/') !== (baseUrl.length - 1)) { + baseUrl += '/'; + } + return function (line, callback) { + callback(core.BaseTexture.from(line, crossOrigin)); + }; + } + /** + * @public + */ + function staticImageLoader(pages) { + return function (line, callback) { + var page = pages[line] || pages['default']; + if (page && page.baseTexture) + callback(page.baseTexture); + else + callback(page); + }; + } + + /* eslint-disable */ + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + var extendStatics$3 = function(d, b) { + extendStatics$3 = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics$3(d, b); + }; + + function __extends$3(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics$3(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + + /** + * @public + */ + var Attachment$2 = /** @class */ (function () { + function Attachment(name) { + if (name == null) + throw new Error("name cannot be null."); + this.name = name; + } + return Attachment; + }()); + /** + * @public + */ + var VertexAttachment$2 = /** @class */ (function (_super) { + __extends$3(VertexAttachment, _super); + function VertexAttachment(name) { + var _this = _super.call(this, name) || this; + _this.id = (VertexAttachment.nextID++ & 65535) << 11; + _this.worldVerticesLength = 0; + _this.deformAttachment = _this; + return _this; + } + VertexAttachment.prototype.computeWorldVerticesOld = function (slot, worldVertices) { + this.computeWorldVertices(slot, 0, this.worldVerticesLength, worldVertices, 0, 2); + }; + /** Transforms local vertices to world coordinates. + * @param start The index of the first local vertex value to transform. Each vertex has 2 values, x and y. + * @param count The number of world vertex values to output. Must be <= {@link #getWorldVerticesLength()} - start. + * @param worldVertices The output world vertices. Must have a length >= offset + count. + * @param offset The worldVertices index to begin writing values. */ + VertexAttachment.prototype.computeWorldVertices = function (slot, start, count, worldVertices, offset, stride) { + count = offset + (count >> 1) * stride; + var skeleton = slot.bone.skeleton; + var deformArray = slot.deform; + var vertices = this.vertices; + var bones = this.bones; + if (bones == null) { + if (deformArray.length > 0) + vertices = deformArray; + var mat = slot.bone.matrix; + var x = mat.tx; + var y = mat.ty; + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + for (var v_1 = start, w = offset; w < count; v_1 += 2, w += stride) { + var vx = vertices[v_1], vy = vertices[v_1 + 1]; + worldVertices[w] = vx * a + vy * b + x; + worldVertices[w + 1] = vx * c + vy * d + y; + } + return; + } + var v = 0, skip = 0; + for (var i = 0; i < start; i += 2) { + var n = bones[v]; + v += n + 1; + skip += n; + } + var skeletonBones = skeleton.bones; + if (deformArray.length == 0) { + for (var w = offset, b = skip * 3; w < count; w += stride) { + var wx = 0, wy = 0; + var n = bones[v++]; + n += v; + for (; v < n; v++, b += 3) { + var mat = skeletonBones[bones[v]].matrix; + var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; + wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; + wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + else { + var deform = deformArray; + for (var w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { + var wx = 0, wy = 0; + var n = bones[v++]; + n += v; + for (; v < n; v++, b += 3, f += 2) { + var mat = skeletonBones[bones[v]].matrix; + var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; + wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; + wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + }; + VertexAttachment.prototype.copyTo = function (attachment) { + if (this.bones != null) { + attachment.bones = new Array(this.bones.length); + Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length); + } + else + attachment.bones = null; + if (this.vertices != null) { + attachment.vertices = Utils.newFloatArray(this.vertices.length); + Utils.arrayCopy(this.vertices, 0, attachment.vertices, 0, this.vertices.length); + } + else + attachment.vertices = null; + attachment.worldVerticesLength = this.worldVerticesLength; + attachment.deformAttachment = this.deformAttachment; + }; + VertexAttachment.nextID = 0; + return VertexAttachment; + }(Attachment$2)); + + /** + * @public + */ + var BoundingBoxAttachment$2 = /** @class */ (function (_super) { + __extends$3(BoundingBoxAttachment, _super); + function BoundingBoxAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.BoundingBox; + _this.color = new Color(1, 1, 1, 1); + return _this; + } + BoundingBoxAttachment.prototype.copy = function () { + var copy = new BoundingBoxAttachment(this.name); + this.copyTo(copy); + copy.color.setFromColor(this.color); + return copy; + }; + return BoundingBoxAttachment; + }(VertexAttachment$2)); + + /** + * @public + */ + var ClippingAttachment$2 = /** @class */ (function (_super) { + __extends$3(ClippingAttachment, _super); + function ClippingAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Clipping; + // Nonessential. + _this.color = new Color(0.2275, 0.2275, 0.8078, 1); // ce3a3aff + return _this; + } + ClippingAttachment.prototype.copy = function () { + var copy = new ClippingAttachment(this.name); + this.copyTo(copy); + copy.endSlot = this.endSlot; + copy.color.setFromColor(this.color); + return copy; + }; + return ClippingAttachment; + }(VertexAttachment$2)); + + /** + * @public + */ + var MeshAttachment$2 = /** @class */ (function (_super) { + __extends$3(MeshAttachment, _super); + function MeshAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Mesh; + _this.color = new Color(1, 1, 1, 1); + _this.tempColor = new Color(0, 0, 0, 0); + return _this; + } + MeshAttachment.prototype.getParentMesh = function () { + return this.parentMesh; + }; + /** @param parentMesh May be null. */ + MeshAttachment.prototype.setParentMesh = function (parentMesh) { + this.parentMesh = parentMesh; + if (parentMesh != null) { + this.bones = parentMesh.bones; + this.vertices = parentMesh.vertices; + this.worldVerticesLength = parentMesh.worldVerticesLength; + this.regionUVs = parentMesh.regionUVs; + this.triangles = parentMesh.triangles; + this.hullLength = parentMesh.hullLength; + this.worldVerticesLength = parentMesh.worldVerticesLength; + } + }; + MeshAttachment.prototype.copy = function () { + if (this.parentMesh != null) + return this.newLinkedMesh(); + var copy = new MeshAttachment(this.name); + copy.region = this.region; + copy.path = this.path; + copy.color.setFromColor(this.color); + this.copyTo(copy); + copy.regionUVs = new Float32Array(this.regionUVs.length); + Utils.arrayCopy(this.regionUVs, 0, copy.regionUVs, 0, this.regionUVs.length); + copy.triangles = new Array(this.triangles.length); + Utils.arrayCopy(this.triangles, 0, copy.triangles, 0, this.triangles.length); + copy.hullLength = this.hullLength; + // Nonessential. + if (this.edges != null) { + copy.edges = new Array(this.edges.length); + Utils.arrayCopy(this.edges, 0, copy.edges, 0, this.edges.length); + } + copy.width = this.width; + copy.height = this.height; + return copy; + }; + MeshAttachment.prototype.newLinkedMesh = function () { + var copy = new MeshAttachment(this.name); + copy.region = this.region; + copy.path = this.path; + copy.color.setFromColor(this.color); + copy.deformAttachment = this.deformAttachment; + copy.setParentMesh(this.parentMesh != null ? this.parentMesh : this); + // copy.updateUVs(); + return copy; + }; + return MeshAttachment; + }(VertexAttachment$2)); + + /** + * @public + */ + var PathAttachment$2 = /** @class */ (function (_super) { + __extends$3(PathAttachment, _super); + function PathAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Path; + _this.closed = false; + _this.constantSpeed = false; + _this.color = new Color(1, 1, 1, 1); + return _this; + } + PathAttachment.prototype.copy = function () { + var copy = new PathAttachment(this.name); + this.copyTo(copy); + copy.lengths = new Array(this.lengths.length); + Utils.arrayCopy(this.lengths, 0, copy.lengths, 0, this.lengths.length); + copy.closed = closed; + copy.constantSpeed = this.constantSpeed; + copy.color.setFromColor(this.color); + return copy; + }; + return PathAttachment; + }(VertexAttachment$2)); + + /** + * @public + */ + var PointAttachment$2 = /** @class */ (function (_super) { + __extends$3(PointAttachment, _super); + function PointAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Point; + _this.color = new Color(0.38, 0.94, 0, 1); + return _this; + } + PointAttachment.prototype.computeWorldPosition = function (bone, point) { + var mat = bone.matrix; + point.x = this.x * mat.a + this.y * mat.c + bone.worldX; + point.y = this.x * mat.b + this.y * mat.d + bone.worldY; + return point; + }; + PointAttachment.prototype.computeWorldRotation = function (bone) { + var mat = bone.matrix; + var cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation); + var x = cos * mat.a + sin * mat.c; + var y = cos * mat.b + sin * mat.d; + return Math.atan2(y, x) * MathUtils.radDeg; + }; + PointAttachment.prototype.copy = function () { + var copy = new PointAttachment(this.name); + copy.x = this.x; + copy.y = this.y; + copy.rotation = this.rotation; + copy.color.setFromColor(this.color); + return copy; + }; + return PointAttachment; + }(VertexAttachment$2)); + + /** + * @public + */ + var Slot$2 = /** @class */ (function () { + function Slot(data, bone) { + this.deform = new Array(); + if (data == null) + throw new Error("data cannot be null."); + if (bone == null) + throw new Error("bone cannot be null."); + this.data = data; + this.bone = bone; + this.color = new Color(); + this.darkColor = data.darkColor == null ? null : new Color(); + this.setToSetupPose(); + this.blendMode = this.data.blendMode; + } + /** @return May be null. */ + Slot.prototype.getAttachment = function () { + return this.attachment; + }; + /** Sets the attachment and if it changed, resets {@link #getAttachmentTime()} and clears {@link #getAttachmentVertices()}. + * @param attachment May be null. */ + Slot.prototype.setAttachment = function (attachment) { + if (this.attachment == attachment) + return; + this.attachment = attachment; + this.attachmentTime = this.bone.skeleton.time; + this.deform.length = 0; + }; + Slot.prototype.setAttachmentTime = function (time) { + this.attachmentTime = this.bone.skeleton.time - time; + }; + /** Returns the time since the attachment was set. */ + Slot.prototype.getAttachmentTime = function () { + return this.bone.skeleton.time - this.attachmentTime; + }; + Slot.prototype.setToSetupPose = function () { + this.color.setFromColor(this.data.color); + if (this.darkColor != null) + this.darkColor.setFromColor(this.data.darkColor); + if (this.data.attachmentName == null) + this.attachment = null; + else { + this.attachment = null; + this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName)); + } + }; + return Slot; + }()); + + /** + * @public + */ + var RegionAttachment$2 = /** @class */ (function (_super) { + __extends$3(RegionAttachment, _super); + function RegionAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Region; + _this.x = 0; + _this.y = 0; + _this.scaleX = 1; + _this.scaleY = 1; + _this.rotation = 0; + _this.width = 0; + _this.height = 0; + _this.color = new Color(1, 1, 1, 1); + _this.offset = Utils.newFloatArray(8); + _this.uvs = Utils.newFloatArray(8); + _this.tempColor = new Color(1, 1, 1, 1); + return _this; + } + RegionAttachment.prototype.updateOffset = function () { + var regionScaleX = this.width / this.region.originalWidth * this.scaleX; + var regionScaleY = this.height / this.region.originalHeight * this.scaleY; + var localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; + var localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; + var localX2 = localX + this.region.width * regionScaleX; + var localY2 = localY + this.region.height * regionScaleY; + var radians = this.rotation * Math.PI / 180; + var cos = Math.cos(radians); + var sin = Math.sin(radians); + var localXCos = localX * cos + this.x; + var localXSin = localX * sin; + var localYCos = localY * cos + this.y; + var localYSin = localY * sin; + var localX2Cos = localX2 * cos + this.x; + var localX2Sin = localX2 * sin; + var localY2Cos = localY2 * cos + this.y; + var localY2Sin = localY2 * sin; + var offset = this.offset; + offset[RegionAttachment.OX1] = localXCos - localYSin; + offset[RegionAttachment.OY1] = localYCos + localXSin; + offset[RegionAttachment.OX2] = localXCos - localY2Sin; + offset[RegionAttachment.OY2] = localY2Cos + localXSin; + offset[RegionAttachment.OX3] = localX2Cos - localY2Sin; + offset[RegionAttachment.OY3] = localY2Cos + localX2Sin; + offset[RegionAttachment.OX4] = localX2Cos - localYSin; + offset[RegionAttachment.OY4] = localYCos + localX2Sin; + }; + RegionAttachment.prototype.setRegion = function (region) { + this.region = region; + var uvs = this.uvs; + if (region.rotate) { + uvs[2] = region.u; + uvs[3] = region.v2; + uvs[4] = region.u; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v; + uvs[0] = region.u2; + uvs[1] = region.v2; + } + else { + uvs[0] = region.u; + uvs[1] = region.v2; + uvs[2] = region.u; + uvs[3] = region.v; + uvs[4] = region.u2; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v2; + } + }; + RegionAttachment.prototype.computeWorldVertices = function (bone, worldVertices, offset, stride) { + var vertexOffset = this.offset; + var mat = bone instanceof Slot$2 ? bone.bone.matrix : bone.matrix; + var x = mat.tx, y = mat.ty; + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var offsetX = 0, offsetY = 0; + offsetX = vertexOffset[RegionAttachment.OX1]; + offsetY = vertexOffset[RegionAttachment.OY1]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // br + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX2]; + offsetY = vertexOffset[RegionAttachment.OY2]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // bl + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX3]; + offsetY = vertexOffset[RegionAttachment.OY3]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // ul + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX4]; + offsetY = vertexOffset[RegionAttachment.OY4]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // ur + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + }; + RegionAttachment.prototype.copy = function () { + var copy = new RegionAttachment(this.name); + copy.region = this.region; + copy.rendererObject = this.rendererObject; + copy.path = this.path; + copy.x = this.x; + copy.y = this.y; + copy.scaleX = this.scaleX; + copy.scaleY = this.scaleY; + copy.rotation = this.rotation; + copy.width = this.width; + copy.height = this.height; + Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, 8); + Utils.arrayCopy(this.offset, 0, copy.offset, 0, 8); + copy.color.setFromColor(this.color); + return copy; + }; + RegionAttachment.OX1 = 0; + RegionAttachment.OY1 = 1; + RegionAttachment.OX2 = 2; + RegionAttachment.OY2 = 3; + RegionAttachment.OX3 = 4; + RegionAttachment.OY3 = 5; + RegionAttachment.OX4 = 6; + RegionAttachment.OY4 = 7; + RegionAttachment.X1 = 0; + RegionAttachment.Y1 = 1; + RegionAttachment.C1R = 2; + RegionAttachment.C1G = 3; + RegionAttachment.C1B = 4; + RegionAttachment.C1A = 5; + RegionAttachment.U1 = 6; + RegionAttachment.V1 = 7; + RegionAttachment.X2 = 8; + RegionAttachment.Y2 = 9; + RegionAttachment.C2R = 10; + RegionAttachment.C2G = 11; + RegionAttachment.C2B = 12; + RegionAttachment.C2A = 13; + RegionAttachment.U2 = 14; + RegionAttachment.V2 = 15; + RegionAttachment.X3 = 16; + RegionAttachment.Y3 = 17; + RegionAttachment.C3R = 18; + RegionAttachment.C3G = 19; + RegionAttachment.C3B = 20; + RegionAttachment.C3A = 21; + RegionAttachment.U3 = 22; + RegionAttachment.V3 = 23; + RegionAttachment.X4 = 24; + RegionAttachment.Y4 = 25; + RegionAttachment.C4R = 26; + RegionAttachment.C4G = 27; + RegionAttachment.C4B = 28; + RegionAttachment.C4A = 29; + RegionAttachment.U4 = 30; + RegionAttachment.V4 = 31; + return RegionAttachment; + }(Attachment$2)); + + /** + * @public + */ + var JitterEffect$1 = /** @class */ (function () { + function JitterEffect(jitterX, jitterY) { + this.jitterX = 0; + this.jitterY = 0; + this.jitterX = jitterX; + this.jitterY = jitterY; + } + JitterEffect.prototype.begin = function (skeleton) { + }; + JitterEffect.prototype.transform = function (position, uv, light, dark) { + position.x += MathUtils.randomTriangular(-this.jitterX, this.jitterY); + position.y += MathUtils.randomTriangular(-this.jitterX, this.jitterY); + }; + JitterEffect.prototype.end = function () { + }; + return JitterEffect; + }()); + + /** + * @public + */ + var SwirlEffect$1 = /** @class */ (function () { + function SwirlEffect(radius) { + this.centerX = 0; + this.centerY = 0; + this.radius = 0; + this.angle = 0; + this.worldX = 0; + this.worldY = 0; + this.radius = radius; + } + SwirlEffect.prototype.begin = function (skeleton) { + this.worldX = skeleton.x + this.centerX; + this.worldY = skeleton.y + this.centerY; + }; + SwirlEffect.prototype.transform = function (position, uv, light, dark) { + var radAngle = this.angle * MathUtils.degreesToRadians; + var x = position.x - this.worldX; + var y = position.y - this.worldY; + var dist = Math.sqrt(x * x + y * y); + if (dist < this.radius) { + var theta = SwirlEffect.interpolation.apply(0, radAngle, (this.radius - dist) / this.radius); + var cos = Math.cos(theta); + var sin = Math.sin(theta); + position.x = cos * x - sin * y + this.worldX; + position.y = sin * x + cos * y + this.worldY; + } + }; + SwirlEffect.prototype.end = function () { + }; + SwirlEffect.interpolation = new PowOut(2); + return SwirlEffect; + }()); + + /** A simple container for a list of timelines and a name. */ + /** + * @public + */ + var Animation$2 = /** @class */ (function () { + function Animation(name, timelines, duration) { + if (name == null) + throw new Error("name cannot be null."); + if (timelines == null) + throw new Error("timelines cannot be null."); + this.name = name; + this.timelines = timelines; + this.timelineIds = []; + for (var i = 0; i < timelines.length; i++) + this.timelineIds[timelines[i].getPropertyId()] = true; + this.duration = duration; + } + Animation.prototype.hasTimeline = function (id) { + return this.timelineIds[id] == true; + }; + /** Applies all the animation's timelines to the specified skeleton. + * + * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. + * @param loop If true, the animation repeats after {@link #getDuration()}. + * @param events May be null to ignore fired events. */ + Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, blend, direction) { + if (skeleton == null) + throw new Error("skeleton cannot be null."); + if (loop && this.duration != 0) { + time %= this.duration; + if (lastTime > 0) + lastTime %= this.duration; + } + var timelines = this.timelines; + for (var i = 0, n = timelines.length; i < n; i++) + timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction); + }; + /** @param target After the first and before the last value. + * @returns index of first value greater than the target. */ + Animation.binarySearch = function (values, target, step) { + if (step === void 0) { step = 1; } + var low = 0; + var high = values.length / step - 2; + if (high == 0) + return step; + var current = high >>> 1; + while (true) { + if (values[(current + 1) * step] <= target) + low = current + 1; + else + high = current; + if (low == high) + return (low + 1) * step; + current = (low + high) >>> 1; + } + }; + Animation.linearSearch = function (values, target, step) { + for (var i = 0, last = values.length - step; i <= last; i += step) + if (values[i] > target) + return i; + return -1; + }; + return Animation; + }()); + /** + * @public + */ + var TimelineType$1; + (function (TimelineType) { + TimelineType[TimelineType["rotate"] = 0] = "rotate"; + TimelineType[TimelineType["translate"] = 1] = "translate"; + TimelineType[TimelineType["scale"] = 2] = "scale"; + TimelineType[TimelineType["shear"] = 3] = "shear"; + TimelineType[TimelineType["attachment"] = 4] = "attachment"; + TimelineType[TimelineType["color"] = 5] = "color"; + TimelineType[TimelineType["deform"] = 6] = "deform"; + TimelineType[TimelineType["event"] = 7] = "event"; + TimelineType[TimelineType["drawOrder"] = 8] = "drawOrder"; + TimelineType[TimelineType["ikConstraint"] = 9] = "ikConstraint"; + TimelineType[TimelineType["transformConstraint"] = 10] = "transformConstraint"; + TimelineType[TimelineType["pathConstraintPosition"] = 11] = "pathConstraintPosition"; + TimelineType[TimelineType["pathConstraintSpacing"] = 12] = "pathConstraintSpacing"; + TimelineType[TimelineType["pathConstraintMix"] = 13] = "pathConstraintMix"; + TimelineType[TimelineType["twoColor"] = 14] = "twoColor"; + })(TimelineType$1 || (TimelineType$1 = {})); + /** The base class for timelines that use interpolation between key frame values. */ + /** + * @public + */ + var CurveTimeline$2 = /** @class */ (function () { + function CurveTimeline(frameCount) { + if (frameCount <= 0) + throw new Error("frameCount must be > 0: " + frameCount); + this.curves = Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE); + } + /** The number of key frames for this timeline. */ + CurveTimeline.prototype.getFrameCount = function () { + return this.curves.length / CurveTimeline.BEZIER_SIZE + 1; + }; + /** Sets the specified key frame to linear interpolation. */ + CurveTimeline.prototype.setLinear = function (frameIndex) { + this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.LINEAR; + }; + /** Sets the specified key frame to stepped interpolation. */ + CurveTimeline.prototype.setStepped = function (frameIndex) { + this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.STEPPED; + }; + /** Returns the interpolation type for the specified key frame. + * @returns Linear is 0, stepped is 1, Bezier is 2. */ + CurveTimeline.prototype.getCurveType = function (frameIndex) { + var index = frameIndex * CurveTimeline.BEZIER_SIZE; + if (index == this.curves.length) + return CurveTimeline.LINEAR; + var type = this.curves[index]; + if (type == CurveTimeline.LINEAR) + return CurveTimeline.LINEAR; + if (type == CurveTimeline.STEPPED) + return CurveTimeline.STEPPED; + return CurveTimeline.BEZIER; + }; + /** Sets the specified key frame to Bezier interpolation. `cx1` and `cx2` are from 0 to 1, + * representing the percent of time between the two key frames. `cy1` and `cy2` are the percent of the + * difference between the key frame's values. */ + CurveTimeline.prototype.setCurve = function (frameIndex, cx1, cy1, cx2, cy2) { + var tmpx = (-cx1 * 2 + cx2) * 0.03, tmpy = (-cy1 * 2 + cy2) * 0.03; + var dddfx = ((cx1 - cx2) * 3 + 1) * 0.006, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006; + var ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy; + var dfx = cx1 * 0.3 + tmpx + dddfx * 0.16666667, dfy = cy1 * 0.3 + tmpy + dddfy * 0.16666667; + var i = frameIndex * CurveTimeline.BEZIER_SIZE; + var curves = this.curves; + curves[i++] = CurveTimeline.BEZIER; + var x = dfx, y = dfy; + for (var n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { + curves[i] = x; + curves[i + 1] = y; + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + x += dfx; + y += dfy; + } + }; + /** Returns the interpolated percentage for the specified key frame and linear percentage. */ + CurveTimeline.prototype.getCurvePercent = function (frameIndex, percent) { + percent = MathUtils.clamp(percent, 0, 1); + var curves = this.curves; + var i = frameIndex * CurveTimeline.BEZIER_SIZE; + var type = curves[i]; + if (type == CurveTimeline.LINEAR) + return percent; + if (type == CurveTimeline.STEPPED) + return 0; + i++; + var x = 0; + for (var start = i, n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { + x = curves[i]; + if (x >= percent) { + var prevX = void 0, prevY = void 0; + if (i == start) { + prevX = 0; + prevY = 0; + } + else { + prevX = curves[i - 2]; + prevY = curves[i - 1]; + } + return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX); + } + } + var y = curves[i - 1]; + return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1. + }; + CurveTimeline.LINEAR = 0; + CurveTimeline.STEPPED = 1; + CurveTimeline.BEZIER = 2; + CurveTimeline.BEZIER_SIZE = 10 * 2 - 1; + return CurveTimeline; + }()); + /** Changes a bone's local {@link Bone#rotation}. */ + /** + * @public + */ + var RotateTimeline$2 = /** @class */ (function (_super) { + __extends$3(RotateTimeline, _super); + function RotateTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount << 1); + return _this; + } + RotateTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.rotate << 24) + this.boneIndex; + }; + /** Sets the time and angle of the specified keyframe. */ + RotateTimeline.prototype.setFrame = function (frameIndex, time, degrees) { + frameIndex <<= 1; + this.frames[frameIndex] = time; + this.frames[frameIndex + RotateTimeline.ROTATION] = degrees; + }; + RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var frames = this.frames; + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.rotation = bone.data.rotation; + return; + case exports.MixBlend.first: + var r_1 = bone.data.rotation - bone.rotation; + bone.rotation += (r_1 - (16384 - ((16384.499999999996 - r_1 / 360) | 0)) * 360) * alpha; + } + return; + } + if (time >= frames[frames.length - RotateTimeline.ENTRIES]) { // Time is after last frame. + var r_2 = frames[frames.length + RotateTimeline.PREV_ROTATION]; + switch (blend) { + case exports.MixBlend.setup: + bone.rotation = bone.data.rotation + r_2 * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + r_2 += bone.data.rotation - bone.rotation; + r_2 -= (16384 - ((16384.499999999996 - r_2 / 360) | 0)) * 360; // Wrap within -180 and 180. + case exports.MixBlend.add: + bone.rotation += r_2 * alpha; + } + return; + } + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, RotateTimeline.ENTRIES); + var prevRotation = frames[frame + RotateTimeline.PREV_ROTATION]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime)); + var r = frames[frame + RotateTimeline.ROTATION] - prevRotation; + r = prevRotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * percent; + switch (blend) { + case exports.MixBlend.setup: + bone.rotation = bone.data.rotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + r += bone.data.rotation - bone.rotation; + case exports.MixBlend.add: + bone.rotation += (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; + } + }; + RotateTimeline.ENTRIES = 2; + RotateTimeline.PREV_TIME = -2; + RotateTimeline.PREV_ROTATION = -1; + RotateTimeline.ROTATION = 1; + return RotateTimeline; + }(CurveTimeline$2)); + /** Changes a bone's local {@link Bone#x} and {@link Bone#y}. */ + /** + * @public + */ + var TranslateTimeline$2 = /** @class */ (function (_super) { + __extends$3(TranslateTimeline, _super); + function TranslateTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES); + return _this; + } + TranslateTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.translate << 24) + this.boneIndex; + }; + /** Sets the time in seconds, x, and y values for the specified key frame. */ + TranslateTimeline.prototype.setFrame = function (frameIndex, time, x, y) { + frameIndex *= TranslateTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TranslateTimeline.X] = x; + this.frames[frameIndex + TranslateTimeline.Y] = y; + }; + TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var frames = this.frames; + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.x = bone.data.x; + bone.y = bone.data.y; + return; + case exports.MixBlend.first: + bone.x += (bone.data.x - bone.x) * alpha; + bone.y += (bone.data.y - bone.y) * alpha; + } + return; + } + var x = 0, y = 0; + if (time >= frames[frames.length - TranslateTimeline.ENTRIES]) { // Time is after last frame. + x = frames[frames.length + TranslateTimeline.PREV_X]; + y = frames[frames.length + TranslateTimeline.PREV_Y]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, TranslateTimeline.ENTRIES); + x = frames[frame + TranslateTimeline.PREV_X]; + y = frames[frame + TranslateTimeline.PREV_Y]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / TranslateTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TranslateTimeline.PREV_TIME] - frameTime)); + x += (frames[frame + TranslateTimeline.X] - x) * percent; + y += (frames[frame + TranslateTimeline.Y] - y) * percent; + } + switch (blend) { + case exports.MixBlend.setup: + bone.x = bone.data.x + x * alpha; + bone.y = bone.data.y + y * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bone.x += (bone.data.x + x - bone.x) * alpha; + bone.y += (bone.data.y + y - bone.y) * alpha; + break; + case exports.MixBlend.add: + bone.x += x * alpha; + bone.y += y * alpha; + } + }; + TranslateTimeline.ENTRIES = 3; + TranslateTimeline.PREV_TIME = -3; + TranslateTimeline.PREV_X = -2; + TranslateTimeline.PREV_Y = -1; + TranslateTimeline.X = 1; + TranslateTimeline.Y = 2; + return TranslateTimeline; + }(CurveTimeline$2)); + /** Changes a bone's local {@link Bone#scaleX)} and {@link Bone#scaleY}. */ + /** + * @public + */ + var ScaleTimeline$2 = /** @class */ (function (_super) { + __extends$3(ScaleTimeline, _super); + function ScaleTimeline(frameCount) { + return _super.call(this, frameCount) || this; + } + ScaleTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.scale << 24) + this.boneIndex; + }; + ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var frames = this.frames; + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.scaleX = bone.data.scaleX; + bone.scaleY = bone.data.scaleY; + return; + case exports.MixBlend.first: + bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; + } + return; + } + var x = 0, y = 0; + if (time >= frames[frames.length - ScaleTimeline.ENTRIES]) { // Time is after last frame. + x = frames[frames.length + ScaleTimeline.PREV_X] * bone.data.scaleX; + y = frames[frames.length + ScaleTimeline.PREV_Y] * bone.data.scaleY; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, ScaleTimeline.ENTRIES); + x = frames[frame + ScaleTimeline.PREV_X]; + y = frames[frame + ScaleTimeline.PREV_Y]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / ScaleTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ScaleTimeline.PREV_TIME] - frameTime)); + x = (x + (frames[frame + ScaleTimeline.X] - x) * percent) * bone.data.scaleX; + y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY; + } + if (alpha == 1) { + if (blend == exports.MixBlend.add) { + bone.scaleX += x - bone.data.scaleX; + bone.scaleY += y - bone.data.scaleY; + } + else { + bone.scaleX = x; + bone.scaleY = y; + } + } + else { + var bx = 0, by = 0; + if (direction == exports.MixDirection.mixOut) { + switch (blend) { + case exports.MixBlend.setup: + bx = bone.data.scaleX; + by = bone.data.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case exports.MixBlend.add: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bone.data.scaleX) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - bone.data.scaleY) * alpha; + } + } + else { + switch (blend) { + case exports.MixBlend.setup: + bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x); + by = Math.abs(bone.data.scaleY) * MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bx = Math.abs(bone.scaleX) * MathUtils.signum(x); + by = Math.abs(bone.scaleY) * MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case exports.MixBlend.add: + bx = MathUtils.signum(x); + by = MathUtils.signum(y); + bone.scaleX = Math.abs(bone.scaleX) * bx + (x - Math.abs(bone.data.scaleX) * bx) * alpha; + bone.scaleY = Math.abs(bone.scaleY) * by + (y - Math.abs(bone.data.scaleY) * by) * alpha; + } + } + } + }; + return ScaleTimeline; + }(TranslateTimeline$2)); + /** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. */ + /** + * @public + */ + var ShearTimeline$2 = /** @class */ (function (_super) { + __extends$3(ShearTimeline, _super); + function ShearTimeline(frameCount) { + return _super.call(this, frameCount) || this; + } + ShearTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.shear << 24) + this.boneIndex; + }; + ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var frames = this.frames; + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.shearX = bone.data.shearX; + bone.shearY = bone.data.shearY; + return; + case exports.MixBlend.first: + bone.shearX += (bone.data.shearX - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY - bone.shearY) * alpha; + } + return; + } + var x = 0, y = 0; + if (time >= frames[frames.length - ShearTimeline.ENTRIES]) { // Time is after last frame. + x = frames[frames.length + ShearTimeline.PREV_X]; + y = frames[frames.length + ShearTimeline.PREV_Y]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, ShearTimeline.ENTRIES); + x = frames[frame + ShearTimeline.PREV_X]; + y = frames[frame + ShearTimeline.PREV_Y]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / ShearTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ShearTimeline.PREV_TIME] - frameTime)); + x = x + (frames[frame + ShearTimeline.X] - x) * percent; + y = y + (frames[frame + ShearTimeline.Y] - y) * percent; + } + switch (blend) { + case exports.MixBlend.setup: + bone.shearX = bone.data.shearX + x * alpha; + bone.shearY = bone.data.shearY + y * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; + break; + case exports.MixBlend.add: + bone.shearX += x * alpha; + bone.shearY += y * alpha; + } + }; + return ShearTimeline; + }(TranslateTimeline$2)); + /** Changes a slot's {@link Slot#color}. */ + /** + * @public + */ + var ColorTimeline$1 = /** @class */ (function (_super) { + __extends$3(ColorTimeline, _super); + function ColorTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES); + return _this; + } + ColorTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.color << 24) + this.slotIndex; + }; + /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ + ColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a) { + frameIndex *= ColorTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + ColorTimeline.R] = r; + this.frames[frameIndex + ColorTimeline.G] = g; + this.frames[frameIndex + ColorTimeline.B] = b; + this.frames[frameIndex + ColorTimeline.A] = a; + }; + ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + slot.color.setFromColor(slot.data.color); + return; + case exports.MixBlend.first: + var color = slot.color, setup = slot.data.color; + color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha); + } + return; + } + var r = 0, g = 0, b = 0, a = 0; + if (time >= frames[frames.length - ColorTimeline.ENTRIES]) { // Time is after last frame. + var i = frames.length; + r = frames[i + ColorTimeline.PREV_R]; + g = frames[i + ColorTimeline.PREV_G]; + b = frames[i + ColorTimeline.PREV_B]; + a = frames[i + ColorTimeline.PREV_A]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, ColorTimeline.ENTRIES); + r = frames[frame + ColorTimeline.PREV_R]; + g = frames[frame + ColorTimeline.PREV_G]; + b = frames[frame + ColorTimeline.PREV_B]; + a = frames[frame + ColorTimeline.PREV_A]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / ColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ColorTimeline.PREV_TIME] - frameTime)); + r += (frames[frame + ColorTimeline.R] - r) * percent; + g += (frames[frame + ColorTimeline.G] - g) * percent; + b += (frames[frame + ColorTimeline.B] - b) * percent; + a += (frames[frame + ColorTimeline.A] - a) * percent; + } + if (alpha == 1) + slot.color.set(r, g, b, a); + else { + var color = slot.color; + if (blend == exports.MixBlend.setup) + color.setFromColor(slot.data.color); + color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha); + } + }; + ColorTimeline.ENTRIES = 5; + ColorTimeline.PREV_TIME = -5; + ColorTimeline.PREV_R = -4; + ColorTimeline.PREV_G = -3; + ColorTimeline.PREV_B = -2; + ColorTimeline.PREV_A = -1; + ColorTimeline.R = 1; + ColorTimeline.G = 2; + ColorTimeline.B = 3; + ColorTimeline.A = 4; + return ColorTimeline; + }(CurveTimeline$2)); + /** Changes a slot's {@link Slot#color} and {@link Slot#darkColor} for two color tinting. */ + /** + * @public + */ + var TwoColorTimeline$1 = /** @class */ (function (_super) { + __extends$3(TwoColorTimeline, _super); + function TwoColorTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES); + return _this; + } + TwoColorTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.twoColor << 24) + this.slotIndex; + }; + /** Sets the time in seconds, light, and dark colors for the specified key frame. */ + TwoColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a, r2, g2, b2) { + frameIndex *= TwoColorTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TwoColorTimeline.R] = r; + this.frames[frameIndex + TwoColorTimeline.G] = g; + this.frames[frameIndex + TwoColorTimeline.B] = b; + this.frames[frameIndex + TwoColorTimeline.A] = a; + this.frames[frameIndex + TwoColorTimeline.R2] = r2; + this.frames[frameIndex + TwoColorTimeline.G2] = g2; + this.frames[frameIndex + TwoColorTimeline.B2] = b2; + }; + TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + slot.color.setFromColor(slot.data.color); + slot.darkColor.setFromColor(slot.data.darkColor); + return; + case exports.MixBlend.first: + var light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor; + light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha); + dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0); + } + return; + } + var r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; + if (time >= frames[frames.length - TwoColorTimeline.ENTRIES]) { // Time is after last frame. + var i = frames.length; + r = frames[i + TwoColorTimeline.PREV_R]; + g = frames[i + TwoColorTimeline.PREV_G]; + b = frames[i + TwoColorTimeline.PREV_B]; + a = frames[i + TwoColorTimeline.PREV_A]; + r2 = frames[i + TwoColorTimeline.PREV_R2]; + g2 = frames[i + TwoColorTimeline.PREV_G2]; + b2 = frames[i + TwoColorTimeline.PREV_B2]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, TwoColorTimeline.ENTRIES); + r = frames[frame + TwoColorTimeline.PREV_R]; + g = frames[frame + TwoColorTimeline.PREV_G]; + b = frames[frame + TwoColorTimeline.PREV_B]; + a = frames[frame + TwoColorTimeline.PREV_A]; + r2 = frames[frame + TwoColorTimeline.PREV_R2]; + g2 = frames[frame + TwoColorTimeline.PREV_G2]; + b2 = frames[frame + TwoColorTimeline.PREV_B2]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / TwoColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TwoColorTimeline.PREV_TIME] - frameTime)); + r += (frames[frame + TwoColorTimeline.R] - r) * percent; + g += (frames[frame + TwoColorTimeline.G] - g) * percent; + b += (frames[frame + TwoColorTimeline.B] - b) * percent; + a += (frames[frame + TwoColorTimeline.A] - a) * percent; + r2 += (frames[frame + TwoColorTimeline.R2] - r2) * percent; + g2 += (frames[frame + TwoColorTimeline.G2] - g2) * percent; + b2 += (frames[frame + TwoColorTimeline.B2] - b2) * percent; + } + if (alpha == 1) { + slot.color.set(r, g, b, a); + slot.darkColor.set(r2, g2, b2, 1); + } + else { + var light = slot.color, dark = slot.darkColor; + if (blend == exports.MixBlend.setup) { + light.setFromColor(slot.data.color); + dark.setFromColor(slot.data.darkColor); + } + light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha); + dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0); + } + }; + TwoColorTimeline.ENTRIES = 8; + TwoColorTimeline.PREV_TIME = -8; + TwoColorTimeline.PREV_R = -7; + TwoColorTimeline.PREV_G = -6; + TwoColorTimeline.PREV_B = -5; + TwoColorTimeline.PREV_A = -4; + TwoColorTimeline.PREV_R2 = -3; + TwoColorTimeline.PREV_G2 = -2; + TwoColorTimeline.PREV_B2 = -1; + TwoColorTimeline.R = 1; + TwoColorTimeline.G = 2; + TwoColorTimeline.B = 3; + TwoColorTimeline.A = 4; + TwoColorTimeline.R2 = 5; + TwoColorTimeline.G2 = 6; + TwoColorTimeline.B2 = 7; + return TwoColorTimeline; + }(CurveTimeline$2)); + /** Changes a slot's {@link Slot#attachment}. */ + /** + * @public + */ + var AttachmentTimeline$2 = /** @class */ (function () { + function AttachmentTimeline(frameCount) { + this.frames = Utils.newFloatArray(frameCount); + this.attachmentNames = new Array(frameCount); + } + AttachmentTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.attachment << 24) + this.slotIndex; + }; + /** The number of key frames for this timeline. */ + AttachmentTimeline.prototype.getFrameCount = function () { + return this.frames.length; + }; + /** Sets the time in seconds and the attachment name for the specified key frame. */ + AttachmentTimeline.prototype.setFrame = function (frameIndex, time, attachmentName) { + this.frames[frameIndex] = time; + this.attachmentNames[frameIndex] = attachmentName; + }; + AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + if (direction == exports.MixDirection.mixOut) { + if (blend == exports.MixBlend.setup) + this.setAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + var frames = this.frames; + if (time < frames[0]) { + if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) + this.setAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + var frameIndex = 0; + if (time >= frames[frames.length - 1]) // Time is after last frame. + frameIndex = frames.length - 1; + else + frameIndex = Animation$2.binarySearch(frames, time, 1) - 1; + var attachmentName = this.attachmentNames[frameIndex]; + skeleton.slots[this.slotIndex] + .setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); + }; + AttachmentTimeline.prototype.setAttachment = function (skeleton, slot, attachmentName) { + slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); + }; + return AttachmentTimeline; + }()); + var zeros$1 = null; + /** Changes a slot's {@link Slot#deform} to deform a {@link VertexAttachment}. */ + /** + * @public + */ + var DeformTimeline$2 = /** @class */ (function (_super) { + __extends$3(DeformTimeline, _super); + function DeformTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount); + _this.frameVertices = new Array(frameCount); + if (zeros$1 == null) + zeros$1 = Utils.newFloatArray(64); + return _this; + } + DeformTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.deform << 27) + +this.attachment.id + this.slotIndex; + }; + /** Sets the time in seconds and the vertices for the specified key frame. + * @param vertices Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */ + DeformTimeline.prototype.setFrame = function (frameIndex, time, vertices) { + this.frames[frameIndex] = time; + this.frameVertices[frameIndex] = vertices; + }; + DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + var slotAttachment = slot.getAttachment(); + if (!(slotAttachment instanceof VertexAttachment$2) || !(slotAttachment.deformAttachment == this.attachment)) + return; + var deformArray = slot.deform; + if (deformArray.length == 0) + blend = exports.MixBlend.setup; + var frameVertices = this.frameVertices; + var vertexCount = frameVertices[0].length; + var frames = this.frames; + if (time < frames[0]) { + var vertexAttachment = slotAttachment; + switch (blend) { + case exports.MixBlend.setup: + deformArray.length = 0; + return; + case exports.MixBlend.first: + if (alpha == 1) { + deformArray.length = 0; + break; + } + var deform_1 = Utils.setArraySize(deformArray, vertexCount); + if (vertexAttachment.bones == null) { + // Unweighted vertex positions. + var setupVertices = vertexAttachment.vertices; + for (var i = 0; i < vertexCount; i++) + deform_1[i] += (setupVertices[i] - deform_1[i]) * alpha; + } + else { + // Weighted deform offsets. + alpha = 1 - alpha; + for (var i = 0; i < vertexCount; i++) + deform_1[i] *= alpha; + } + } + return; + } + var deform = Utils.setArraySize(deformArray, vertexCount); + if (time >= frames[frames.length - 1]) { // Time is after last frame. + var lastVertices = frameVertices[frames.length - 1]; + if (alpha == 1) { + if (blend == exports.MixBlend.add) { + var vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i_1 = 0; i_1 < vertexCount; i_1++) { + deform[i_1] += lastVertices[i_1] - setupVertices[i_1]; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i_2 = 0; i_2 < vertexCount; i_2++) + deform[i_2] += lastVertices[i_2]; + } + } + else { + Utils.arrayCopy(lastVertices, 0, deform, 0, vertexCount); + } + } + else { + switch (blend) { + case exports.MixBlend.setup: { + var vertexAttachment_1 = slotAttachment; + if (vertexAttachment_1.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment_1.vertices; + for (var i_3 = 0; i_3 < vertexCount; i_3++) { + var setup = setupVertices[i_3]; + deform[i_3] = setup + (lastVertices[i_3] - setup) * alpha; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i_4 = 0; i_4 < vertexCount; i_4++) + deform[i_4] = lastVertices[i_4] * alpha; + } + break; + } + case exports.MixBlend.first: + case exports.MixBlend.replace: + for (var i_5 = 0; i_5 < vertexCount; i_5++) + deform[i_5] += (lastVertices[i_5] - deform[i_5]) * alpha; + break; + case exports.MixBlend.add: + var vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i_6 = 0; i_6 < vertexCount; i_6++) { + deform[i_6] += (lastVertices[i_6] - setupVertices[i_6]) * alpha; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i_7 = 0; i_7 < vertexCount; i_7++) + deform[i_7] += lastVertices[i_7] * alpha; + } + } + } + return; + } + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time); + var prevVertices = frameVertices[frame - 1]; + var nextVertices = frameVertices[frame]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime)); + if (alpha == 1) { + if (blend == exports.MixBlend.add) { + var vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i_8 = 0; i_8 < vertexCount; i_8++) { + var prev = prevVertices[i_8]; + deform[i_8] += prev + (nextVertices[i_8] - prev) * percent - setupVertices[i_8]; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i_9 = 0; i_9 < vertexCount; i_9++) { + var prev = prevVertices[i_9]; + deform[i_9] += prev + (nextVertices[i_9] - prev) * percent; + } + } + } + else { + for (var i_10 = 0; i_10 < vertexCount; i_10++) { + var prev = prevVertices[i_10]; + deform[i_10] = prev + (nextVertices[i_10] - prev) * percent; + } + } + } + else { + switch (blend) { + case exports.MixBlend.setup: { + var vertexAttachment_2 = slotAttachment; + if (vertexAttachment_2.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment_2.vertices; + for (var i_11 = 0; i_11 < vertexCount; i_11++) { + var prev = prevVertices[i_11], setup = setupVertices[i_11]; + deform[i_11] = setup + (prev + (nextVertices[i_11] - prev) * percent - setup) * alpha; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i_12 = 0; i_12 < vertexCount; i_12++) { + var prev = prevVertices[i_12]; + deform[i_12] = (prev + (nextVertices[i_12] - prev) * percent) * alpha; + } + } + break; + } + case exports.MixBlend.first: + case exports.MixBlend.replace: + for (var i_13 = 0; i_13 < vertexCount; i_13++) { + var prev = prevVertices[i_13]; + deform[i_13] += (prev + (nextVertices[i_13] - prev) * percent - deform[i_13]) * alpha; + } + break; + case exports.MixBlend.add: + var vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i_14 = 0; i_14 < vertexCount; i_14++) { + var prev = prevVertices[i_14]; + deform[i_14] += (prev + (nextVertices[i_14] - prev) * percent - setupVertices[i_14]) * alpha; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i_15 = 0; i_15 < vertexCount; i_15++) { + var prev = prevVertices[i_15]; + deform[i_15] += (prev + (nextVertices[i_15] - prev) * percent) * alpha; + } + } + } + } + }; + return DeformTimeline; + }(CurveTimeline$2)); + /** Fires an {@link Event} when specific animation times are reached. */ + /** + * @public + */ + var EventTimeline$2 = /** @class */ (function () { + function EventTimeline(frameCount) { + this.frames = Utils.newFloatArray(frameCount); + this.events = new Array(frameCount); + } + EventTimeline.prototype.getPropertyId = function () { + return TimelineType$1.event << 24; + }; + /** The number of key frames for this timeline. */ + EventTimeline.prototype.getFrameCount = function () { + return this.frames.length; + }; + /** Sets the time in seconds and the event for the specified key frame. */ + EventTimeline.prototype.setFrame = function (frameIndex, event) { + this.frames[frameIndex] = event.time; + this.events[frameIndex] = event; + }; + /** Fires events for frames > `lastTime` and <= `time`. */ + EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + if (firedEvents == null) + return; + var frames = this.frames; + var frameCount = this.frames.length; + if (lastTime > time) { // Fire events after last time for looped animations. + this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction); + lastTime = -1; + } + else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame. + return; + if (time < frames[0]) + return; // Time is before first frame. + var frame = 0; + if (lastTime < frames[0]) + frame = 0; + else { + frame = Animation$2.binarySearch(frames, lastTime); + var frameTime = frames[frame]; + while (frame > 0) { // Fire multiple events with the same frame. + if (frames[frame - 1] != frameTime) + break; + frame--; + } + } + for (; frame < frameCount && time >= frames[frame]; frame++) + firedEvents.push(this.events[frame]); + }; + return EventTimeline; + }()); + /** Changes a skeleton's {@link Skeleton#drawOrder}. */ + /** + * @public + */ + var DrawOrderTimeline$2 = /** @class */ (function () { + function DrawOrderTimeline(frameCount) { + this.frames = Utils.newFloatArray(frameCount); + this.drawOrders = new Array(frameCount); + } + DrawOrderTimeline.prototype.getPropertyId = function () { + return TimelineType$1.drawOrder << 24; + }; + /** The number of key frames for this timeline. */ + DrawOrderTimeline.prototype.getFrameCount = function () { + return this.frames.length; + }; + /** Sets the time in seconds and the draw order for the specified key frame. + * @param drawOrder For each slot in {@link Skeleton#slots}, the index of the new draw order. May be null to use setup pose + * draw order. */ + DrawOrderTimeline.prototype.setFrame = function (frameIndex, time, drawOrder) { + this.frames[frameIndex] = time; + this.drawOrders[frameIndex] = drawOrder; + }; + DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var drawOrder = skeleton.drawOrder; + var slots = skeleton.slots; + if (direction == exports.MixDirection.mixOut && blend == exports.MixBlend.setup) { + Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + var frames = this.frames; + if (time < frames[0]) { + if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) + Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + var frame = 0; + if (time >= frames[frames.length - 1]) // Time is after last frame. + frame = frames.length - 1; + else + frame = Animation$2.binarySearch(frames, time) - 1; + var drawOrderToSetupIndex = this.drawOrders[frame]; + if (drawOrderToSetupIndex == null) + Utils.arrayCopy(slots, 0, drawOrder, 0, slots.length); + else { + for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++) + drawOrder[i] = slots[drawOrderToSetupIndex[i]]; + } + }; + return DrawOrderTimeline; + }()); + /** Changes an IK constraint's {@link IkConstraint#mix}, {@link IkConstraint#softness}, + * {@link IkConstraint#bendDirection}, {@link IkConstraint#stretch}, and {@link IkConstraint#compress}. */ + /** + * @public + */ + var IkConstraintTimeline$2 = /** @class */ (function (_super) { + __extends$3(IkConstraintTimeline, _super); + function IkConstraintTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES); + return _this; + } + IkConstraintTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.ikConstraint << 24) + this.ikConstraintIndex; + }; + /** Sets the time in seconds, mix, softness, bend direction, compress, and stretch for the specified key frame. */ + IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, softness, bendDirection, compress, stretch) { + frameIndex *= IkConstraintTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; + this.frames[frameIndex + IkConstraintTimeline.SOFTNESS] = softness; + this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; + this.frames[frameIndex + IkConstraintTimeline.COMPRESS] = compress ? 1 : 0; + this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0; + }; + IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var frames = this.frames; + var constraint = skeleton.ikConstraints[this.ikConstraintIndex]; + if (!constraint.active) + return; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.mix = constraint.data.mix; + constraint.softness = constraint.data.softness; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + return; + case exports.MixBlend.first: + constraint.mix += (constraint.data.mix - constraint.mix) * alpha; + constraint.softness += (constraint.data.softness - constraint.softness) * alpha; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + return; + } + if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { // Time is after last frame. + if (blend == exports.MixBlend.setup) { + constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; + constraint.softness = constraint.data.softness + + (frames[frames.length + IkConstraintTimeline.PREV_SOFTNESS] - constraint.data.softness) * alpha; + if (direction == exports.MixDirection.mixOut) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + else { + constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + else { + constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; + constraint.softness += (frames[frames.length + IkConstraintTimeline.PREV_SOFTNESS] - constraint.softness) * alpha; + if (direction == exports.MixDirection.mixIn) { + constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + return; + } + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, IkConstraintTimeline.ENTRIES); + var mix = frames[frame + IkConstraintTimeline.PREV_MIX]; + var softness = frames[frame + IkConstraintTimeline.PREV_SOFTNESS]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); + if (blend == exports.MixBlend.setup) { + constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; + constraint.softness = constraint.data.softness + + (softness + (frames[frame + IkConstraintTimeline.SOFTNESS] - softness) * percent - constraint.data.softness) * alpha; + if (direction == exports.MixDirection.mixOut) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + else { + constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + else { + constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; + constraint.softness += (softness + (frames[frame + IkConstraintTimeline.SOFTNESS] - softness) * percent - constraint.softness) * alpha; + if (direction == exports.MixDirection.mixIn) { + constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + }; + IkConstraintTimeline.ENTRIES = 6; + IkConstraintTimeline.PREV_TIME = -6; + IkConstraintTimeline.PREV_MIX = -5; + IkConstraintTimeline.PREV_SOFTNESS = -4; + IkConstraintTimeline.PREV_BEND_DIRECTION = -3; + IkConstraintTimeline.PREV_COMPRESS = -2; + IkConstraintTimeline.PREV_STRETCH = -1; + IkConstraintTimeline.MIX = 1; + IkConstraintTimeline.SOFTNESS = 2; + IkConstraintTimeline.BEND_DIRECTION = 3; + IkConstraintTimeline.COMPRESS = 4; + IkConstraintTimeline.STRETCH = 5; + return IkConstraintTimeline; + }(CurveTimeline$2)); + /** Changes a transform constraint's {@link TransformConstraint#rotateMix}, {@link TransformConstraint#translateMix}, + * {@link TransformConstraint#scaleMix}, and {@link TransformConstraint#shearMix}. */ + /** + * @public + */ + var TransformConstraintTimeline$2 = /** @class */ (function (_super) { + __extends$3(TransformConstraintTimeline, _super); + function TransformConstraintTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES); + return _this; + } + TransformConstraintTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.transformConstraint << 24) + this.transformConstraintIndex; + }; + /** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. */ + TransformConstraintTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix, scaleMix, shearMix) { + frameIndex *= TransformConstraintTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TransformConstraintTimeline.ROTATE] = rotateMix; + this.frames[frameIndex + TransformConstraintTimeline.TRANSLATE] = translateMix; + this.frames[frameIndex + TransformConstraintTimeline.SCALE] = scaleMix; + this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix; + }; + TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var frames = this.frames; + var constraint = skeleton.transformConstraints[this.transformConstraintIndex]; + if (!constraint.active) + return; + if (time < frames[0]) { + var data = constraint.data; + switch (blend) { + case exports.MixBlend.setup: + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + constraint.scaleMix = data.scaleMix; + constraint.shearMix = data.shearMix; + return; + case exports.MixBlend.first: + constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha; + constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha; + constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha; + constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha; + } + return; + } + var rotate = 0, translate = 0, scale = 0, shear = 0; + if (time >= frames[frames.length - TransformConstraintTimeline.ENTRIES]) { // Time is after last frame. + var i = frames.length; + rotate = frames[i + TransformConstraintTimeline.PREV_ROTATE]; + translate = frames[i + TransformConstraintTimeline.PREV_TRANSLATE]; + scale = frames[i + TransformConstraintTimeline.PREV_SCALE]; + shear = frames[i + TransformConstraintTimeline.PREV_SHEAR]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, TransformConstraintTimeline.ENTRIES); + rotate = frames[frame + TransformConstraintTimeline.PREV_ROTATE]; + translate = frames[frame + TransformConstraintTimeline.PREV_TRANSLATE]; + scale = frames[frame + TransformConstraintTimeline.PREV_SCALE]; + shear = frames[frame + TransformConstraintTimeline.PREV_SHEAR]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / TransformConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TransformConstraintTimeline.PREV_TIME] - frameTime)); + rotate += (frames[frame + TransformConstraintTimeline.ROTATE] - rotate) * percent; + translate += (frames[frame + TransformConstraintTimeline.TRANSLATE] - translate) * percent; + scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent; + shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent; + } + if (blend == exports.MixBlend.setup) { + var data = constraint.data; + constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha; + constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha; + constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha; + constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha; + } + else { + constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; + constraint.translateMix += (translate - constraint.translateMix) * alpha; + constraint.scaleMix += (scale - constraint.scaleMix) * alpha; + constraint.shearMix += (shear - constraint.shearMix) * alpha; + } + }; + TransformConstraintTimeline.ENTRIES = 5; + TransformConstraintTimeline.PREV_TIME = -5; + TransformConstraintTimeline.PREV_ROTATE = -4; + TransformConstraintTimeline.PREV_TRANSLATE = -3; + TransformConstraintTimeline.PREV_SCALE = -2; + TransformConstraintTimeline.PREV_SHEAR = -1; + TransformConstraintTimeline.ROTATE = 1; + TransformConstraintTimeline.TRANSLATE = 2; + TransformConstraintTimeline.SCALE = 3; + TransformConstraintTimeline.SHEAR = 4; + return TransformConstraintTimeline; + }(CurveTimeline$2)); + /** Changes a path constraint's {@link PathConstraint#position}. */ + /** + * @public + */ + var PathConstraintPositionTimeline$2 = /** @class */ (function (_super) { + __extends$3(PathConstraintPositionTimeline, _super); + function PathConstraintPositionTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES); + return _this; + } + PathConstraintPositionTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.pathConstraintPosition << 24) + this.pathConstraintIndex; + }; + /** Sets the time in seconds and path constraint position for the specified key frame. */ + PathConstraintPositionTimeline.prototype.setFrame = function (frameIndex, time, value) { + frameIndex *= PathConstraintPositionTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value; + }; + PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var frames = this.frames; + var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (!constraint.active) + return; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.position = constraint.data.position; + return; + case exports.MixBlend.first: + constraint.position += (constraint.data.position - constraint.position) * alpha; + } + return; + } + var position = 0; + if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES]) // Time is after last frame. + position = frames[frames.length + PathConstraintPositionTimeline.PREV_VALUE]; + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, PathConstraintPositionTimeline.ENTRIES); + position = frames[frame + PathConstraintPositionTimeline.PREV_VALUE]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime)); + position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent; + } + if (blend == exports.MixBlend.setup) + constraint.position = constraint.data.position + (position - constraint.data.position) * alpha; + else + constraint.position += (position - constraint.position) * alpha; + }; + PathConstraintPositionTimeline.ENTRIES = 2; + PathConstraintPositionTimeline.PREV_TIME = -2; + PathConstraintPositionTimeline.PREV_VALUE = -1; + PathConstraintPositionTimeline.VALUE = 1; + return PathConstraintPositionTimeline; + }(CurveTimeline$2)); + /** Changes a path constraint's {@link PathConstraint#spacing}. */ + /** + * @public + */ + var PathConstraintSpacingTimeline$2 = /** @class */ (function (_super) { + __extends$3(PathConstraintSpacingTimeline, _super); + function PathConstraintSpacingTimeline(frameCount) { + return _super.call(this, frameCount) || this; + } + PathConstraintSpacingTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.pathConstraintSpacing << 24) + this.pathConstraintIndex; + }; + PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var frames = this.frames; + var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (!constraint.active) + return; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.spacing = constraint.data.spacing; + return; + case exports.MixBlend.first: + constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha; + } + return; + } + var spacing = 0; + if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES]) // Time is after last frame. + spacing = frames[frames.length + PathConstraintSpacingTimeline.PREV_VALUE]; + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, PathConstraintSpacingTimeline.ENTRIES); + spacing = frames[frame + PathConstraintSpacingTimeline.PREV_VALUE]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime)); + spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent; + } + if (blend == exports.MixBlend.setup) + constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha; + else + constraint.spacing += (spacing - constraint.spacing) * alpha; + }; + return PathConstraintSpacingTimeline; + }(PathConstraintPositionTimeline$2)); + /** Changes a transform constraint's {@link PathConstraint#rotateMix} and + * {@link TransformConstraint#translateMix}. */ + /** + * @public + */ + var PathConstraintMixTimeline$2 = /** @class */ (function (_super) { + __extends$3(PathConstraintMixTimeline, _super); + function PathConstraintMixTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES); + return _this; + } + PathConstraintMixTimeline.prototype.getPropertyId = function () { + return (TimelineType$1.pathConstraintMix << 24) + this.pathConstraintIndex; + }; + /** The time in seconds, rotate mix, and translate mix for the specified key frame. */ + PathConstraintMixTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix) { + frameIndex *= PathConstraintMixTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + PathConstraintMixTimeline.ROTATE] = rotateMix; + this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix; + }; + PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var frames = this.frames; + var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (!constraint.active) + return; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.rotateMix = constraint.data.rotateMix; + constraint.translateMix = constraint.data.translateMix; + return; + case exports.MixBlend.first: + constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha; + constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha; + } + return; + } + var rotate = 0, translate = 0; + if (time >= frames[frames.length - PathConstraintMixTimeline.ENTRIES]) { // Time is after last frame. + rotate = frames[frames.length + PathConstraintMixTimeline.PREV_ROTATE]; + translate = frames[frames.length + PathConstraintMixTimeline.PREV_TRANSLATE]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, PathConstraintMixTimeline.ENTRIES); + rotate = frames[frame + PathConstraintMixTimeline.PREV_ROTATE]; + translate = frames[frame + PathConstraintMixTimeline.PREV_TRANSLATE]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / PathConstraintMixTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintMixTimeline.PREV_TIME] - frameTime)); + rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent; + translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent; + } + if (blend == exports.MixBlend.setup) { + constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha; + constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha; + } + else { + constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; + constraint.translateMix += (translate - constraint.translateMix) * alpha; + } + }; + PathConstraintMixTimeline.ENTRIES = 3; + PathConstraintMixTimeline.PREV_TIME = -3; + PathConstraintMixTimeline.PREV_ROTATE = -2; + PathConstraintMixTimeline.PREV_TRANSLATE = -1; + PathConstraintMixTimeline.ROTATE = 1; + PathConstraintMixTimeline.TRANSLATE = 2; + return PathConstraintMixTimeline; + }(CurveTimeline$2)); + + /** Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies + * multiple animations on top of each other (layering). + * + * See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. */ + /** + * @public + */ + var AnimationState$2 = /** @class */ (function () { + function AnimationState(data) { + /** The list of tracks that currently have animations, which may contain null entries. */ + this.tracks = new Array(); + /** Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower + * or faster. Defaults to 1. + * + * See TrackEntry {@link TrackEntry#timeScale} for affecting a single animation. */ + this.timeScale = 1; + this.unkeyedState = 0; + this.events = new Array(); + this.listeners = new Array(); + this.queue = new EventQueue$2(this); + this.propertyIDs = new IntSet(); + this.animationsChanged = false; + this.trackEntryPool = new Pool(function () { return new TrackEntry$2(); }); + this.data = data; + } + /** Increments each track entry {@link TrackEntry#trackTime()}, setting queued animations as current if needed. */ + AnimationState.prototype.update = function (delta) { + delta *= this.timeScale; + var tracks = this.tracks; + for (var i = 0, n = tracks.length; i < n; i++) { + var current = tracks[i]; + if (current == null) + continue; + current.animationLast = current.nextAnimationLast; + current.trackLast = current.nextTrackLast; + var currentDelta = delta * current.timeScale; + if (current.delay > 0) { + current.delay -= currentDelta; + if (current.delay > 0) + continue; + currentDelta = -current.delay; + current.delay = 0; + } + var next = current.next; + if (next != null) { + // When the next entry's delay is passed, change to the next entry, preserving leftover time. + var nextTime = current.trackLast - next.delay; + if (nextTime >= 0) { + next.delay = 0; + next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale; + current.trackTime += currentDelta; + this.setCurrent(i, next, true); + while (next.mixingFrom != null) { + next.mixTime += delta; + next = next.mixingFrom; + } + continue; + } + } + else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) { + tracks[i] = null; + this.queue.end(current); + this.disposeNext(current); + continue; + } + if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) { + // End mixing from entries once all have completed. + var from = current.mixingFrom; + current.mixingFrom = null; + if (from != null) + from.mixingTo = null; + while (from != null) { + this.queue.end(from); + from = from.mixingFrom; + } + } + current.trackTime += currentDelta; + } + this.queue.drain(); + }; + /** Returns true when all mixing from entries are complete. */ + AnimationState.prototype.updateMixingFrom = function (to, delta) { + var from = to.mixingFrom; + if (from == null) + return true; + var finished = this.updateMixingFrom(from, delta); + from.animationLast = from.nextAnimationLast; + from.trackLast = from.nextTrackLast; + // Require mixTime > 0 to ensure the mixing from entry was applied at least once. + if (to.mixTime > 0 && to.mixTime >= to.mixDuration) { + // Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame). + if (from.totalAlpha == 0 || to.mixDuration == 0) { + to.mixingFrom = from.mixingFrom; + if (from.mixingFrom != null) + from.mixingFrom.mixingTo = to; + to.interruptAlpha = from.interruptAlpha; + this.queue.end(from); + } + return finished; + } + from.trackTime += delta * from.timeScale; + to.mixTime += delta; + return false; + }; + /** Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the + * animation state can be applied to multiple skeletons to pose them identically. + * @returns True if any animations were applied. */ + AnimationState.prototype.apply = function (skeleton) { + if (skeleton == null) + throw new Error("skeleton cannot be null."); + if (this.animationsChanged) + this._animationsChanged(); + var events = this.events; + var tracks = this.tracks; + var applied = false; + for (var i_1 = 0, n_1 = tracks.length; i_1 < n_1; i_1++) { + var current = tracks[i_1]; + if (current == null || current.delay > 0) + continue; + applied = true; + var blend = i_1 == 0 ? exports.MixBlend.first : current.mixBlend; + // Apply mixing from entries first. + var mix = current.alpha; + if (current.mixingFrom != null) + mix *= this.applyMixingFrom(current, skeleton, blend); + else if (current.trackTime >= current.trackEnd && current.next == null) + mix = 0; + // Apply current entry. + var animationLast = current.animationLast, animationTime = current.getAnimationTime(); + var timelineCount = current.animation.timelines.length; + var timelines = current.animation.timelines; + if ((i_1 == 0 && mix == 1) || blend == exports.MixBlend.add) { + for (var ii = 0; ii < timelineCount; ii++) { + // Fixes issue #302 on IOS9 where mix, blend sometimes became undefined and caused assets + // to sometimes stop rendering when using color correction, as their RGBA values become NaN. + // (https://github.com/pixijs/pixi-spine/issues/302) + Utils.webkit602BugfixHelper(mix, blend); + var timeline = timelines[ii]; + if (timeline instanceof AttachmentTimeline$2) + this.applyAttachmentTimeline(timeline, skeleton, animationTime, blend, true); + else + timeline.apply(skeleton, animationLast, animationTime, events, mix, blend, exports.MixDirection.mixIn); + } + } + else { + var timelineMode = current.timelineMode; + var firstFrame = current.timelinesRotation.length == 0; + if (firstFrame) + Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null); + var timelinesRotation = current.timelinesRotation; + for (var ii = 0; ii < timelineCount; ii++) { + var timeline_1 = timelines[ii]; + var timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : exports.MixBlend.setup; + if (timeline_1 instanceof RotateTimeline$2) { + this.applyRotateTimeline(timeline_1, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame); + } + else if (timeline_1 instanceof AttachmentTimeline$2) { + this.applyAttachmentTimeline(timeline_1, skeleton, animationTime, blend, true); + } + else { + // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 + Utils.webkit602BugfixHelper(mix, blend); + timeline_1.apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, exports.MixDirection.mixIn); + } + } + } + this.queueEvents(current, animationTime); + events.length = 0; + current.nextAnimationLast = animationTime; + current.nextTrackLast = current.trackTime; + } + // Set slots attachments to the setup pose, if needed. This occurs if an animation that is mixing out sets attachments so + // subsequent timelines see any deform, but the subsequent timelines don't set an attachment (eg they are also mixing out or + // the time is before the first key). + var setupState = this.unkeyedState + AnimationState.SETUP; + var slots = skeleton.slots; + for (var i = 0, n = skeleton.slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.attachmentState == setupState) { + var attachmentName = slot.data.attachmentName; + slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName)); + } + } + this.unkeyedState += 2; // Increasing after each use avoids the need to reset attachmentState for every slot. + this.queue.drain(); + return applied; + }; + AnimationState.prototype.applyMixingFrom = function (to, skeleton, blend) { + var from = to.mixingFrom; + if (from.mixingFrom != null) + this.applyMixingFrom(from, skeleton, blend); + var mix = 0; + if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. + mix = 1; + if (blend == exports.MixBlend.first) + blend = exports.MixBlend.setup; + } + else { + mix = to.mixTime / to.mixDuration; + if (mix > 1) + mix = 1; + if (blend != exports.MixBlend.first) + blend = from.mixBlend; + } + var events = mix < from.eventThreshold ? this.events : null; + var attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold; + var animationLast = from.animationLast, animationTime = from.getAnimationTime(); + var timelineCount = from.animation.timelines.length; + var timelines = from.animation.timelines; + var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); + if (blend == exports.MixBlend.add) { + for (var i = 0; i < timelineCount; i++) + timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, exports.MixDirection.mixOut); + } + else { + var timelineMode = from.timelineMode; + var timelineHoldMix = from.timelineHoldMix; + var firstFrame = from.timelinesRotation.length == 0; + if (firstFrame) + Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null); + var timelinesRotation = from.timelinesRotation; + from.totalAlpha = 0; + for (var i = 0; i < timelineCount; i++) { + var timeline = timelines[i]; + var direction = exports.MixDirection.mixOut; + var timelineBlend = void 0; + var alpha = 0; + switch (timelineMode[i]) { + case AnimationState.SUBSEQUENT: + if (!drawOrder && timeline instanceof DrawOrderTimeline$2) + continue; + timelineBlend = blend; + alpha = alphaMix; + break; + case AnimationState.FIRST: + timelineBlend = exports.MixBlend.setup; + alpha = alphaMix; + break; + case AnimationState.HOLD_SUBSEQUENT: + timelineBlend = blend; + alpha = alphaHold; + break; + case AnimationState.HOLD_FIRST: + timelineBlend = exports.MixBlend.setup; + alpha = alphaHold; + break; + default: + timelineBlend = exports.MixBlend.setup; + var holdMix = timelineHoldMix[i]; + alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration); + break; + } + from.totalAlpha += alpha; + if (timeline instanceof RotateTimeline$2) + this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame); + else if (timeline instanceof AttachmentTimeline$2) + this.applyAttachmentTimeline(timeline, skeleton, animationTime, timelineBlend, attachments); + else { + // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 + Utils.webkit602BugfixHelper(alpha, blend); + if (drawOrder && timeline instanceof DrawOrderTimeline$2 && timelineBlend == exports.MixBlend.setup) + direction = exports.MixDirection.mixIn; + timeline.apply(skeleton, animationLast, animationTime, events, alpha, timelineBlend, direction); + } + } + } + if (to.mixDuration > 0) + this.queueEvents(from, animationTime); + this.events.length = 0; + from.nextAnimationLast = animationTime; + from.nextTrackLast = from.trackTime; + return mix; + }; + AnimationState.prototype.applyAttachmentTimeline = function (timeline, skeleton, time, blend, attachments) { + var slot = skeleton.slots[timeline.slotIndex]; + if (!slot.bone.active) + return; + var frames = timeline.frames; + if (time < frames[0]) { // Time is before first frame. + if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) + this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments); + } + else { + var frameIndex; + if (time >= frames[frames.length - 1]) // Time is after last frame. + frameIndex = frames.length - 1; + else + frameIndex = Animation$2.binarySearch(frames, time) - 1; + this.setAttachment(skeleton, slot, timeline.attachmentNames[frameIndex], attachments); + } + // If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later. + if (slot.attachmentState <= this.unkeyedState) + slot.attachmentState = this.unkeyedState + AnimationState.SETUP; + }; + AnimationState.prototype.setAttachment = function (skeleton, slot, attachmentName, attachments) { + slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName)); + if (attachments) + slot.attachmentState = this.unkeyedState + AnimationState.CURRENT; + }; + AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) { + if (firstFrame) + timelinesRotation[i] = 0; + if (alpha == 1) { + timeline.apply(skeleton, 0, time, null, 1, blend, exports.MixDirection.mixIn); + return; + } + var rotateTimeline = timeline; + var frames = rotateTimeline.frames; + var bone = skeleton.bones[rotateTimeline.boneIndex]; + if (!bone.active) + return; + var r1 = 0, r2 = 0; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.rotation = bone.data.rotation; + default: + return; + case exports.MixBlend.first: + r1 = bone.rotation; + r2 = bone.data.rotation; + } + } + else { + r1 = blend == exports.MixBlend.setup ? bone.data.rotation : bone.rotation; + if (time >= frames[frames.length - RotateTimeline$2.ENTRIES]) // Time is after last frame. + r2 = bone.data.rotation + frames[frames.length + RotateTimeline$2.PREV_ROTATION]; + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$2.binarySearch(frames, time, RotateTimeline$2.ENTRIES); + var prevRotation = frames[frame + RotateTimeline$2.PREV_ROTATION]; + var frameTime = frames[frame]; + var percent = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline$2.PREV_TIME] - frameTime)); + r2 = frames[frame + RotateTimeline$2.ROTATION] - prevRotation; + r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; + r2 = prevRotation + r2 * percent + bone.data.rotation; + r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; + } + } + // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. + var total = 0, diff = r2 - r1; + diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360; + if (diff == 0) { + total = timelinesRotation[i]; + } + else { + var lastTotal = 0, lastDiff = 0; + if (firstFrame) { + lastTotal = 0; + lastDiff = diff; + } + else { + lastTotal = timelinesRotation[i]; // Angle and direction of mix, including loops. + lastDiff = timelinesRotation[i + 1]; // Difference between bones. + } + var current = diff > 0, dir = lastTotal >= 0; + // Detect cross at 0 (not 180). + if (MathUtils.signum(lastDiff) != MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) { + // A cross after a 360 rotation is a loop. + if (Math.abs(lastTotal) > 180) + lastTotal += 360 * MathUtils.signum(lastTotal); + dir = current; + } + total = diff + lastTotal - lastTotal % 360; // Store loops as part of lastTotal. + if (dir != current) + total += 360 * MathUtils.signum(lastTotal); + timelinesRotation[i] = total; + } + timelinesRotation[i + 1] = diff; + r1 += total * alpha; + bone.rotation = r1 - (16384 - ((16384.499999999996 - r1 / 360) | 0)) * 360; + }; + AnimationState.prototype.queueEvents = function (entry, animationTime) { + var animationStart = entry.animationStart, animationEnd = entry.animationEnd; + var duration = animationEnd - animationStart; + var trackLastWrapped = entry.trackLast % duration; + // Queue events before complete. + var events = this.events; + var i = 0, n = events.length; + for (; i < n; i++) { + var event_1 = events[i]; + if (event_1.time < trackLastWrapped) + break; + if (event_1.time > animationEnd) + continue; // Discard events outside animation start/end. + this.queue.event(entry, event_1); + } + // Queue complete if completed a loop iteration or the animation. + var complete = false; + if (entry.loop) + complete = duration == 0 || trackLastWrapped > entry.trackTime % duration; + else + complete = animationTime >= animationEnd && entry.animationLast < animationEnd; + if (complete) + this.queue.complete(entry); + // Queue events after complete. + for (; i < n; i++) { + var event_2 = events[i]; + if (event_2.time < animationStart) + continue; // Discard events outside animation start/end. + this.queue.event(entry, events[i]); + } + }; + /** Removes all animations from all tracks, leaving skeletons in their current pose. + * + * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, + * rather than leaving them in their current pose. */ + AnimationState.prototype.clearTracks = function () { + var oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (var i = 0, n = this.tracks.length; i < n; i++) + this.clearTrack(i); + this.tracks.length = 0; + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + }; + /** Removes all animations from the track, leaving skeletons in their current pose. + * + * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, + * rather than leaving them in their current pose. */ + AnimationState.prototype.clearTrack = function (trackIndex) { + if (trackIndex >= this.tracks.length) + return; + var current = this.tracks[trackIndex]; + if (current == null) + return; + this.queue.end(current); + this.disposeNext(current); + var entry = current; + while (true) { + var from = entry.mixingFrom; + if (from == null) + break; + this.queue.end(from); + entry.mixingFrom = null; + entry.mixingTo = null; + entry = from; + } + this.tracks[current.trackIndex] = null; + this.queue.drain(); + }; + AnimationState.prototype.setCurrent = function (index, current, interrupt) { + var from = this.expandToIndex(index); + this.tracks[index] = current; + if (from != null) { + if (interrupt) + this.queue.interrupt(from); + current.mixingFrom = from; + from.mixingTo = current; + current.mixTime = 0; + // Store the interrupted mix percentage. + if (from.mixingFrom != null && from.mixDuration > 0) + current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration); + from.timelinesRotation.length = 0; // Reset rotation for mixing out, in case entry was mixed in. + } + this.queue.start(current); + }; + /** Sets an animation by name. + * + * {@link #setAnimationWith(}. */ + AnimationState.prototype.setAnimation = function (trackIndex, animationName, loop) { + var animation = this.data.skeletonData.findAnimation(animationName); + if (animation == null) + throw new Error("Animation not found: " + animationName); + return this.setAnimationWith(trackIndex, animation, loop); + }; + /** Sets the current animation for a track, discarding any queued animations. If the formerly current track entry was never + * applied to a skeleton, it is replaced (not mixed from). + * @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its + * duration. In either case {@link TrackEntry#trackEnd} determines when the track is cleared. + * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + AnimationState.prototype.setAnimationWith = function (trackIndex, animation, loop) { + if (animation == null) + throw new Error("animation cannot be null."); + var interrupt = true; + var current = this.expandToIndex(trackIndex); + if (current != null) { + if (current.nextTrackLast == -1) { + // Don't mix from an entry that was never applied. + this.tracks[trackIndex] = current.mixingFrom; + this.queue.interrupt(current); + this.queue.end(current); + this.disposeNext(current); + current = current.mixingFrom; + interrupt = false; + } + else + this.disposeNext(current); + } + var entry = this.trackEntry(trackIndex, animation, loop, current); + this.setCurrent(trackIndex, entry, interrupt); + this.queue.drain(); + return entry; + }; + /** Queues an animation by name. + * + * See {@link #addAnimationWith()}. */ + AnimationState.prototype.addAnimation = function (trackIndex, animationName, loop, delay) { + var animation = this.data.skeletonData.findAnimation(animationName); + if (animation == null) + throw new Error("Animation not found: " + animationName); + return this.addAnimationWith(trackIndex, animation, loop, delay); + }; + /** Adds an animation to be played after the current or last queued animation for a track. If the track is empty, it is + * equivalent to calling {@link #setAnimationWith()}. + * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry + * minus any mix duration (from the {@link AnimationStateData}) plus the specified `delay` (ie the mix + * ends at (`delay` = 0) or before (`delay` < 0) the previous track entry duration). If the + * previous entry is looping, its next loop completion is used instead of its duration. + * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + AnimationState.prototype.addAnimationWith = function (trackIndex, animation, loop, delay) { + if (animation == null) + throw new Error("animation cannot be null."); + var last = this.expandToIndex(trackIndex); + if (last != null) { + while (last.next != null) + last = last.next; + } + var entry = this.trackEntry(trackIndex, animation, loop, last); + if (last == null) { + this.setCurrent(trackIndex, entry, true); + this.queue.drain(); + } + else { + last.next = entry; + if (delay <= 0) { + var duration = last.animationEnd - last.animationStart; + if (duration != 0) { + if (last.loop) + delay += duration * (1 + ((last.trackTime / duration) | 0)); + else + delay += Math.max(duration, last.trackTime); + delay -= this.data.getMix(last.animation, animation); + } + else + delay = last.trackTime; + } + } + entry.delay = delay; + return entry; + }; + /** Sets an empty animation for a track, discarding any queued animations, and sets the track entry's + * {@link TrackEntry#mixduration}. An empty animation has no timelines and serves as a placeholder for mixing in or out. + * + * Mixing out is done by setting an empty animation with a mix duration using either {@link #setEmptyAnimation()}, + * {@link #setEmptyAnimations()}, or {@link #addEmptyAnimation()}. Mixing to an empty animation causes + * the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation + * transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of + * 0 still mixes out over one frame. + * + * Mixing in is done by first setting an empty animation, then adding an animation using + * {@link #addAnimation()} and on the returned track entry, set the + * {@link TrackEntry#setMixDuration()}. Mixing from an empty animation causes the new animation to be applied more and + * more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the + * setup pose value if no lower tracks key the property to the value keyed in the new animation. */ + AnimationState.prototype.setEmptyAnimation = function (trackIndex, mixDuration) { + var entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation, false); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + }; + /** Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's + * {@link TrackEntry#mixDuration}. If the track is empty, it is equivalent to calling + * {@link #setEmptyAnimation()}. + * + * See {@link #setEmptyAnimation()}. + * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry + * minus any mix duration plus the specified `delay` (ie the mix ends at (`delay` = 0) or + * before (`delay` < 0) the previous track entry duration). If the previous entry is looping, its next + * loop completion is used instead of its duration. + * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + AnimationState.prototype.addEmptyAnimation = function (trackIndex, mixDuration, delay) { + if (delay <= 0) + delay -= mixDuration; + var entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation, false, delay); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + }; + /** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix + * duration. */ + AnimationState.prototype.setEmptyAnimations = function (mixDuration) { + var oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (var i = 0, n = this.tracks.length; i < n; i++) { + var current = this.tracks[i]; + if (current != null) + this.setEmptyAnimation(current.trackIndex, mixDuration); + } + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + }; + AnimationState.prototype.expandToIndex = function (index) { + if (index < this.tracks.length) + return this.tracks[index]; + Utils.ensureArrayCapacity(this.tracks, index + 1, null); + this.tracks.length = index + 1; + return null; + }; + /** @param last May be null. */ + AnimationState.prototype.trackEntry = function (trackIndex, animation, loop, last) { + var entry = this.trackEntryPool.obtain(); + entry.trackIndex = trackIndex; + entry.animation = animation; + entry.loop = loop; + entry.holdPrevious = false; + entry.eventThreshold = 0; + entry.attachmentThreshold = 0; + entry.drawOrderThreshold = 0; + entry.animationStart = 0; + entry.animationEnd = animation.duration; + entry.animationLast = -1; + entry.nextAnimationLast = -1; + entry.delay = 0; + entry.trackTime = 0; + entry.trackLast = -1; + entry.nextTrackLast = -1; + entry.trackEnd = Number.MAX_VALUE; + entry.timeScale = 1; + entry.alpha = 1; + entry.interruptAlpha = 1; + entry.mixTime = 0; + entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation); + entry.mixBlend = exports.MixBlend.replace; + return entry; + }; + AnimationState.prototype.disposeNext = function (entry) { + var next = entry.next; + while (next != null) { + this.queue.dispose(next); + next = next.next; + } + entry.next = null; + }; + AnimationState.prototype._animationsChanged = function () { + this.animationsChanged = false; + this.propertyIDs.clear(); + for (var i = 0, n = this.tracks.length; i < n; i++) { + var entry = this.tracks[i]; + if (entry == null) + continue; + while (entry.mixingFrom != null) + entry = entry.mixingFrom; + do { + if (entry.mixingFrom == null || entry.mixBlend != exports.MixBlend.add) + this.computeHold(entry); + entry = entry.mixingTo; + } while (entry != null); + } + }; + AnimationState.prototype.computeHold = function (entry) { + var to = entry.mixingTo; + var timelines = entry.animation.timelines; + var timelinesCount = entry.animation.timelines.length; + var timelineMode = Utils.setArraySize(entry.timelineMode, timelinesCount); + entry.timelineHoldMix.length = 0; + var timelineDipMix = Utils.setArraySize(entry.timelineHoldMix, timelinesCount); + var propertyIDs = this.propertyIDs; + if (to != null && to.holdPrevious) { + for (var i = 0; i < timelinesCount; i++) { + timelineMode[i] = propertyIDs.add(timelines[i].getPropertyId()) ? AnimationState.HOLD_FIRST : AnimationState.HOLD_SUBSEQUENT; + } + return; + } + outer: for (var i = 0; i < timelinesCount; i++) { + var timeline = timelines[i]; + var id = timeline.getPropertyId(); + if (!propertyIDs.add(id)) + timelineMode[i] = AnimationState.SUBSEQUENT; + else if (to == null || timeline instanceof AttachmentTimeline$2 || timeline instanceof DrawOrderTimeline$2 + || timeline instanceof EventTimeline$2 || !to.animation.hasTimeline(id)) { + timelineMode[i] = AnimationState.FIRST; + } + else { + for (var next = to.mixingTo; next != null; next = next.mixingTo) { + if (next.animation.hasTimeline(id)) + continue; + if (entry.mixDuration > 0) { + timelineMode[i] = AnimationState.HOLD_MIX; + timelineDipMix[i] = next; + continue outer; + } + break; + } + timelineMode[i] = AnimationState.HOLD_FIRST; + } + } + }; + /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */ + AnimationState.prototype.getCurrent = function (trackIndex) { + if (trackIndex >= this.tracks.length) + return null; + return this.tracks[trackIndex]; + }; + /** Adds a listener to receive events for all track entries. */ + AnimationState.prototype.addListener = function (listener) { + if (listener == null) + throw new Error("listener cannot be null."); + this.listeners.push(listener); + }; + /** Removes the listener added with {@link #addListener()}. */ + AnimationState.prototype.removeListener = function (listener) { + var index = this.listeners.indexOf(listener); + if (index >= 0) + this.listeners.splice(index, 1); + }; + /** Removes all listeners added with {@link #addListener()}. */ + AnimationState.prototype.clearListeners = function () { + this.listeners.length = 0; + }; + /** Discards all listener notifications that have not yet been delivered. This can be useful to call from an + * {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery + * are not wanted because new animations are being set. */ + AnimationState.prototype.clearListenerNotifications = function () { + this.queue.clear(); + }; + AnimationState.prototype.setAnimationByName = function (trackIndex, animationName, loop) { + if (!AnimationState.deprecatedWarning1) { + AnimationState.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on."); + } + this.setAnimation(trackIndex, animationName, loop); + }; + AnimationState.prototype.addAnimationByName = function (trackIndex, animationName, loop, delay) { + if (!AnimationState.deprecatedWarning2) { + AnimationState.deprecatedWarning2 = true; + console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on."); + } + this.addAnimation(trackIndex, animationName, loop, delay); + }; + AnimationState.prototype.hasAnimation = function (animationName) { + var animation = this.data.skeletonData.findAnimation(animationName); + return animation !== null; + }; + AnimationState.prototype.hasAnimationByName = function (animationName) { + if (!AnimationState.deprecatedWarning3) { + AnimationState.deprecatedWarning3 = true; + console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on."); + } + return this.hasAnimation(animationName); + }; + AnimationState.emptyAnimation = new Animation$2("", [], 0); + /** 1. A previously applied timeline has set this property. + * + * Result: Mix from the current pose to the timeline pose. */ + AnimationState.SUBSEQUENT = 0; + /** 1. This is the first timeline to set this property. + * 2. The next track entry applied after this one does not have a timeline to set this property. + * + * Result: Mix from the setup pose to the timeline pose. */ + AnimationState.FIRST = 1; + /** 1) A previously applied timeline has set this property.
+ * 2) The next track entry to be applied does have a timeline to set this property.
+ * 3) The next track entry after that one does not have a timeline to set this property.
+ * Result: Mix from the current pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading + * animations that key the same property. A subsequent timeline will set this property using a mix. */ + AnimationState.HOLD_SUBSEQUENT = 2; + /** 1) This is the first timeline to set this property.
+ * 2) The next track entry to be applied does have a timeline to set this property.
+ * 3) The next track entry after that one does not have a timeline to set this property.
+ * Result: Mix from the setup pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading animations + * that key the same property. A subsequent timeline will set this property using a mix. */ + AnimationState.HOLD_FIRST = 3; + /** 1. This is the first timeline to set this property. + * 2. The next track entry to be applied does have a timeline to set this property. + * 3. The next track entry after that one does have a timeline to set this property. + * 4. timelineHoldMix stores the first subsequent track entry that does not have a timeline to set this property. + * + * Result: The same as HOLD except the mix percentage from the timelineHoldMix track entry is used. This handles when more than + * 2 track entries in a row have a timeline that sets the same property. + * + * Eg, A -> B -> C -> D where A, B, and C have a timeline setting same property, but D does not. When A is applied, to avoid + * "dipping" A is not mixed out, however D (the first entry that doesn't set the property) mixing in is used to mix out A + * (which affects B and C). Without using D to mix out, A would be applied fully until mixing completes, then snap into + * place. */ + AnimationState.HOLD_MIX = 4; + AnimationState.SETUP = 1; + AnimationState.CURRENT = 2; + AnimationState.deprecatedWarning1 = false; + AnimationState.deprecatedWarning2 = false; + AnimationState.deprecatedWarning3 = false; + return AnimationState; + }()); + /** Stores settings and other state for the playback of an animation on an {@link AnimationState} track. + * + * References to a track entry must not be kept after the {@link AnimationStateListener#dispose()} event occurs. */ + /** + * @public + */ + var TrackEntry$2 = /** @class */ (function () { + function TrackEntry() { + /** Controls how properties keyed in the animation are mixed with lower tracks. Defaults to {@link MixBlend#replace}, which + * replaces the values from the lower tracks with the animation values. {@link MixBlend#add} adds the animation values to + * the values from the lower tracks. + * + * The `mixBlend` can be set for a new track entry only before {@link AnimationState#apply()} is first + * called. */ + this.mixBlend = exports.MixBlend.replace; + this.timelineMode = new Array(); + this.timelineHoldMix = new Array(); + this.timelinesRotation = new Array(); + } + TrackEntry.prototype.reset = function () { + this.next = null; + this.mixingFrom = null; + this.mixingTo = null; + this.animation = null; + this.listener = null; + this.timelineMode.length = 0; + this.timelineHoldMix.length = 0; + this.timelinesRotation.length = 0; + }; + /** Uses {@link #trackTime} to compute the `animationTime`, which is between {@link #animationStart} + * and {@link #animationEnd}. When the `trackTime` is 0, the `animationTime` is equal to the + * `animationStart` time. */ + TrackEntry.prototype.getAnimationTime = function () { + if (this.loop) { + var duration = this.animationEnd - this.animationStart; + if (duration == 0) + return this.animationStart; + return (this.trackTime % duration) + this.animationStart; + } + return Math.min(this.trackTime + this.animationStart, this.animationEnd); + }; + TrackEntry.prototype.setAnimationLast = function (animationLast) { + this.animationLast = animationLast; + this.nextAnimationLast = animationLast; + }; + /** Returns true if at least one loop has been completed. + * + * See {@link AnimationStateListener#complete()}. */ + TrackEntry.prototype.isComplete = function () { + return this.trackTime >= this.animationEnd - this.animationStart; + }; + /** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the + * long way around when using {@link #alpha} and starting animations on other tracks. + * + * Mixing with {@link MixBlend#replace} involves finding a rotation between two others, which has two possible solutions: + * the short way or the long way around. The two rotations likely change over time, so which direction is the short or long + * way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the + * long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. */ + TrackEntry.prototype.resetRotationDirections = function () { + this.timelinesRotation.length = 0; + }; + Object.defineProperty(TrackEntry.prototype, "time", { + get: function () { + if (!TrackEntry.deprecatedWarning1) { + TrackEntry.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); + } + return this.trackTime; + }, + set: function (value) { + if (!TrackEntry.deprecatedWarning1) { + TrackEntry.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); + } + this.trackTime = value; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TrackEntry.prototype, "endTime", { + get: function () { + if (!TrackEntry.deprecatedWarning2) { + TrackEntry.deprecatedWarning2 = true; + console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); + } + return this.trackTime; + }, + set: function (value) { + if (!TrackEntry.deprecatedWarning2) { + TrackEntry.deprecatedWarning2 = true; + console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); + } + this.trackTime = value; + }, + enumerable: false, + configurable: true + }); + TrackEntry.prototype.loopsCount = function () { + return Math.floor(this.trackTime / this.trackEnd); + }; + TrackEntry.deprecatedWarning1 = false; + TrackEntry.deprecatedWarning2 = false; + return TrackEntry; + }()); + /** + * @public + */ + var EventQueue$2 = /** @class */ (function () { + function EventQueue(animState) { + this.objects = []; + this.drainDisabled = false; + this.animState = animState; + } + EventQueue.prototype.start = function (entry) { + this.objects.push(EventType$2.start); + this.objects.push(entry); + this.animState.animationsChanged = true; + }; + EventQueue.prototype.interrupt = function (entry) { + this.objects.push(EventType$2.interrupt); + this.objects.push(entry); + }; + EventQueue.prototype.end = function (entry) { + this.objects.push(EventType$2.end); + this.objects.push(entry); + this.animState.animationsChanged = true; + }; + EventQueue.prototype.dispose = function (entry) { + this.objects.push(EventType$2.dispose); + this.objects.push(entry); + }; + EventQueue.prototype.complete = function (entry) { + this.objects.push(EventType$2.complete); + this.objects.push(entry); + }; + EventQueue.prototype.event = function (entry, event) { + this.objects.push(EventType$2.event); + this.objects.push(entry); + this.objects.push(event); + }; + EventQueue.prototype.deprecateStuff = function () { + if (!EventQueue.deprecatedWarning1) { + EventQueue.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: onComplete, onStart, onEnd, onEvent art deprecated, please use listeners from now on. 'state.addListener({ complete: function(track, event) { } })'"); + } + return true; + }; + EventQueue.prototype.drain = function () { + if (this.drainDisabled) + return; + this.drainDisabled = true; + var objects = this.objects; + var listeners = this.animState.listeners; + for (var i = 0; i < objects.length; i += 2) { + var type = objects[i]; + var entry = objects[i + 1]; + switch (type) { + case EventType$2.start: + if (entry.listener != null && entry.listener.start) + entry.listener.start(entry); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].start) + listeners[ii].start(entry); + //deprecation + entry.onStart && this.deprecateStuff() && entry.onStart(entry.trackIndex); + this.animState.onStart && this.deprecateStuff() && this.deprecateStuff && this.animState.onStart(entry.trackIndex); + break; + case EventType$2.interrupt: + if (entry.listener != null && entry.listener.interrupt) + entry.listener.interrupt(entry); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].interrupt) + listeners[ii].interrupt(entry); + break; + case EventType$2.end: + if (entry.listener != null && entry.listener.end) + entry.listener.end(entry); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].end) + listeners[ii].end(entry); + //deprecation + entry.onEnd && this.deprecateStuff() && entry.onEnd(entry.trackIndex); + this.animState.onEnd && this.deprecateStuff() && this.animState.onEnd(entry.trackIndex); + // Fall through. + case EventType$2.dispose: + if (entry.listener != null && entry.listener.dispose) + entry.listener.dispose(entry); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].dispose) + listeners[ii].dispose(entry); + this.animState.trackEntryPool.free(entry); + break; + case EventType$2.complete: + if (entry.listener != null && entry.listener.complete) + entry.listener.complete(entry); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].complete) + listeners[ii].complete(entry); + //deprecation + var count = MathUtils.toInt(entry.loopsCount()); + entry.onComplete && this.deprecateStuff() && entry.onComplete(entry.trackIndex, count); + this.animState.onComplete && this.deprecateStuff() && this.animState.onComplete(entry.trackIndex, count); + break; + case EventType$2.event: + var event_3 = objects[i++ + 2]; + if (entry.listener != null && entry.listener.event) + entry.listener.event(entry, event_3); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].event) + listeners[ii].event(entry, event_3); + //deprecation + entry.onEvent && this.deprecateStuff() && entry.onEvent(entry.trackIndex, event_3); + this.animState.onEvent && this.deprecateStuff() && this.animState.onEvent(entry.trackIndex, event_3); + break; + } + } + this.clear(); + this.drainDisabled = false; + }; + EventQueue.prototype.clear = function () { + this.objects.length = 0; + }; + EventQueue.deprecatedWarning1 = false; + return EventQueue; + }()); + /** + * @public + */ + var EventType$2; + (function (EventType) { + EventType[EventType["start"] = 0] = "start"; + EventType[EventType["interrupt"] = 1] = "interrupt"; + EventType[EventType["end"] = 2] = "end"; + EventType[EventType["dispose"] = 3] = "dispose"; + EventType[EventType["complete"] = 4] = "complete"; + EventType[EventType["event"] = 5] = "event"; + })(EventType$2 || (EventType$2 = {})); + /** + * @public + */ + var AnimationStateAdapter$1 = /** @class */ (function () { + function AnimationStateAdapter() { + } + AnimationStateAdapter.prototype.start = function (entry) { + }; + AnimationStateAdapter.prototype.interrupt = function (entry) { + }; + AnimationStateAdapter.prototype.end = function (entry) { + }; + AnimationStateAdapter.prototype.dispose = function (entry) { + }; + AnimationStateAdapter.prototype.complete = function (entry) { + }; + AnimationStateAdapter.prototype.event = function (entry, event) { + }; + return AnimationStateAdapter; + }()); + + /** + * @public + */ + var AnimationStateData$2 = /** @class */ (function () { + function AnimationStateData(skeletonData) { + this.animationToMixTime = {}; + this.defaultMix = 0; + if (skeletonData == null) + throw new Error("skeletonData cannot be null."); + this.skeletonData = skeletonData; + } + AnimationStateData.prototype.setMix = function (fromName, toName, duration) { + var from = this.skeletonData.findAnimation(fromName); + if (from == null) + throw new Error("Animation not found: " + fromName); + var to = this.skeletonData.findAnimation(toName); + if (to == null) + throw new Error("Animation not found: " + toName); + this.setMixWith(from, to, duration); + }; + AnimationStateData.prototype.setMixByName = function (fromName, toName, duration) { + if (!AnimationStateData.deprecatedWarning1) { + AnimationStateData.deprecatedWarning1 = true; + console.warn("Deprecation Warning: AnimationStateData.setMixByName is deprecated, please use setMix from now on."); + } + this.setMix(fromName, toName, duration); + }; + AnimationStateData.prototype.setMixWith = function (from, to, duration) { + if (from == null) + throw new Error("from cannot be null."); + if (to == null) + throw new Error("to cannot be null."); + var key = from.name + "." + to.name; + this.animationToMixTime[key] = duration; + }; + AnimationStateData.prototype.getMix = function (from, to) { + var key = from.name + "." + to.name; + var value = this.animationToMixTime[key]; + return value === undefined ? this.defaultMix : value; + }; + AnimationStateData.deprecatedWarning1 = false; + return AnimationStateData; + }()); + + /** + * @public + */ + var AtlasAttachmentLoader$2 = /** @class */ (function () { + function AtlasAttachmentLoader(atlas) { + this.atlas = atlas; + } + /** @return May be null to not load an attachment. */ + AtlasAttachmentLoader.prototype.newRegionAttachment = function (skin, name, path) { + var region = this.atlas.findRegion(path); + if (region == null) + throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); + var attachment = new RegionAttachment$2(name); + attachment.region = region; + return attachment; + }; + /** @return May be null to not load an attachment. */ + AtlasAttachmentLoader.prototype.newMeshAttachment = function (skin, name, path) { + var region = this.atlas.findRegion(path); + if (region == null) + throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); + var attachment = new MeshAttachment$2(name); + attachment.region = region; + return attachment; + }; + /** @return May be null to not load an attachment. */ + AtlasAttachmentLoader.prototype.newBoundingBoxAttachment = function (skin, name) { + return new BoundingBoxAttachment$2(name); + }; + /** @return May be null to not load an attachment */ + AtlasAttachmentLoader.prototype.newPathAttachment = function (skin, name) { + return new PathAttachment$2(name); + }; + AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) { + return new PointAttachment$2(name); + }; + AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) { + return new ClippingAttachment$2(name); + }; + return AtlasAttachmentLoader; + }()); + + /** + * @public + */ + var Bone$2 = /** @class */ (function () { + /** @param parent May be null. */ + function Bone(data, skeleton, parent) { + //be careful! Spine b,c is c,b in pixi matrix + this.matrix = new math.Matrix(); + this.children = new Array(); + this.x = 0; + this.y = 0; + this.rotation = 0; + this.scaleX = 0; + this.scaleY = 0; + this.shearX = 0; + this.shearY = 0; + this.ax = 0; + this.ay = 0; + this.arotation = 0; + this.ascaleX = 0; + this.ascaleY = 0; + this.ashearX = 0; + this.ashearY = 0; + this.appliedValid = false; + this.sorted = false; + this.active = false; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.skeleton = skeleton; + this.parent = parent; + this.setToSetupPose(); + } + Object.defineProperty(Bone.prototype, "worldX", { + get: function () { + return this.matrix.tx; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Bone.prototype, "worldY", { + get: function () { + return this.matrix.ty; + }, + enumerable: false, + configurable: true + }); + Bone.prototype.isActive = function () { + return this.active; + }; + /** Same as {@link #updateWorldTransform()}. This method exists for Bone to implement {@link Updatable}. */ + Bone.prototype.update = function () { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + }; + /** Computes the world transform using the parent bone and this bone's local transform. */ + Bone.prototype.updateWorldTransform = function () { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + }; + /** Computes the world transform using the parent bone and the specified local transform. */ + Bone.prototype.updateWorldTransformWith = function (x, y, rotation, scaleX, scaleY, shearX, shearY) { + this.ax = x; + this.ay = y; + this.arotation = rotation; + this.ascaleX = scaleX; + this.ascaleY = scaleY; + this.ashearX = shearX; + this.ashearY = shearY; + this.appliedValid = true; + var parent = this.parent; + var m = this.matrix; + var sx = this.skeleton.scaleX; + var sy = settings.yDown ? -this.skeleton.scaleY : this.skeleton.scaleY; + if (parent == null) { // Root bone. + var skeleton = this.skeleton; + var rotationY = rotation + 90 + shearY; + m.a = MathUtils.cosDeg(rotation + shearX) * scaleX * sx; + m.c = MathUtils.cosDeg(rotationY) * scaleY * sx; + m.b = MathUtils.sinDeg(rotation + shearX) * scaleX * sy; + m.d = MathUtils.sinDeg(rotationY) * scaleY * sy; + m.tx = x * sx + skeleton.x; + m.ty = y * sy + skeleton.y; + return; + } + var pa = parent.matrix.a, pb = parent.matrix.c, pc = parent.matrix.b, pd = parent.matrix.d; + m.tx = pa * x + pb * y + parent.matrix.tx; + m.ty = pc * x + pd * y + parent.matrix.ty; + switch (this.data.transformMode) { + case exports.TransformMode.Normal: { + var rotationY = rotation + 90 + shearY; + var la = MathUtils.cosDeg(rotation + shearX) * scaleX; + var lb = MathUtils.cosDeg(rotationY) * scaleY; + var lc = MathUtils.sinDeg(rotation + shearX) * scaleX; + var ld = MathUtils.sinDeg(rotationY) * scaleY; + m.a = pa * la + pb * lc; + m.c = pa * lb + pb * ld; + m.b = pc * la + pd * lc; + m.d = pc * lb + pd * ld; + return; + } + case exports.TransformMode.OnlyTranslation: { + var rotationY = rotation + 90 + shearY; + m.a = MathUtils.cosDeg(rotation + shearX) * scaleX; + m.c = MathUtils.cosDeg(rotationY) * scaleY; + m.b = MathUtils.sinDeg(rotation + shearX) * scaleX; + m.d = MathUtils.sinDeg(rotationY) * scaleY; + break; + } + case exports.TransformMode.NoRotationOrReflection: { + var s = pa * pa + pc * pc; + var prx = 0; + if (s > 0.0001) { + s = Math.abs(pa * pd - pb * pc) / s; + pa /= this.skeleton.scaleX; + pc /= this.skeleton.scaleY; + pb = pc * s; + pd = pa * s; + prx = Math.atan2(pc, pa) * MathUtils.radDeg; + } + else { + pa = 0; + pc = 0; + prx = 90 - Math.atan2(pd, pb) * MathUtils.radDeg; + } + var rx = rotation + shearX - prx; + var ry = rotation + shearY - prx + 90; + var la = MathUtils.cosDeg(rx) * scaleX; + var lb = MathUtils.cosDeg(ry) * scaleY; + var lc = MathUtils.sinDeg(rx) * scaleX; + var ld = MathUtils.sinDeg(ry) * scaleY; + m.a = pa * la - pb * lc; + m.c = pa * lb - pb * ld; + m.b = pc * la + pd * lc; + m.d = pc * lb + pd * ld; + break; + } + case exports.TransformMode.NoScale: + case exports.TransformMode.NoScaleOrReflection: { + var cos = MathUtils.cosDeg(rotation); + var sin = MathUtils.sinDeg(rotation); + var za = (pa * cos + pb * sin) / sx; + var zc = (pc * cos + pd * sin) / sy; + var s = Math.sqrt(za * za + zc * zc); + if (s > 0.00001) + s = 1 / s; + za *= s; + zc *= s; + s = Math.sqrt(za * za + zc * zc); + if (this.data.transformMode == exports.TransformMode.NoScale + && (pa * pd - pb * pc < 0) != (settings.yDown ? + (this.skeleton.scaleX < 0 != this.skeleton.scaleY > 0) : + (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0))) + s = -s; + var r = Math.PI / 2 + Math.atan2(zc, za); + var zb = Math.cos(r) * s; + var zd = Math.sin(r) * s; + var la = MathUtils.cosDeg(shearX) * scaleX; + var lb = MathUtils.cosDeg(90 + shearY) * scaleY; + var lc = MathUtils.sinDeg(shearX) * scaleX; + var ld = MathUtils.sinDeg(90 + shearY) * scaleY; + m.a = za * la + zb * lc; + m.c = za * lb + zb * ld; + m.b = zc * la + zd * lc; + m.d = zc * lb + zd * ld; + break; + } + } + m.a *= sx; + m.c *= sx; + m.b *= sy; + m.d *= sy; + }; + Bone.prototype.setToSetupPose = function () { + var data = this.data; + this.x = data.x; + this.y = data.y; + this.rotation = data.rotation; + this.scaleX = data.scaleX; + this.scaleY = data.scaleY; + this.shearX = data.shearX; + this.shearY = data.shearY; + }; + Bone.prototype.getWorldRotationX = function () { + return Math.atan2(this.matrix.b, this.matrix.a) * MathUtils.radDeg; + }; + Bone.prototype.getWorldRotationY = function () { + return Math.atan2(this.matrix.d, this.matrix.c) * MathUtils.radDeg; + }; + Bone.prototype.getWorldScaleX = function () { + var m = this.matrix; + return Math.sqrt(m.a * m.a + m.c * m.c); + }; + Bone.prototype.getWorldScaleY = function () { + var m = this.matrix; + return Math.sqrt(m.b * m.b + m.d * m.d); + }; + /** Computes the individual applied transform values from the world transform. This can be useful to perform processing using + * the applied transform after the world transform has been modified directly (eg, by a constraint). + *

+ * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. */ + Bone.prototype.updateAppliedTransform = function () { + this.appliedValid = true; + var parent = this.parent; + var m = this.matrix; + if (parent == null) { + this.ax = m.tx; + this.ay = m.ty; + this.arotation = Math.atan2(m.b, m.a) * MathUtils.radDeg; + this.ascaleX = Math.sqrt(m.a * m.a + m.b * m.b); + this.ascaleY = Math.sqrt(m.c * m.c + m.d * m.d); + this.ashearX = 0; + this.ashearY = Math.atan2(m.a * m.c + m.b * m.d, m.a * m.d - m.b * m.c) * MathUtils.radDeg; + return; + } + var pm = parent.matrix; + var pid = 1 / (pm.a * pm.d - pm.b * pm.c); + var dx = m.tx - pm.tx, dy = m.ty - pm.ty; + this.ax = (dx * pm.d * pid - dy * pm.c * pid); + this.ay = (dy * pm.a * pid - dx * pm.b * pid); + var ia = pid * pm.d; + var id = pid * pm.a; + var ib = pid * pm.c; + var ic = pid * pm.b; + var ra = ia * m.a - ib * m.b; + var rb = ia * m.c - ib * m.d; + var rc = id * m.b - ic * m.a; + var rd = id * m.d - ic * m.c; + this.ashearX = 0; + this.ascaleX = Math.sqrt(ra * ra + rc * rc); + if (this.ascaleX > 0.0001) { + var det = ra * rd - rb * rc; + this.ascaleY = det / this.ascaleX; + this.ashearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg; + this.arotation = Math.atan2(rc, ra) * MathUtils.radDeg; + } + else { + this.ascaleX = 0; + this.ascaleY = Math.sqrt(rb * rb + rd * rd); + this.ashearY = 0; + this.arotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg; + } + }; + Bone.prototype.worldToLocal = function (world) { + var m = this.matrix; + var a = m.a, b = m.c, c = m.b, d = m.d; + var invDet = 1 / (a * d - b * c); + var x = world.x - m.tx, y = world.y - m.ty; + world.x = (x * d * invDet - y * b * invDet); + world.y = (y * a * invDet - x * c * invDet); + return world; + }; + Bone.prototype.localToWorld = function (local) { + var m = this.matrix; + var x = local.x, y = local.y; + local.x = x * m.a + y * m.c + m.tx; + local.y = x * m.b + y * m.d + m.ty; + return local; + }; + Bone.prototype.worldToLocalRotation = function (worldRotation) { + var sin = MathUtils.sinDeg(worldRotation), cos = MathUtils.cosDeg(worldRotation); + var mat = this.matrix; + return Math.atan2(mat.a * sin - mat.b * cos, mat.d * cos - mat.c * sin) * MathUtils.radDeg; + }; + Bone.prototype.localToWorldRotation = function (localRotation) { + var sin = MathUtils.sinDeg(localRotation), cos = MathUtils.cosDeg(localRotation); + var mat = this.matrix; + return Math.atan2(cos * mat.b + sin * mat.d, cos * mat.a + sin * mat.c) * MathUtils.radDeg; + }; + Bone.prototype.rotateWorld = function (degrees) { + var mat = this.matrix; + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var cos = MathUtils.cosDeg(degrees), sin = MathUtils.sinDeg(degrees); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + this.appliedValid = false; + }; + return Bone; + }()); + + /** + * @public + */ + var BoneData$2 = /** @class */ (function () { + function BoneData(index, name, parent) { + this.x = 0; + this.y = 0; + this.rotation = 0; + this.scaleX = 1; + this.scaleY = 1; + this.shearX = 0; + this.shearY = 0; + this.transformMode = exports.TransformMode.Normal; + this.skinRequired = false; + this.color = new Color(); + if (index < 0) + throw new Error("index must be >= 0."); + if (name == null) + throw new Error("name cannot be null."); + this.index = index; + this.name = name; + this.parent = parent; + } + return BoneData; + }()); + + /** + * @public + */ + var ConstraintData$1 = /** @class */ (function () { + function ConstraintData(name, order, skinRequired) { + this.name = name; + this.order = order; + this.skinRequired = skinRequired; + } + return ConstraintData; + }()); + + /** + * @public + */ + var Event$2 = /** @class */ (function () { + function Event(time, data) { + if (data == null) + throw new Error("data cannot be null."); + this.time = time; + this.data = data; + } + return Event; + }()); + + /** + * @public + */ + var EventData$2 = /** @class */ (function () { + function EventData(name) { + this.name = name; + } + return EventData; + }()); + + /** + * @public + */ + var IkConstraint$2 = /** @class */ (function () { + function IkConstraint(data, skeleton) { + this.bendDirection = 0; + this.compress = false; + this.stretch = false; + this.mix = 1; + this.softness = 0; + this.active = false; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.mix = data.mix; + this.softness = data.softness; + this.bendDirection = data.bendDirection; + this.compress = data.compress; + this.stretch = data.stretch; + this.bones = new Array(); + for (var i = 0; i < data.bones.length; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findBone(data.target.name); + } + IkConstraint.prototype.isActive = function () { + return this.active; + }; + IkConstraint.prototype.apply = function () { + this.update(); + }; + IkConstraint.prototype.update = function () { + var target = this.target; + var bones = this.bones; + switch (bones.length) { + case 1: + this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix); + break; + case 2: + this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.softness, this.mix); + break; + } + }; + /** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world + * coordinate system. */ + IkConstraint.prototype.apply1 = function (bone, targetX, targetY, compress, stretch, uniform, alpha) { + if (!bone.appliedValid) + bone.updateAppliedTransform(); + var p = bone.parent.matrix; + var pa = p.a, pb = p.c, pc = p.b, pd = p.d; + var rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0; + switch (bone.data.transformMode) { + case exports.TransformMode.OnlyTranslation: + tx = targetX - bone.worldX; + ty = targetY - bone.worldY; + break; + case exports.TransformMode.NoRotationOrReflection: + var s = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc); + var sa = pa / bone.skeleton.scaleX; + var sc = pc / bone.skeleton.scaleY; + pb = -sc * s * bone.skeleton.scaleX; + pd = sa * s * bone.skeleton.scaleY; + rotationIK += Math.atan2(sc, sa) * MathUtils.radDeg; + // Fall through + default: + var x = targetX - p.tx, y = targetY - p.ty; + var d = pa * pd - pb * pc; + tx = (x * pd - y * pb) / d - bone.ax; + ty = (y * pa - x * pc) / d - bone.ay; + } + rotationIK += Math.atan2(ty, tx) * MathUtils.radDeg; + if (bone.ascaleX < 0) + rotationIK += 180; + if (rotationIK > 180) + rotationIK -= 360; + else if (rotationIK < -180) + rotationIK += 360; + var sx = bone.ascaleX, sy = bone.ascaleY; + if (compress || stretch) { + switch (bone.data.transformMode) { + case exports.TransformMode.NoScale: + case exports.TransformMode.NoScaleOrReflection: + tx = targetX - bone.worldX; + ty = targetY - bone.worldY; + } + var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty); + if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001) { + var s = (dd / b - 1) * alpha + 1; + sx *= s; + if (uniform) + sy *= s; + } + } + bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY); + }; + /** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The + * target is specified in the world coordinate system. + * @param child A direct descendant of the parent bone. */ + IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, softness, alpha) { + if (alpha == 0) { + child.updateWorldTransform(); + return; + } + if (!parent.appliedValid) + parent.updateAppliedTransform(); + if (!child.appliedValid) + child.updateAppliedTransform(); + var px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX; + var pmat = parent.matrix; + var os1 = 0, os2 = 0, s2 = 0; + if (psx < 0) { + psx = -psx; + os1 = 180; + s2 = -1; + } + else { + os1 = 0; + s2 = 1; + } + if (psy < 0) { + psy = -psy; + s2 = -s2; + } + if (csx < 0) { + csx = -csx; + os2 = 180; + } + else + os2 = 0; + var cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = pmat.a, b = pmat.c, c = pmat.b, d = pmat.d; + var u = Math.abs(psx - psy) <= 0.0001; + if (!u) { + cy = 0; + cwx = a * cx + pmat.tx; + cwy = c * cx + pmat.ty; + } + else { + cy = child.ay; + cwx = a * cx + b * cy + pmat.tx; + cwy = c * cx + d * cy + pmat.ty; + } + var pp = parent.parent.matrix; + a = pp.a; + b = pp.c; + c = pp.b; + d = pp.d; + var id = 1 / (a * d - b * c), x = cwx - pp.tx, y = cwy - pp.ty; + var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; + var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2; + if (l1 < 0.0001) { + this.apply1(parent, targetX, targetY, false, stretch, false, alpha); + child.updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + return; + } + x = targetX - pp.tx; + y = targetY - pp.ty; + var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; + var dd = tx * tx + ty * ty; + if (softness != 0) { + softness *= psx * (csx + 1) / 2; + var td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness; + if (sd > 0) { + var p = Math.min(1, sd / (softness * 2)) - 1; + p = (sd - softness * (1 - p * p)) / td; + tx -= p * tx; + ty -= p * ty; + dd = tx * tx + ty * ty; + } + } + outer: if (u) { + l2 *= psx; + var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2); + if (cos < -1) + cos = -1; + else if (cos > 1) { + cos = 1; + if (stretch) + sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1; + } + a2 = Math.acos(cos) * bendDir; + a = l1 + l2 * cos; + b = l2 * Math.sin(a2); + a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b); + } + else { + a = psx * l2; + b = psy * l2; + var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx); + c = bb * l1 * l1 + aa * dd - aa * bb; + var c1 = -2 * bb * l1, c2 = bb - aa; + d = c1 * c1 - 4 * c2 * c; + if (d >= 0) { + var q = Math.sqrt(d); + if (c1 < 0) + q = -q; + q = -(c1 + q) / 2; + var r0 = q / c2, r1 = c / q; + var r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; + if (r * r <= dd) { + y = Math.sqrt(dd - r * r) * bendDir; + a1 = ta - Math.atan2(y, r); + a2 = Math.atan2(y / psy, (r - l1) / psx); + break outer; + } + } + var minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; + var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; + c = -a * l1 / (aa - bb); + if (c >= -1 && c <= 1) { + c = Math.acos(c); + x = a * Math.cos(c) + l1; + y = b * Math.sin(c); + d = x * x + y * y; + if (d < minDist) { + minAngle = c; + minDist = d; + minX = x; + minY = y; + } + if (d > maxDist) { + maxAngle = c; + maxDist = d; + maxX = x; + maxY = y; + } + } + if (dd <= (minDist + maxDist) / 2) { + a1 = ta - Math.atan2(minY * bendDir, minX); + a2 = minAngle * bendDir; + } + else { + a1 = ta - Math.atan2(maxY * bendDir, maxX); + a2 = maxAngle * bendDir; + } + } + var os = Math.atan2(cy, cx) * s2; + var rotation = parent.arotation; + a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation; + if (a1 > 180) + a1 -= 360; + else if (a1 < -180) + a1 += 360; + parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0); + rotation = child.arotation; + a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; + if (a2 > 180) + a2 -= 360; + else if (a2 < -180) + a2 += 360; + child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + }; + return IkConstraint; + }()); + + /** + * @public + */ + var IkConstraintData$2 = /** @class */ (function (_super) { + __extends$3(IkConstraintData, _super); + function IkConstraintData(name) { + var _this = _super.call(this, name, 0, false) || this; + _this.bones = new Array(); + _this.bendDirection = 1; + _this.compress = false; + _this.stretch = false; + _this.uniform = false; + _this.mix = 1; + _this.softness = 0; + return _this; + } + return IkConstraintData; + }(ConstraintData$1)); + + /** + * @public + */ + var PathConstraintData$2 = /** @class */ (function (_super) { + __extends$3(PathConstraintData, _super); + function PathConstraintData(name) { + var _this = _super.call(this, name, 0, false) || this; + _this.bones = new Array(); + return _this; + } + return PathConstraintData; + }(ConstraintData$1)); + /** + * @public + */ + var SpacingMode$2; + (function (SpacingMode) { + SpacingMode[SpacingMode["Length"] = 0] = "Length"; + SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed"; + SpacingMode[SpacingMode["Percent"] = 2] = "Percent"; + })(SpacingMode$2 || (SpacingMode$2 = {})); + + /** + * @public + */ + var PathConstraint$2 = /** @class */ (function () { + function PathConstraint(data, skeleton) { + this.position = 0; + this.spacing = 0; + this.rotateMix = 0; + this.translateMix = 0; + this.spaces = new Array(); + this.positions = new Array(); + this.world = new Array(); + this.curves = new Array(); + this.lengths = new Array(); + this.segments = new Array(); + this.active = false; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.bones = new Array(); + for (var i = 0, n = data.bones.length; i < n; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findSlot(data.target.name); + this.position = data.position; + this.spacing = data.spacing; + this.rotateMix = data.rotateMix; + this.translateMix = data.translateMix; + } + PathConstraint.prototype.isActive = function () { + return this.active; + }; + PathConstraint.prototype.apply = function () { + this.update(); + }; + PathConstraint.prototype.update = function () { + var attachment = this.target.getAttachment(); + if (!(attachment instanceof PathAttachment$2)) + return; + var rotateMix = this.rotateMix, translateMix = this.translateMix; + var translate = translateMix > 0, rotate = rotateMix > 0; + if (!translate && !rotate) + return; + var data = this.data; + var spacingMode = data.spacingMode; + var lengthSpacing = spacingMode == SpacingMode$2.Length; + var rotateMode = data.rotateMode; + var tangents = rotateMode == exports.RotateMode.Tangent, scale = rotateMode == exports.RotateMode.ChainScale; + var boneCount = this.bones.length, spacesCount = tangents ? boneCount : boneCount + 1; + var bones = this.bones; + var spaces = Utils.setArraySize(this.spaces, spacesCount), lengths = null; + var spacing = this.spacing; + if (scale || lengthSpacing) { + if (scale) + lengths = Utils.setArraySize(this.lengths, boneCount); + for (var i = 0, n = spacesCount - 1; i < n;) { + var bone = bones[i]; + var setupLength = bone.data.length; + if (setupLength < PathConstraint.epsilon) { + if (scale) + lengths[i] = 0; + spaces[++i] = 0; + } + else { + var x = setupLength * bone.matrix.a, y = setupLength * bone.matrix.b; + var length_1 = Math.sqrt(x * x + y * y); + if (scale) + lengths[i] = length_1; + spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length_1 / setupLength; + } + } + } + else { + for (var i = 1; i < spacesCount; i++) + spaces[i] = spacing; + } + var positions = this.computeWorldPositions(attachment, spacesCount, tangents, data.positionMode == exports.PositionMode.Percent, spacingMode == SpacingMode$2.Percent); + var boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; + var tip = false; + if (offsetRotation == 0) + tip = rotateMode == exports.RotateMode.Chain; + else { + tip = false; + var p = this.target.bone.matrix; + offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.degRad : -MathUtils.degRad; + } + for (var i = 0, p = 3; i < boneCount; i++, p += 3) { + var bone = bones[i]; + var mat = bone.matrix; + mat.tx += (boneX - mat.tx) * translateMix; + mat.ty += (boneY - mat.ty) * translateMix; + var x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; + if (scale) { + var length_2 = lengths[i]; + if (length_2 != 0) { + var s = (Math.sqrt(dx * dx + dy * dy) / length_2 - 1) * rotateMix + 1; + mat.a *= s; + mat.b *= s; + } + } + boneX = x; + boneY = y; + if (rotate) { + var a = mat.a, b = mat.c, c = mat.b, d = mat.d, r = 0, cos = 0, sin = 0; + if (tangents) + r = positions[p - 1]; + else if (spaces[i + 1] == 0) + r = positions[p + 2]; + else + r = Math.atan2(dy, dx); + r -= Math.atan2(c, a); + if (tip) { + cos = Math.cos(r); + sin = Math.sin(r); + var length_3 = bone.data.length; + boneX += (length_3 * (cos * a - sin * c) - dx) * rotateMix; + boneY += (length_3 * (sin * a + cos * c) - dy) * rotateMix; + } + else { + r += offsetRotation; + } + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; + r *= rotateMix; + cos = Math.cos(r); + sin = Math.sin(r); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + } + bone.appliedValid = false; + } + }; + PathConstraint.prototype.computeWorldPositions = function (path, spacesCount, tangents, percentPosition, percentSpacing) { + var target = this.target; + var position = this.position; + var spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = null; + var closed = path.closed; + var verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE; + if (!path.constantSpeed) { + var lengths = path.lengths; + curveCount -= closed ? 1 : 2; + var pathLength_1 = lengths[curveCount]; + if (percentPosition) + position *= pathLength_1; + if (percentSpacing) { + for (var i = 0; i < spacesCount; i++) + spaces[i] *= pathLength_1; + } + world = Utils.setArraySize(this.world, 8); + for (var i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { + var space = spaces[i]; + position += space; + var p = position; + if (closed) { + p %= pathLength_1; + if (p < 0) + p += pathLength_1; + curve = 0; + } + else if (p < 0) { + if (prevCurve != PathConstraint.BEFORE) { + prevCurve = PathConstraint.BEFORE; + path.computeWorldVertices(target, 2, 4, world, 0, 2); + } + this.addBeforePosition(p, world, 0, out, o); + continue; + } + else if (p > pathLength_1) { + if (prevCurve != PathConstraint.AFTER) { + prevCurve = PathConstraint.AFTER; + path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); + } + this.addAfterPosition(p - pathLength_1, world, 0, out, o); + continue; + } + // Determine curve containing position. + for (;; curve++) { + var length_4 = lengths[curve]; + if (p > length_4) + continue; + if (curve == 0) + p /= length_4; + else { + var prev = lengths[curve - 1]; + p = (p - prev) / (length_4 - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + if (closed && curve == curveCount) { + path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); + path.computeWorldVertices(target, 0, 4, world, 4, 2); + } + else + path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); + } + this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0)); + } + return out; + } + // World vertices. + if (closed) { + verticesLength += 2; + world = Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); + path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); + world[verticesLength - 2] = world[0]; + world[verticesLength - 1] = world[1]; + } + else { + curveCount--; + verticesLength -= 4; + world = Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); + } + // Curve lengths. + var curves = Utils.setArraySize(this.curves, curveCount); + var pathLength = 0; + var x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; + var tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0; + for (var i = 0, w = 2; i < curveCount; i++, w += 6) { + cx1 = world[w]; + cy1 = world[w + 1]; + cx2 = world[w + 2]; + cy2 = world[w + 3]; + x2 = world[w + 4]; + y2 = world[w + 5]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.1875; + tmpy = (y1 - cy1 * 2 + cy2) * 0.1875; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + curves[i] = pathLength; + x1 = x2; + y1 = y2; + } + if (percentPosition) + position *= pathLength; + if (percentSpacing) { + for (var i = 0; i < spacesCount; i++) + spaces[i] *= pathLength; + } + var segments = this.segments; + var curveLength = 0; + for (var i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { + var space = spaces[i]; + position += space; + var p = position; + if (closed) { + p %= pathLength; + if (p < 0) + p += pathLength; + curve = 0; + } + else if (p < 0) { + this.addBeforePosition(p, world, 0, out, o); + continue; + } + else if (p > pathLength) { + this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o); + continue; + } + // Determine curve containing position. + for (;; curve++) { + var length_5 = curves[curve]; + if (p > length_5) + continue; + if (curve == 0) + p /= length_5; + else { + var prev = curves[curve - 1]; + p = (p - prev) / (length_5 - prev); + } + break; + } + // Curve segment lengths. + if (curve != prevCurve) { + prevCurve = curve; + var ii = curve * 6; + x1 = world[ii]; + y1 = world[ii + 1]; + cx1 = world[ii + 2]; + cy1 = world[ii + 3]; + cx2 = world[ii + 4]; + cy2 = world[ii + 5]; + x2 = world[ii + 6]; + y2 = world[ii + 7]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.03; + tmpy = (y1 - cy1 * 2 + cy2) * 0.03; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667; + curveLength = Math.sqrt(dfx * dfx + dfy * dfy); + segments[0] = curveLength; + for (ii = 1; ii < 8; ii++) { + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[ii] = curveLength; + } + dfx += ddfx; + dfy += ddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[8] = curveLength; + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[9] = curveLength; + segment = 0; + } + // Weight by segment length. + p *= curveLength; + for (;; segment++) { + var length_6 = segments[segment]; + if (p > length_6) + continue; + if (segment == 0) + p /= length_6; + else { + var prev = segments[segment - 1]; + p = segment + (p - prev) / (length_6 - prev); + } + break; + } + this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0)); + } + return out; + }; + PathConstraint.prototype.addBeforePosition = function (p, temp, i, out, o) { + var x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + }; + PathConstraint.prototype.addAfterPosition = function (p, temp, i, out, o) { + var x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + }; + PathConstraint.prototype.addCurvePosition = function (p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) { + if (p == 0 || isNaN(p)) + p = 0.0001; + var tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; + var ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; + var x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; + out[o] = x; + out[o + 1] = y; + if (tangents) + out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); + }; + PathConstraint.NONE = -1; + PathConstraint.BEFORE = -2; + PathConstraint.AFTER = -3; + PathConstraint.epsilon = 0.00001; + return PathConstraint; + }()); + + /** + * @public + */ + var TransformConstraint$2 = /** @class */ (function () { + function TransformConstraint(data, skeleton) { + this.rotateMix = 0; + this.translateMix = 0; + this.scaleMix = 0; + this.shearMix = 0; + this.temp = new Vector2(); + this.active = false; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.rotateMix = data.rotateMix; + this.translateMix = data.translateMix; + this.scaleMix = data.scaleMix; + this.shearMix = data.shearMix; + this.bones = new Array(); + for (var i = 0; i < data.bones.length; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findBone(data.target.name); + } + TransformConstraint.prototype.isActive = function () { + return this.active; + }; + TransformConstraint.prototype.apply = function () { + this.update(); + }; + TransformConstraint.prototype.update = function () { + if (this.data.local) { + if (this.data.relative) + this.applyRelativeLocal(); + else + this.applyAbsoluteLocal(); + } + else { + if (this.data.relative) + this.applyRelativeWorld(); + else + this.applyAbsoluteWorld(); + } + }; + TransformConstraint.prototype.applyAbsoluteWorld = function () { + var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + var target = this.target; + var targetMat = target.matrix; + var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; + var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; + var offsetRotation = this.data.offsetRotation * degRadReflect; + var offsetShearY = this.data.offsetShearY * degRadReflect; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + var modified = false; + var mat = bone.matrix; + if (rotateMix != 0) { + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r *= rotateMix; + var cos = Math.cos(r), sin = Math.sin(r); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + modified = true; + } + if (translateMix != 0) { + var temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + mat.tx += (temp.x - mat.tx) * translateMix; + mat.ty += (temp.y - mat.ty) * translateMix; + modified = true; + } + if (scaleMix > 0) { + var s = Math.sqrt(mat.a * mat.a + mat.b * mat.b); + var ts = Math.sqrt(ta * ta + tc * tc); + if (s > 0.00001) + s = (s + (ts - s + this.data.offsetScaleX) * scaleMix) / s; + mat.a *= s; + mat.b *= s; + s = Math.sqrt(mat.c * mat.c + mat.d * mat.d); + ts = Math.sqrt(tb * tb + td * td); + if (s > 0.00001) + s = (s + (ts - s + this.data.offsetScaleY) * scaleMix) / s; + mat.c *= s; + mat.d *= s; + modified = true; + } + if (shearMix > 0) { + var b = mat.c, d = mat.d; + var by = Math.atan2(d, b); + var r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(mat.b, mat.a)); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r = by + (r + offsetShearY) * shearMix; + var s = Math.sqrt(b * b + d * d); + mat.c = Math.cos(r) * s; + mat.d = Math.sin(r) * s; + modified = true; + } + if (modified) + bone.appliedValid = false; + } + }; + TransformConstraint.prototype.applyRelativeWorld = function () { + var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + var target = this.target; + var targetMat = target.matrix; + var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; + var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; + var offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + var modified = false; + var mat = bone.matrix; + if (rotateMix != 0) { + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var r = Math.atan2(tc, ta) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r *= rotateMix; + var cos = Math.cos(r), sin = Math.sin(r); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + modified = true; + } + if (translateMix != 0) { + var temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + mat.tx += temp.x * translateMix; + mat.ty += temp.y * translateMix; + modified = true; + } + if (scaleMix > 0) { + var s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * scaleMix + 1; + mat.a *= s; + mat.b *= s; + s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1; + mat.c *= s; + mat.d *= s; + modified = true; + } + if (shearMix > 0) { + var r = Math.atan2(td, tb) - Math.atan2(tc, ta); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + var b = mat.c, d = mat.d; + r = Math.atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * shearMix; + var s = Math.sqrt(b * b + d * d); + mat.c = Math.cos(r) * s; + mat.d = Math.sin(r) * s; + modified = true; + } + if (modified) + bone.appliedValid = false; + } + }; + TransformConstraint.prototype.applyAbsoluteLocal = function () { + var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + var target = this.target; + if (!target.appliedValid) + target.updateAppliedTransform(); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (!bone.appliedValid) + bone.updateAppliedTransform(); + var rotation = bone.arotation; + if (rotateMix != 0) { + var r = target.arotation - rotation + this.data.offsetRotation; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + rotation += r * rotateMix; + } + var x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax - x + this.data.offsetX) * translateMix; + y += (target.ay - y + this.data.offsetY) * translateMix; + } + var scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix > 0) { + if (scaleX > 0.00001) + scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * scaleMix) / scaleX; + if (scaleY > 0.00001) + scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * scaleMix) / scaleY; + } + var shearY = bone.ashearY; + if (shearMix > 0) { + var r = target.ashearY - shearY + this.data.offsetShearY; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + bone.shearY += r * shearMix; + } + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + }; + TransformConstraint.prototype.applyRelativeLocal = function () { + var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + var target = this.target; + if (!target.appliedValid) + target.updateAppliedTransform(); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (!bone.appliedValid) + bone.updateAppliedTransform(); + var rotation = bone.arotation; + if (rotateMix != 0) + rotation += (target.arotation + this.data.offsetRotation) * rotateMix; + var x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax + this.data.offsetX) * translateMix; + y += (target.ay + this.data.offsetY) * translateMix; + } + var scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix > 0) { + if (scaleX > 0.00001) + scaleX *= ((target.ascaleX - 1 + this.data.offsetScaleX) * scaleMix) + 1; + if (scaleY > 0.00001) + scaleY *= ((target.ascaleY - 1 + this.data.offsetScaleY) * scaleMix) + 1; + } + var shearY = bone.ashearY; + if (shearMix > 0) + shearY += (target.ashearY + this.data.offsetShearY) * shearMix; + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + }; + return TransformConstraint; + }()); + + /** + * @public + */ + var Skeleton$2 = /** @class */ (function () { + function Skeleton(data) { + this._updateCache = new Array(); + this.updateCacheReset = new Array(); + this.time = 0; + this.scaleX = 1; + this.scaleY = 1; + this.x = 0; + this.y = 0; + if (data == null) + throw new Error("data cannot be null."); + this.data = data; + this.bones = new Array(); + for (var i = 0; i < data.bones.length; i++) { + var boneData = data.bones[i]; + var bone = void 0; + if (boneData.parent == null) + bone = new Bone$2(boneData, this, null); + else { + var parent_1 = this.bones[boneData.parent.index]; + bone = new Bone$2(boneData, this, parent_1); + parent_1.children.push(bone); + } + this.bones.push(bone); + } + this.slots = new Array(); + this.drawOrder = new Array(); + for (var i = 0; i < data.slots.length; i++) { + var slotData = data.slots[i]; + var bone = this.bones[slotData.boneData.index]; + var slot = new Slot$2(slotData, bone); + this.slots.push(slot); + this.drawOrder.push(slot); + } + this.ikConstraints = new Array(); + for (var i = 0; i < data.ikConstraints.length; i++) { + var ikConstraintData = data.ikConstraints[i]; + this.ikConstraints.push(new IkConstraint$2(ikConstraintData, this)); + } + this.transformConstraints = new Array(); + for (var i = 0; i < data.transformConstraints.length; i++) { + var transformConstraintData = data.transformConstraints[i]; + this.transformConstraints.push(new TransformConstraint$2(transformConstraintData, this)); + } + this.pathConstraints = new Array(); + for (var i = 0; i < data.pathConstraints.length; i++) { + var pathConstraintData = data.pathConstraints[i]; + this.pathConstraints.push(new PathConstraint$2(pathConstraintData, this)); + } + this.color = new Color(1, 1, 1, 1); + this.updateCache(); + } + Skeleton.prototype.updateCache = function () { + var updateCache = this._updateCache; + updateCache.length = 0; + this.updateCacheReset.length = 0; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + bone.sorted = bone.data.skinRequired; + bone.active = !bone.sorted; + } + if (this.skin != null) { + var skinBones = this.skin.bones; + for (var i = 0, n = this.skin.bones.length; i < n; i++) { + var bone = this.bones[skinBones[i].index]; + do { + bone.sorted = false; + bone.active = true; + bone = bone.parent; + } while (bone != null); + } + } + // IK first, lowest hierarchy depth first. + var ikConstraints = this.ikConstraints; + var transformConstraints = this.transformConstraints; + var pathConstraints = this.pathConstraints; + var ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length; + var constraintCount = ikCount + transformCount + pathCount; + outer: for (var i = 0; i < constraintCount; i++) { + for (var ii = 0; ii < ikCount; ii++) { + var constraint = ikConstraints[ii]; + if (constraint.data.order == i) { + this.sortIkConstraint(constraint); + continue outer; + } + } + for (var ii = 0; ii < transformCount; ii++) { + var constraint = transformConstraints[ii]; + if (constraint.data.order == i) { + this.sortTransformConstraint(constraint); + continue outer; + } + } + for (var ii = 0; ii < pathCount; ii++) { + var constraint = pathConstraints[ii]; + if (constraint.data.order == i) { + this.sortPathConstraint(constraint); + continue outer; + } + } + } + for (var i = 0, n = bones.length; i < n; i++) + this.sortBone(bones[i]); + }; + Skeleton.prototype.sortIkConstraint = function (constraint) { + constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true))); + if (!constraint.active) + return; + var target = constraint.target; + this.sortBone(target); + var constrained = constraint.bones; + var parent = constrained[0]; + this.sortBone(parent); + if (constrained.length > 1) { + var child = constrained[constrained.length - 1]; + if (!(this._updateCache.indexOf(child) > -1)) + this.updateCacheReset.push(child); + } + this._updateCache.push(constraint); + this.sortReset(parent.children); + constrained[constrained.length - 1].sorted = true; + }; + Skeleton.prototype.sortPathConstraint = function (constraint) { + constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true))); + if (!constraint.active) + return; + var slot = constraint.target; + var slotIndex = slot.data.index; + var slotBone = slot.bone; + if (this.skin != null) + this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone); + if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin) + this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone); + for (var i = 0, n = this.data.skins.length; i < n; i++) + this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone); + var attachment = slot.getAttachment(); + if (attachment instanceof PathAttachment$2) + this.sortPathConstraintAttachmentWith(attachment, slotBone); + var constrained = constraint.bones; + var boneCount = constrained.length; + for (var i = 0; i < boneCount; i++) + this.sortBone(constrained[i]); + this._updateCache.push(constraint); + for (var i = 0; i < boneCount; i++) + this.sortReset(constrained[i].children); + for (var i = 0; i < boneCount; i++) + constrained[i].sorted = true; + }; + Skeleton.prototype.sortTransformConstraint = function (constraint) { + constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true))); + if (!constraint.active) + return; + this.sortBone(constraint.target); + var constrained = constraint.bones; + var boneCount = constrained.length; + if (constraint.data.local) { + for (var i = 0; i < boneCount; i++) { + var child = constrained[i]; + this.sortBone(child.parent); + if (!(this._updateCache.indexOf(child) > -1)) + this.updateCacheReset.push(child); + } + } + else { + for (var i = 0; i < boneCount; i++) { + this.sortBone(constrained[i]); + } + } + this._updateCache.push(constraint); + for (var ii = 0; ii < boneCount; ii++) + this.sortReset(constrained[ii].children); + for (var ii = 0; ii < boneCount; ii++) + constrained[ii].sorted = true; + }; + Skeleton.prototype.sortPathConstraintAttachment = function (skin, slotIndex, slotBone) { + var attachments = skin.attachments[slotIndex]; + if (!attachments) + return; + for (var key in attachments) { + this.sortPathConstraintAttachmentWith(attachments[key], slotBone); + } + }; + Skeleton.prototype.sortPathConstraintAttachmentWith = function (attachment, slotBone) { + if (!(attachment instanceof PathAttachment$2)) + return; + var pathBones = attachment.bones; + if (pathBones == null) + this.sortBone(slotBone); + else { + var bones = this.bones; + var i = 0; + while (i < pathBones.length) { + var boneCount = pathBones[i++]; + for (var n = i + boneCount; i < n; i++) { + var boneIndex = pathBones[i]; + this.sortBone(bones[boneIndex]); + } + } + } + }; + Skeleton.prototype.sortBone = function (bone) { + if (bone.sorted) + return; + var parent = bone.parent; + if (parent != null) + this.sortBone(parent); + bone.sorted = true; + this._updateCache.push(bone); + }; + Skeleton.prototype.sortReset = function (bones) { + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (!bone.active) + continue; + if (bone.sorted) + this.sortReset(bone.children); + bone.sorted = false; + } + }; + /** Updates the world transform for each bone and applies constraints. */ + Skeleton.prototype.updateWorldTransform = function () { + var updateCacheReset = this.updateCacheReset; + for (var i = 0, n = updateCacheReset.length; i < n; i++) { + var bone = updateCacheReset[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + bone.appliedValid = true; + } + var updateCache = this._updateCache; + for (var i = 0, n = updateCache.length; i < n; i++) + updateCache[i].update(); + }; + /** Sets the bones, constraints, and slots to their setup pose values. */ + Skeleton.prototype.setToSetupPose = function () { + this.setBonesToSetupPose(); + this.setSlotsToSetupPose(); + }; + /** Sets the bones and constraints to their setup pose values. */ + Skeleton.prototype.setBonesToSetupPose = function () { + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + bones[i].setToSetupPose(); + var ikConstraints = this.ikConstraints; + for (var i = 0, n = ikConstraints.length; i < n; i++) { + var constraint = ikConstraints[i]; + constraint.mix = constraint.data.mix; + constraint.softness = constraint.data.softness; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + var transformConstraints = this.transformConstraints; + for (var i = 0, n = transformConstraints.length; i < n; i++) { + var constraint = transformConstraints[i]; + var data = constraint.data; + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + constraint.scaleMix = data.scaleMix; + constraint.shearMix = data.shearMix; + } + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) { + var constraint = pathConstraints[i]; + var data = constraint.data; + constraint.position = data.position; + constraint.spacing = data.spacing; + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + } + }; + Skeleton.prototype.setSlotsToSetupPose = function () { + var slots = this.slots; + Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length); + for (var i = 0, n = slots.length; i < n; i++) + slots[i].setToSetupPose(); + }; + /** @return May return null. */ + Skeleton.prototype.getRootBone = function () { + if (this.bones.length == 0) + return null; + return this.bones[0]; + }; + /** @return May be null. */ + Skeleton.prototype.findBone = function (boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (bone.data.name == boneName) + return bone; + } + return null; + }; + /** @return -1 if the bone was not found. */ + Skeleton.prototype.findBoneIndex = function (boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + if (bones[i].data.name == boneName) + return i; + return -1; + }; + /** @return May be null. */ + Skeleton.prototype.findSlot = function (slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.data.name == slotName) + return slot; + } + return null; + }; + /** @return -1 if the bone was not found. */ + Skeleton.prototype.findSlotIndex = function (slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) + if (slots[i].data.name == slotName) + return i; + return -1; + }; + /** Sets a skin by name. + * @see #setSkin(Skin) */ + Skeleton.prototype.setSkinByName = function (skinName) { + var skin = this.data.findSkin(skinName); + if (skin == null) + throw new Error("Skin not found: " + skinName); + this.setSkin(skin); + }; + /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}. + * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no + * old skin, each slot's setup mode attachment is attached from the new skin. + * @param newSkin May be null. */ + Skeleton.prototype.setSkin = function (newSkin) { + if (newSkin == this.skin) + return; + if (newSkin != null) { + if (this.skin != null) + newSkin.attachAll(this, this.skin); + else { + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + var name_1 = slot.data.attachmentName; + if (name_1 != null) { + var attachment = newSkin.getAttachment(i, name_1); + if (attachment != null) + slot.setAttachment(attachment); + } + } + } + } + this.skin = newSkin; + this.updateCache(); + }; + /** @return May be null. */ + Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) { + return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName); + }; + /** @return May be null. */ + Skeleton.prototype.getAttachment = function (slotIndex, attachmentName) { + if (attachmentName == null) + throw new Error("attachmentName cannot be null."); + if (this.skin != null) { + var attachment = this.skin.getAttachment(slotIndex, attachmentName); + if (attachment != null) + return attachment; + } + if (this.data.defaultSkin != null) + return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); + return null; + }; + /** @param attachmentName May be null. */ + Skeleton.prototype.setAttachment = function (slotName, attachmentName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.data.name == slotName) { + var attachment = null; + if (attachmentName != null) { + attachment = this.getAttachment(i, attachmentName); + if (attachment == null) + throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName); + } + slot.setAttachment(attachment); + return; + } + } + throw new Error("Slot not found: " + slotName); + }; + /** @return May be null. */ + Skeleton.prototype.findIkConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var ikConstraints = this.ikConstraints; + for (var i = 0, n = ikConstraints.length; i < n; i++) { + var ikConstraint = ikConstraints[i]; + if (ikConstraint.data.name == constraintName) + return ikConstraint; + } + return null; + }; + /** @return May be null. */ + Skeleton.prototype.findTransformConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var transformConstraints = this.transformConstraints; + for (var i = 0, n = transformConstraints.length; i < n; i++) { + var constraint = transformConstraints[i]; + if (constraint.data.name == constraintName) + return constraint; + } + return null; + }; + /** @return May be null. */ + Skeleton.prototype.findPathConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) { + var constraint = pathConstraints[i]; + if (constraint.data.name == constraintName) + return constraint; + } + return null; + }; + /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. + * @param offset The distance from the skeleton origin to the bottom left corner of the AABB. + * @param size The width and height of the AABB. + * @param temp Working memory */ + Skeleton.prototype.getBounds = function (offset, size, temp) { + if (temp === void 0) { temp = new Array(2); } + if (offset == null) + throw new Error("offset cannot be null."); + if (size == null) + throw new Error("size cannot be null."); + var drawOrder = this.drawOrder; + var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + for (var i = 0, n = drawOrder.length; i < n; i++) { + var slot = drawOrder[i]; + if (!slot.bone.active) + continue; + var verticesLength = 0; + var vertices = null; + var attachment = slot.getAttachment(); + if (attachment instanceof RegionAttachment$2) { + verticesLength = 8; + vertices = Utils.setArraySize(temp, verticesLength, 0); + attachment.computeWorldVertices(slot.bone, vertices, 0, 2); + } + else if (attachment instanceof MeshAttachment$2) { + var mesh = attachment; + verticesLength = mesh.worldVerticesLength; + vertices = Utils.setArraySize(temp, verticesLength, 0); + mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2); + } + if (vertices != null) { + for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) { + var x = vertices[ii], y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + } + offset.set(minX, minY); + size.set(maxX - minX, maxY - minY); + }; + Skeleton.prototype.update = function (delta) { + this.time += delta; + }; + Object.defineProperty(Skeleton.prototype, "flipX", { + get: function () { + return this.scaleX == -1; + }, + set: function (value) { + if (!Skeleton.deprecatedWarning1) { + Skeleton.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); + } + this.scaleX = value ? 1.0 : -1.0; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Skeleton.prototype, "flipY", { + get: function () { + return this.scaleY == -1; + }, + set: function (value) { + if (!Skeleton.deprecatedWarning1) { + Skeleton.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); + } + this.scaleY = value ? 1.0 : -1.0; + }, + enumerable: false, + configurable: true + }); + Skeleton.deprecatedWarning1 = false; + return Skeleton; + }()); + + /** + * @public + */ + var SkeletonData$2 = /** @class */ (function () { + function SkeletonData() { + this.bones = new Array(); // Ordered parents first. + this.slots = new Array(); // Setup pose draw order. + this.skins = new Array(); + this.events = new Array(); + this.animations = new Array(); + this.ikConstraints = new Array(); + this.transformConstraints = new Array(); + this.pathConstraints = new Array(); + // Nonessential + this.fps = 0; + } + SkeletonData.prototype.findBone = function (boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (bone.name == boneName) + return bone; + } + return null; + }; + SkeletonData.prototype.findBoneIndex = function (boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + if (bones[i].name == boneName) + return i; + return -1; + }; + SkeletonData.prototype.findSlot = function (slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.name == slotName) + return slot; + } + return null; + }; + SkeletonData.prototype.findSlotIndex = function (slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) + if (slots[i].name == slotName) + return i; + return -1; + }; + SkeletonData.prototype.findSkin = function (skinName) { + if (skinName == null) + throw new Error("skinName cannot be null."); + var skins = this.skins; + for (var i = 0, n = skins.length; i < n; i++) { + var skin = skins[i]; + if (skin.name == skinName) + return skin; + } + return null; + }; + SkeletonData.prototype.findEvent = function (eventDataName) { + if (eventDataName == null) + throw new Error("eventDataName cannot be null."); + var events = this.events; + for (var i = 0, n = events.length; i < n; i++) { + var event_1 = events[i]; + if (event_1.name == eventDataName) + return event_1; + } + return null; + }; + SkeletonData.prototype.findAnimation = function (animationName) { + if (animationName == null) + throw new Error("animationName cannot be null."); + var animations = this.animations; + for (var i = 0, n = animations.length; i < n; i++) { + var animation = animations[i]; + if (animation.name == animationName) + return animation; + } + return null; + }; + SkeletonData.prototype.findIkConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var ikConstraints = this.ikConstraints; + for (var i = 0, n = ikConstraints.length; i < n; i++) { + var constraint = ikConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + }; + SkeletonData.prototype.findTransformConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var transformConstraints = this.transformConstraints; + for (var i = 0, n = transformConstraints.length; i < n; i++) { + var constraint = transformConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + }; + SkeletonData.prototype.findPathConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) { + var constraint = pathConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + }; + SkeletonData.prototype.findPathConstraintIndex = function (pathConstraintName) { + if (pathConstraintName == null) + throw new Error("pathConstraintName cannot be null."); + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) + if (pathConstraints[i].name == pathConstraintName) + return i; + return -1; + }; + return SkeletonData; + }()); + + /** + * @public + */ + var SlotData$2 = /** @class */ (function () { + function SlotData(index, name, boneData) { + this.color = new Color(1, 1, 1, 1); + if (index < 0) + throw new Error("index must be >= 0."); + if (name == null) + throw new Error("name cannot be null."); + if (boneData == null) + throw new Error("boneData cannot be null."); + this.index = index; + this.name = name; + this.boneData = boneData; + } + return SlotData; + }()); + + /** + * @public + */ + var TransformConstraintData$2 = /** @class */ (function (_super) { + __extends$3(TransformConstraintData, _super); + function TransformConstraintData(name) { + var _this = _super.call(this, name, 0, false) || this; + _this.bones = new Array(); + _this.rotateMix = 0; + _this.translateMix = 0; + _this.scaleMix = 0; + _this.shearMix = 0; + _this.offsetRotation = 0; + _this.offsetX = 0; + _this.offsetY = 0; + _this.offsetScaleX = 0; + _this.offsetScaleY = 0; + _this.offsetShearY = 0; + _this.relative = false; + _this.local = false; + return _this; + } + return TransformConstraintData; + }(ConstraintData$1)); + + /** + * @public + */ + var SkinEntry$1 = /** @class */ (function () { + function SkinEntry(slotIndex, name, attachment) { + this.slotIndex = slotIndex; + this.name = name; + this.attachment = attachment; + } + return SkinEntry; + }()); + /** + * @public + */ + var Skin$2 = /** @class */ (function () { + function Skin(name) { + this.attachments = new Array(); + this.bones = Array(); + this.constraints = new Array(); + if (name == null) + throw new Error("name cannot be null."); + this.name = name; + } + Skin.prototype.setAttachment = function (slotIndex, name, attachment) { + if (attachment == null) + throw new Error("attachment cannot be null."); + var attachments = this.attachments; + if (slotIndex >= attachments.length) + attachments.length = slotIndex + 1; + if (!attachments[slotIndex]) + attachments[slotIndex] = {}; + attachments[slotIndex][name] = attachment; + }; + Skin.prototype.addSkin = function (skin) { + for (var i = 0; i < skin.bones.length; i++) { + var bone = skin.bones[i]; + var contained = false; + for (var j = 0; j < this.bones.length; j++) { + if (this.bones[j] == bone) { + contained = true; + break; + } + } + if (!contained) + this.bones.push(bone); + } + for (var i = 0; i < skin.constraints.length; i++) { + var constraint = skin.constraints[i]; + var contained = false; + for (var j = 0; j < this.constraints.length; j++) { + if (this.constraints[j] == constraint) { + contained = true; + break; + } + } + if (!contained) + this.constraints.push(constraint); + } + var attachments = skin.getAttachments(); + for (var i = 0; i < attachments.length; i++) { + var attachment = attachments[i]; + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + }; + Skin.prototype.copySkin = function (skin) { + for (var i = 0; i < skin.bones.length; i++) { + var bone = skin.bones[i]; + var contained = false; + for (var j = 0; j < this.bones.length; j++) { + if (this.bones[j] == bone) { + contained = true; + break; + } + } + if (!contained) + this.bones.push(bone); + } + for (var i = 0; i < skin.constraints.length; i++) { + var constraint = skin.constraints[i]; + var contained = false; + for (var j = 0; j < this.constraints.length; j++) { + if (this.constraints[j] == constraint) { + contained = true; + break; + } + } + if (!contained) + this.constraints.push(constraint); + } + var attachments = skin.getAttachments(); + for (var i = 0; i < attachments.length; i++) { + var attachment = attachments[i]; + if (attachment.attachment == null) + continue; + if (attachment.attachment instanceof MeshAttachment$2) { + attachment.attachment = attachment.attachment.newLinkedMesh(); + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + else { + attachment.attachment = attachment.attachment.copy(); + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + } + }; + /** @return May be null. */ + Skin.prototype.getAttachment = function (slotIndex, name) { + var dictionary = this.attachments[slotIndex]; + return dictionary ? dictionary[name] : null; + }; + Skin.prototype.removeAttachment = function (slotIndex, name) { + var dictionary = this.attachments[slotIndex]; + if (dictionary) + dictionary[name] = null; + }; + Skin.prototype.getAttachments = function () { + var entries = new Array(); + for (var i = 0; i < this.attachments.length; i++) { + var slotAttachments = this.attachments[i]; + if (slotAttachments) { + for (var name_1 in slotAttachments) { + var attachment = slotAttachments[name_1]; + if (attachment) + entries.push(new SkinEntry$1(i, name_1, attachment)); + } + } + } + return entries; + }; + Skin.prototype.getAttachmentsForSlot = function (slotIndex, attachments) { + var slotAttachments = this.attachments[slotIndex]; + if (slotAttachments) { + for (var name_2 in slotAttachments) { + var attachment = slotAttachments[name_2]; + if (attachment) + attachments.push(new SkinEntry$1(slotIndex, name_2, attachment)); + } + } + }; + Skin.prototype.clear = function () { + this.attachments.length = 0; + this.bones.length = 0; + this.constraints.length = 0; + }; + /** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */ + Skin.prototype.attachAll = function (skeleton, oldSkin) { + var slotIndex = 0; + for (var i = 0; i < skeleton.slots.length; i++) { + var slot = skeleton.slots[i]; + var slotAttachment = slot.getAttachment(); + if (slotAttachment && slotIndex < oldSkin.attachments.length) { + var dictionary = oldSkin.attachments[slotIndex]; + for (var key in dictionary) { + var skinAttachment = dictionary[key]; + if (slotAttachment == skinAttachment) { + var attachment = this.getAttachment(slotIndex, key); + if (attachment != null) + slot.setAttachment(attachment); + break; + } + } + } + slotIndex++; + } + }; + return Skin; + }()); + + /** + * @public + */ + var SkeletonBinary$1 = /** @class */ (function () { + function SkeletonBinary(attachmentLoader) { + this.scale = 1; + this.linkedMeshes = new Array(); + this.attachmentLoader = attachmentLoader; + } + SkeletonBinary.prototype.readSkeletonData = function (binary) { + var scale = this.scale; + var skeletonData = new SkeletonData$2(); + skeletonData.name = ""; // BOZO + var input = new BinaryInput(binary); + skeletonData.hash = input.readString(); + skeletonData.version = input.readString(); + if (skeletonData.version === '3.8.75') { + var error = "Unsupported skeleton data, 3.8.75 is deprecated, please export with a newer version of Spine."; + console.error(error); + } + skeletonData.x = input.readFloat(); + skeletonData.y = input.readFloat(); + skeletonData.width = input.readFloat(); + skeletonData.height = input.readFloat(); + var nonessential = input.readBoolean(); + if (nonessential) { + skeletonData.fps = input.readFloat(); + skeletonData.imagesPath = input.readString(); + skeletonData.audioPath = input.readString(); + } + var n = 0; + // Strings. + n = input.readInt(true); + for (var i = 0; i < n; i++) + input.strings.push(input.readString()); + // Bones. + n = input.readInt(true); + for (var i = 0; i < n; i++) { + var name_1 = input.readString(); + var parent_1 = i == 0 ? null : skeletonData.bones[input.readInt(true)]; + var data = new BoneData$2(i, name_1, parent_1); + data.rotation = input.readFloat(); + data.x = input.readFloat() * scale; + data.y = input.readFloat() * scale; + data.scaleX = input.readFloat(); + data.scaleY = input.readFloat(); + data.shearX = input.readFloat(); + data.shearY = input.readFloat(); + data.length = input.readFloat() * scale; + data.transformMode = SkeletonBinary.TransformModeValues[input.readInt(true)]; + data.skinRequired = input.readBoolean(); + if (nonessential) + Color.rgba8888ToColor(data.color, input.readInt32()); + skeletonData.bones.push(data); + } + // Slots. + n = input.readInt(true); + for (var i = 0; i < n; i++) { + var slotName = input.readString(); + var boneData = skeletonData.bones[input.readInt(true)]; + var data = new SlotData$2(i, slotName, boneData); + Color.rgba8888ToColor(data.color, input.readInt32()); + var darkColor = input.readInt32(); + if (darkColor != -1) + Color.rgb888ToColor(data.darkColor = new Color(), darkColor); + data.attachmentName = input.readStringRef(); + data.blendMode = SkeletonBinary.BlendModeValues[input.readInt(true)]; + skeletonData.slots.push(data); + } + // IK constraints. + n = input.readInt(true); + for (var i = 0, nn = void 0; i < n; i++) { + var data = new IkConstraintData$2(input.readString()); + data.order = input.readInt(true); + data.skinRequired = input.readBoolean(); + nn = input.readInt(true); + for (var ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.bones[input.readInt(true)]; + data.mix = input.readFloat(); + data.softness = input.readFloat() * scale; + data.bendDirection = input.readByte(); + data.compress = input.readBoolean(); + data.stretch = input.readBoolean(); + data.uniform = input.readBoolean(); + skeletonData.ikConstraints.push(data); + } + // Transform constraints. + n = input.readInt(true); + for (var i = 0, nn = void 0; i < n; i++) { + var data = new TransformConstraintData$2(input.readString()); + data.order = input.readInt(true); + data.skinRequired = input.readBoolean(); + nn = input.readInt(true); + for (var ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.bones[input.readInt(true)]; + data.local = input.readBoolean(); + data.relative = input.readBoolean(); + data.offsetRotation = input.readFloat(); + data.offsetX = input.readFloat() * scale; + data.offsetY = input.readFloat() * scale; + data.offsetScaleX = input.readFloat(); + data.offsetScaleY = input.readFloat(); + data.offsetShearY = input.readFloat(); + data.rotateMix = input.readFloat(); + data.translateMix = input.readFloat(); + data.scaleMix = input.readFloat(); + data.shearMix = input.readFloat(); + skeletonData.transformConstraints.push(data); + } + // Path constraints. + n = input.readInt(true); + for (var i = 0, nn = void 0; i < n; i++) { + var data = new PathConstraintData$2(input.readString()); + data.order = input.readInt(true); + data.skinRequired = input.readBoolean(); + nn = input.readInt(true); + for (var ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.slots[input.readInt(true)]; + data.positionMode = SkeletonBinary.PositionModeValues[input.readInt(true)]; + data.spacingMode = SkeletonBinary.SpacingModeValues[input.readInt(true)]; + data.rotateMode = SkeletonBinary.RotateModeValues[input.readInt(true)]; + data.offsetRotation = input.readFloat(); + data.position = input.readFloat(); + if (data.positionMode == exports.PositionMode.Fixed) + data.position *= scale; + data.spacing = input.readFloat(); + if (data.spacingMode == SpacingMode$2.Length || data.spacingMode == SpacingMode$2.Fixed) + data.spacing *= scale; + data.rotateMix = input.readFloat(); + data.translateMix = input.readFloat(); + skeletonData.pathConstraints.push(data); + } + // Default skin. + var defaultSkin = this.readSkin(input, skeletonData, true, nonessential); + if (defaultSkin != null) { + skeletonData.defaultSkin = defaultSkin; + skeletonData.skins.push(defaultSkin); + } + // Skins. + { + var i = skeletonData.skins.length; + Utils.setArraySize(skeletonData.skins, n = i + input.readInt(true)); + for (; i < n; i++) + skeletonData.skins[i] = this.readSkin(input, skeletonData, false, nonessential); + } + // Linked meshes. + n = this.linkedMeshes.length; + for (var i = 0; i < n; i++) { + var linkedMesh = this.linkedMeshes[i]; + var skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); + if (skin == null) + throw new Error("Skin not found: " + linkedMesh.skin); + var parent_2 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (parent_2 == null) + throw new Error("Parent mesh not found: " + linkedMesh.parent); + linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent_2 : linkedMesh.mesh; + linkedMesh.mesh.setParentMesh(parent_2); + // linkedMesh.mesh.updateUVs(); + } + this.linkedMeshes.length = 0; + // Events. + n = input.readInt(true); + for (var i = 0; i < n; i++) { + var data = new EventData$2(input.readStringRef()); + data.intValue = input.readInt(false); + data.floatValue = input.readFloat(); + data.stringValue = input.readString(); + data.audioPath = input.readString(); + if (data.audioPath != null) { + data.volume = input.readFloat(); + data.balance = input.readFloat(); + } + skeletonData.events.push(data); + } + // Animations. + n = input.readInt(true); + for (var i = 0; i < n; i++) + skeletonData.animations.push(this.readAnimation(input, input.readString(), skeletonData)); + return skeletonData; + }; + SkeletonBinary.prototype.readSkin = function (input, skeletonData, defaultSkin, nonessential) { + var skin = null; + var slotCount = 0; + if (defaultSkin) { + slotCount = input.readInt(true); + if (slotCount == 0) + return null; + skin = new Skin$2("default"); + } + else { + skin = new Skin$2(input.readStringRef()); + skin.bones.length = input.readInt(true); + for (var i = 0, n = skin.bones.length; i < n; i++) + skin.bones[i] = skeletonData.bones[input.readInt(true)]; + for (var i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.ikConstraints[input.readInt(true)]); + for (var i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.transformConstraints[input.readInt(true)]); + for (var i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.pathConstraints[input.readInt(true)]); + slotCount = input.readInt(true); + } + for (var i = 0; i < slotCount; i++) { + var slotIndex = input.readInt(true); + for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { + var name_2 = input.readStringRef(); + var attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name_2, nonessential); + if (attachment != null) + skin.setAttachment(slotIndex, name_2, attachment); + } + } + return skin; + }; + SkeletonBinary.prototype.readAttachment = function (input, skeletonData, skin, slotIndex, attachmentName, nonessential) { + var scale = this.scale; + var name = input.readStringRef(); + if (name == null) + name = attachmentName; + var typeIndex = input.readByte(); + var type = SkeletonBinary.AttachmentTypeValues[typeIndex]; + switch (type) { + case exports.AttachmentType.Region: { + var path = input.readStringRef(); + var rotation = input.readFloat(); + var x = input.readFloat(); + var y = input.readFloat(); + var scaleX = input.readFloat(); + var scaleY = input.readFloat(); + var width = input.readFloat(); + var height = input.readFloat(); + var color = input.readInt32(); + if (path == null) + path = name; + var region = this.attachmentLoader.newRegionAttachment(skin, name, path); + if (region == null) + return null; + region.path = path; + region.x = x * scale; + region.y = y * scale; + region.scaleX = scaleX; + region.scaleY = scaleY; + region.rotation = rotation; + region.width = width * scale; + region.height = height * scale; + Color.rgba8888ToColor(region.color, color); + // region.updateOffset(); + return region; + } + case exports.AttachmentType.BoundingBox: { + var vertexCount = input.readInt(true); + var vertices = this.readVertices(input, vertexCount); + var color = nonessential ? input.readInt32() : 0; + var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (box == null) + return null; + box.worldVerticesLength = vertexCount << 1; + box.vertices = vertices.vertices; + box.bones = vertices.bones; + if (nonessential) + Color.rgba8888ToColor(box.color, color); + return box; + } + case exports.AttachmentType.Mesh: { + var path = input.readStringRef(); + var color = input.readInt32(); + var vertexCount = input.readInt(true); + var uvs = this.readFloatArray(input, vertexCount << 1, 1); + var triangles = this.readShortArray(input); + var vertices = this.readVertices(input, vertexCount); + var hullLength = input.readInt(true); + var edges = null; + var width = 0, height = 0; + if (nonessential) { + edges = this.readShortArray(input); + width = input.readFloat(); + height = input.readFloat(); + } + if (path == null) + path = name; + var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); + if (mesh == null) + return null; + mesh.path = path; + Color.rgba8888ToColor(mesh.color, color); + mesh.bones = vertices.bones; + mesh.vertices = vertices.vertices; + mesh.worldVerticesLength = vertexCount << 1; + mesh.triangles = triangles; + mesh.regionUVs = new Float32Array(uvs); + // mesh.updateUVs(); + mesh.hullLength = hullLength << 1; + if (nonessential) { + mesh.edges = edges; + mesh.width = width * scale; + mesh.height = height * scale; + } + return mesh; + } + case exports.AttachmentType.LinkedMesh: { + var path = input.readStringRef(); + var color = input.readInt32(); + var skinName = input.readStringRef(); + var parent_3 = input.readStringRef(); + var inheritDeform = input.readBoolean(); + var width = 0, height = 0; + if (nonessential) { + width = input.readFloat(); + height = input.readFloat(); + } + if (path == null) + path = name; + var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); + if (mesh == null) + return null; + mesh.path = path; + Color.rgba8888ToColor(mesh.color, color); + if (nonessential) { + mesh.width = width * scale; + mesh.height = height * scale; + } + this.linkedMeshes.push(new LinkedMesh$1$1(mesh, skinName, slotIndex, parent_3, inheritDeform)); + return mesh; + } + case exports.AttachmentType.Path: { + var closed_1 = input.readBoolean(); + var constantSpeed = input.readBoolean(); + var vertexCount = input.readInt(true); + var vertices = this.readVertices(input, vertexCount); + var lengths = Utils.newArray(vertexCount / 3, 0); + for (var i = 0, n = lengths.length; i < n; i++) + lengths[i] = input.readFloat() * scale; + var color = nonessential ? input.readInt32() : 0; + var path = this.attachmentLoader.newPathAttachment(skin, name); + if (path == null) + return null; + path.closed = closed_1; + path.constantSpeed = constantSpeed; + path.worldVerticesLength = vertexCount << 1; + path.vertices = vertices.vertices; + path.bones = vertices.bones; + path.lengths = lengths; + if (nonessential) + Color.rgba8888ToColor(path.color, color); + return path; + } + case exports.AttachmentType.Point: { + var rotation = input.readFloat(); + var x = input.readFloat(); + var y = input.readFloat(); + var color = nonessential ? input.readInt32() : 0; + var point = this.attachmentLoader.newPointAttachment(skin, name); + if (point == null) + return null; + point.x = x * scale; + point.y = y * scale; + point.rotation = rotation; + if (nonessential) + Color.rgba8888ToColor(point.color, color); + return point; + } + case exports.AttachmentType.Clipping: { + var endSlotIndex = input.readInt(true); + var vertexCount = input.readInt(true); + var vertices = this.readVertices(input, vertexCount); + var color = nonessential ? input.readInt32() : 0; + var clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (clip == null) + return null; + clip.endSlot = skeletonData.slots[endSlotIndex]; + clip.worldVerticesLength = vertexCount << 1; + clip.vertices = vertices.vertices; + clip.bones = vertices.bones; + if (nonessential) + Color.rgba8888ToColor(clip.color, color); + return clip; + } + } + return null; + }; + SkeletonBinary.prototype.readVertices = function (input, vertexCount) { + var verticesLength = vertexCount << 1; + var vertices = new Vertices$1(); + var scale = this.scale; + if (!input.readBoolean()) { + vertices.vertices = this.readFloatArray(input, verticesLength, scale); + return vertices; + } + var weights = new Array(); + var bonesArray = new Array(); + for (var i = 0; i < vertexCount; i++) { + var boneCount = input.readInt(true); + bonesArray.push(boneCount); + for (var ii = 0; ii < boneCount; ii++) { + bonesArray.push(input.readInt(true)); + weights.push(input.readFloat() * scale); + weights.push(input.readFloat() * scale); + weights.push(input.readFloat()); + } + } + vertices.vertices = Utils.toFloatArray(weights); + vertices.bones = bonesArray; + return vertices; + }; + SkeletonBinary.prototype.readFloatArray = function (input, n, scale) { + var array = new Array(n); + if (scale == 1) { + for (var i = 0; i < n; i++) + array[i] = input.readFloat(); + } + else { + for (var i = 0; i < n; i++) + array[i] = input.readFloat() * scale; + } + return array; + }; + SkeletonBinary.prototype.readShortArray = function (input) { + var n = input.readInt(true); + var array = new Array(n); + for (var i = 0; i < n; i++) + array[i] = input.readShort(); + return array; + }; + SkeletonBinary.prototype.readAnimation = function (input, name, skeletonData) { + var timelines = new Array(); + var scale = this.scale; + var duration = 0; + var tempColor1 = new Color(); + var tempColor2 = new Color(); + // Slot timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var slotIndex = input.readInt(true); + for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { + var timelineType = input.readByte(); + var frameCount = input.readInt(true); + switch (timelineType) { + case SkeletonBinary.SLOT_ATTACHMENT: { + var timeline = new AttachmentTimeline$2(frameCount); + timeline.slotIndex = slotIndex; + for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) + timeline.setFrame(frameIndex, input.readFloat(), input.readStringRef()); + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[frameCount - 1]); + break; + } + case SkeletonBinary.SLOT_COLOR: { + var timeline = new ColorTimeline$1(frameCount); + timeline.slotIndex = slotIndex; + for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { + var time = input.readFloat(); + Color.rgba8888ToColor(tempColor1, input.readInt32()); + timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * ColorTimeline$1.ENTRIES]); + break; + } + case SkeletonBinary.SLOT_TWO_COLOR: { + var timeline = new TwoColorTimeline$1(frameCount); + timeline.slotIndex = slotIndex; + for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { + var time = input.readFloat(); + Color.rgba8888ToColor(tempColor1, input.readInt32()); + Color.rgb888ToColor(tempColor2, input.readInt32()); + timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a, tempColor2.r, tempColor2.g, tempColor2.b); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * TwoColorTimeline$1.ENTRIES]); + break; + } + } + } + } + // Bone timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var boneIndex = input.readInt(true); + for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { + var timelineType = input.readByte(); + var frameCount = input.readInt(true); + switch (timelineType) { + case SkeletonBinary.BONE_ROTATE: { + var timeline = new RotateTimeline$2(frameCount); + timeline.boneIndex = boneIndex; + for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat()); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * RotateTimeline$2.ENTRIES]); + break; + } + case SkeletonBinary.BONE_TRANSLATE: + case SkeletonBinary.BONE_SCALE: + case SkeletonBinary.BONE_SHEAR: { + var timeline = void 0; + var timelineScale = 1; + if (timelineType == SkeletonBinary.BONE_SCALE) + timeline = new ScaleTimeline$2(frameCount); + else if (timelineType == SkeletonBinary.BONE_SHEAR) + timeline = new ShearTimeline$2(frameCount); + else { + timeline = new TranslateTimeline$2(frameCount); + timelineScale = scale; + } + timeline.boneIndex = boneIndex; + for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale, input.readFloat() * timelineScale); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * TranslateTimeline$2.ENTRIES]); + break; + } + } + } + } + // IK constraint timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var index = input.readInt(true); + var frameCount = input.readInt(true); + var timeline = new IkConstraintTimeline$2(frameCount); + timeline.ikConstraintIndex = index; + for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat() * scale, input.readByte(), input.readBoolean(), input.readBoolean()); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * IkConstraintTimeline$2.ENTRIES]); + } + // Transform constraint timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var index = input.readInt(true); + var frameCount = input.readInt(true); + var timeline = new TransformConstraintTimeline$2(frameCount); + timeline.transformConstraintIndex = index; + for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat()); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline$2.ENTRIES]); + } + // Path constraint timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var index = input.readInt(true); + var data = skeletonData.pathConstraints[index]; + for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { + var timelineType = input.readByte(); + var frameCount = input.readInt(true); + switch (timelineType) { + case SkeletonBinary.PATH_POSITION: + case SkeletonBinary.PATH_SPACING: { + var timeline = void 0; + var timelineScale = 1; + if (timelineType == SkeletonBinary.PATH_SPACING) { + timeline = new PathConstraintSpacingTimeline$2(frameCount); + if (data.spacingMode == SpacingMode$2.Length || data.spacingMode == SpacingMode$2.Fixed) + timelineScale = scale; + } + else { + timeline = new PathConstraintPositionTimeline$2(frameCount); + if (data.positionMode == exports.PositionMode.Fixed) + timelineScale = scale; + } + timeline.pathConstraintIndex = index; + for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline$2.ENTRIES]); + break; + } + case SkeletonBinary.PATH_MIX: { + var timeline = new PathConstraintMixTimeline$2(frameCount); + timeline.pathConstraintIndex = index; + for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat()); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline$2.ENTRIES]); + break; + } + } + } + } + // Deform timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var skin = skeletonData.skins[input.readInt(true)]; + for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { + var slotIndex = input.readInt(true); + for (var iii = 0, nnn = input.readInt(true); iii < nnn; iii++) { + var attachment = skin.getAttachment(slotIndex, input.readStringRef()); + var weighted = attachment.bones != null; + var vertices = attachment.vertices; + var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + var frameCount = input.readInt(true); + var timeline = new DeformTimeline$2(frameCount); + timeline.slotIndex = slotIndex; + timeline.attachment = attachment; + for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { + var time = input.readFloat(); + var deform = void 0; + var end = input.readInt(true); + if (end == 0) + deform = weighted ? Utils.newFloatArray(deformLength) : vertices; + else { + deform = Utils.newFloatArray(deformLength); + var start = input.readInt(true); + end += start; + if (scale == 1) { + for (var v = start; v < end; v++) + deform[v] = input.readFloat(); + } + else { + for (var v = start; v < end; v++) + deform[v] = input.readFloat() * scale; + } + if (!weighted) { + for (var v = 0, vn = deform.length; v < vn; v++) + deform[v] += vertices[v]; + } + } + timeline.setFrame(frameIndex, time, deform); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[frameCount - 1]); + } + } + } + // Draw order timeline. + var drawOrderCount = input.readInt(true); + if (drawOrderCount > 0) { + var timeline = new DrawOrderTimeline$2(drawOrderCount); + var slotCount = skeletonData.slots.length; + for (var i = 0; i < drawOrderCount; i++) { + var time = input.readFloat(); + var offsetCount = input.readInt(true); + var drawOrder = Utils.newArray(slotCount, 0); + for (var ii = slotCount - 1; ii >= 0; ii--) + drawOrder[ii] = -1; + var unchanged = Utils.newArray(slotCount - offsetCount, 0); + var originalIndex = 0, unchangedIndex = 0; + for (var ii = 0; ii < offsetCount; ii++) { + var slotIndex = input.readInt(true); + // Collect unchanged items. + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + // Set changed items. + drawOrder[originalIndex + input.readInt(true)] = originalIndex++; + } + // Collect remaining unchanged items. + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + // Fill in unchanged items. + for (var ii = slotCount - 1; ii >= 0; ii--) + if (drawOrder[ii] == -1) + drawOrder[ii] = unchanged[--unchangedIndex]; + timeline.setFrame(i, time, drawOrder); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[drawOrderCount - 1]); + } + // Event timeline. + var eventCount = input.readInt(true); + if (eventCount > 0) { + var timeline = new EventTimeline$2(eventCount); + for (var i = 0; i < eventCount; i++) { + var time = input.readFloat(); + var eventData = skeletonData.events[input.readInt(true)]; + var event_1 = new Event$2(time, eventData); + event_1.intValue = input.readInt(false); + event_1.floatValue = input.readFloat(); + event_1.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue; + if (event_1.data.audioPath != null) { + event_1.volume = input.readFloat(); + event_1.balance = input.readFloat(); + } + timeline.setFrame(i, event_1); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[eventCount - 1]); + } + return new Animation$2(name, timelines, duration); + }; + SkeletonBinary.prototype.readCurve = function (input, frameIndex, timeline) { + switch (input.readByte()) { + case SkeletonBinary.CURVE_STEPPED: + timeline.setStepped(frameIndex); + break; + case SkeletonBinary.CURVE_BEZIER: + this.setCurve(timeline, frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat()); + break; + } + }; + SkeletonBinary.prototype.setCurve = function (timeline, frameIndex, cx1, cy1, cx2, cy2) { + timeline.setCurve(frameIndex, cx1, cy1, cx2, cy2); + }; + SkeletonBinary.AttachmentTypeValues = [0 /*AttachmentType.Region*/, 1 /*AttachmentType.BoundingBox*/, 2 /*AttachmentType.Mesh*/, 3 /*AttachmentType.LinkedMesh*/, 4 /*AttachmentType.Path*/, 5 /*AttachmentType.Point*/, 6 /*AttachmentType.Clipping*/]; + SkeletonBinary.TransformModeValues = [exports.TransformMode.Normal, exports.TransformMode.OnlyTranslation, exports.TransformMode.NoRotationOrReflection, exports.TransformMode.NoScale, exports.TransformMode.NoScaleOrReflection]; + SkeletonBinary.PositionModeValues = [exports.PositionMode.Fixed, exports.PositionMode.Percent]; + SkeletonBinary.SpacingModeValues = [SpacingMode$2.Length, SpacingMode$2.Fixed, SpacingMode$2.Percent]; + SkeletonBinary.RotateModeValues = [exports.RotateMode.Tangent, exports.RotateMode.Chain, exports.RotateMode.ChainScale]; + SkeletonBinary.BlendModeValues = [constants.BLEND_MODES.NORMAL, constants.BLEND_MODES.ADD, constants.BLEND_MODES.MULTIPLY, constants.BLEND_MODES.SCREEN]; + SkeletonBinary.BONE_ROTATE = 0; + SkeletonBinary.BONE_TRANSLATE = 1; + SkeletonBinary.BONE_SCALE = 2; + SkeletonBinary.BONE_SHEAR = 3; + SkeletonBinary.SLOT_ATTACHMENT = 0; + SkeletonBinary.SLOT_COLOR = 1; + SkeletonBinary.SLOT_TWO_COLOR = 2; + SkeletonBinary.PATH_POSITION = 0; + SkeletonBinary.PATH_SPACING = 1; + SkeletonBinary.PATH_MIX = 2; + SkeletonBinary.CURVE_LINEAR = 0; + SkeletonBinary.CURVE_STEPPED = 1; + SkeletonBinary.CURVE_BEZIER = 2; + return SkeletonBinary; + }()); + var LinkedMesh$1$1 = /** @class */ (function () { + function LinkedMesh(mesh, skin, slotIndex, parent, inheritDeform) { + this.mesh = mesh; + this.skin = skin; + this.slotIndex = slotIndex; + this.parent = parent; + this.inheritDeform = inheritDeform; + } + return LinkedMesh; + }()); + var Vertices$1 = /** @class */ (function () { + function Vertices(bones, vertices) { + if (bones === void 0) { bones = null; } + if (vertices === void 0) { vertices = null; } + this.bones = bones; + this.vertices = vertices; + } + return Vertices; + }()); + + /** Collects each visible {@link BoundingBoxAttachment} and computes the world vertices for its polygon. The polygon vertices are + * provided along with convenience methods for doing hit detection. + * @public + * */ + var SkeletonBounds$2 = /** @class */ (function (_super) { + __extends$3(SkeletonBounds, _super); + function SkeletonBounds() { + return _super !== null && _super.apply(this, arguments) || this; + } + return SkeletonBounds; + }(SkeletonBoundsBase)); + + /** + * @public + */ + var SkeletonJson$2 = /** @class */ (function () { + function SkeletonJson(attachmentLoader) { + this.scale = 1; + this.linkedMeshes = new Array(); + this.attachmentLoader = attachmentLoader; + } + SkeletonJson.prototype.readSkeletonData = function (json) { + var scale = this.scale; + var skeletonData = new SkeletonData$2(); + var root = typeof (json) === "string" ? JSON.parse(json) : json; + // Skeleton + var skeletonMap = root.skeleton; + if (skeletonMap != null) { + skeletonData.hash = skeletonMap.hash; + skeletonData.version = skeletonMap.spine; + if (skeletonData.version.substr(0, 3) !== '3.8') { + var error = "Spine 3.8 loader cant load version " + skeletonMap.spine + ". Please configure your pixi-spine bundle"; + console.error(error); + } + if (skeletonData.version === '3.8.75') { + var error = "Unsupported skeleton data, 3.8.75 is deprecated, please export with a newer version of Spine."; + console.error(error); + } + skeletonData.x = skeletonMap.x; + skeletonData.y = skeletonMap.y; + skeletonData.width = skeletonMap.width; + skeletonData.height = skeletonMap.height; + skeletonData.fps = skeletonMap.fps; + skeletonData.imagesPath = skeletonMap.images; + } + // Bones + if (root.bones) { + for (var i = 0; i < root.bones.length; i++) { + var boneMap = root.bones[i]; + var parent_1 = null; + var parentName = this.getValue(boneMap, "parent", null); + if (parentName != null) { + parent_1 = skeletonData.findBone(parentName); + if (parent_1 == null) + throw new Error("Parent bone not found: " + parentName); + } + var data = new BoneData$2(skeletonData.bones.length, boneMap.name, parent_1); + data.length = this.getValue(boneMap, "length", 0) * scale; + data.x = this.getValue(boneMap, "x", 0) * scale; + data.y = this.getValue(boneMap, "y", 0) * scale; + data.rotation = this.getValue(boneMap, "rotation", 0); + data.scaleX = this.getValue(boneMap, "scaleX", 1); + data.scaleY = this.getValue(boneMap, "scaleY", 1); + data.shearX = this.getValue(boneMap, "shearX", 0); + data.shearY = this.getValue(boneMap, "shearY", 0); + data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal")); + data.skinRequired = this.getValue(boneMap, "skin", false); + skeletonData.bones.push(data); + } + } + // Slots. + if (root.slots) { + for (var i = 0; i < root.slots.length; i++) { + var slotMap = root.slots[i]; + var slotName = slotMap.name; + var boneName = slotMap.bone; + var boneData = skeletonData.findBone(boneName); + if (boneData == null) + throw new Error("Slot bone not found: " + boneName); + var data = new SlotData$2(skeletonData.slots.length, slotName, boneData); + var color = this.getValue(slotMap, "color", null); + if (color != null) + data.color.setFromString(color); + var dark = this.getValue(slotMap, "dark", null); + if (dark != null) { + data.darkColor = new Color(1, 1, 1, 1); + data.darkColor.setFromString(dark); + } + data.attachmentName = this.getValue(slotMap, "attachment", null); + data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal")); + skeletonData.slots.push(data); + } + } + // IK constraints + if (root.ik) { + for (var i = 0; i < root.ik.length; i++) { + var constraintMap = root.ik[i]; + var data = new IkConstraintData$2(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + data.skinRequired = this.getValue(constraintMap, "skin", false); + for (var j = 0; j < constraintMap.bones.length; j++) { + var boneName = constraintMap.bones[j]; + var bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("IK bone not found: " + boneName); + data.bones.push(bone); + } + var targetName = constraintMap.target; + data.target = skeletonData.findBone(targetName); + if (data.target == null) + throw new Error("IK target bone not found: " + targetName); + data.mix = this.getValue(constraintMap, "mix", 1); + data.softness = this.getValue(constraintMap, "softness", 0) * scale; + data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; + data.compress = this.getValue(constraintMap, "compress", false); + data.stretch = this.getValue(constraintMap, "stretch", false); + data.uniform = this.getValue(constraintMap, "uniform", false); + skeletonData.ikConstraints.push(data); + } + } + // Transform constraints. + if (root.transform) { + for (var i = 0; i < root.transform.length; i++) { + var constraintMap = root.transform[i]; + var data = new TransformConstraintData$2(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + data.skinRequired = this.getValue(constraintMap, "skin", false); + for (var j = 0; j < constraintMap.bones.length; j++) { + var boneName = constraintMap.bones[j]; + var bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("Transform constraint bone not found: " + boneName); + data.bones.push(bone); + } + var targetName = constraintMap.target; + data.target = skeletonData.findBone(targetName); + if (data.target == null) + throw new Error("Transform constraint target bone not found: " + targetName); + data.local = this.getValue(constraintMap, "local", false); + data.relative = this.getValue(constraintMap, "relative", false); + data.offsetRotation = this.getValue(constraintMap, "rotation", 0); + data.offsetX = this.getValue(constraintMap, "x", 0) * scale; + data.offsetY = this.getValue(constraintMap, "y", 0) * scale; + data.offsetScaleX = this.getValue(constraintMap, "scaleX", 0); + data.offsetScaleY = this.getValue(constraintMap, "scaleY", 0); + data.offsetShearY = this.getValue(constraintMap, "shearY", 0); + data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); + data.translateMix = this.getValue(constraintMap, "translateMix", 1); + data.scaleMix = this.getValue(constraintMap, "scaleMix", 1); + data.shearMix = this.getValue(constraintMap, "shearMix", 1); + skeletonData.transformConstraints.push(data); + } + } + // Path constraints. + if (root.path) { + for (var i = 0; i < root.path.length; i++) { + var constraintMap = root.path[i]; + var data = new PathConstraintData$2(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + data.skinRequired = this.getValue(constraintMap, "skin", false); + for (var j = 0; j < constraintMap.bones.length; j++) { + var boneName = constraintMap.bones[j]; + var bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("Transform constraint bone not found: " + boneName); + data.bones.push(bone); + } + var targetName = constraintMap.target; + data.target = skeletonData.findSlot(targetName); + if (data.target == null) + throw new Error("Path target slot not found: " + targetName); + data.positionMode = SkeletonJson.positionModeFromString(this.getValue(constraintMap, "positionMode", "percent")); + data.spacingMode = SkeletonJson.spacingModeFromString(this.getValue(constraintMap, "spacingMode", "length")); + data.rotateMode = SkeletonJson.rotateModeFromString(this.getValue(constraintMap, "rotateMode", "tangent")); + data.offsetRotation = this.getValue(constraintMap, "rotation", 0); + data.position = this.getValue(constraintMap, "position", 0); + if (data.positionMode == exports.PositionMode.Fixed) + data.position *= scale; + data.spacing = this.getValue(constraintMap, "spacing", 0); + if (data.spacingMode == SpacingMode$2.Length || data.spacingMode == SpacingMode$2.Fixed) + data.spacing *= scale; + data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); + data.translateMix = this.getValue(constraintMap, "translateMix", 1); + skeletonData.pathConstraints.push(data); + } + } + // Skins. + if (root.skins) { + for (var i = 0; i < root.skins.length; i++) { + var skinMap = root.skins[i]; + var skin = new Skin$2(skinMap.name); + if (skinMap.bones) { + for (var ii = 0; ii < skinMap.bones.length; ii++) { + var bone = skeletonData.findBone(skinMap.bones[ii]); + if (bone == null) + throw new Error("Skin bone not found: " + skinMap.bones[i]); + skin.bones.push(bone); + } + } + if (skinMap.ik) { + for (var ii = 0; ii < skinMap.ik.length; ii++) { + var constraint = skeletonData.findIkConstraint(skinMap.ik[ii]); + if (constraint == null) + throw new Error("Skin IK constraint not found: " + skinMap.ik[i]); + skin.constraints.push(constraint); + } + } + if (skinMap.transform) { + for (var ii = 0; ii < skinMap.transform.length; ii++) { + var constraint = skeletonData.findTransformConstraint(skinMap.transform[ii]); + if (constraint == null) + throw new Error("Skin transform constraint not found: " + skinMap.transform[i]); + skin.constraints.push(constraint); + } + } + if (skinMap.path) { + for (var ii = 0; ii < skinMap.path.length; ii++) { + var constraint = skeletonData.findPathConstraint(skinMap.path[ii]); + if (constraint == null) + throw new Error("Skin path constraint not found: " + skinMap.path[i]); + skin.constraints.push(constraint); + } + } + for (var slotName in skinMap.attachments) { + var slot = skeletonData.findSlot(slotName); + if (slot == null) + throw new Error("Slot not found: " + slotName); + var slotMap = skinMap.attachments[slotName]; + for (var entryName in slotMap) { + var attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData); + if (attachment != null) + skin.setAttachment(slot.index, entryName, attachment); + } + } + skeletonData.skins.push(skin); + if (skin.name == "default") + skeletonData.defaultSkin = skin; + } + } + // Linked meshes. + for (var i = 0, n = this.linkedMeshes.length; i < n; i++) { + var linkedMesh = this.linkedMeshes[i]; + var skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); + if (skin == null) + throw new Error("Skin not found: " + linkedMesh.skin); + var parent_2 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (parent_2 == null) + throw new Error("Parent mesh not found: " + linkedMesh.parent); + linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent_2 : linkedMesh.mesh; + linkedMesh.mesh.setParentMesh(parent_2); + // linkedMesh.mesh.updateUVs(); + } + this.linkedMeshes.length = 0; + // Events. + if (root.events) { + for (var eventName in root.events) { + var eventMap = root.events[eventName]; + var data = new EventData$2(eventName); + data.intValue = this.getValue(eventMap, "int", 0); + data.floatValue = this.getValue(eventMap, "float", 0); + data.stringValue = this.getValue(eventMap, "string", ""); + data.audioPath = this.getValue(eventMap, "audio", null); + if (data.audioPath != null) { + data.volume = this.getValue(eventMap, "volume", 1); + data.balance = this.getValue(eventMap, "balance", 0); + } + skeletonData.events.push(data); + } + } + // Animations. + if (root.animations) { + for (var animationName in root.animations) { + var animationMap = root.animations[animationName]; + this.readAnimation(animationMap, animationName, skeletonData); + } + } + return skeletonData; + }; + SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) { + var scale = this.scale; + name = this.getValue(map, "name", name); + var type = this.getValue(map, "type", "region"); + switch (type) { + case "region": { + var path = this.getValue(map, "path", name); + var region = this.attachmentLoader.newRegionAttachment(skin, name, path); + if (region == null) + return null; + region.path = path; + region.x = this.getValue(map, "x", 0) * scale; + region.y = this.getValue(map, "y", 0) * scale; + region.scaleX = this.getValue(map, "scaleX", 1); + region.scaleY = this.getValue(map, "scaleY", 1); + region.rotation = this.getValue(map, "rotation", 0); + region.width = map.width * scale; + region.height = map.height * scale; + var color = this.getValue(map, "color", null); + if (color != null) + region.color.setFromString(color); + // region.updateOffset(); + return region; + } + case "boundingbox": { + var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (box == null) + return null; + this.readVertices(map, box, map.vertexCount << 1); + var color = this.getValue(map, "color", null); + if (color != null) + box.color.setFromString(color); + return box; + } + case "mesh": + case "linkedmesh": { + var path = this.getValue(map, "path", name); + var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); + if (mesh == null) + return null; + mesh.path = path; + var color = this.getValue(map, "color", null); + if (color != null) + mesh.color.setFromString(color); + mesh.width = this.getValue(map, "width", 0) * scale; + mesh.height = this.getValue(map, "height", 0) * scale; + var parent_3 = this.getValue(map, "parent", null); + if (parent_3 != null) { + this.linkedMeshes.push(new LinkedMesh$3(mesh, this.getValue(map, "skin", null), slotIndex, parent_3, this.getValue(map, "deform", true))); + return mesh; + } + var uvs = map.uvs; + this.readVertices(map, mesh, uvs.length); + mesh.triangles = map.triangles; + mesh.regionUVs = new Float32Array(uvs); + // mesh.updateUVs(); + mesh.edges = this.getValue(map, "edges", null); + mesh.hullLength = this.getValue(map, "hull", 0) * 2; + return mesh; + } + case "path": { + var path = this.attachmentLoader.newPathAttachment(skin, name); + if (path == null) + return null; + path.closed = this.getValue(map, "closed", false); + path.constantSpeed = this.getValue(map, "constantSpeed", true); + var vertexCount = map.vertexCount; + this.readVertices(map, path, vertexCount << 1); + var lengths = Utils.newArray(vertexCount / 3, 0); + for (var i = 0; i < map.lengths.length; i++) + lengths[i] = map.lengths[i] * scale; + path.lengths = lengths; + var color = this.getValue(map, "color", null); + if (color != null) + path.color.setFromString(color); + return path; + } + case "point": { + var point = this.attachmentLoader.newPointAttachment(skin, name); + if (point == null) + return null; + point.x = this.getValue(map, "x", 0) * scale; + point.y = this.getValue(map, "y", 0) * scale; + point.rotation = this.getValue(map, "rotation", 0); + var color = this.getValue(map, "color", null); + if (color != null) + point.color.setFromString(color); + return point; + } + case "clipping": { + var clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (clip == null) + return null; + var end = this.getValue(map, "end", null); + if (end != null) { + var slot = skeletonData.findSlot(end); + if (slot == null) + throw new Error("Clipping end slot not found: " + end); + clip.endSlot = slot; + } + var vertexCount = map.vertexCount; + this.readVertices(map, clip, vertexCount << 1); + var color = this.getValue(map, "color", null); + if (color != null) + clip.color.setFromString(color); + return clip; + } + } + return null; + }; + SkeletonJson.prototype.readVertices = function (map, attachment, verticesLength) { + var scale = this.scale; + attachment.worldVerticesLength = verticesLength; + var vertices = map.vertices; + if (verticesLength == vertices.length) { + var scaledVertices = Utils.toFloatArray(vertices); + if (scale != 1) { + for (var i = 0, n = vertices.length; i < n; i++) + scaledVertices[i] *= scale; + } + attachment.vertices = scaledVertices; + return; + } + var weights = new Array(); + var bones = new Array(); + for (var i = 0, n = vertices.length; i < n;) { + var boneCount = vertices[i++]; + bones.push(boneCount); + for (var nn = i + boneCount * 4; i < nn; i += 4) { + bones.push(vertices[i]); + weights.push(vertices[i + 1] * scale); + weights.push(vertices[i + 2] * scale); + weights.push(vertices[i + 3]); + } + } + attachment.bones = bones; + attachment.vertices = Utils.toFloatArray(weights); + }; + SkeletonJson.prototype.readAnimation = function (map, name, skeletonData) { + var scale = this.scale; + var timelines = new Array(); + var duration = 0; + // Slot timelines. + if (map.slots) { + for (var slotName in map.slots) { + var slotMap = map.slots[slotName]; + var slotIndex = skeletonData.findSlotIndex(slotName); + if (slotIndex == -1) + throw new Error("Slot not found: " + slotName); + for (var timelineName in slotMap) { + var timelineMap = slotMap[timelineName]; + if (timelineName == "attachment") { + var timeline = new AttachmentTimeline$2(timelineMap.length); + timeline.slotIndex = slotIndex; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + else if (timelineName == "color") { + var timeline = new ColorTimeline$1(timelineMap.length); + timeline.slotIndex = slotIndex; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + var color = new Color(); + color.setFromString(valueMap.color || "ffffffff"); + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * ColorTimeline$1.ENTRIES]); + } + else if (timelineName == "twoColor") { + var timeline = new TwoColorTimeline$1(timelineMap.length); + timeline.slotIndex = slotIndex; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + var light = new Color(); + var dark = new Color(); + light.setFromString(valueMap.light); + dark.setFromString(valueMap.dark); + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TwoColorTimeline$1.ENTRIES]); + } + else + throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); + } + } + } + // Bone timelines. + if (map.bones) { + for (var boneName in map.bones) { + var boneMap = map.bones[boneName]; + var boneIndex = skeletonData.findBoneIndex(boneName); + if (boneIndex == -1) + throw new Error("Bone not found: " + boneName); + for (var timelineName in boneMap) { + var timelineMap = boneMap[timelineName]; + if (timelineName === "rotate") { + var timeline = new RotateTimeline$2(timelineMap.length); + timeline.boneIndex = boneIndex; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * RotateTimeline$2.ENTRIES]); + } + else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") { + var timeline = null; + var timelineScale = 1, defaultValue = 0; + if (timelineName === "scale") { + timeline = new ScaleTimeline$2(timelineMap.length); + defaultValue = 1; + } + else if (timelineName === "shear") + timeline = new ShearTimeline$2(timelineMap.length); + else { + timeline = new TranslateTimeline$2(timelineMap.length); + timelineScale = scale; + } + timeline.boneIndex = boneIndex; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + var x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue); + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TranslateTimeline$2.ENTRIES]); + } + else + throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); + } + } + } + // IK constraint timelines. + if (map.ik) { + for (var constraintName in map.ik) { + var constraintMap = map.ik[constraintName]; + var constraint = skeletonData.findIkConstraint(constraintName); + var timeline = new IkConstraintTimeline$2(constraintMap.length); + timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(constraint); + var frameIndex = 0; + for (var i = 0; i < constraintMap.length; i++) { + var valueMap = constraintMap[i]; + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "softness", 0) * scale, this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * IkConstraintTimeline$2.ENTRIES]); + } + } + // Transform constraint timelines. + if (map.transform) { + for (var constraintName in map.transform) { + var constraintMap = map.transform[constraintName]; + var constraint = skeletonData.findTransformConstraint(constraintName); + var timeline = new TransformConstraintTimeline$2(constraintMap.length); + timeline.transformConstraintIndex = skeletonData.transformConstraints.indexOf(constraint); + var frameIndex = 0; + for (var i = 0; i < constraintMap.length; i++) { + var valueMap = constraintMap[i]; + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TransformConstraintTimeline$2.ENTRIES]); + } + } + // Path constraint timelines. + if (map.path) { + for (var constraintName in map.path) { + var constraintMap = map.path[constraintName]; + var index = skeletonData.findPathConstraintIndex(constraintName); + if (index == -1) + throw new Error("Path constraint not found: " + constraintName); + var data = skeletonData.pathConstraints[index]; + for (var timelineName in constraintMap) { + var timelineMap = constraintMap[timelineName]; + if (timelineName === "position" || timelineName === "spacing") { + var timeline = null; + var timelineScale = 1; + if (timelineName === "spacing") { + timeline = new PathConstraintSpacingTimeline$2(timelineMap.length); + if (data.spacingMode == SpacingMode$2.Length || data.spacingMode == SpacingMode$2.Fixed) + timelineScale = scale; + } + else { + timeline = new PathConstraintPositionTimeline$2(timelineMap.length); + if (data.positionMode == exports.PositionMode.Fixed) + timelineScale = scale; + } + timeline.pathConstraintIndex = index; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * PathConstraintPositionTimeline$2.ENTRIES]); + } + else if (timelineName === "mix") { + var timeline = new PathConstraintMixTimeline$2(timelineMap.length); + timeline.pathConstraintIndex = index; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * PathConstraintMixTimeline$2.ENTRIES]); + } + } + } + } + // Deform timelines. + if (map.deform) { + for (var deformName in map.deform) { + var deformMap = map.deform[deformName]; + var skin = skeletonData.findSkin(deformName); + if (skin == null) { + if (settings.FAIL_ON_NON_EXISTING_SKIN) { + throw new Error("Skin not found: " + deformName); + } + else { + continue; + } + } + for (var slotName in deformMap) { + var slotMap = deformMap[slotName]; + var slotIndex = skeletonData.findSlotIndex(slotName); + if (slotIndex == -1) + throw new Error("Slot not found: " + slotMap.name); + for (var timelineName in slotMap) { + var timelineMap = slotMap[timelineName]; + var attachment = skin.getAttachment(slotIndex, timelineName); + if (attachment == null) + throw new Error("Deform attachment not found: " + timelineMap.name); + var weighted = attachment.bones != null; + var vertices = attachment.vertices; + var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + var timeline = new DeformTimeline$2(timelineMap.length); + timeline.slotIndex = slotIndex; + timeline.attachment = attachment; + var frameIndex = 0; + for (var j = 0; j < timelineMap.length; j++) { + var valueMap = timelineMap[j]; + var deform = void 0; + var verticesValue = this.getValue(valueMap, "vertices", null); + if (verticesValue == null) + deform = weighted ? Utils.newFloatArray(deformLength) : vertices; + else { + deform = Utils.newFloatArray(deformLength); + var start = this.getValue(valueMap, "offset", 0); + Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); + if (scale != 1) { + for (var i = start, n = i + verticesValue.length; i < n; i++) + deform[i] *= scale; + } + if (!weighted) { + for (var i = 0; i < deformLength; i++) + deform[i] += vertices[i]; + } + } + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + } + } + } + // Draw order timeline. + var drawOrderNode = map.drawOrder; + if (drawOrderNode == null) + drawOrderNode = map.draworder; + if (drawOrderNode != null) { + var timeline = new DrawOrderTimeline$2(drawOrderNode.length); + var slotCount = skeletonData.slots.length; + var frameIndex = 0; + for (var j = 0; j < drawOrderNode.length; j++) { + var drawOrderMap = drawOrderNode[j]; + var drawOrder = null; + var offsets = this.getValue(drawOrderMap, "offsets", null); + if (offsets != null) { + drawOrder = Utils.newArray(slotCount, -1); + var unchanged = Utils.newArray(slotCount - offsets.length, 0); + var originalIndex = 0, unchangedIndex = 0; + for (var i = 0; i < offsets.length; i++) { + var offsetMap = offsets[i]; + var slotIndex = skeletonData.findSlotIndex(offsetMap.slot); + if (slotIndex == -1) + throw new Error("Slot not found: " + offsetMap.slot); + // Collect unchanged items. + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + // Set changed items. + drawOrder[originalIndex + offsetMap.offset] = originalIndex++; + } + // Collect remaining unchanged items. + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + // Fill in unchanged items. + for (var i = slotCount - 1; i >= 0; i--) + if (drawOrder[i] == -1) + drawOrder[i] = unchanged[--unchangedIndex]; + } + timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + // Event timeline. + if (map.events) { + var timeline = new EventTimeline$2(map.events.length); + var frameIndex = 0; + for (var i = 0; i < map.events.length; i++) { + var eventMap = map.events[i]; + var eventData = skeletonData.findEvent(eventMap.name); + if (eventData == null) + throw new Error("Event not found: " + eventMap.name); + var event_1 = new Event$2(Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData); + event_1.intValue = this.getValue(eventMap, "int", eventData.intValue); + event_1.floatValue = this.getValue(eventMap, "float", eventData.floatValue); + event_1.stringValue = this.getValue(eventMap, "string", eventData.stringValue); + if (event_1.data.audioPath != null) { + event_1.volume = this.getValue(eventMap, "volume", 1); + event_1.balance = this.getValue(eventMap, "balance", 0); + } + timeline.setFrame(frameIndex++, event_1); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + if (isNaN(duration)) { + throw new Error("Error while parsing animation, duration is NaN"); + } + skeletonData.animations.push(new Animation$2(name, timelines, duration)); + }; + SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) { + if (!map.hasOwnProperty("curve")) + return; + if (map.curve === "stepped") + timeline.setStepped(frameIndex); + else { + var curve = map.curve; + timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1)); + } + }; + SkeletonJson.prototype.getValue = function (map, prop, defaultValue) { + return map[prop] !== undefined ? map[prop] : defaultValue; + }; + SkeletonJson.blendModeFromString = function (str) { + str = str.toLowerCase(); + if (str == "normal") + return constants.BLEND_MODES.NORMAL; + if (str == "additive") + return constants.BLEND_MODES.ADD; + if (str == "multiply") + return constants.BLEND_MODES.MULTIPLY; + if (str == "screen") + return constants.BLEND_MODES.SCREEN; + throw new Error("Unknown blend mode: " + str); + }; + SkeletonJson.positionModeFromString = function (str) { + str = str.toLowerCase(); + if (str == "fixed") + return exports.PositionMode.Fixed; + if (str == "percent") + return exports.PositionMode.Percent; + throw new Error("Unknown position mode: " + str); + }; + SkeletonJson.spacingModeFromString = function (str) { + str = str.toLowerCase(); + if (str == "length") + return SpacingMode$2.Length; + if (str == "fixed") + return SpacingMode$2.Fixed; + if (str == "percent") + return SpacingMode$2.Percent; + throw new Error("Unknown position mode: " + str); + }; + SkeletonJson.rotateModeFromString = function (str) { + str = str.toLowerCase(); + if (str == "tangent") + return exports.RotateMode.Tangent; + if (str == "chain") + return exports.RotateMode.Chain; + if (str == "chainscale") + return exports.RotateMode.ChainScale; + throw new Error("Unknown rotate mode: " + str); + }; + SkeletonJson.transformModeFromString = function (str) { + str = str.toLowerCase(); + if (str == "normal") + return exports.TransformMode.Normal; + if (str == "onlytranslation") + return exports.TransformMode.OnlyTranslation; + if (str == "norotationorreflection") + return exports.TransformMode.NoRotationOrReflection; + if (str == "noscale") + return exports.TransformMode.NoScale; + if (str == "noscaleorreflection") + return exports.TransformMode.NoScaleOrReflection; + throw new Error("Unknown transform mode: " + str); + }; + return SkeletonJson; + }()); + var LinkedMesh$3 = /** @class */ (function () { + function LinkedMesh(mesh, skin, slotIndex, parent, inheritDeform) { + this.mesh = mesh; + this.skin = skin; + this.slotIndex = slotIndex; + this.parent = parent; + this.inheritDeform = inheritDeform; + } + return LinkedMesh; + }()); + + /** + * @public + */ + var Spine$3 = /** @class */ (function (_super) { + __extends$3(Spine, _super); + function Spine() { + return _super !== null && _super.apply(this, arguments) || this; + } + Spine.prototype.createSkeleton = function (spineData) { + this.skeleton = new Skeleton$2(spineData); + this.skeleton.updateWorldTransform(); + this.stateData = new AnimationStateData$2(spineData); + this.state = new AnimationState$2(this.stateData); + }; + return Spine; + }(SpineBase)); + + var spine38 = /*#__PURE__*/Object.freeze({ + __proto__: null, + Animation: Animation$2, + AnimationState: AnimationState$2, + AnimationStateAdapter: AnimationStateAdapter$1, + AnimationStateData: AnimationStateData$2, + AtlasAttachmentLoader: AtlasAttachmentLoader$2, + Attachment: Attachment$2, + AttachmentTimeline: AttachmentTimeline$2, + Bone: Bone$2, + BoneData: BoneData$2, + BoundingBoxAttachment: BoundingBoxAttachment$2, + ClippingAttachment: ClippingAttachment$2, + ColorTimeline: ColorTimeline$1, + ConstraintData: ConstraintData$1, + CurveTimeline: CurveTimeline$2, + DeformTimeline: DeformTimeline$2, + DrawOrderTimeline: DrawOrderTimeline$2, + Event: Event$2, + EventData: EventData$2, + EventQueue: EventQueue$2, + EventTimeline: EventTimeline$2, + get EventType () { return EventType$2; }, + IkConstraint: IkConstraint$2, + IkConstraintData: IkConstraintData$2, + IkConstraintTimeline: IkConstraintTimeline$2, + JitterEffect: JitterEffect$1, + MeshAttachment: MeshAttachment$2, + PathAttachment: PathAttachment$2, + PathConstraint: PathConstraint$2, + PathConstraintData: PathConstraintData$2, + PathConstraintMixTimeline: PathConstraintMixTimeline$2, + PathConstraintPositionTimeline: PathConstraintPositionTimeline$2, + PathConstraintSpacingTimeline: PathConstraintSpacingTimeline$2, + PointAttachment: PointAttachment$2, + RegionAttachment: RegionAttachment$2, + RotateTimeline: RotateTimeline$2, + ScaleTimeline: ScaleTimeline$2, + ShearTimeline: ShearTimeline$2, + Skeleton: Skeleton$2, + SkeletonBinary: SkeletonBinary$1, + SkeletonBounds: SkeletonBounds$2, + SkeletonData: SkeletonData$2, + SkeletonJson: SkeletonJson$2, + Skin: Skin$2, + SkinEntry: SkinEntry$1, + Slot: Slot$2, + SlotData: SlotData$2, + get SpacingMode () { return SpacingMode$2; }, + Spine: Spine$3, + SwirlEffect: SwirlEffect$1, + get TimelineType () { return TimelineType$1; }, + TrackEntry: TrackEntry$2, + TransformConstraint: TransformConstraint$2, + TransformConstraintData: TransformConstraintData$2, + TransformConstraintTimeline: TransformConstraintTimeline$2, + TranslateTimeline: TranslateTimeline$2, + TwoColorTimeline: TwoColorTimeline$1, + VertexAttachment: VertexAttachment$2 + }); + + /* eslint-disable */ + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + var extendStatics$2 = function(d, b) { + extendStatics$2 = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics$2(d, b); + }; + + function __extends$2(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics$2(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + + /** + * @public + */ + var Attachment$1 = /** @class */ (function () { + function Attachment(name) { + if (name == null) + throw new Error("name cannot be null."); + this.name = name; + } + return Attachment; + }()); + /** + * @public + */ + var VertexAttachment$1 = /** @class */ (function (_super) { + __extends$2(VertexAttachment, _super); + function VertexAttachment(name) { + var _this = _super.call(this, name) || this; + _this.id = (VertexAttachment.nextID++ & 65535) << 11; + _this.worldVerticesLength = 0; + return _this; + } + VertexAttachment.prototype.computeWorldVerticesOld = function (slot, worldVertices) { + this.computeWorldVertices(slot, 0, this.worldVerticesLength, worldVertices, 0, 2); + }; + /** Transforms local vertices to world coordinates. + * @param start The index of the first local vertex value to transform. Each vertex has 2 values, x and y. + * @param count The number of world vertex values to output. Must be <= {@link #getWorldVerticesLength()} - start. + * @param worldVertices The output world vertices. Must have a length >= offset + count. + * @param offset The worldVertices index to begin writing values. */ + VertexAttachment.prototype.computeWorldVertices = function (slot, start, count, worldVertices, offset, stride) { + count = offset + (count >> 1) * stride; + var skeleton = slot.bone.skeleton; + var deformArray = slot.attachmentVertices; + var vertices = this.vertices; + var bones = this.bones; + if (bones == null) { + if (deformArray.length > 0) + vertices = deformArray; + var mat = slot.bone.matrix; + var x = mat.tx; + var y = mat.ty; + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + for (var v_1 = start, w = offset; w < count; v_1 += 2, w += stride) { + var vx = vertices[v_1], vy = vertices[v_1 + 1]; + worldVertices[w] = vx * a + vy * b + x; + worldVertices[w + 1] = vx * c + vy * d + y; + } + return; + } + var v = 0, skip = 0; + for (var i = 0; i < start; i += 2) { + var n = bones[v]; + v += n + 1; + skip += n; + } + var skeletonBones = skeleton.bones; + if (deformArray.length == 0) { + for (var w = offset, b = skip * 3; w < count; w += stride) { + var wx = 0, wy = 0; + var n = bones[v++]; + n += v; + for (; v < n; v++, b += 3) { + var mat = skeletonBones[bones[v]].matrix; + var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; + wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; + wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + else { + var deform = deformArray; + for (var w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { + var wx = 0, wy = 0; + var n = bones[v++]; + n += v; + for (; v < n; v++, b += 3, f += 2) { + var mat = skeletonBones[bones[v]].matrix; + var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; + wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; + wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + }; + /** Returns true if a deform originally applied to the specified attachment should be applied to this attachment. */ + VertexAttachment.prototype.applyDeform = function (sourceAttachment) { + return this == sourceAttachment; + }; + VertexAttachment.nextID = 0; + return VertexAttachment; + }(Attachment$1)); + + /** + * @public + */ + var BoundingBoxAttachment$1 = /** @class */ (function (_super) { + __extends$2(BoundingBoxAttachment, _super); + function BoundingBoxAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.BoundingBox; + _this.color = new Color(1, 1, 1, 1); + return _this; + } + return BoundingBoxAttachment; + }(VertexAttachment$1)); + + /** + * @public + */ + var ClippingAttachment$1 = /** @class */ (function (_super) { + __extends$2(ClippingAttachment, _super); + function ClippingAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Clipping; + // Nonessential. + _this.color = new Color(0.2275, 0.2275, 0.8078, 1); // ce3a3aff + return _this; + } + return ClippingAttachment; + }(VertexAttachment$1)); + + /** + * @public + */ + var MeshAttachment$1 = /** @class */ (function (_super) { + __extends$2(MeshAttachment, _super); + function MeshAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Mesh; + _this.color = new Color(1, 1, 1, 1); + _this.inheritDeform = false; + _this.tempColor = new Color(0, 0, 0, 0); + return _this; + } + MeshAttachment.prototype.applyDeform = function (sourceAttachment) { + return this == sourceAttachment || (this.inheritDeform && this.parentMesh == sourceAttachment); + }; + MeshAttachment.prototype.getParentMesh = function () { + return this.parentMesh; + }; + /** @param parentMesh May be null. */ + MeshAttachment.prototype.setParentMesh = function (parentMesh) { + this.parentMesh = parentMesh; + if (parentMesh != null) { + this.bones = parentMesh.bones; + this.vertices = parentMesh.vertices; + this.worldVerticesLength = parentMesh.worldVerticesLength; + this.regionUVs = parentMesh.regionUVs; + this.triangles = parentMesh.triangles; + this.hullLength = parentMesh.hullLength; + this.worldVerticesLength = parentMesh.worldVerticesLength; + } + }; + return MeshAttachment; + }(VertexAttachment$1)); + + /** + * @public + */ + var PathAttachment$1 = /** @class */ (function (_super) { + __extends$2(PathAttachment, _super); + function PathAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Path; + _this.closed = false; + _this.constantSpeed = false; + _this.color = new Color(1, 1, 1, 1); + return _this; + } + return PathAttachment; + }(VertexAttachment$1)); + + /** + * @public + */ + var PointAttachment$1 = /** @class */ (function (_super) { + __extends$2(PointAttachment, _super); + function PointAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Point; + _this.color = new Color(0.38, 0.94, 0, 1); + return _this; + } + PointAttachment.prototype.computeWorldPosition = function (bone, point) { + var mat = bone.matrix; + point.x = this.x * mat.a + this.y * mat.c + bone.worldX; + point.y = this.x * mat.b + this.y * mat.d + bone.worldY; + return point; + }; + PointAttachment.prototype.computeWorldRotation = function (bone) { + var mat = bone.matrix; + var cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation); + var x = cos * mat.a + sin * mat.c; + var y = cos * mat.b + sin * mat.d; + return Math.atan2(y, x) * MathUtils.radDeg; + }; + return PointAttachment; + }(VertexAttachment$1)); + + /** + * @public + */ + var Slot$1 = /** @class */ (function () { + function Slot(data, bone) { + this.attachmentVertices = new Array(); + if (data == null) + throw new Error("data cannot be null."); + if (bone == null) + throw new Error("bone cannot be null."); + this.data = data; + this.bone = bone; + this.color = new Color(); + this.darkColor = data.darkColor == null ? null : new Color(); + this.setToSetupPose(); + this.blendMode = this.data.blendMode; + } + /** @return May be null. */ + Slot.prototype.getAttachment = function () { + return this.attachment; + }; + /** Sets the attachment and if it changed, resets {@link #getAttachmentTime()} and clears {@link #getAttachmentVertices()}. + * @param attachment May be null. */ + Slot.prototype.setAttachment = function (attachment) { + if (this.attachment == attachment) + return; + this.attachment = attachment; + this.attachmentTime = this.bone.skeleton.time; + this.attachmentVertices.length = 0; + }; + Slot.prototype.setAttachmentTime = function (time) { + this.attachmentTime = this.bone.skeleton.time - time; + }; + /** Returns the time since the attachment was set. */ + Slot.prototype.getAttachmentTime = function () { + return this.bone.skeleton.time - this.attachmentTime; + }; + Slot.prototype.setToSetupPose = function () { + this.color.setFromColor(this.data.color); + if (this.darkColor != null) + this.darkColor.setFromColor(this.data.darkColor); + if (this.data.attachmentName == null) + this.attachment = null; + else { + this.attachment = null; + this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName)); + } + }; + return Slot; + }()); + + /** + * @public + */ + var RegionAttachment$1 = /** @class */ (function (_super) { + __extends$2(RegionAttachment, _super); + function RegionAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Region; + _this.x = 0; + _this.y = 0; + _this.scaleX = 1; + _this.scaleY = 1; + _this.rotation = 0; + _this.width = 0; + _this.height = 0; + _this.color = new Color(1, 1, 1, 1); + _this.offset = Utils.newFloatArray(8); + _this.uvs = Utils.newFloatArray(8); + _this.tempColor = new Color(1, 1, 1, 1); + return _this; + } + RegionAttachment.prototype.updateOffset = function () { + var regionScaleX = this.width / this.region.originalWidth * this.scaleX; + var regionScaleY = this.height / this.region.originalHeight * this.scaleY; + var localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; + var localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; + var localX2 = localX + this.region.width * regionScaleX; + var localY2 = localY + this.region.height * regionScaleY; + var radians = this.rotation * Math.PI / 180; + var cos = Math.cos(radians); + var sin = Math.sin(radians); + var localXCos = localX * cos + this.x; + var localXSin = localX * sin; + var localYCos = localY * cos + this.y; + var localYSin = localY * sin; + var localX2Cos = localX2 * cos + this.x; + var localX2Sin = localX2 * sin; + var localY2Cos = localY2 * cos + this.y; + var localY2Sin = localY2 * sin; + var offset = this.offset; + offset[RegionAttachment.OX1] = localXCos - localYSin; + offset[RegionAttachment.OY1] = localYCos + localXSin; + offset[RegionAttachment.OX2] = localXCos - localY2Sin; + offset[RegionAttachment.OY2] = localY2Cos + localXSin; + offset[RegionAttachment.OX3] = localX2Cos - localY2Sin; + offset[RegionAttachment.OY3] = localY2Cos + localX2Sin; + offset[RegionAttachment.OX4] = localX2Cos - localYSin; + offset[RegionAttachment.OY4] = localYCos + localX2Sin; + }; + RegionAttachment.prototype.setRegion = function (region) { + this.region = region; + var uvs = this.uvs; + if (region.rotate) { + uvs[2] = region.u; + uvs[3] = region.v2; + uvs[4] = region.u; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v; + uvs[0] = region.u2; + uvs[1] = region.v2; + } + else { + uvs[0] = region.u; + uvs[1] = region.v2; + uvs[2] = region.u; + uvs[3] = region.v; + uvs[4] = region.u2; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v2; + } + }; + RegionAttachment.prototype.computeWorldVertices = function (bone, worldVertices, offset, stride) { + var vertexOffset = this.offset; + var mat = bone instanceof Slot$1 ? bone.bone.matrix : bone.matrix; + var x = mat.tx, y = mat.ty; + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var offsetX = 0, offsetY = 0; + offsetX = vertexOffset[RegionAttachment.OX1]; + offsetY = vertexOffset[RegionAttachment.OY1]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // br + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX2]; + offsetY = vertexOffset[RegionAttachment.OY2]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // bl + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX3]; + offsetY = vertexOffset[RegionAttachment.OY3]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // ul + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX4]; + offsetY = vertexOffset[RegionAttachment.OY4]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // ur + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + }; + RegionAttachment.OX1 = 0; + RegionAttachment.OY1 = 1; + RegionAttachment.OX2 = 2; + RegionAttachment.OY2 = 3; + RegionAttachment.OX3 = 4; + RegionAttachment.OY3 = 5; + RegionAttachment.OX4 = 6; + RegionAttachment.OY4 = 7; + RegionAttachment.X1 = 0; + RegionAttachment.Y1 = 1; + RegionAttachment.C1R = 2; + RegionAttachment.C1G = 3; + RegionAttachment.C1B = 4; + RegionAttachment.C1A = 5; + RegionAttachment.U1 = 6; + RegionAttachment.V1 = 7; + RegionAttachment.X2 = 8; + RegionAttachment.Y2 = 9; + RegionAttachment.C2R = 10; + RegionAttachment.C2G = 11; + RegionAttachment.C2B = 12; + RegionAttachment.C2A = 13; + RegionAttachment.U2 = 14; + RegionAttachment.V2 = 15; + RegionAttachment.X3 = 16; + RegionAttachment.Y3 = 17; + RegionAttachment.C3R = 18; + RegionAttachment.C3G = 19; + RegionAttachment.C3B = 20; + RegionAttachment.C3A = 21; + RegionAttachment.U3 = 22; + RegionAttachment.V3 = 23; + RegionAttachment.X4 = 24; + RegionAttachment.Y4 = 25; + RegionAttachment.C4R = 26; + RegionAttachment.C4G = 27; + RegionAttachment.C4B = 28; + RegionAttachment.C4A = 29; + RegionAttachment.U4 = 30; + RegionAttachment.V4 = 31; + return RegionAttachment; + }(Attachment$1)); + + /** + * @public + */ + var JitterEffect = /** @class */ (function () { + function JitterEffect(jitterX, jitterY) { + this.jitterX = 0; + this.jitterY = 0; + this.jitterX = jitterX; + this.jitterY = jitterY; + } + JitterEffect.prototype.begin = function (skeleton) { + }; + JitterEffect.prototype.transform = function (position, uv, light, dark) { + position.x += MathUtils.randomTriangular(-this.jitterX, this.jitterY); + position.y += MathUtils.randomTriangular(-this.jitterX, this.jitterY); + }; + JitterEffect.prototype.end = function () { + }; + return JitterEffect; + }()); + + /** + * @public + */ + var SwirlEffect = /** @class */ (function () { + function SwirlEffect(radius) { + this.centerX = 0; + this.centerY = 0; + this.radius = 0; + this.angle = 0; + this.worldX = 0; + this.worldY = 0; + this.radius = radius; + } + SwirlEffect.prototype.begin = function (skeleton) { + this.worldX = skeleton.x + this.centerX; + this.worldY = skeleton.y + this.centerY; + }; + SwirlEffect.prototype.transform = function (position, uv, light, dark) { + var radAngle = this.angle * MathUtils.degreesToRadians; + var x = position.x - this.worldX; + var y = position.y - this.worldY; + var dist = Math.sqrt(x * x + y * y); + if (dist < this.radius) { + var theta = SwirlEffect.interpolation.apply(0, radAngle, (this.radius - dist) / this.radius); + var cos = Math.cos(theta); + var sin = Math.sin(theta); + position.x = cos * x - sin * y + this.worldX; + position.y = sin * x + cos * y + this.worldY; + } + }; + SwirlEffect.prototype.end = function () { + }; + SwirlEffect.interpolation = new PowOut(2); + return SwirlEffect; + }()); + + /** + * @public + */ + var Animation$1 = /** @class */ (function () { + function Animation(name, timelines, duration) { + if (name == null) + throw new Error("name cannot be null."); + if (timelines == null) + throw new Error("timelines cannot be null."); + this.name = name; + this.timelines = timelines; + this.duration = duration; + } + Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, blend, direction) { + if (skeleton == null) + throw new Error("skeleton cannot be null."); + if (loop && this.duration != 0) { + time %= this.duration; + if (lastTime > 0) + lastTime %= this.duration; + } + var timelines = this.timelines; + for (var i = 0, n = timelines.length; i < n; i++) + timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction); + }; + Animation.binarySearch = function (values, target, step) { + if (step === void 0) { step = 1; } + var low = 0; + var high = values.length / step - 2; + if (high == 0) + return step; + var current = high >>> 1; + while (true) { + if (values[(current + 1) * step] <= target) + low = current + 1; + else + high = current; + if (low == high) + return (low + 1) * step; + current = (low + high) >>> 1; + } + }; + Animation.linearSearch = function (values, target, step) { + for (var i = 0, last = values.length - step; i <= last; i += step) + if (values[i] > target) + return i; + return -1; + }; + return Animation; + }()); + /** + * @public + */ + var TimelineType; + (function (TimelineType) { + TimelineType[TimelineType["rotate"] = 0] = "rotate"; + TimelineType[TimelineType["translate"] = 1] = "translate"; + TimelineType[TimelineType["scale"] = 2] = "scale"; + TimelineType[TimelineType["shear"] = 3] = "shear"; + TimelineType[TimelineType["attachment"] = 4] = "attachment"; + TimelineType[TimelineType["color"] = 5] = "color"; + TimelineType[TimelineType["deform"] = 6] = "deform"; + TimelineType[TimelineType["event"] = 7] = "event"; + TimelineType[TimelineType["drawOrder"] = 8] = "drawOrder"; + TimelineType[TimelineType["ikConstraint"] = 9] = "ikConstraint"; + TimelineType[TimelineType["transformConstraint"] = 10] = "transformConstraint"; + TimelineType[TimelineType["pathConstraintPosition"] = 11] = "pathConstraintPosition"; + TimelineType[TimelineType["pathConstraintSpacing"] = 12] = "pathConstraintSpacing"; + TimelineType[TimelineType["pathConstraintMix"] = 13] = "pathConstraintMix"; + TimelineType[TimelineType["twoColor"] = 14] = "twoColor"; + })(TimelineType || (TimelineType = {})); + /** + * @public + */ + var CurveTimeline$1 = /** @class */ (function () { + function CurveTimeline(frameCount) { + if (frameCount <= 0) + throw new Error("frameCount must be > 0: " + frameCount); + this.curves = Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE); + } + CurveTimeline.prototype.getFrameCount = function () { + return this.curves.length / CurveTimeline.BEZIER_SIZE + 1; + }; + CurveTimeline.prototype.setLinear = function (frameIndex) { + this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.LINEAR; + }; + CurveTimeline.prototype.setStepped = function (frameIndex) { + this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.STEPPED; + }; + CurveTimeline.prototype.getCurveType = function (frameIndex) { + var index = frameIndex * CurveTimeline.BEZIER_SIZE; + if (index == this.curves.length) + return CurveTimeline.LINEAR; + var type = this.curves[index]; + if (type == CurveTimeline.LINEAR) + return CurveTimeline.LINEAR; + if (type == CurveTimeline.STEPPED) + return CurveTimeline.STEPPED; + return CurveTimeline.BEZIER; + }; + /** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next. + * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of + * the difference between the keyframe's values. */ + CurveTimeline.prototype.setCurve = function (frameIndex, cx1, cy1, cx2, cy2) { + var tmpx = (-cx1 * 2 + cx2) * 0.03, tmpy = (-cy1 * 2 + cy2) * 0.03; + var dddfx = ((cx1 - cx2) * 3 + 1) * 0.006, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006; + var ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy; + var dfx = cx1 * 0.3 + tmpx + dddfx * 0.16666667, dfy = cy1 * 0.3 + tmpy + dddfy * 0.16666667; + var i = frameIndex * CurveTimeline.BEZIER_SIZE; + var curves = this.curves; + curves[i++] = CurveTimeline.BEZIER; + var x = dfx, y = dfy; + for (var n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { + curves[i] = x; + curves[i + 1] = y; + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + x += dfx; + y += dfy; + } + }; + CurveTimeline.prototype.getCurvePercent = function (frameIndex, percent) { + percent = MathUtils.clamp(percent, 0, 1); + var curves = this.curves; + var i = frameIndex * CurveTimeline.BEZIER_SIZE; + var type = curves[i]; + if (type == CurveTimeline.LINEAR) + return percent; + if (type == CurveTimeline.STEPPED) + return 0; + i++; + var x = 0; + for (var start = i, n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { + x = curves[i]; + if (x >= percent) { + var prevX = void 0, prevY = void 0; + if (i == start) { + prevX = 0; + prevY = 0; + } + else { + prevX = curves[i - 2]; + prevY = curves[i - 1]; + } + return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX); + } + } + var y = curves[i - 1]; + return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1. + }; + CurveTimeline.LINEAR = 0; + CurveTimeline.STEPPED = 1; + CurveTimeline.BEZIER = 2; + CurveTimeline.BEZIER_SIZE = 10 * 2 - 1; + return CurveTimeline; + }()); + /** + * @public + */ + var RotateTimeline$1 = /** @class */ (function (_super) { + __extends$2(RotateTimeline, _super); + function RotateTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount << 1); + return _this; + } + RotateTimeline.prototype.getPropertyId = function () { + return (TimelineType.rotate << 24) + this.boneIndex; + }; + /** Sets the time and angle of the specified keyframe. */ + RotateTimeline.prototype.setFrame = function (frameIndex, time, degrees) { + frameIndex <<= 1; + this.frames[frameIndex] = time; + this.frames[frameIndex + RotateTimeline.ROTATION] = degrees; + }; + RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var frames = this.frames; + var bone = skeleton.bones[this.boneIndex]; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.rotation = bone.data.rotation; + return; + case exports.MixBlend.first: + var r_1 = bone.data.rotation - bone.rotation; + bone.rotation += (r_1 - (16384 - ((16384.499999999996 - r_1 / 360) | 0)) * 360) * alpha; + } + return; + } + if (time >= frames[frames.length - RotateTimeline.ENTRIES]) { // Time is after last frame. + var r_2 = frames[frames.length + RotateTimeline.PREV_ROTATION]; + switch (blend) { + case exports.MixBlend.setup: + bone.rotation = bone.data.rotation + r_2 * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + r_2 += bone.data.rotation - bone.rotation; + r_2 -= (16384 - ((16384.499999999996 - r_2 / 360) | 0)) * 360; // Wrap within -180 and 180. + case exports.MixBlend.add: + bone.rotation += r_2 * alpha; + } + return; + } + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, RotateTimeline.ENTRIES); + var prevRotation = frames[frame + RotateTimeline.PREV_ROTATION]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime)); + var r = frames[frame + RotateTimeline.ROTATION] - prevRotation; + r = prevRotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * percent; + switch (blend) { + case exports.MixBlend.setup: + bone.rotation = bone.data.rotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + r += bone.data.rotation - bone.rotation; + case exports.MixBlend.add: + bone.rotation += (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; + } + }; + RotateTimeline.ENTRIES = 2; + RotateTimeline.PREV_TIME = -2; + RotateTimeline.PREV_ROTATION = -1; + RotateTimeline.ROTATION = 1; + return RotateTimeline; + }(CurveTimeline$1)); + /** + * @public + */ + var TranslateTimeline$1 = /** @class */ (function (_super) { + __extends$2(TranslateTimeline, _super); + function TranslateTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES); + return _this; + } + TranslateTimeline.prototype.getPropertyId = function () { + return (TimelineType.translate << 24) + this.boneIndex; + }; + /** Sets the time and value of the specified keyframe. */ + TranslateTimeline.prototype.setFrame = function (frameIndex, time, x, y) { + frameIndex *= TranslateTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TranslateTimeline.X] = x; + this.frames[frameIndex + TranslateTimeline.Y] = y; + }; + TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var frames = this.frames; + var bone = skeleton.bones[this.boneIndex]; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.x = bone.data.x; + bone.y = bone.data.y; + return; + case exports.MixBlend.first: + bone.x += (bone.data.x - bone.x) * alpha; + bone.y += (bone.data.y - bone.y) * alpha; + } + return; + } + var x = 0, y = 0; + if (time >= frames[frames.length - TranslateTimeline.ENTRIES]) { // Time is after last frame. + x = frames[frames.length + TranslateTimeline.PREV_X]; + y = frames[frames.length + TranslateTimeline.PREV_Y]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, TranslateTimeline.ENTRIES); + x = frames[frame + TranslateTimeline.PREV_X]; + y = frames[frame + TranslateTimeline.PREV_Y]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / TranslateTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TranslateTimeline.PREV_TIME] - frameTime)); + x += (frames[frame + TranslateTimeline.X] - x) * percent; + y += (frames[frame + TranslateTimeline.Y] - y) * percent; + } + switch (blend) { + case exports.MixBlend.setup: + bone.x = bone.data.x + x * alpha; + bone.y = bone.data.y + y * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bone.x += (bone.data.x + x - bone.x) * alpha; + bone.y += (bone.data.y + y - bone.y) * alpha; + break; + case exports.MixBlend.add: + bone.x += x * alpha; + bone.y += y * alpha; + } + }; + TranslateTimeline.ENTRIES = 3; + TranslateTimeline.PREV_TIME = -3; + TranslateTimeline.PREV_X = -2; + TranslateTimeline.PREV_Y = -1; + TranslateTimeline.X = 1; + TranslateTimeline.Y = 2; + return TranslateTimeline; + }(CurveTimeline$1)); + /** + * @public + */ + var ScaleTimeline$1 = /** @class */ (function (_super) { + __extends$2(ScaleTimeline, _super); + function ScaleTimeline(frameCount) { + return _super.call(this, frameCount) || this; + } + ScaleTimeline.prototype.getPropertyId = function () { + return (TimelineType.scale << 24) + this.boneIndex; + }; + ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var frames = this.frames; + var bone = skeleton.bones[this.boneIndex]; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.scaleX = bone.data.scaleX; + bone.scaleY = bone.data.scaleY; + return; + case exports.MixBlend.first: + bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; + } + return; + } + var x = 0, y = 0; + if (time >= frames[frames.length - ScaleTimeline.ENTRIES]) { // Time is after last frame. + x = frames[frames.length + ScaleTimeline.PREV_X] * bone.data.scaleX; + y = frames[frames.length + ScaleTimeline.PREV_Y] * bone.data.scaleY; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, ScaleTimeline.ENTRIES); + x = frames[frame + ScaleTimeline.PREV_X]; + y = frames[frame + ScaleTimeline.PREV_Y]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / ScaleTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ScaleTimeline.PREV_TIME] - frameTime)); + x = (x + (frames[frame + ScaleTimeline.X] - x) * percent) * bone.data.scaleX; + y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY; + } + if (alpha == 1) { + if (blend == exports.MixBlend.add) { + bone.scaleX += x - bone.data.scaleX; + bone.scaleY += y - bone.data.scaleY; + } + else { + bone.scaleX = x; + bone.scaleY = y; + } + } + else { + var bx = 0, by = 0; + if (direction == exports.MixDirection.mixOut) { + switch (blend) { + case exports.MixBlend.setup: + bx = bone.data.scaleX; + by = bone.data.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case exports.MixBlend.add: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bone.data.scaleX) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - bone.data.scaleY) * alpha; + } + } + else { + switch (blend) { + case exports.MixBlend.setup: + bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x); + by = Math.abs(bone.data.scaleY) * MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bx = Math.abs(bone.scaleX) * MathUtils.signum(x); + by = Math.abs(bone.scaleY) * MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case exports.MixBlend.add: + bx = MathUtils.signum(x); + by = MathUtils.signum(y); + bone.scaleX = Math.abs(bone.scaleX) * bx + (x - Math.abs(bone.data.scaleX) * bx) * alpha; + bone.scaleY = Math.abs(bone.scaleY) * by + (y - Math.abs(bone.data.scaleY) * by) * alpha; + } + } + } + }; + return ScaleTimeline; + }(TranslateTimeline$1)); + /** + * @public + */ + var ShearTimeline$1 = /** @class */ (function (_super) { + __extends$2(ShearTimeline, _super); + function ShearTimeline(frameCount) { + return _super.call(this, frameCount) || this; + } + ShearTimeline.prototype.getPropertyId = function () { + return (TimelineType.shear << 24) + this.boneIndex; + }; + ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var frames = this.frames; + var bone = skeleton.bones[this.boneIndex]; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.shearX = bone.data.shearX; + bone.shearY = bone.data.shearY; + return; + case exports.MixBlend.first: + bone.shearX += (bone.data.shearX - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY - bone.shearY) * alpha; + } + return; + } + var x = 0, y = 0; + if (time >= frames[frames.length - ShearTimeline.ENTRIES]) { // Time is after last frame. + x = frames[frames.length + ShearTimeline.PREV_X]; + y = frames[frames.length + ShearTimeline.PREV_Y]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, ShearTimeline.ENTRIES); + x = frames[frame + ShearTimeline.PREV_X]; + y = frames[frame + ShearTimeline.PREV_Y]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / ShearTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ShearTimeline.PREV_TIME] - frameTime)); + x = x + (frames[frame + ShearTimeline.X] - x) * percent; + y = y + (frames[frame + ShearTimeline.Y] - y) * percent; + } + switch (blend) { + case exports.MixBlend.setup: + bone.shearX = bone.data.shearX + x * alpha; + bone.shearY = bone.data.shearY + y * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; + break; + case exports.MixBlend.add: + bone.shearX += x * alpha; + bone.shearY += y * alpha; + } + }; + return ShearTimeline; + }(TranslateTimeline$1)); + /** + * @public + */ + var ColorTimeline = /** @class */ (function (_super) { + __extends$2(ColorTimeline, _super); + function ColorTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES); + return _this; + } + ColorTimeline.prototype.getPropertyId = function () { + return (TimelineType.color << 24) + this.slotIndex; + }; + /** Sets the time and value of the specified keyframe. */ + ColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a) { + frameIndex *= ColorTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + ColorTimeline.R] = r; + this.frames[frameIndex + ColorTimeline.G] = g; + this.frames[frameIndex + ColorTimeline.B] = b; + this.frames[frameIndex + ColorTimeline.A] = a; + }; + ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + slot.color.setFromColor(slot.data.color); + return; + case exports.MixBlend.first: + var color = slot.color, setup = slot.data.color; + color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha); + } + return; + } + var r = 0, g = 0, b = 0, a = 0; + if (time >= frames[frames.length - ColorTimeline.ENTRIES]) { // Time is after last frame. + var i = frames.length; + r = frames[i + ColorTimeline.PREV_R]; + g = frames[i + ColorTimeline.PREV_G]; + b = frames[i + ColorTimeline.PREV_B]; + a = frames[i + ColorTimeline.PREV_A]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, ColorTimeline.ENTRIES); + r = frames[frame + ColorTimeline.PREV_R]; + g = frames[frame + ColorTimeline.PREV_G]; + b = frames[frame + ColorTimeline.PREV_B]; + a = frames[frame + ColorTimeline.PREV_A]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / ColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ColorTimeline.PREV_TIME] - frameTime)); + r += (frames[frame + ColorTimeline.R] - r) * percent; + g += (frames[frame + ColorTimeline.G] - g) * percent; + b += (frames[frame + ColorTimeline.B] - b) * percent; + a += (frames[frame + ColorTimeline.A] - a) * percent; + } + if (alpha == 1) + slot.color.set(r, g, b, a); + else { + var color = slot.color; + if (blend == exports.MixBlend.setup) + color.setFromColor(slot.data.color); + color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha); + } + }; + ColorTimeline.ENTRIES = 5; + ColorTimeline.PREV_TIME = -5; + ColorTimeline.PREV_R = -4; + ColorTimeline.PREV_G = -3; + ColorTimeline.PREV_B = -2; + ColorTimeline.PREV_A = -1; + ColorTimeline.R = 1; + ColorTimeline.G = 2; + ColorTimeline.B = 3; + ColorTimeline.A = 4; + return ColorTimeline; + }(CurveTimeline$1)); + /** + * @public + */ + var TwoColorTimeline = /** @class */ (function (_super) { + __extends$2(TwoColorTimeline, _super); + function TwoColorTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES); + return _this; + } + TwoColorTimeline.prototype.getPropertyId = function () { + return (TimelineType.twoColor << 24) + this.slotIndex; + }; + /** Sets the time and value of the specified keyframe. */ + TwoColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a, r2, g2, b2) { + frameIndex *= TwoColorTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TwoColorTimeline.R] = r; + this.frames[frameIndex + TwoColorTimeline.G] = g; + this.frames[frameIndex + TwoColorTimeline.B] = b; + this.frames[frameIndex + TwoColorTimeline.A] = a; + this.frames[frameIndex + TwoColorTimeline.R2] = r2; + this.frames[frameIndex + TwoColorTimeline.G2] = g2; + this.frames[frameIndex + TwoColorTimeline.B2] = b2; + }; + TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + slot.color.setFromColor(slot.data.color); + slot.darkColor.setFromColor(slot.data.darkColor); + return; + case exports.MixBlend.first: + var light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor; + light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha); + dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0); + } + return; + } + var r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; + if (time >= frames[frames.length - TwoColorTimeline.ENTRIES]) { // Time is after last frame. + var i = frames.length; + r = frames[i + TwoColorTimeline.PREV_R]; + g = frames[i + TwoColorTimeline.PREV_G]; + b = frames[i + TwoColorTimeline.PREV_B]; + a = frames[i + TwoColorTimeline.PREV_A]; + r2 = frames[i + TwoColorTimeline.PREV_R2]; + g2 = frames[i + TwoColorTimeline.PREV_G2]; + b2 = frames[i + TwoColorTimeline.PREV_B2]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, TwoColorTimeline.ENTRIES); + r = frames[frame + TwoColorTimeline.PREV_R]; + g = frames[frame + TwoColorTimeline.PREV_G]; + b = frames[frame + TwoColorTimeline.PREV_B]; + a = frames[frame + TwoColorTimeline.PREV_A]; + r2 = frames[frame + TwoColorTimeline.PREV_R2]; + g2 = frames[frame + TwoColorTimeline.PREV_G2]; + b2 = frames[frame + TwoColorTimeline.PREV_B2]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / TwoColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TwoColorTimeline.PREV_TIME] - frameTime)); + r += (frames[frame + TwoColorTimeline.R] - r) * percent; + g += (frames[frame + TwoColorTimeline.G] - g) * percent; + b += (frames[frame + TwoColorTimeline.B] - b) * percent; + a += (frames[frame + TwoColorTimeline.A] - a) * percent; + r2 += (frames[frame + TwoColorTimeline.R2] - r2) * percent; + g2 += (frames[frame + TwoColorTimeline.G2] - g2) * percent; + b2 += (frames[frame + TwoColorTimeline.B2] - b2) * percent; + } + if (alpha == 1) { + slot.color.set(r, g, b, a); + slot.darkColor.set(r2, g2, b2, 1); + } + else { + var light = slot.color, dark = slot.darkColor; + if (blend == exports.MixBlend.setup) { + light.setFromColor(slot.data.color); + dark.setFromColor(slot.data.darkColor); + } + light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha); + dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0); + } + }; + TwoColorTimeline.ENTRIES = 8; + TwoColorTimeline.PREV_TIME = -8; + TwoColorTimeline.PREV_R = -7; + TwoColorTimeline.PREV_G = -6; + TwoColorTimeline.PREV_B = -5; + TwoColorTimeline.PREV_A = -4; + TwoColorTimeline.PREV_R2 = -3; + TwoColorTimeline.PREV_G2 = -2; + TwoColorTimeline.PREV_B2 = -1; + TwoColorTimeline.R = 1; + TwoColorTimeline.G = 2; + TwoColorTimeline.B = 3; + TwoColorTimeline.A = 4; + TwoColorTimeline.R2 = 5; + TwoColorTimeline.G2 = 6; + TwoColorTimeline.B2 = 7; + return TwoColorTimeline; + }(CurveTimeline$1)); + /** + * @public + */ + var AttachmentTimeline$1 = /** @class */ (function () { + function AttachmentTimeline(frameCount) { + this.frames = Utils.newFloatArray(frameCount); + this.attachmentNames = new Array(frameCount); + } + AttachmentTimeline.prototype.getPropertyId = function () { + return (TimelineType.attachment << 24) + this.slotIndex; + }; + AttachmentTimeline.prototype.getFrameCount = function () { + return this.frames.length; + }; + /** Sets the time and value of the specified keyframe. */ + AttachmentTimeline.prototype.setFrame = function (frameIndex, time, attachmentName) { + this.frames[frameIndex] = time; + this.attachmentNames[frameIndex] = attachmentName; + }; + AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (direction == exports.MixDirection.mixOut && blend == exports.MixBlend.setup) { + var attachmentName_1 = slot.data.attachmentName; + slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1)); + return; + } + var frames = this.frames; + if (time < frames[0]) { + if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) { + var attachmentName_2 = slot.data.attachmentName; + slot.setAttachment(attachmentName_2 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_2)); + } + return; + } + var frameIndex = 0; + if (time >= frames[frames.length - 1]) // Time is after last frame. + frameIndex = frames.length - 1; + else + frameIndex = Animation$1.binarySearch(frames, time, 1) - 1; + var attachmentName = this.attachmentNames[frameIndex]; + skeleton.slots[this.slotIndex] + .setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); + }; + return AttachmentTimeline; + }()); + var zeros = null; + /** + * @public + */ + var DeformTimeline$1 = /** @class */ (function (_super) { + __extends$2(DeformTimeline, _super); + function DeformTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount); + _this.frameVertices = new Array(frameCount); + if (zeros == null) + zeros = Utils.newFloatArray(64); + return _this; + } + DeformTimeline.prototype.getPropertyId = function () { + return (TimelineType.deform << 27) + +this.attachment.id + this.slotIndex; + }; + /** Sets the time of the specified keyframe. */ + DeformTimeline.prototype.setFrame = function (frameIndex, time, vertices) { + this.frames[frameIndex] = time; + this.frameVertices[frameIndex] = vertices; + }; + DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + var slotAttachment = slot.getAttachment(); + if (!(slotAttachment instanceof VertexAttachment$1) || !slotAttachment.applyDeform(this.attachment)) + return; + var verticesArray = slot.attachmentVertices; + if (verticesArray.length == 0) + blend = exports.MixBlend.setup; + var frameVertices = this.frameVertices; + var vertexCount = frameVertices[0].length; + var frames = this.frames; + if (time < frames[0]) { + var vertexAttachment = slotAttachment; + switch (blend) { + case exports.MixBlend.setup: + verticesArray.length = 0; + return; + case exports.MixBlend.first: + if (alpha == 1) { + verticesArray.length = 0; + break; + } + var vertices_1 = Utils.setArraySize(verticesArray, vertexCount); + if (vertexAttachment.bones == null) { + // Unweighted vertex positions. + var setupVertices = vertexAttachment.vertices; + for (var i = 0; i < vertexCount; i++) + vertices_1[i] += (setupVertices[i] - vertices_1[i]) * alpha; + } + else { + // Weighted deform offsets. + alpha = 1 - alpha; + for (var i = 0; i < vertexCount; i++) + vertices_1[i] *= alpha; + } + } + return; + } + var vertices = Utils.setArraySize(verticesArray, vertexCount); + if (time >= frames[frames.length - 1]) { // Time is after last frame. + var lastVertices = frameVertices[frames.length - 1]; + if (alpha == 1) { + if (blend == exports.MixBlend.add) { + var vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i = 0; i < vertexCount; i++) { + vertices[i] += lastVertices[i] - setupVertices[i]; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i = 0; i < vertexCount; i++) + vertices[i] += lastVertices[i]; + } + } + else { + Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount); + } + } + else { + switch (blend) { + case exports.MixBlend.setup: { + var vertexAttachment_1 = slotAttachment; + if (vertexAttachment_1.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment_1.vertices; + for (var i = 0; i < vertexCount; i++) { + var setup = setupVertices[i]; + vertices[i] = setup + (lastVertices[i] - setup) * alpha; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i = 0; i < vertexCount; i++) + vertices[i] = lastVertices[i] * alpha; + } + break; + } + case exports.MixBlend.first: + case exports.MixBlend.replace: + for (var i = 0; i < vertexCount; i++) + vertices[i] += (lastVertices[i] - vertices[i]) * alpha; + case exports.MixBlend.add: + var vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i = 0; i < vertexCount; i++) { + vertices[i] += (lastVertices[i] - setupVertices[i]) * alpha; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i = 0; i < vertexCount; i++) + vertices[i] += lastVertices[i] * alpha; + } + } + } + return; + } + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time); + var prevVertices = frameVertices[frame - 1]; + var nextVertices = frameVertices[frame]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime)); + if (alpha == 1) { + if (blend == exports.MixBlend.add) { + var vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i = 0; i < vertexCount; i++) { + var prev = prevVertices[i]; + vertices[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i]; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i = 0; i < vertexCount; i++) { + var prev = prevVertices[i]; + vertices[i] += prev + (nextVertices[i] - prev) * percent; + } + } + } + else { + for (var i = 0; i < vertexCount; i++) { + var prev = prevVertices[i]; + vertices[i] = prev + (nextVertices[i] - prev) * percent; + } + } + } + else { + switch (blend) { + case exports.MixBlend.setup: { + var vertexAttachment_2 = slotAttachment; + if (vertexAttachment_2.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment_2.vertices; + for (var i = 0; i < vertexCount; i++) { + var prev = prevVertices[i], setup = setupVertices[i]; + vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i = 0; i < vertexCount; i++) { + var prev = prevVertices[i]; + vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha; + } + } + break; + } + case exports.MixBlend.first: + case exports.MixBlend.replace: + for (var i = 0; i < vertexCount; i++) { + var prev = prevVertices[i]; + vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha; + } + break; + case exports.MixBlend.add: + var vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i = 0; i < vertexCount; i++) { + var prev = prevVertices[i]; + vertices[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i = 0; i < vertexCount; i++) { + var prev = prevVertices[i]; + vertices[i] += (prev + (nextVertices[i] - prev) * percent) * alpha; + } + } + } + } + }; + return DeformTimeline; + }(CurveTimeline$1)); + /** + * @public + */ + var EventTimeline$1 = /** @class */ (function () { + function EventTimeline(frameCount) { + this.frames = Utils.newFloatArray(frameCount); + this.events = new Array(frameCount); + } + EventTimeline.prototype.getPropertyId = function () { + return TimelineType.event << 24; + }; + EventTimeline.prototype.getFrameCount = function () { + return this.frames.length; + }; + /** Sets the time of the specified keyframe. */ + EventTimeline.prototype.setFrame = function (frameIndex, event) { + this.frames[frameIndex] = event.time; + this.events[frameIndex] = event; + }; + /** Fires events for frames > lastTime and <= time. */ + EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + if (firedEvents == null) + return; + var frames = this.frames; + var frameCount = this.frames.length; + if (lastTime > time) { // Fire events after last time for looped animations. + this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction); + lastTime = -1; + } + else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame. + return; + if (time < frames[0]) + return; // Time is before first frame. + var frame = 0; + if (lastTime < frames[0]) + frame = 0; + else { + frame = Animation$1.binarySearch(frames, lastTime); + var frameTime = frames[frame]; + while (frame > 0) { // Fire multiple events with the same frame. + if (frames[frame - 1] != frameTime) + break; + frame--; + } + } + for (; frame < frameCount && time >= frames[frame]; frame++) + firedEvents.push(this.events[frame]); + }; + return EventTimeline; + }()); + /** + * @public + */ + var DrawOrderTimeline$1 = /** @class */ (function () { + function DrawOrderTimeline(frameCount) { + this.frames = Utils.newFloatArray(frameCount); + this.drawOrders = new Array(frameCount); + } + DrawOrderTimeline.prototype.getPropertyId = function () { + return TimelineType.drawOrder << 24; + }; + DrawOrderTimeline.prototype.getFrameCount = function () { + return this.frames.length; + }; + /** Sets the time of the specified keyframe. + * @param drawOrder May be null to use bind pose draw order. */ + DrawOrderTimeline.prototype.setFrame = function (frameIndex, time, drawOrder) { + this.frames[frameIndex] = time; + this.drawOrders[frameIndex] = drawOrder; + }; + DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var drawOrder = skeleton.drawOrder; + var slots = skeleton.slots; + if (direction == exports.MixDirection.mixOut && blend == exports.MixBlend.setup) { + Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + var frames = this.frames; + if (time < frames[0]) { + if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) + Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + var frame = 0; + if (time >= frames[frames.length - 1]) // Time is after last frame. + frame = frames.length - 1; + else + frame = Animation$1.binarySearch(frames, time) - 1; + var drawOrderToSetupIndex = this.drawOrders[frame]; + if (drawOrderToSetupIndex == null) + Utils.arrayCopy(slots, 0, drawOrder, 0, slots.length); + else { + for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++) + drawOrder[i] = slots[drawOrderToSetupIndex[i]]; + } + }; + return DrawOrderTimeline; + }()); + /** + * @public + */ + var IkConstraintTimeline$1 = /** @class */ (function (_super) { + __extends$2(IkConstraintTimeline, _super); + function IkConstraintTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES); + return _this; + } + IkConstraintTimeline.prototype.getPropertyId = function () { + return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex; + }; + /** Sets the time, mix and bend direction of the specified keyframe. */ + IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection, compress, stretch) { + frameIndex *= IkConstraintTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; + this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; + this.frames[frameIndex + IkConstraintTimeline.COMPRESS] = compress ? 1 : 0; + this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0; + }; + IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var frames = this.frames; + var constraint = skeleton.ikConstraints[this.ikConstraintIndex]; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.mix = constraint.data.mix; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + return; + case exports.MixBlend.first: + constraint.mix += (constraint.data.mix - constraint.mix) * alpha; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + return; + } + if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { // Time is after last frame. + if (blend == exports.MixBlend.setup) { + constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; + if (direction == exports.MixDirection.mixOut) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + else { + constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + else { + constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; + if (direction == exports.MixDirection.mixIn) { + constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + return; + } + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, IkConstraintTimeline.ENTRIES); + var mix = frames[frame + IkConstraintTimeline.PREV_MIX]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); + if (blend == exports.MixBlend.setup) { + constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; + if (direction == exports.MixDirection.mixOut) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + else { + constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + else { + constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; + if (direction == exports.MixDirection.mixIn) { + constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + }; + IkConstraintTimeline.ENTRIES = 5; + IkConstraintTimeline.PREV_TIME = -5; + IkConstraintTimeline.PREV_MIX = -4; + IkConstraintTimeline.PREV_BEND_DIRECTION = -3; + IkConstraintTimeline.PREV_COMPRESS = -2; + IkConstraintTimeline.PREV_STRETCH = -1; + IkConstraintTimeline.MIX = 1; + IkConstraintTimeline.BEND_DIRECTION = 2; + IkConstraintTimeline.COMPRESS = 3; + IkConstraintTimeline.STRETCH = 4; + return IkConstraintTimeline; + }(CurveTimeline$1)); + /** + * @public + */ + var TransformConstraintTimeline$1 = /** @class */ (function (_super) { + __extends$2(TransformConstraintTimeline, _super); + function TransformConstraintTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES); + return _this; + } + TransformConstraintTimeline.prototype.getPropertyId = function () { + return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex; + }; + /** Sets the time and mixes of the specified keyframe. */ + TransformConstraintTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix, scaleMix, shearMix) { + frameIndex *= TransformConstraintTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TransformConstraintTimeline.ROTATE] = rotateMix; + this.frames[frameIndex + TransformConstraintTimeline.TRANSLATE] = translateMix; + this.frames[frameIndex + TransformConstraintTimeline.SCALE] = scaleMix; + this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix; + }; + TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var frames = this.frames; + var constraint = skeleton.transformConstraints[this.transformConstraintIndex]; + if (time < frames[0]) { + var data = constraint.data; + switch (blend) { + case exports.MixBlend.setup: + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + constraint.scaleMix = data.scaleMix; + constraint.shearMix = data.shearMix; + return; + case exports.MixBlend.first: + constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha; + constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha; + constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha; + constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha; + } + return; + } + var rotate = 0, translate = 0, scale = 0, shear = 0; + if (time >= frames[frames.length - TransformConstraintTimeline.ENTRIES]) { // Time is after last frame. + var i = frames.length; + rotate = frames[i + TransformConstraintTimeline.PREV_ROTATE]; + translate = frames[i + TransformConstraintTimeline.PREV_TRANSLATE]; + scale = frames[i + TransformConstraintTimeline.PREV_SCALE]; + shear = frames[i + TransformConstraintTimeline.PREV_SHEAR]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, TransformConstraintTimeline.ENTRIES); + rotate = frames[frame + TransformConstraintTimeline.PREV_ROTATE]; + translate = frames[frame + TransformConstraintTimeline.PREV_TRANSLATE]; + scale = frames[frame + TransformConstraintTimeline.PREV_SCALE]; + shear = frames[frame + TransformConstraintTimeline.PREV_SHEAR]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / TransformConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TransformConstraintTimeline.PREV_TIME] - frameTime)); + rotate += (frames[frame + TransformConstraintTimeline.ROTATE] - rotate) * percent; + translate += (frames[frame + TransformConstraintTimeline.TRANSLATE] - translate) * percent; + scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent; + shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent; + } + if (blend == exports.MixBlend.setup) { + var data = constraint.data; + constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha; + constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha; + constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha; + constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha; + } + else { + constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; + constraint.translateMix += (translate - constraint.translateMix) * alpha; + constraint.scaleMix += (scale - constraint.scaleMix) * alpha; + constraint.shearMix += (shear - constraint.shearMix) * alpha; + } + }; + TransformConstraintTimeline.ENTRIES = 5; + TransformConstraintTimeline.PREV_TIME = -5; + TransformConstraintTimeline.PREV_ROTATE = -4; + TransformConstraintTimeline.PREV_TRANSLATE = -3; + TransformConstraintTimeline.PREV_SCALE = -2; + TransformConstraintTimeline.PREV_SHEAR = -1; + TransformConstraintTimeline.ROTATE = 1; + TransformConstraintTimeline.TRANSLATE = 2; + TransformConstraintTimeline.SCALE = 3; + TransformConstraintTimeline.SHEAR = 4; + return TransformConstraintTimeline; + }(CurveTimeline$1)); + /** + * @public + */ + var PathConstraintPositionTimeline$1 = /** @class */ (function (_super) { + __extends$2(PathConstraintPositionTimeline, _super); + function PathConstraintPositionTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES); + return _this; + } + PathConstraintPositionTimeline.prototype.getPropertyId = function () { + return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex; + }; + /** Sets the time and value of the specified keyframe. */ + PathConstraintPositionTimeline.prototype.setFrame = function (frameIndex, time, value) { + frameIndex *= PathConstraintPositionTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value; + }; + PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var frames = this.frames; + var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.position = constraint.data.position; + return; + case exports.MixBlend.first: + constraint.position += (constraint.data.position - constraint.position) * alpha; + } + return; + } + var position = 0; + if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES]) // Time is after last frame. + position = frames[frames.length + PathConstraintPositionTimeline.PREV_VALUE]; + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, PathConstraintPositionTimeline.ENTRIES); + position = frames[frame + PathConstraintPositionTimeline.PREV_VALUE]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime)); + position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent; + } + if (blend == exports.MixBlend.setup) + constraint.position = constraint.data.position + (position - constraint.data.position) * alpha; + else + constraint.position += (position - constraint.position) * alpha; + }; + PathConstraintPositionTimeline.ENTRIES = 2; + PathConstraintPositionTimeline.PREV_TIME = -2; + PathConstraintPositionTimeline.PREV_VALUE = -1; + PathConstraintPositionTimeline.VALUE = 1; + return PathConstraintPositionTimeline; + }(CurveTimeline$1)); + /** + * @public + */ + var PathConstraintSpacingTimeline$1 = /** @class */ (function (_super) { + __extends$2(PathConstraintSpacingTimeline, _super); + function PathConstraintSpacingTimeline(frameCount) { + return _super.call(this, frameCount) || this; + } + PathConstraintSpacingTimeline.prototype.getPropertyId = function () { + return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex; + }; + PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var frames = this.frames; + var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.spacing = constraint.data.spacing; + return; + case exports.MixBlend.first: + constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha; + } + return; + } + var spacing = 0; + if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES]) // Time is after last frame. + spacing = frames[frames.length + PathConstraintSpacingTimeline.PREV_VALUE]; + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, PathConstraintSpacingTimeline.ENTRIES); + spacing = frames[frame + PathConstraintSpacingTimeline.PREV_VALUE]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime)); + spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent; + } + if (blend == exports.MixBlend.setup) + constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha; + else + constraint.spacing += (spacing - constraint.spacing) * alpha; + }; + return PathConstraintSpacingTimeline; + }(PathConstraintPositionTimeline$1)); + /** + * @public + */ + var PathConstraintMixTimeline$1 = /** @class */ (function (_super) { + __extends$2(PathConstraintMixTimeline, _super); + function PathConstraintMixTimeline(frameCount) { + var _this = _super.call(this, frameCount) || this; + _this.frames = Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES); + return _this; + } + PathConstraintMixTimeline.prototype.getPropertyId = function () { + return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex; + }; + /** Sets the time and mixes of the specified keyframe. */ + PathConstraintMixTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix) { + frameIndex *= PathConstraintMixTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + PathConstraintMixTimeline.ROTATE] = rotateMix; + this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix; + }; + PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var frames = this.frames; + var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.rotateMix = constraint.data.rotateMix; + constraint.translateMix = constraint.data.translateMix; + return; + case exports.MixBlend.first: + constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha; + constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha; + } + return; + } + var rotate = 0, translate = 0; + if (time >= frames[frames.length - PathConstraintMixTimeline.ENTRIES]) { // Time is after last frame. + rotate = frames[frames.length + PathConstraintMixTimeline.PREV_ROTATE]; + translate = frames[frames.length + PathConstraintMixTimeline.PREV_TRANSLATE]; + } + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, PathConstraintMixTimeline.ENTRIES); + rotate = frames[frame + PathConstraintMixTimeline.PREV_ROTATE]; + translate = frames[frame + PathConstraintMixTimeline.PREV_TRANSLATE]; + var frameTime = frames[frame]; + var percent = this.getCurvePercent(frame / PathConstraintMixTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintMixTimeline.PREV_TIME] - frameTime)); + rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent; + translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent; + } + if (blend == exports.MixBlend.setup) { + constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha; + constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha; + } + else { + constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; + constraint.translateMix += (translate - constraint.translateMix) * alpha; + } + }; + PathConstraintMixTimeline.ENTRIES = 3; + PathConstraintMixTimeline.PREV_TIME = -3; + PathConstraintMixTimeline.PREV_ROTATE = -2; + PathConstraintMixTimeline.PREV_TRANSLATE = -1; + PathConstraintMixTimeline.ROTATE = 1; + PathConstraintMixTimeline.TRANSLATE = 2; + return PathConstraintMixTimeline; + }(CurveTimeline$1)); + + /** + * @public + */ + var AnimationState$1 = /** @class */ (function () { + function AnimationState(data) { + this.tracks = new Array(); + this.events = new Array(); + this.listeners = new Array(); + this.queue = new EventQueue$1(this); + this.propertyIDs = new IntSet(); + this.animationsChanged = false; + this.timeScale = 1; + this.trackEntryPool = new Pool(function () { return new TrackEntry$1(); }); + this.data = data; + } + AnimationState.prototype.update = function (delta) { + delta *= this.timeScale; + var tracks = this.tracks; + for (var i = 0, n = tracks.length; i < n; i++) { + var current = tracks[i]; + if (current == null) + continue; + current.animationLast = current.nextAnimationLast; + current.trackLast = current.nextTrackLast; + var currentDelta = delta * current.timeScale; + if (current.delay > 0) { + current.delay -= currentDelta; + if (current.delay > 0) + continue; + currentDelta = -current.delay; + current.delay = 0; + } + var next = current.next; + if (next != null) { + // When the next entry's delay is passed, change to the next entry, preserving leftover time. + var nextTime = current.trackLast - next.delay; + if (nextTime >= 0) { + next.delay = 0; + next.trackTime = current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale; + current.trackTime += currentDelta; + this.setCurrent(i, next, true); + while (next.mixingFrom != null) { + next.mixTime += delta; + next = next.mixingFrom; + } + continue; + } + } + else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) { + tracks[i] = null; + this.queue.end(current); + this.disposeNext(current); + continue; + } + if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) { + // End mixing from entries once all have completed. + var from = current.mixingFrom; + current.mixingFrom = null; + if (from != null) + from.mixingTo = null; + while (from != null) { + this.queue.end(from); + from = from.mixingFrom; + } + } + current.trackTime += currentDelta; + } + this.queue.drain(); + }; + AnimationState.prototype.updateMixingFrom = function (to, delta) { + var from = to.mixingFrom; + if (from == null) + return true; + var finished = this.updateMixingFrom(from, delta); + from.animationLast = from.nextAnimationLast; + from.trackLast = from.nextTrackLast; + // Require mixTime > 0 to ensure the mixing from entry was applied at least once. + if (to.mixTime > 0 && to.mixTime >= to.mixDuration) { + // Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame). + if (from.totalAlpha == 0 || to.mixDuration == 0) { + to.mixingFrom = from.mixingFrom; + if (from.mixingFrom != null) + from.mixingFrom.mixingTo = to; + to.interruptAlpha = from.interruptAlpha; + this.queue.end(from); + } + return finished; + } + from.trackTime += delta * from.timeScale; + to.mixTime += delta; + return false; + }; + AnimationState.prototype.apply = function (skeleton) { + if (skeleton == null) + throw new Error("skeleton cannot be null."); + if (this.animationsChanged) + this._animationsChanged(); + var events = this.events; + var tracks = this.tracks; + var applied = false; + for (var i = 0, n = tracks.length; i < n; i++) { + var current = tracks[i]; + if (current == null || current.delay > 0) + continue; + applied = true; + var blend = i == 0 ? exports.MixBlend.first : current.mixBlend; + // Apply mixing from entries first. + var mix = current.alpha; + if (current.mixingFrom != null) + mix *= this.applyMixingFrom(current, skeleton, blend); + else if (current.trackTime >= current.trackEnd && current.next == null) + mix = 0; + // Apply current entry. + var animationLast = current.animationLast, animationTime = current.getAnimationTime(); + var timelineCount = current.animation.timelines.length; + var timelines = current.animation.timelines; + if ((i == 0 && mix == 1) || blend == exports.MixBlend.add) { + for (var ii = 0; ii < timelineCount; ii++) { + // Fixes issue #302 on IOS9 where mix, blend sometimes became undefined and caused assets + // to sometimes stop rendering when using color correction, as their RGBA values become NaN. + // (https://github.com/pixijs/pixi-spine/issues/302) + Utils.webkit602BugfixHelper(mix, blend); + timelines[ii].apply(skeleton, animationLast, animationTime, events, mix, blend, exports.MixDirection.mixIn); + } + } + else { + var timelineMode = current.timelineMode; + var firstFrame = current.timelinesRotation.length == 0; + if (firstFrame) + Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null); + var timelinesRotation = current.timelinesRotation; + for (var ii = 0; ii < timelineCount; ii++) { + var timeline = timelines[ii]; + var timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : exports.MixBlend.setup; + if (timeline instanceof RotateTimeline$1) { + this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame); + } + else { + // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 + Utils.webkit602BugfixHelper(mix, blend); + timeline.apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, exports.MixDirection.mixIn); + } + } + } + this.queueEvents(current, animationTime); + events.length = 0; + current.nextAnimationLast = animationTime; + current.nextTrackLast = current.trackTime; + } + this.queue.drain(); + return applied; + }; + AnimationState.prototype.applyMixingFrom = function (to, skeleton, blend) { + var from = to.mixingFrom; + if (from.mixingFrom != null) + this.applyMixingFrom(from, skeleton, blend); + var mix = 0; + if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. + mix = 1; + if (blend == exports.MixBlend.first) + blend = exports.MixBlend.setup; + } + else { + mix = to.mixTime / to.mixDuration; + if (mix > 1) + mix = 1; + if (blend != exports.MixBlend.first) + blend = from.mixBlend; + } + var events = mix < from.eventThreshold ? this.events : null; + var attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold; + var animationLast = from.animationLast, animationTime = from.getAnimationTime(); + var timelineCount = from.animation.timelines.length; + var timelines = from.animation.timelines; + var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); + if (blend == exports.MixBlend.add) { + for (var i = 0; i < timelineCount; i++) + timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, exports.MixDirection.mixOut); + } + else { + var timelineMode = from.timelineMode; + var timelineHoldMix = from.timelineHoldMix; + var firstFrame = from.timelinesRotation.length == 0; + if (firstFrame) + Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null); + var timelinesRotation = from.timelinesRotation; + from.totalAlpha = 0; + for (var i = 0; i < timelineCount; i++) { + var timeline = timelines[i]; + var direction = exports.MixDirection.mixOut; + var timelineBlend = void 0; + var alpha = 0; + switch (timelineMode[i]) { + case AnimationState.SUBSEQUENT: + if (!attachments && timeline instanceof AttachmentTimeline$1) + continue; + if (!drawOrder && timeline instanceof DrawOrderTimeline$1) + continue; + timelineBlend = blend; + alpha = alphaMix; + break; + case AnimationState.FIRST: + timelineBlend = exports.MixBlend.setup; + alpha = alphaMix; + break; + case AnimationState.HOLD: + timelineBlend = exports.MixBlend.setup; + alpha = alphaHold; + break; + default: + timelineBlend = exports.MixBlend.setup; + var holdMix = timelineHoldMix[i]; + alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration); + break; + } + from.totalAlpha += alpha; + if (timeline instanceof RotateTimeline$1) + this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame); + else { + // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 + Utils.webkit602BugfixHelper(alpha, blend); + if (timelineBlend == exports.MixBlend.setup) { + if (timeline instanceof AttachmentTimeline$1) { + if (attachments) + direction = exports.MixDirection.mixOut; + } + else if (timeline instanceof DrawOrderTimeline$1) { + if (drawOrder) + direction = exports.MixDirection.mixOut; + } + } + timeline.apply(skeleton, animationLast, animationTime, events, alpha, timelineBlend, direction); + } + } + } + if (to.mixDuration > 0) + this.queueEvents(from, animationTime); + this.events.length = 0; + from.nextAnimationLast = animationTime; + from.nextTrackLast = from.trackTime; + return mix; + }; + AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) { + if (firstFrame) + timelinesRotation[i] = 0; + if (alpha == 1) { + timeline.apply(skeleton, 0, time, null, 1, blend, exports.MixDirection.mixIn); + return; + } + var rotateTimeline = timeline; + var frames = rotateTimeline.frames; + var bone = skeleton.bones[rotateTimeline.boneIndex]; + var r1 = 0, r2 = 0; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.rotation = bone.data.rotation; + default: + return; + case exports.MixBlend.first: + r1 = bone.rotation; + r2 = bone.data.rotation; + } + } + else { + r1 = blend == exports.MixBlend.setup ? bone.data.rotation : bone.rotation; + if (time >= frames[frames.length - RotateTimeline$1.ENTRIES]) // Time is after last frame. + r2 = bone.data.rotation + frames[frames.length + RotateTimeline$1.PREV_ROTATION]; + else { + // Interpolate between the previous frame and the current frame. + var frame = Animation$1.binarySearch(frames, time, RotateTimeline$1.ENTRIES); + var prevRotation = frames[frame + RotateTimeline$1.PREV_ROTATION]; + var frameTime = frames[frame]; + var percent = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline$1.PREV_TIME] - frameTime)); + r2 = frames[frame + RotateTimeline$1.ROTATION] - prevRotation; + r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; + r2 = prevRotation + r2 * percent + bone.data.rotation; + r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; + } + } + // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. + var total = 0, diff = r2 - r1; + diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360; + if (diff == 0) { + total = timelinesRotation[i]; + } + else { + var lastTotal = 0, lastDiff = 0; + if (firstFrame) { + lastTotal = 0; + lastDiff = diff; + } + else { + lastTotal = timelinesRotation[i]; // Angle and direction of mix, including loops. + lastDiff = timelinesRotation[i + 1]; // Difference between bones. + } + var current = diff > 0, dir = lastTotal >= 0; + // Detect cross at 0 (not 180). + if (MathUtils.signum(lastDiff) != MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) { + // A cross after a 360 rotation is a loop. + if (Math.abs(lastTotal) > 180) + lastTotal += 360 * MathUtils.signum(lastTotal); + dir = current; + } + total = diff + lastTotal - lastTotal % 360; // Store loops as part of lastTotal. + if (dir != current) + total += 360 * MathUtils.signum(lastTotal); + timelinesRotation[i] = total; + } + timelinesRotation[i + 1] = diff; + r1 += total * alpha; + bone.rotation = r1 - (16384 - ((16384.499999999996 - r1 / 360) | 0)) * 360; + }; + AnimationState.prototype.queueEvents = function (entry, animationTime) { + var animationStart = entry.animationStart, animationEnd = entry.animationEnd; + var duration = animationEnd - animationStart; + var trackLastWrapped = entry.trackLast % duration; + // Queue events before complete. + var events = this.events; + var i = 0, n = events.length; + for (; i < n; i++) { + var event_1 = events[i]; + if (event_1.time < trackLastWrapped) + break; + if (event_1.time > animationEnd) + continue; // Discard events outside animation start/end. + this.queue.event(entry, event_1); + } + // Queue complete if completed a loop iteration or the animation. + var complete = false; + if (entry.loop) + complete = duration == 0 || trackLastWrapped > entry.trackTime % duration; + else + complete = animationTime >= animationEnd && entry.animationLast < animationEnd; + if (complete) + this.queue.complete(entry); + // Queue events after complete. + for (; i < n; i++) { + var event_2 = events[i]; + if (event_2.time < animationStart) + continue; // Discard events outside animation start/end. + this.queue.event(entry, events[i]); + } + }; + AnimationState.prototype.clearTracks = function () { + var oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (var i = 0, n = this.tracks.length; i < n; i++) + this.clearTrack(i); + this.tracks.length = 0; + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + }; + AnimationState.prototype.clearTrack = function (trackIndex) { + if (trackIndex >= this.tracks.length) + return; + var current = this.tracks[trackIndex]; + if (current == null) + return; + this.queue.end(current); + this.disposeNext(current); + var entry = current; + while (true) { + var from = entry.mixingFrom; + if (from == null) + break; + this.queue.end(from); + entry.mixingFrom = null; + entry.mixingTo = null; + entry = from; + } + this.tracks[current.trackIndex] = null; + this.queue.drain(); + }; + AnimationState.prototype.setCurrent = function (index, current, interrupt) { + var from = this.expandToIndex(index); + this.tracks[index] = current; + if (from != null) { + if (interrupt) + this.queue.interrupt(from); + current.mixingFrom = from; + from.mixingTo = current; + current.mixTime = 0; + // Store the interrupted mix percentage. + if (from.mixingFrom != null && from.mixDuration > 0) + current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration); + from.timelinesRotation.length = 0; // Reset rotation for mixing out, in case entry was mixed in. + } + this.queue.start(current); + }; + AnimationState.prototype.setAnimation = function (trackIndex, animationName, loop) { + var animation = this.data.skeletonData.findAnimation(animationName); + if (animation == null) + throw new Error("Animation not found: " + animationName); + return this.setAnimationWith(trackIndex, animation, loop); + }; + AnimationState.prototype.setAnimationWith = function (trackIndex, animation, loop) { + if (animation == null) + throw new Error("animation cannot be null."); + var interrupt = true; + var current = this.expandToIndex(trackIndex); + if (current != null) { + if (current.nextTrackLast == -1) { + // Don't mix from an entry that was never applied. + this.tracks[trackIndex] = current.mixingFrom; + this.queue.interrupt(current); + this.queue.end(current); + this.disposeNext(current); + current = current.mixingFrom; + interrupt = false; + } + else + this.disposeNext(current); + } + var entry = this.trackEntry(trackIndex, animation, loop, current); + this.setCurrent(trackIndex, entry, interrupt); + this.queue.drain(); + return entry; + }; + AnimationState.prototype.addAnimation = function (trackIndex, animationName, loop, delay) { + var animation = this.data.skeletonData.findAnimation(animationName); + if (animation == null) + throw new Error("Animation not found: " + animationName); + return this.addAnimationWith(trackIndex, animation, loop, delay); + }; + AnimationState.prototype.addAnimationWith = function (trackIndex, animation, loop, delay) { + if (animation == null) + throw new Error("animation cannot be null."); + var last = this.expandToIndex(trackIndex); + if (last != null) { + while (last.next != null) + last = last.next; + } + var entry = this.trackEntry(trackIndex, animation, loop, last); + if (last == null) { + this.setCurrent(trackIndex, entry, true); + this.queue.drain(); + } + else { + last.next = entry; + if (delay <= 0) { + var duration = last.animationEnd - last.animationStart; + if (duration != 0) { + if (last.loop) + delay += duration * (1 + ((last.trackTime / duration) | 0)); + else + delay += Math.max(duration, last.trackTime); + delay -= this.data.getMix(last.animation, animation); + } + else + delay = last.trackTime; + } + } + entry.delay = delay; + return entry; + }; + AnimationState.prototype.setEmptyAnimation = function (trackIndex, mixDuration) { + var entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation, false); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + }; + AnimationState.prototype.addEmptyAnimation = function (trackIndex, mixDuration, delay) { + if (delay <= 0) + delay -= mixDuration; + var entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation, false, delay); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + }; + AnimationState.prototype.setEmptyAnimations = function (mixDuration) { + var oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (var i = 0, n = this.tracks.length; i < n; i++) { + var current = this.tracks[i]; + if (current != null) + this.setEmptyAnimation(current.trackIndex, mixDuration); + } + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + }; + AnimationState.prototype.expandToIndex = function (index) { + if (index < this.tracks.length) + return this.tracks[index]; + Utils.ensureArrayCapacity(this.tracks, index - this.tracks.length + 1, null); + this.tracks.length = index + 1; + return null; + }; + AnimationState.prototype.trackEntry = function (trackIndex, animation, loop, last) { + var entry = this.trackEntryPool.obtain(); + entry.trackIndex = trackIndex; + entry.animation = animation; + entry.loop = loop; + entry.holdPrevious = false; + entry.eventThreshold = 0; + entry.attachmentThreshold = 0; + entry.drawOrderThreshold = 0; + entry.animationStart = 0; + entry.animationEnd = animation.duration; + entry.animationLast = -1; + entry.nextAnimationLast = -1; + entry.delay = 0; + entry.trackTime = 0; + entry.trackLast = -1; + entry.nextTrackLast = -1; + entry.trackEnd = Number.MAX_VALUE; + entry.timeScale = 1; + entry.alpha = 1; + entry.interruptAlpha = 1; + entry.mixTime = 0; + entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation); + return entry; + }; + AnimationState.prototype.disposeNext = function (entry) { + var next = entry.next; + while (next != null) { + this.queue.dispose(next); + next = next.next; + } + entry.next = null; + }; + AnimationState.prototype._animationsChanged = function () { + this.animationsChanged = false; + this.propertyIDs.clear(); + for (var i = 0, n = this.tracks.length; i < n; i++) { + var entry = this.tracks[i]; + if (entry == null) + continue; + while (entry.mixingFrom != null) + entry = entry.mixingFrom; + do { + if (entry.mixingFrom == null || entry.mixBlend != exports.MixBlend.add) + this.setTimelineModes(entry); + entry = entry.mixingTo; + } while (entry != null); + } + }; + AnimationState.prototype.setTimelineModes = function (entry) { + var to = entry.mixingTo; + var timelines = entry.animation.timelines; + var timelinesCount = entry.animation.timelines.length; + var timelineMode = Utils.setArraySize(entry.timelineMode, timelinesCount); + entry.timelineHoldMix.length = 0; + var timelineDipMix = Utils.setArraySize(entry.timelineHoldMix, timelinesCount); + var propertyIDs = this.propertyIDs; + if (to != null && to.holdPrevious) { + for (var i = 0; i < timelinesCount; i++) { + propertyIDs.add(timelines[i].getPropertyId()); + timelineMode[i] = AnimationState.HOLD; + } + return; + } + outer: for (var i = 0; i < timelinesCount; i++) { + var id = timelines[i].getPropertyId(); + if (!propertyIDs.add(id)) + timelineMode[i] = AnimationState.SUBSEQUENT; + else if (to == null || !this.hasTimeline(to, id)) + timelineMode[i] = AnimationState.FIRST; + else { + for (var next = to.mixingTo; next != null; next = next.mixingTo) { + if (this.hasTimeline(next, id)) + continue; + if (entry.mixDuration > 0) { + timelineMode[i] = AnimationState.HOLD_MIX; + timelineDipMix[i] = next; + continue outer; + } + break; + } + timelineMode[i] = AnimationState.HOLD; + } + } + }; + AnimationState.prototype.hasTimeline = function (entry, id) { + var timelines = entry.animation.timelines; + for (var i = 0, n = timelines.length; i < n; i++) + if (timelines[i].getPropertyId() == id) + return true; + return false; + }; + AnimationState.prototype.getCurrent = function (trackIndex) { + if (trackIndex >= this.tracks.length) + return null; + return this.tracks[trackIndex]; + }; + AnimationState.prototype.addListener = function (listener) { + if (listener == null) + throw new Error("listener cannot be null."); + this.listeners.push(listener); + }; + /** Removes the listener added with {@link #addListener(AnimationStateListener)}. */ + AnimationState.prototype.removeListener = function (listener) { + var index = this.listeners.indexOf(listener); + if (index >= 0) + this.listeners.splice(index, 1); + }; + AnimationState.prototype.clearListeners = function () { + this.listeners.length = 0; + }; + AnimationState.prototype.clearListenerNotifications = function () { + this.queue.clear(); + }; + AnimationState.prototype.setAnimationByName = function (trackIndex, animationName, loop) { + if (!AnimationState.deprecatedWarning1) { + AnimationState.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on."); + } + this.setAnimation(trackIndex, animationName, loop); + }; + AnimationState.prototype.addAnimationByName = function (trackIndex, animationName, loop, delay) { + if (!AnimationState.deprecatedWarning2) { + AnimationState.deprecatedWarning2 = true; + console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on."); + } + this.addAnimation(trackIndex, animationName, loop, delay); + }; + AnimationState.prototype.hasAnimation = function (animationName) { + var animation = this.data.skeletonData.findAnimation(animationName); + return animation !== null; + }; + AnimationState.prototype.hasAnimationByName = function (animationName) { + if (!AnimationState.deprecatedWarning3) { + AnimationState.deprecatedWarning3 = true; + console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on."); + } + return this.hasAnimation(animationName); + }; + AnimationState.emptyAnimation = new Animation$1("", [], 0); + AnimationState.SUBSEQUENT = 0; + AnimationState.FIRST = 1; + AnimationState.HOLD = 2; + AnimationState.HOLD_MIX = 3; + AnimationState.deprecatedWarning1 = false; + AnimationState.deprecatedWarning2 = false; + AnimationState.deprecatedWarning3 = false; + return AnimationState; + }()); + /** + * @public + */ + var TrackEntry$1 = /** @class */ (function () { + function TrackEntry() { + this.mixBlend = exports.MixBlend.replace; + this.timelineMode = new Array(); + this.timelineHoldMix = new Array(); + this.timelinesRotation = new Array(); + } + TrackEntry.prototype.reset = function () { + this.next = null; + this.mixingFrom = null; + this.mixingTo = null; + this.animation = null; + this.listener = null; + this.timelineMode.length = 0; + this.timelineHoldMix.length = 0; + this.timelinesRotation.length = 0; + }; + TrackEntry.prototype.getAnimationTime = function () { + if (this.loop) { + var duration = this.animationEnd - this.animationStart; + if (duration == 0) + return this.animationStart; + return (this.trackTime % duration) + this.animationStart; + } + return Math.min(this.trackTime + this.animationStart, this.animationEnd); + }; + TrackEntry.prototype.setAnimationLast = function (animationLast) { + this.animationLast = animationLast; + this.nextAnimationLast = animationLast; + }; + TrackEntry.prototype.isComplete = function () { + return this.trackTime >= this.animationEnd - this.animationStart; + }; + TrackEntry.prototype.resetRotationDirections = function () { + this.timelinesRotation.length = 0; + }; + Object.defineProperty(TrackEntry.prototype, "time", { + get: function () { + if (!TrackEntry.deprecatedWarning1) { + TrackEntry.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); + } + return this.trackTime; + }, + set: function (value) { + if (!TrackEntry.deprecatedWarning1) { + TrackEntry.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); + } + this.trackTime = value; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TrackEntry.prototype, "endTime", { + get: function () { + if (!TrackEntry.deprecatedWarning2) { + TrackEntry.deprecatedWarning2 = true; + console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); + } + return this.trackTime; + }, + set: function (value) { + if (!TrackEntry.deprecatedWarning2) { + TrackEntry.deprecatedWarning2 = true; + console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); + } + this.trackTime = value; + }, + enumerable: false, + configurable: true + }); + TrackEntry.prototype.loopsCount = function () { + return Math.floor(this.trackTime / this.trackEnd); + }; + TrackEntry.deprecatedWarning1 = false; + TrackEntry.deprecatedWarning2 = false; + return TrackEntry; + }()); + /** + * @public + */ + var EventQueue$1 = /** @class */ (function () { + function EventQueue(animState) { + this.objects = []; + this.drainDisabled = false; + this.animState = animState; + } + EventQueue.prototype.start = function (entry) { + this.objects.push(EventType$1.start); + this.objects.push(entry); + this.animState.animationsChanged = true; + }; + EventQueue.prototype.interrupt = function (entry) { + this.objects.push(EventType$1.interrupt); + this.objects.push(entry); + }; + EventQueue.prototype.end = function (entry) { + this.objects.push(EventType$1.end); + this.objects.push(entry); + this.animState.animationsChanged = true; + }; + EventQueue.prototype.dispose = function (entry) { + this.objects.push(EventType$1.dispose); + this.objects.push(entry); + }; + EventQueue.prototype.complete = function (entry) { + this.objects.push(EventType$1.complete); + this.objects.push(entry); + }; + EventQueue.prototype.event = function (entry, event) { + this.objects.push(EventType$1.event); + this.objects.push(entry); + this.objects.push(event); + }; + EventQueue.prototype.deprecateStuff = function () { + if (!EventQueue.deprecatedWarning1) { + EventQueue.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: onComplete, onStart, onEnd, onEvent art deprecated, please use listeners from now on. 'state.addListener({ complete: function(track, event) { } })'"); + } + return true; + }; + EventQueue.prototype.drain = function () { + if (this.drainDisabled) + return; + this.drainDisabled = true; + var objects = this.objects; + var listeners = this.animState.listeners; + for (var i = 0; i < objects.length; i += 2) { + var type = objects[i]; + var entry = objects[i + 1]; + switch (type) { + case EventType$1.start: + if (entry.listener != null && entry.listener.start) + entry.listener.start(entry); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].start) + listeners[ii].start(entry); + //deprecation + entry.onStart && this.deprecateStuff() && entry.onStart(entry.trackIndex); + this.animState.onStart && this.deprecateStuff() && this.deprecateStuff && this.animState.onStart(entry.trackIndex); + break; + case EventType$1.interrupt: + if (entry.listener != null && entry.listener.interrupt) + entry.listener.interrupt(entry); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].interrupt) + listeners[ii].interrupt(entry); + break; + case EventType$1.end: + if (entry.listener != null && entry.listener.end) + entry.listener.end(entry); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].end) + listeners[ii].end(entry); + //deprecation + entry.onEnd && this.deprecateStuff() && entry.onEnd(entry.trackIndex); + this.animState.onEnd && this.deprecateStuff() && this.animState.onEnd(entry.trackIndex); + // Fall through. + case EventType$1.dispose: + if (entry.listener != null && entry.listener.dispose) + entry.listener.dispose(entry); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].dispose) + listeners[ii].dispose(entry); + this.animState.trackEntryPool.free(entry); + break; + case EventType$1.complete: + if (entry.listener != null && entry.listener.complete) + entry.listener.complete(entry); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].complete) + listeners[ii].complete(entry); + //deprecation + var count = MathUtils.toInt(entry.loopsCount()); + entry.onComplete && this.deprecateStuff() && entry.onComplete(entry.trackIndex, count); + this.animState.onComplete && this.deprecateStuff() && this.animState.onComplete(entry.trackIndex, count); + break; + case EventType$1.event: + var event_3 = objects[i++ + 2]; + if (entry.listener != null && entry.listener.event) + entry.listener.event(entry, event_3); + for (var ii = 0; ii < listeners.length; ii++) + if (listeners[ii].event) + listeners[ii].event(entry, event_3); + //deprecation + entry.onEvent && this.deprecateStuff() && entry.onEvent(entry.trackIndex, event_3); + this.animState.onEvent && this.deprecateStuff() && this.animState.onEvent(entry.trackIndex, event_3); + break; + } + } + this.clear(); + this.drainDisabled = false; + }; + EventQueue.prototype.clear = function () { + this.objects.length = 0; + }; + EventQueue.deprecatedWarning1 = false; + return EventQueue; + }()); + /** + * @public + */ + var EventType$1; + (function (EventType) { + EventType[EventType["start"] = 0] = "start"; + EventType[EventType["interrupt"] = 1] = "interrupt"; + EventType[EventType["end"] = 2] = "end"; + EventType[EventType["dispose"] = 3] = "dispose"; + EventType[EventType["complete"] = 4] = "complete"; + EventType[EventType["event"] = 5] = "event"; + })(EventType$1 || (EventType$1 = {})); + /** + * @public + */ + var AnimationStateAdapter2 = /** @class */ (function () { + function AnimationStateAdapter2() { + } + AnimationStateAdapter2.prototype.start = function (entry) { + }; + AnimationStateAdapter2.prototype.interrupt = function (entry) { + }; + AnimationStateAdapter2.prototype.end = function (entry) { + }; + AnimationStateAdapter2.prototype.dispose = function (entry) { + }; + AnimationStateAdapter2.prototype.complete = function (entry) { + }; + AnimationStateAdapter2.prototype.event = function (entry, event) { + }; + return AnimationStateAdapter2; + }()); + + /** + * @public + */ + var AnimationStateData$1 = /** @class */ (function () { + function AnimationStateData(skeletonData) { + this.animationToMixTime = {}; + this.defaultMix = 0; + if (skeletonData == null) + throw new Error("skeletonData cannot be null."); + this.skeletonData = skeletonData; + } + AnimationStateData.prototype.setMix = function (fromName, toName, duration) { + var from = this.skeletonData.findAnimation(fromName); + if (from == null) + throw new Error("Animation not found: " + fromName); + var to = this.skeletonData.findAnimation(toName); + if (to == null) + throw new Error("Animation not found: " + toName); + this.setMixWith(from, to, duration); + }; + AnimationStateData.prototype.setMixByName = function (fromName, toName, duration) { + if (!AnimationStateData.deprecatedWarning1) { + AnimationStateData.deprecatedWarning1 = true; + console.warn("Deprecation Warning: AnimationStateData.setMixByName is deprecated, please use setMix from now on."); + } + this.setMix(fromName, toName, duration); + }; + AnimationStateData.prototype.setMixWith = function (from, to, duration) { + if (from == null) + throw new Error("from cannot be null."); + if (to == null) + throw new Error("to cannot be null."); + var key = from.name + "." + to.name; + this.animationToMixTime[key] = duration; + }; + AnimationStateData.prototype.getMix = function (from, to) { + var key = from.name + "." + to.name; + var value = this.animationToMixTime[key]; + return value === undefined ? this.defaultMix : value; + }; + AnimationStateData.deprecatedWarning1 = false; + return AnimationStateData; + }()); + + /** + * @public + */ + var AtlasAttachmentLoader$1 = /** @class */ (function () { + function AtlasAttachmentLoader(atlas) { + this.atlas = atlas; + } + /** @return May be null to not load an attachment. */ + AtlasAttachmentLoader.prototype.newRegionAttachment = function (skin, name, path) { + var region = this.atlas.findRegion(path); + if (region == null) + throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); + var attachment = new RegionAttachment$1(name); + attachment.region = region; + return attachment; + }; + /** @return May be null to not load an attachment. */ + AtlasAttachmentLoader.prototype.newMeshAttachment = function (skin, name, path) { + var region = this.atlas.findRegion(path); + if (region == null) + throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); + var attachment = new MeshAttachment$1(name); + attachment.region = region; + return attachment; + }; + /** @return May be null to not load an attachment. */ + AtlasAttachmentLoader.prototype.newBoundingBoxAttachment = function (skin, name) { + return new BoundingBoxAttachment$1(name); + }; + /** @return May be null to not load an attachment */ + AtlasAttachmentLoader.prototype.newPathAttachment = function (skin, name) { + return new PathAttachment$1(name); + }; + AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) { + return new PointAttachment$1(name); + }; + AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) { + return new ClippingAttachment$1(name); + }; + return AtlasAttachmentLoader; + }()); + + /** + * @public + */ + var Bone$1 = /** @class */ (function () { + /** @param parent May be null. */ + function Bone(data, skeleton, parent) { + //be careful! Spine b,c is c,b in pixi matrix + this.matrix = new math.Matrix(); + this.children = new Array(); + this.x = 0; + this.y = 0; + this.rotation = 0; + this.scaleX = 0; + this.scaleY = 0; + this.shearX = 0; + this.shearY = 0; + this.ax = 0; + this.ay = 0; + this.arotation = 0; + this.ascaleX = 0; + this.ascaleY = 0; + this.ashearX = 0; + this.ashearY = 0; + this.appliedValid = false; + this.sorted = false; + /** NOT USED IN 3.7. Needed for the debug graph code */ + this.active = true; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.skeleton = skeleton; + this.parent = parent; + this.setToSetupPose(); + } + Object.defineProperty(Bone.prototype, "worldX", { + get: function () { + return this.matrix.tx; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Bone.prototype, "worldY", { + get: function () { + return this.matrix.ty; + }, + enumerable: false, + configurable: true + }); + /** Same as {@link #updateWorldTransform()}. This method exists for Bone to implement {@link Updatable}. */ + Bone.prototype.update = function () { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + }; + /** Computes the world transform using the parent bone and this bone's local transform. */ + Bone.prototype.updateWorldTransform = function () { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + }; + /** Computes the world transform using the parent bone and the specified local transform. */ + Bone.prototype.updateWorldTransformWith = function (x, y, rotation, scaleX, scaleY, shearX, shearY) { + this.ax = x; + this.ay = y; + this.arotation = rotation; + this.ascaleX = scaleX; + this.ascaleY = scaleY; + this.ashearX = shearX; + this.ashearY = shearY; + this.appliedValid = true; + var parent = this.parent; + var m = this.matrix; + var sx = this.skeleton.scaleX; + var sy = settings.yDown ? -this.skeleton.scaleY : this.skeleton.scaleY; + if (parent == null) { // Root bone. + var skeleton = this.skeleton; + var rotationY = rotation + 90 + shearY; + m.a = MathUtils.cosDeg(rotation + shearX) * scaleX * sx; + m.c = MathUtils.cosDeg(rotationY) * scaleY * sx; + m.b = MathUtils.sinDeg(rotation + shearX) * scaleX * sy; + m.d = MathUtils.sinDeg(rotationY) * scaleY * sy; + m.tx = x * sx + skeleton.x; + m.ty = y * sy + skeleton.y; + return; + } + var pa = parent.matrix.a, pb = parent.matrix.c, pc = parent.matrix.b, pd = parent.matrix.d; + m.tx = pa * x + pb * y + parent.matrix.tx; + m.ty = pc * x + pd * y + parent.matrix.ty; + switch (this.data.transformMode) { + case exports.TransformMode.Normal: { + var rotationY = rotation + 90 + shearY; + var la = MathUtils.cosDeg(rotation + shearX) * scaleX; + var lb = MathUtils.cosDeg(rotationY) * scaleY; + var lc = MathUtils.sinDeg(rotation + shearX) * scaleX; + var ld = MathUtils.sinDeg(rotationY) * scaleY; + m.a = pa * la + pb * lc; + m.c = pa * lb + pb * ld; + m.b = pc * la + pd * lc; + m.d = pc * lb + pd * ld; + return; + } + case exports.TransformMode.OnlyTranslation: { + var rotationY = rotation + 90 + shearY; + m.a = MathUtils.cosDeg(rotation + shearX) * scaleX; + m.c = MathUtils.cosDeg(rotationY) * scaleY; + m.b = MathUtils.sinDeg(rotation + shearX) * scaleX; + m.d = MathUtils.sinDeg(rotationY) * scaleY; + break; + } + case exports.TransformMode.NoRotationOrReflection: { + var s = pa * pa + pc * pc; + var prx = 0; + if (s > 0.0001) { + s = Math.abs(pa * pd - pb * pc) / s; + pb = pc * s; + pd = pa * s; + prx = Math.atan2(pc, pa) * MathUtils.radDeg; + } + else { + pa = 0; + pc = 0; + prx = 90 - Math.atan2(pd, pb) * MathUtils.radDeg; + } + var rx = rotation + shearX - prx; + var ry = rotation + shearY - prx + 90; + var la = MathUtils.cosDeg(rx) * scaleX; + var lb = MathUtils.cosDeg(ry) * scaleY; + var lc = MathUtils.sinDeg(rx) * scaleX; + var ld = MathUtils.sinDeg(ry) * scaleY; + m.a = pa * la - pb * lc; + m.c = pa * lb - pb * ld; + m.b = pc * la + pd * lc; + m.d = pc * lb + pd * ld; + break; + } + case exports.TransformMode.NoScale: + case exports.TransformMode.NoScaleOrReflection: { + var cos = MathUtils.cosDeg(rotation); + var sin = MathUtils.sinDeg(rotation); + var za = (pa * cos + pb * sin) / sx; + var zc = (pc * cos + pd * sin) / sy; + var s = Math.sqrt(za * za + zc * zc); + if (s > 0.00001) + s = 1 / s; + za *= s; + zc *= s; + s = Math.sqrt(za * za + zc * zc); + if (this.data.transformMode == exports.TransformMode.NoScale + && (pa * pd - pb * pc < 0) != (settings.yDown ? + (this.skeleton.scaleX < 0 != this.skeleton.scaleY > 0) : + (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0))) + s = -s; + var r = Math.PI / 2 + Math.atan2(zc, za); + var zb = Math.cos(r) * s; + var zd = Math.sin(r) * s; + var la = MathUtils.cosDeg(shearX) * scaleX; + var lb = MathUtils.cosDeg(90 + shearY) * scaleY; + var lc = MathUtils.sinDeg(shearX) * scaleX; + var ld = MathUtils.sinDeg(90 + shearY) * scaleY; + m.a = za * la + zb * lc; + m.c = za * lb + zb * ld; + m.b = zc * la + zd * lc; + m.d = zc * lb + zd * ld; + break; + } + } + m.a *= sx; + m.c *= sx; + m.b *= sy; + m.d *= sy; + }; + Bone.prototype.setToSetupPose = function () { + var data = this.data; + this.x = data.x; + this.y = data.y; + this.rotation = data.rotation; + this.scaleX = data.scaleX; + this.scaleY = data.scaleY; + this.shearX = data.shearX; + this.shearY = data.shearY; + }; + Bone.prototype.getWorldRotationX = function () { + return Math.atan2(this.matrix.b, this.matrix.a) * MathUtils.radDeg; + }; + Bone.prototype.getWorldRotationY = function () { + return Math.atan2(this.matrix.d, this.matrix.c) * MathUtils.radDeg; + }; + Bone.prototype.getWorldScaleX = function () { + var m = this.matrix; + return Math.sqrt(m.a * m.a + m.c * m.c); + }; + Bone.prototype.getWorldScaleY = function () { + var m = this.matrix; + return Math.sqrt(m.b * m.b + m.d * m.d); + }; + /** Computes the individual applied transform values from the world transform. This can be useful to perform processing using + * the applied transform after the world transform has been modified directly (eg, by a constraint). + *

+ * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. */ + Bone.prototype.updateAppliedTransform = function () { + this.appliedValid = true; + var parent = this.parent; + var m = this.matrix; + if (parent == null) { + this.ax = m.tx; + this.ay = m.ty; + this.arotation = Math.atan2(m.b, m.a) * MathUtils.radDeg; + this.ascaleX = Math.sqrt(m.a * m.a + m.b * m.b); + this.ascaleY = Math.sqrt(m.c * m.c + m.d * m.d); + this.ashearX = 0; + this.ashearY = Math.atan2(m.a * m.c + m.b * m.d, m.a * m.d - m.b * m.c) * MathUtils.radDeg; + return; + } + var pm = parent.matrix; + var pid = 1 / (pm.a * pm.d - pm.b * pm.c); + var dx = m.tx - pm.tx, dy = m.ty - pm.ty; + this.ax = (dx * pm.d * pid - dy * pm.c * pid); + this.ay = (dy * pm.a * pid - dx * pm.b * pid); + var ia = pid * pm.d; + var id = pid * pm.a; + var ib = pid * pm.c; + var ic = pid * pm.b; + var ra = ia * m.a - ib * m.b; + var rb = ia * m.c - ib * m.d; + var rc = id * m.b - ic * m.a; + var rd = id * m.d - ic * m.c; + this.ashearX = 0; + this.ascaleX = Math.sqrt(ra * ra + rc * rc); + if (this.ascaleX > 0.0001) { + var det = ra * rd - rb * rc; + this.ascaleY = det / this.ascaleX; + this.ashearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg; + this.arotation = Math.atan2(rc, ra) * MathUtils.radDeg; + } + else { + this.ascaleX = 0; + this.ascaleY = Math.sqrt(rb * rb + rd * rd); + this.ashearY = 0; + this.arotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg; + } + }; + Bone.prototype.worldToLocal = function (world) { + var m = this.matrix; + var a = m.a, b = m.c, c = m.b, d = m.d; + var invDet = 1 / (a * d - b * c); + var x = world.x - m.tx, y = world.y - m.ty; + world.x = (x * d * invDet - y * b * invDet); + world.y = (y * a * invDet - x * c * invDet); + return world; + }; + Bone.prototype.localToWorld = function (local) { + var m = this.matrix; + var x = local.x, y = local.y; + local.x = x * m.a + y * m.c + m.tx; + local.y = x * m.b + y * m.d + m.ty; + return local; + }; + Bone.prototype.worldToLocalRotation = function (worldRotation) { + var sin = MathUtils.sinDeg(worldRotation), cos = MathUtils.cosDeg(worldRotation); + var mat = this.matrix; + return Math.atan2(mat.a * sin - mat.b * cos, mat.d * cos - mat.c * sin) * MathUtils.radDeg; + }; + Bone.prototype.localToWorldRotation = function (localRotation) { + var sin = MathUtils.sinDeg(localRotation), cos = MathUtils.cosDeg(localRotation); + var mat = this.matrix; + return Math.atan2(cos * mat.b + sin * mat.d, cos * mat.a + sin * mat.c) * MathUtils.radDeg; + }; + Bone.prototype.rotateWorld = function (degrees) { + var mat = this.matrix; + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var cos = MathUtils.cosDeg(degrees), sin = MathUtils.sinDeg(degrees); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + this.appliedValid = false; + }; + return Bone; + }()); + + /** + * @public + */ + var BoneData$1 = /** @class */ (function () { + function BoneData(index, name, parent) { + this.x = 0; + this.y = 0; + this.rotation = 0; + this.scaleX = 1; + this.scaleY = 1; + this.shearX = 0; + this.shearY = 0; + this.transformMode = exports.TransformMode.Normal; + if (index < 0) + throw new Error("index must be >= 0."); + if (name == null) + throw new Error("name cannot be null."); + this.index = index; + this.name = name; + this.parent = parent; + } + return BoneData; + }()); + + /** + * @public + */ + var Event$1 = /** @class */ (function () { + function Event(time, data) { + if (data == null) + throw new Error("data cannot be null."); + this.time = time; + this.data = data; + } + return Event; + }()); + + /** + * @public + */ + var EventData$1 = /** @class */ (function () { + function EventData(name) { + this.name = name; + } + return EventData; + }()); + + /** + * @public + */ + var IkConstraint$1 = /** @class */ (function () { + function IkConstraint(data, skeleton) { + this.bendDirection = 0; + this.compress = false; + this.stretch = false; + this.mix = 1; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.mix = data.mix; + this.bendDirection = data.bendDirection; + this.compress = data.compress; + this.stretch = data.stretch; + this.bones = new Array(); + for (var i = 0; i < data.bones.length; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findBone(data.target.name); + } + IkConstraint.prototype.getOrder = function () { + return this.data.order; + }; + IkConstraint.prototype.apply = function () { + this.update(); + }; + IkConstraint.prototype.update = function () { + var target = this.target; + var bones = this.bones; + switch (bones.length) { + case 1: + this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix); + break; + case 2: + this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.mix); + break; + } + }; + /** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world + * coordinate system. */ + IkConstraint.prototype.apply1 = function (bone, targetX, targetY, compress, stretch, uniform, alpha) { + if (!bone.appliedValid) + bone.updateAppliedTransform(); + var p = bone.parent.matrix; + var id = 1 / (p.a * p.d - p.b * p.c); + var x = targetX - p.tx, y = targetY - p.ty; + var tx = (x * p.d - y * p.c) * id - bone.ax, ty = (y * p.a - x * p.b) * id - bone.ay; + var rotationIK = Math.atan2(ty, tx) * MathUtils.radDeg - bone.ashearX - bone.arotation; + if (bone.ascaleX < 0) + rotationIK += 180; + if (rotationIK > 180) + rotationIK -= 360; + else if (rotationIK < -180) + rotationIK += 360; + var sx = bone.ascaleX, sy = bone.ascaleY; + if (compress || stretch) { + var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty); + if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001) { + var s = (dd / b - 1) * alpha + 1; + sx *= s; + if (uniform) + sy *= s; + } + } + bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY); + }; + /** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The + * target is specified in the world coordinate system. + * @param child A direct descendant of the parent bone. */ + IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, alpha) { + if (alpha == 0) { + child.updateWorldTransform(); + return; + } + if (!parent.appliedValid) + parent.updateAppliedTransform(); + if (!child.appliedValid) + child.updateAppliedTransform(); + var px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX; + var pmat = parent.matrix; + var os1 = 0, os2 = 0, s2 = 0; + if (psx < 0) { + psx = -psx; + os1 = 180; + s2 = -1; + } + else { + os1 = 0; + s2 = 1; + } + if (psy < 0) { + psy = -psy; + s2 = -s2; + } + if (csx < 0) { + csx = -csx; + os2 = 180; + } + else + os2 = 0; + var cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = pmat.a, b = pmat.c, c = pmat.b, d = pmat.d; + var u = Math.abs(psx - psy) <= 0.0001; + if (!u) { + cy = 0; + cwx = a * cx + pmat.tx; + cwy = c * cx + pmat.ty; + } + else { + cy = child.ay; + cwx = a * cx + b * cy + pmat.tx; + cwy = c * cx + d * cy + pmat.ty; + } + var pp = parent.parent.matrix; + a = pp.a; + b = pp.c; + c = pp.b; + d = pp.d; + var id = 1 / (a * d - b * c), x = targetX - pp.tx, y = targetY - pp.ty; + var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py, dd = tx * tx + ty * ty; + x = cwx - pp.tx; + y = cwy - pp.ty; + var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; + var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0; + outer: if (u) { + l2 *= psx; + var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2); + if (cos < -1) + cos = -1; + else if (cos > 1) { + cos = 1; + if (stretch && l1 + l2 > 0.0001) + sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1; + } + a2 = Math.acos(cos) * bendDir; + a = l1 + l2 * cos; + b = l2 * Math.sin(a2); + a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b); + } + else { + a = psx * l2; + b = psy * l2; + var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx); + c = bb * l1 * l1 + aa * dd - aa * bb; + var c1 = -2 * bb * l1, c2 = bb - aa; + d = c1 * c1 - 4 * c2 * c; + if (d >= 0) { + var q = Math.sqrt(d); + if (c1 < 0) + q = -q; + q = -(c1 + q) / 2; + var r0 = q / c2, r1 = c / q; + var r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; + if (r * r <= dd) { + y = Math.sqrt(dd - r * r) * bendDir; + a1 = ta - Math.atan2(y, r); + a2 = Math.atan2(y / psy, (r - l1) / psx); + break outer; + } + } + var minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; + var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; + c = -a * l1 / (aa - bb); + if (c >= -1 && c <= 1) { + c = Math.acos(c); + x = a * Math.cos(c) + l1; + y = b * Math.sin(c); + d = x * x + y * y; + if (d < minDist) { + minAngle = c; + minDist = d; + minX = x; + minY = y; + } + if (d > maxDist) { + maxAngle = c; + maxDist = d; + maxX = x; + maxY = y; + } + } + if (dd <= (minDist + maxDist) / 2) { + a1 = ta - Math.atan2(minY * bendDir, minX); + a2 = minAngle * bendDir; + } + else { + a1 = ta - Math.atan2(maxY * bendDir, maxX); + a2 = maxAngle * bendDir; + } + } + var os = Math.atan2(cy, cx) * s2; + var rotation = parent.arotation; + a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation; + if (a1 > 180) + a1 -= 360; + else if (a1 < -180) + a1 += 360; + parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0); + rotation = child.arotation; + a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; + if (a2 > 180) + a2 -= 360; + else if (a2 < -180) + a2 += 360; + child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + }; + return IkConstraint; + }()); + + /** + * @public + */ + var IkConstraintData$1 = /** @class */ (function () { + function IkConstraintData(name) { + this.order = 0; + this.bones = new Array(); + this.bendDirection = 1; + this.compress = false; + this.stretch = false; + this.uniform = false; + this.mix = 1; + this.name = name; + } + return IkConstraintData; + }()); + + /** + * @public + */ + var PathConstraintData$1 = /** @class */ (function () { + function PathConstraintData(name) { + this.order = 0; + this.bones = new Array(); + this.name = name; + } + return PathConstraintData; + }()); + /** + * @public + */ + var SpacingMode$1; + (function (SpacingMode) { + SpacingMode[SpacingMode["Length"] = 0] = "Length"; + SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed"; + SpacingMode[SpacingMode["Percent"] = 2] = "Percent"; + })(SpacingMode$1 || (SpacingMode$1 = {})); + + /** + * @public + */ + var PathConstraint$1 = /** @class */ (function () { + function PathConstraint(data, skeleton) { + this.position = 0; + this.spacing = 0; + this.rotateMix = 0; + this.translateMix = 0; + this.spaces = new Array(); + this.positions = new Array(); + this.world = new Array(); + this.curves = new Array(); + this.lengths = new Array(); + this.segments = new Array(); + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.bones = new Array(); + for (var i = 0, n = data.bones.length; i < n; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findSlot(data.target.name); + this.position = data.position; + this.spacing = data.spacing; + this.rotateMix = data.rotateMix; + this.translateMix = data.translateMix; + } + PathConstraint.prototype.apply = function () { + this.update(); + }; + PathConstraint.prototype.update = function () { + var attachment = this.target.getAttachment(); + if (!(attachment instanceof PathAttachment$1)) + return; + var rotateMix = this.rotateMix, translateMix = this.translateMix; + var translate = translateMix > 0, rotate = rotateMix > 0; + if (!translate && !rotate) + return; + var data = this.data; + var spacingMode = data.spacingMode; + var lengthSpacing = spacingMode == SpacingMode$1.Length; + var rotateMode = data.rotateMode; + var tangents = rotateMode == exports.RotateMode.Tangent, scale = rotateMode == exports.RotateMode.ChainScale; + var boneCount = this.bones.length, spacesCount = tangents ? boneCount : boneCount + 1; + var bones = this.bones; + var spaces = Utils.setArraySize(this.spaces, spacesCount), lengths = null; + var spacing = this.spacing; + if (scale || lengthSpacing) { + if (scale) + lengths = Utils.setArraySize(this.lengths, boneCount); + for (var i = 0, n = spacesCount - 1; i < n;) { + var bone = bones[i]; + var setupLength = bone.data.length; + if (setupLength < PathConstraint.epsilon) { + if (scale) + lengths[i] = 0; + spaces[++i] = 0; + } + else { + var x = setupLength * bone.matrix.a, y = setupLength * bone.matrix.b; + var length_1 = Math.sqrt(x * x + y * y); + if (scale) + lengths[i] = length_1; + spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length_1 / setupLength; + } + } + } + else { + for (var i = 1; i < spacesCount; i++) + spaces[i] = spacing; + } + var positions = this.computeWorldPositions(attachment, spacesCount, tangents, data.positionMode == exports.PositionMode.Percent, spacingMode == SpacingMode$1.Percent); + var boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; + var tip = false; + if (offsetRotation == 0) + tip = rotateMode == exports.RotateMode.Chain; + else { + tip = false; + var p = this.target.bone.matrix; + offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.degRad : -MathUtils.degRad; + } + for (var i = 0, p = 3; i < boneCount; i++, p += 3) { + var bone = bones[i]; + var mat = bone.matrix; + mat.tx += (boneX - mat.tx) * translateMix; + mat.ty += (boneY - mat.ty) * translateMix; + var x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; + if (scale) { + var length_2 = lengths[i]; + if (length_2 != 0) { + var s = (Math.sqrt(dx * dx + dy * dy) / length_2 - 1) * rotateMix + 1; + mat.a *= s; + mat.b *= s; + } + } + boneX = x; + boneY = y; + if (rotate) { + var a = mat.a, b = mat.c, c = mat.b, d = mat.d, r = 0, cos = 0, sin = 0; + if (tangents) + r = positions[p - 1]; + else if (spaces[i + 1] == 0) + r = positions[p + 2]; + else + r = Math.atan2(dy, dx); + r -= Math.atan2(c, a); + if (tip) { + cos = Math.cos(r); + sin = Math.sin(r); + var length_3 = bone.data.length; + boneX += (length_3 * (cos * a - sin * c) - dx) * rotateMix; + boneY += (length_3 * (sin * a + cos * c) - dy) * rotateMix; + } + else { + r += offsetRotation; + } + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; + r *= rotateMix; + cos = Math.cos(r); + sin = Math.sin(r); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + } + bone.appliedValid = false; + } + }; + PathConstraint.prototype.computeWorldPositions = function (path, spacesCount, tangents, percentPosition, percentSpacing) { + var target = this.target; + var position = this.position; + var spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = null; + var closed = path.closed; + var verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE; + if (!path.constantSpeed) { + var lengths = path.lengths; + curveCount -= closed ? 1 : 2; + var pathLength_1 = lengths[curveCount]; + if (percentPosition) + position *= pathLength_1; + if (percentSpacing) { + for (var i = 0; i < spacesCount; i++) + spaces[i] *= pathLength_1; + } + world = Utils.setArraySize(this.world, 8); + for (var i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { + var space = spaces[i]; + position += space; + var p = position; + if (closed) { + p %= pathLength_1; + if (p < 0) + p += pathLength_1; + curve = 0; + } + else if (p < 0) { + if (prevCurve != PathConstraint.BEFORE) { + prevCurve = PathConstraint.BEFORE; + path.computeWorldVertices(target, 2, 4, world, 0, 2); + } + this.addBeforePosition(p, world, 0, out, o); + continue; + } + else if (p > pathLength_1) { + if (prevCurve != PathConstraint.AFTER) { + prevCurve = PathConstraint.AFTER; + path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); + } + this.addAfterPosition(p - pathLength_1, world, 0, out, o); + continue; + } + // Determine curve containing position. + for (;; curve++) { + var length_4 = lengths[curve]; + if (p > length_4) + continue; + if (curve == 0) + p /= length_4; + else { + var prev = lengths[curve - 1]; + p = (p - prev) / (length_4 - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + if (closed && curve == curveCount) { + path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); + path.computeWorldVertices(target, 0, 4, world, 4, 2); + } + else + path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); + } + this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0)); + } + return out; + } + // World vertices. + if (closed) { + verticesLength += 2; + world = Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); + path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); + world[verticesLength - 2] = world[0]; + world[verticesLength - 1] = world[1]; + } + else { + curveCount--; + verticesLength -= 4; + world = Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); + } + // Curve lengths. + var curves = Utils.setArraySize(this.curves, curveCount); + var pathLength = 0; + var x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; + var tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0; + for (var i = 0, w = 2; i < curveCount; i++, w += 6) { + cx1 = world[w]; + cy1 = world[w + 1]; + cx2 = world[w + 2]; + cy2 = world[w + 3]; + x2 = world[w + 4]; + y2 = world[w + 5]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.1875; + tmpy = (y1 - cy1 * 2 + cy2) * 0.1875; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + curves[i] = pathLength; + x1 = x2; + y1 = y2; + } + if (percentPosition) + position *= pathLength; + if (percentSpacing) { + for (var i = 0; i < spacesCount; i++) + spaces[i] *= pathLength; + } + var segments = this.segments; + var curveLength = 0; + for (var i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { + var space = spaces[i]; + position += space; + var p = position; + if (closed) { + p %= pathLength; + if (p < 0) + p += pathLength; + curve = 0; + } + else if (p < 0) { + this.addBeforePosition(p, world, 0, out, o); + continue; + } + else if (p > pathLength) { + this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o); + continue; + } + // Determine curve containing position. + for (;; curve++) { + var length_5 = curves[curve]; + if (p > length_5) + continue; + if (curve == 0) + p /= length_5; + else { + var prev = curves[curve - 1]; + p = (p - prev) / (length_5 - prev); + } + break; + } + // Curve segment lengths. + if (curve != prevCurve) { + prevCurve = curve; + var ii = curve * 6; + x1 = world[ii]; + y1 = world[ii + 1]; + cx1 = world[ii + 2]; + cy1 = world[ii + 3]; + cx2 = world[ii + 4]; + cy2 = world[ii + 5]; + x2 = world[ii + 6]; + y2 = world[ii + 7]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.03; + tmpy = (y1 - cy1 * 2 + cy2) * 0.03; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667; + curveLength = Math.sqrt(dfx * dfx + dfy * dfy); + segments[0] = curveLength; + for (ii = 1; ii < 8; ii++) { + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[ii] = curveLength; + } + dfx += ddfx; + dfy += ddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[8] = curveLength; + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[9] = curveLength; + segment = 0; + } + // Weight by segment length. + p *= curveLength; + for (;; segment++) { + var length_6 = segments[segment]; + if (p > length_6) + continue; + if (segment == 0) + p /= length_6; + else { + var prev = segments[segment - 1]; + p = segment + (p - prev) / (length_6 - prev); + } + break; + } + this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0)); + } + return out; + }; + PathConstraint.prototype.addBeforePosition = function (p, temp, i, out, o) { + var x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + }; + PathConstraint.prototype.addAfterPosition = function (p, temp, i, out, o) { + var x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + }; + PathConstraint.prototype.addCurvePosition = function (p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) { + if (p == 0 || isNaN(p)) + p = 0.0001; + var tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; + var ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; + var x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; + out[o] = x; + out[o + 1] = y; + if (tangents) + out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); + }; + PathConstraint.prototype.getOrder = function () { + return this.data.order; + }; + PathConstraint.NONE = -1; + PathConstraint.BEFORE = -2; + PathConstraint.AFTER = -3; + PathConstraint.epsilon = 0.00001; + return PathConstraint; + }()); + + /** + * @public + */ + var TransformConstraint$1 = /** @class */ (function () { + function TransformConstraint(data, skeleton) { + this.rotateMix = 0; + this.translateMix = 0; + this.scaleMix = 0; + this.shearMix = 0; + this.temp = new Vector2(); + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.rotateMix = data.rotateMix; + this.translateMix = data.translateMix; + this.scaleMix = data.scaleMix; + this.shearMix = data.shearMix; + this.bones = new Array(); + for (var i = 0; i < data.bones.length; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findBone(data.target.name); + } + TransformConstraint.prototype.apply = function () { + this.update(); + }; + TransformConstraint.prototype.update = function () { + if (this.data.local) { + if (this.data.relative) + this.applyRelativeLocal(); + else + this.applyAbsoluteLocal(); + } + else { + if (this.data.relative) + this.applyRelativeWorld(); + else + this.applyAbsoluteWorld(); + } + }; + TransformConstraint.prototype.applyAbsoluteWorld = function () { + var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + var target = this.target; + var targetMat = target.matrix; + var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; + var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; + var offsetRotation = this.data.offsetRotation * degRadReflect; + var offsetShearY = this.data.offsetShearY * degRadReflect; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + var modified = false; + var mat = bone.matrix; + if (rotateMix != 0) { + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r *= rotateMix; + var cos = Math.cos(r), sin = Math.sin(r); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + modified = true; + } + if (translateMix != 0) { + var temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + mat.tx += (temp.x - mat.tx) * translateMix; + mat.ty += (temp.y - mat.ty) * translateMix; + modified = true; + } + if (scaleMix > 0) { + var s = Math.sqrt(mat.a * mat.a + mat.b * mat.b); + var ts = Math.sqrt(ta * ta + tc * tc); + if (s > 0.00001) + s = (s + (ts - s + this.data.offsetScaleX) * scaleMix) / s; + mat.a *= s; + mat.b *= s; + s = Math.sqrt(mat.c * mat.c + mat.d * mat.d); + ts = Math.sqrt(tb * tb + td * td); + if (s > 0.00001) + s = (s + (ts - s + this.data.offsetScaleY) * scaleMix) / s; + mat.c *= s; + mat.d *= s; + modified = true; + } + if (shearMix > 0) { + var b = mat.c, d = mat.d; + var by = Math.atan2(d, b); + var r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(mat.b, mat.a)); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r = by + (r + offsetShearY) * shearMix; + var s = Math.sqrt(b * b + d * d); + mat.c = Math.cos(r) * s; + mat.d = Math.sin(r) * s; + modified = true; + } + if (modified) + bone.appliedValid = false; + } + }; + TransformConstraint.prototype.applyRelativeWorld = function () { + var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + var target = this.target; + var targetMat = target.matrix; + var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; + var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; + var offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + var modified = false; + var mat = bone.matrix; + if (rotateMix != 0) { + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var r = Math.atan2(tc, ta) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r *= rotateMix; + var cos = Math.cos(r), sin = Math.sin(r); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + modified = true; + } + if (translateMix != 0) { + var temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + mat.tx += temp.x * translateMix; + mat.ty += temp.y * translateMix; + modified = true; + } + if (scaleMix > 0) { + var s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * scaleMix + 1; + mat.a *= s; + mat.b *= s; + s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1; + mat.c *= s; + mat.d *= s; + modified = true; + } + if (shearMix > 0) { + var r = Math.atan2(td, tb) - Math.atan2(tc, ta); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + var b = mat.c, d = mat.d; + r = Math.atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * shearMix; + var s = Math.sqrt(b * b + d * d); + mat.c = Math.cos(r) * s; + mat.d = Math.sin(r) * s; + modified = true; + } + if (modified) + bone.appliedValid = false; + } + }; + TransformConstraint.prototype.applyAbsoluteLocal = function () { + var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + var target = this.target; + if (!target.appliedValid) + target.updateAppliedTransform(); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (!bone.appliedValid) + bone.updateAppliedTransform(); + var rotation = bone.arotation; + if (rotateMix != 0) { + var r = target.arotation - rotation + this.data.offsetRotation; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + rotation += r * rotateMix; + } + var x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax - x + this.data.offsetX) * translateMix; + y += (target.ay - y + this.data.offsetY) * translateMix; + } + var scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix > 0) { + if (scaleX > 0.00001) + scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * scaleMix) / scaleX; + if (scaleY > 0.00001) + scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * scaleMix) / scaleY; + } + var shearY = bone.ashearY; + if (shearMix > 0) { + var r = target.ashearY - shearY + this.data.offsetShearY; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + bone.shearY += r * shearMix; + } + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + }; + TransformConstraint.prototype.applyRelativeLocal = function () { + var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + var target = this.target; + if (!target.appliedValid) + target.updateAppliedTransform(); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (!bone.appliedValid) + bone.updateAppliedTransform(); + var rotation = bone.arotation; + if (rotateMix != 0) + rotation += (target.arotation + this.data.offsetRotation) * rotateMix; + var x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax + this.data.offsetX) * translateMix; + y += (target.ay + this.data.offsetY) * translateMix; + } + var scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix > 0) { + if (scaleX > 0.00001) + scaleX *= ((target.ascaleX - 1 + this.data.offsetScaleX) * scaleMix) + 1; + if (scaleY > 0.00001) + scaleY *= ((target.ascaleY - 1 + this.data.offsetScaleY) * scaleMix) + 1; + } + var shearY = bone.ashearY; + if (shearMix > 0) + shearY += (target.ashearY + this.data.offsetShearY) * shearMix; + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + }; + TransformConstraint.prototype.getOrder = function () { + return this.data.order; + }; + return TransformConstraint; + }()); + + /** + * @public + */ + var Skeleton$1 = /** @class */ (function () { + function Skeleton(data) { + this._updateCache = new Array(); + this.updateCacheReset = new Array(); + this.time = 0; + this.scaleX = 1; + this.scaleY = 1; + this.x = 0; + this.y = 0; + if (data == null) + throw new Error("data cannot be null."); + this.data = data; + this.bones = new Array(); + for (var i = 0; i < data.bones.length; i++) { + var boneData = data.bones[i]; + var bone = void 0; + if (boneData.parent == null) + bone = new Bone$1(boneData, this, null); + else { + var parent_1 = this.bones[boneData.parent.index]; + bone = new Bone$1(boneData, this, parent_1); + parent_1.children.push(bone); + } + this.bones.push(bone); + } + this.slots = new Array(); + this.drawOrder = new Array(); + for (var i = 0; i < data.slots.length; i++) { + var slotData = data.slots[i]; + var bone = this.bones[slotData.boneData.index]; + var slot = new Slot$1(slotData, bone); + this.slots.push(slot); + this.drawOrder.push(slot); + } + this.ikConstraints = new Array(); + for (var i = 0; i < data.ikConstraints.length; i++) { + var ikConstraintData = data.ikConstraints[i]; + this.ikConstraints.push(new IkConstraint$1(ikConstraintData, this)); + } + this.transformConstraints = new Array(); + for (var i = 0; i < data.transformConstraints.length; i++) { + var transformConstraintData = data.transformConstraints[i]; + this.transformConstraints.push(new TransformConstraint$1(transformConstraintData, this)); + } + this.pathConstraints = new Array(); + for (var i = 0; i < data.pathConstraints.length; i++) { + var pathConstraintData = data.pathConstraints[i]; + this.pathConstraints.push(new PathConstraint$1(pathConstraintData, this)); + } + this.color = new Color(1, 1, 1, 1); + this.updateCache(); + } + Skeleton.prototype.updateCache = function () { + var updateCache = this._updateCache; + updateCache.length = 0; + this.updateCacheReset.length = 0; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + bones[i].sorted = false; + // IK first, lowest hierarchy depth first. + var ikConstraints = this.ikConstraints; + var transformConstraints = this.transformConstraints; + var pathConstraints = this.pathConstraints; + var ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length; + var constraintCount = ikCount + transformCount + pathCount; + outer: for (var i = 0; i < constraintCount; i++) { + for (var ii = 0; ii < ikCount; ii++) { + var constraint = ikConstraints[ii]; + if (constraint.data.order == i) { + this.sortIkConstraint(constraint); + continue outer; + } + } + for (var ii = 0; ii < transformCount; ii++) { + var constraint = transformConstraints[ii]; + if (constraint.data.order == i) { + this.sortTransformConstraint(constraint); + continue outer; + } + } + for (var ii = 0; ii < pathCount; ii++) { + var constraint = pathConstraints[ii]; + if (constraint.data.order == i) { + this.sortPathConstraint(constraint); + continue outer; + } + } + } + for (var i = 0, n = bones.length; i < n; i++) + this.sortBone(bones[i]); + }; + Skeleton.prototype.sortIkConstraint = function (constraint) { + var target = constraint.target; + this.sortBone(target); + var constrained = constraint.bones; + var parent = constrained[0]; + this.sortBone(parent); + if (constrained.length > 1) { + var child = constrained[constrained.length - 1]; + if (!(this._updateCache.indexOf(child) > -1)) + this.updateCacheReset.push(child); + } + this._updateCache.push(constraint); + this.sortReset(parent.children); + constrained[constrained.length - 1].sorted = true; + }; + Skeleton.prototype.sortPathConstraint = function (constraint) { + var slot = constraint.target; + var slotIndex = slot.data.index; + var slotBone = slot.bone; + if (this.skin != null) + this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone); + if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin) + this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone); + for (var i = 0, n = this.data.skins.length; i < n; i++) + this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone); + var attachment = slot.getAttachment(); + if (attachment instanceof PathAttachment$1) + this.sortPathConstraintAttachmentWith(attachment, slotBone); + var constrained = constraint.bones; + var boneCount = constrained.length; + for (var i = 0; i < boneCount; i++) + this.sortBone(constrained[i]); + this._updateCache.push(constraint); + for (var i = 0; i < boneCount; i++) + this.sortReset(constrained[i].children); + for (var i = 0; i < boneCount; i++) + constrained[i].sorted = true; + }; + Skeleton.prototype.sortTransformConstraint = function (constraint) { + this.sortBone(constraint.target); + var constrained = constraint.bones; + var boneCount = constrained.length; + if (constraint.data.local) { + for (var i = 0; i < boneCount; i++) { + var child = constrained[i]; + this.sortBone(child.parent); + if (!(this._updateCache.indexOf(child) > -1)) + this.updateCacheReset.push(child); + } + } + else { + for (var i = 0; i < boneCount; i++) { + this.sortBone(constrained[i]); + } + } + this._updateCache.push(constraint); + for (var ii = 0; ii < boneCount; ii++) + this.sortReset(constrained[ii].children); + for (var ii = 0; ii < boneCount; ii++) + constrained[ii].sorted = true; + }; + Skeleton.prototype.sortPathConstraintAttachment = function (skin, slotIndex, slotBone) { + var attachments = skin.attachments[slotIndex]; + if (!attachments) + return; + for (var key in attachments) { + this.sortPathConstraintAttachmentWith(attachments[key], slotBone); + } + }; + Skeleton.prototype.sortPathConstraintAttachmentWith = function (attachment, slotBone) { + if (!(attachment instanceof PathAttachment$1)) + return; + var pathBones = attachment.bones; + if (pathBones == null) + this.sortBone(slotBone); + else { + var bones = this.bones; + var i = 0; + while (i < pathBones.length) { + var boneCount = pathBones[i++]; + for (var n = i + boneCount; i < n; i++) { + var boneIndex = pathBones[i]; + this.sortBone(bones[boneIndex]); + } + } + } + }; + Skeleton.prototype.sortBone = function (bone) { + if (bone.sorted) + return; + var parent = bone.parent; + if (parent != null) + this.sortBone(parent); + bone.sorted = true; + this._updateCache.push(bone); + }; + Skeleton.prototype.sortReset = function (bones) { + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (bone.sorted) + this.sortReset(bone.children); + bone.sorted = false; + } + }; + /** Updates the world transform for each bone and applies constraints. */ + Skeleton.prototype.updateWorldTransform = function () { + var updateCacheReset = this.updateCacheReset; + for (var i = 0, n = updateCacheReset.length; i < n; i++) { + var bone = updateCacheReset[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + bone.appliedValid = true; + } + var updateCache = this._updateCache; + for (var i = 0, n = updateCache.length; i < n; i++) + updateCache[i].update(); + }; + /** Sets the bones, constraints, and slots to their setup pose values. */ + Skeleton.prototype.setToSetupPose = function () { + this.setBonesToSetupPose(); + this.setSlotsToSetupPose(); + }; + /** Sets the bones and constraints to their setup pose values. */ + Skeleton.prototype.setBonesToSetupPose = function () { + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + bones[i].setToSetupPose(); + var ikConstraints = this.ikConstraints; + for (var i = 0, n = ikConstraints.length; i < n; i++) { + var constraint = ikConstraints[i]; + constraint.bendDirection = constraint.data.bendDirection; + constraint.mix = constraint.data.mix; + } + var transformConstraints = this.transformConstraints; + for (var i = 0, n = transformConstraints.length; i < n; i++) { + var constraint = transformConstraints[i]; + var data = constraint.data; + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + constraint.scaleMix = data.scaleMix; + constraint.shearMix = data.shearMix; + } + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) { + var constraint = pathConstraints[i]; + var data = constraint.data; + constraint.position = data.position; + constraint.spacing = data.spacing; + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + } + }; + Skeleton.prototype.setSlotsToSetupPose = function () { + var slots = this.slots; + Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length); + for (var i = 0, n = slots.length; i < n; i++) + slots[i].setToSetupPose(); + }; + /** @return May return null. */ + Skeleton.prototype.getRootBone = function () { + if (this.bones.length == 0) + return null; + return this.bones[0]; + }; + /** @return May be null. */ + Skeleton.prototype.findBone = function (boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (bone.data.name == boneName) + return bone; + } + return null; + }; + /** @return -1 if the bone was not found. */ + Skeleton.prototype.findBoneIndex = function (boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + if (bones[i].data.name == boneName) + return i; + return -1; + }; + /** @return May be null. */ + Skeleton.prototype.findSlot = function (slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.data.name == slotName) + return slot; + } + return null; + }; + /** @return -1 if the bone was not found. */ + Skeleton.prototype.findSlotIndex = function (slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) + if (slots[i].data.name == slotName) + return i; + return -1; + }; + /** Sets a skin by name. + * @see #setSkin(Skin) */ + Skeleton.prototype.setSkinByName = function (skinName) { + var skin = this.data.findSkin(skinName); + if (skin == null) + throw new Error("Skin not found: " + skinName); + this.setSkin(skin); + }; + /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}. + * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no + * old skin, each slot's setup mode attachment is attached from the new skin. + * @param newSkin May be null. */ + Skeleton.prototype.setSkin = function (newSkin) { + if (newSkin != null) { + if (this.skin != null) + newSkin.attachAll(this, this.skin); + else { + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + var name_1 = slot.data.attachmentName; + if (name_1 != null) { + var attachment = newSkin.getAttachment(i, name_1); + if (attachment != null) + slot.setAttachment(attachment); + } + } + } + } + this.skin = newSkin; + }; + /** @return May be null. */ + Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) { + return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName); + }; + /** @return May be null. */ + Skeleton.prototype.getAttachment = function (slotIndex, attachmentName) { + if (attachmentName == null) + throw new Error("attachmentName cannot be null."); + if (this.skin != null) { + var attachment = this.skin.getAttachment(slotIndex, attachmentName); + if (attachment != null) + return attachment; + } + if (this.data.defaultSkin != null) + return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); + return null; + }; + /** @param attachmentName May be null. */ + Skeleton.prototype.setAttachment = function (slotName, attachmentName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.data.name == slotName) { + var attachment = null; + if (attachmentName != null) { + attachment = this.getAttachment(i, attachmentName); + if (attachment == null) + throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName); + } + slot.setAttachment(attachment); + return; + } + } + throw new Error("Slot not found: " + slotName); + }; + /** @return May be null. */ + Skeleton.prototype.findIkConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var ikConstraints = this.ikConstraints; + for (var i = 0, n = ikConstraints.length; i < n; i++) { + var ikConstraint = ikConstraints[i]; + if (ikConstraint.data.name == constraintName) + return ikConstraint; + } + return null; + }; + /** @return May be null. */ + Skeleton.prototype.findTransformConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var transformConstraints = this.transformConstraints; + for (var i = 0, n = transformConstraints.length; i < n; i++) { + var constraint = transformConstraints[i]; + if (constraint.data.name == constraintName) + return constraint; + } + return null; + }; + /** @return May be null. */ + Skeleton.prototype.findPathConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) { + var constraint = pathConstraints[i]; + if (constraint.data.name == constraintName) + return constraint; + } + return null; + }; + /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. + * @param offset The distance from the skeleton origin to the bottom left corner of the AABB. + * @param size The width and height of the AABB. + * @param temp Working memory */ + Skeleton.prototype.getBounds = function (offset, size, temp) { + if (offset == null) + throw new Error("offset cannot be null."); + if (size == null) + throw new Error("size cannot be null."); + var drawOrder = this.drawOrder; + var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + for (var i = 0, n = drawOrder.length; i < n; i++) { + var slot = drawOrder[i]; + var verticesLength = 0; + var vertices = null; + var attachment = slot.getAttachment(); + if (attachment instanceof RegionAttachment$1) { + verticesLength = 8; + vertices = Utils.setArraySize(temp, verticesLength, 0); + attachment.computeWorldVertices(slot.bone, vertices, 0, 2); + } + else if (attachment instanceof MeshAttachment$1) { + var mesh = attachment; + verticesLength = mesh.worldVerticesLength; + vertices = Utils.setArraySize(temp, verticesLength, 0); + mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2); + } + if (vertices != null) { + for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) { + var x = vertices[ii], y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + } + offset.set(minX, minY); + size.set(maxX - minX, maxY - minY); + }; + Skeleton.prototype.update = function (delta) { + this.time += delta; + }; + Object.defineProperty(Skeleton.prototype, "flipX", { + get: function () { + return this.scaleX == -1; + }, + set: function (value) { + if (!Skeleton.deprecatedWarning1) { + Skeleton.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); + } + this.scaleX = value ? 1.0 : -1.0; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Skeleton.prototype, "flipY", { + get: function () { + return this.scaleY == -1; + }, + set: function (value) { + if (!Skeleton.deprecatedWarning1) { + Skeleton.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); + } + this.scaleY = value ? 1.0 : -1.0; + }, + enumerable: false, + configurable: true + }); + Skeleton.deprecatedWarning1 = false; + return Skeleton; + }()); + + /** Collects each visible {@link BoundingBoxAttachment} and computes the world vertices for its polygon. The polygon vertices are + * provided along with convenience methods for doing hit detection. + * @public + * */ + var SkeletonBounds$1 = /** @class */ (function (_super) { + __extends$2(SkeletonBounds, _super); + function SkeletonBounds() { + return _super !== null && _super.apply(this, arguments) || this; + } + return SkeletonBounds; + }(SkeletonBoundsBase)); + + /** + * @public + */ + var SkeletonData$1 = /** @class */ (function () { + function SkeletonData() { + this.bones = new Array(); // Ordered parents first. + this.slots = new Array(); // Setup pose draw order. + this.skins = new Array(); + this.events = new Array(); + this.animations = new Array(); + this.ikConstraints = new Array(); + this.transformConstraints = new Array(); + this.pathConstraints = new Array(); + // Nonessential + this.fps = 0; + } + SkeletonData.prototype.findBone = function (boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (bone.name == boneName) + return bone; + } + return null; + }; + SkeletonData.prototype.findBoneIndex = function (boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + if (bones[i].name == boneName) + return i; + return -1; + }; + SkeletonData.prototype.findSlot = function (slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.name == slotName) + return slot; + } + return null; + }; + SkeletonData.prototype.findSlotIndex = function (slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) + if (slots[i].name == slotName) + return i; + return -1; + }; + SkeletonData.prototype.findSkin = function (skinName) { + if (skinName == null) + throw new Error("skinName cannot be null."); + var skins = this.skins; + for (var i = 0, n = skins.length; i < n; i++) { + var skin = skins[i]; + if (skin.name == skinName) + return skin; + } + return null; + }; + SkeletonData.prototype.findEvent = function (eventDataName) { + if (eventDataName == null) + throw new Error("eventDataName cannot be null."); + var events = this.events; + for (var i = 0, n = events.length; i < n; i++) { + var event_1 = events[i]; + if (event_1.name == eventDataName) + return event_1; + } + return null; + }; + SkeletonData.prototype.findAnimation = function (animationName) { + if (animationName == null) + throw new Error("animationName cannot be null."); + var animations = this.animations; + for (var i = 0, n = animations.length; i < n; i++) { + var animation = animations[i]; + if (animation.name == animationName) + return animation; + } + return null; + }; + SkeletonData.prototype.findIkConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var ikConstraints = this.ikConstraints; + for (var i = 0, n = ikConstraints.length; i < n; i++) { + var constraint = ikConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + }; + SkeletonData.prototype.findTransformConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var transformConstraints = this.transformConstraints; + for (var i = 0, n = transformConstraints.length; i < n; i++) { + var constraint = transformConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + }; + SkeletonData.prototype.findPathConstraint = function (constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) { + var constraint = pathConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + }; + SkeletonData.prototype.findPathConstraintIndex = function (pathConstraintName) { + if (pathConstraintName == null) + throw new Error("pathConstraintName cannot be null."); + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) + if (pathConstraints[i].name == pathConstraintName) + return i; + return -1; + }; + return SkeletonData; + }()); + + /** + * @public + */ + var SlotData$1 = /** @class */ (function () { + function SlotData(index, name, boneData) { + this.color = new Color(1, 1, 1, 1); + if (index < 0) + throw new Error("index must be >= 0."); + if (name == null) + throw new Error("name cannot be null."); + if (boneData == null) + throw new Error("boneData cannot be null."); + this.index = index; + this.name = name; + this.boneData = boneData; + } + return SlotData; + }()); + + /** + * @public + */ + var TransformConstraintData$1 = /** @class */ (function () { + function TransformConstraintData(name) { + this.order = 0; + this.bones = new Array(); + this.rotateMix = 0; + this.translateMix = 0; + this.scaleMix = 0; + this.shearMix = 0; + this.offsetRotation = 0; + this.offsetX = 0; + this.offsetY = 0; + this.offsetScaleX = 0; + this.offsetScaleY = 0; + this.offsetShearY = 0; + this.relative = false; + this.local = false; + if (name == null) + throw new Error("name cannot be null."); + this.name = name; + } + return TransformConstraintData; + }()); + + /** + * @public + */ + var Skin$1 = /** @class */ (function () { + function Skin(name) { + this.attachments = new Array(); + if (name == null) + throw new Error("name cannot be null."); + this.name = name; + } + Skin.prototype.addAttachment = function (slotIndex, name, attachment) { + if (attachment == null) + throw new Error("attachment cannot be null."); + var attachments = this.attachments; + if (slotIndex >= attachments.length) + attachments.length = slotIndex + 1; + if (!attachments[slotIndex]) + attachments[slotIndex] = {}; + attachments[slotIndex][name] = attachment; + }; + /** @return May be null. */ + Skin.prototype.getAttachment = function (slotIndex, name) { + var dictionary = this.attachments[slotIndex]; + return dictionary ? dictionary[name] : null; + }; + /** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */ + Skin.prototype.attachAll = function (skeleton, oldSkin) { + var slotIndex = 0; + for (var i = 0; i < skeleton.slots.length; i++) { + var slot = skeleton.slots[i]; + var slotAttachment = slot.getAttachment(); + if (slotAttachment && slotIndex < oldSkin.attachments.length) { + var dictionary = oldSkin.attachments[slotIndex]; + for (var key in dictionary) { + var skinAttachment = dictionary[key]; + if (slotAttachment == skinAttachment) { + var attachment = this.getAttachment(slotIndex, key); + if (attachment != null) + slot.setAttachment(attachment); + break; + } + } + } + slotIndex++; + } + }; + return Skin; + }()); + + /** + * @public + */ + var SkeletonJson$1 = /** @class */ (function () { + function SkeletonJson(attachmentLoader) { + this.scale = 1; + this.linkedMeshes = new Array(); + this.attachmentLoader = attachmentLoader; + } + SkeletonJson.prototype.readSkeletonData = function (json) { + var scale = this.scale; + var skeletonData = new SkeletonData$1(); + var root = typeof (json) === "string" ? JSON.parse(json) : json; + // Skeleton + var skeletonMap = root.skeleton; + if (skeletonMap != null) { + skeletonData.hash = skeletonMap.hash; + skeletonData.version = skeletonMap.spine; + skeletonData.width = skeletonMap.width; + skeletonData.height = skeletonMap.height; + skeletonData.fps = skeletonMap.fps; + skeletonData.imagesPath = skeletonMap.images; + } + // Bones + if (root.bones) { + for (var i = 0; i < root.bones.length; i++) { + var boneMap = root.bones[i]; + var parent_1 = null; + var parentName = this.getValue(boneMap, "parent", null); + if (parentName != null) { + parent_1 = skeletonData.findBone(parentName); + if (parent_1 == null) + throw new Error("Parent bone not found: " + parentName); + } + var data = new BoneData$1(skeletonData.bones.length, boneMap.name, parent_1); + data.length = this.getValue(boneMap, "length", 0) * scale; + data.x = this.getValue(boneMap, "x", 0) * scale; + data.y = this.getValue(boneMap, "y", 0) * scale; + data.rotation = this.getValue(boneMap, "rotation", 0); + data.scaleX = this.getValue(boneMap, "scaleX", 1); + data.scaleY = this.getValue(boneMap, "scaleY", 1); + data.shearX = this.getValue(boneMap, "shearX", 0); + data.shearY = this.getValue(boneMap, "shearY", 0); + data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal")); + skeletonData.bones.push(data); + } + } + // Slots. + if (root.slots) { + for (var i = 0; i < root.slots.length; i++) { + var slotMap = root.slots[i]; + var slotName = slotMap.name; + var boneName = slotMap.bone; + var boneData = skeletonData.findBone(boneName); + if (boneData == null) + throw new Error("Slot bone not found: " + boneName); + var data = new SlotData$1(skeletonData.slots.length, slotName, boneData); + var color = this.getValue(slotMap, "color", null); + if (color != null) + data.color.setFromString(color); + var dark = this.getValue(slotMap, "dark", null); + if (dark != null) { + data.darkColor = new Color(1, 1, 1, 1); + data.darkColor.setFromString(dark); + } + data.attachmentName = this.getValue(slotMap, "attachment", null); + data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal")); + skeletonData.slots.push(data); + } + } + // IK constraints + if (root.ik) { + for (var i = 0; i < root.ik.length; i++) { + var constraintMap = root.ik[i]; + var data = new IkConstraintData$1(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + for (var j = 0; j < constraintMap.bones.length; j++) { + var boneName = constraintMap.bones[j]; + var bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("IK bone not found: " + boneName); + data.bones.push(bone); + } + var targetName = constraintMap.target; + data.target = skeletonData.findBone(targetName); + if (data.target == null) + throw new Error("IK target bone not found: " + targetName); + data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; + data.mix = this.getValue(constraintMap, "mix", 1); + skeletonData.ikConstraints.push(data); + } + } + // Transform constraints. + if (root.transform) { + for (var i = 0; i < root.transform.length; i++) { + var constraintMap = root.transform[i]; + var data = new TransformConstraintData$1(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + for (var j = 0; j < constraintMap.bones.length; j++) { + var boneName = constraintMap.bones[j]; + var bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("Transform constraint bone not found: " + boneName); + data.bones.push(bone); + } + var targetName = constraintMap.target; + data.target = skeletonData.findBone(targetName); + if (data.target == null) + throw new Error("Transform constraint target bone not found: " + targetName); + data.local = this.getValue(constraintMap, "local", false); + data.relative = this.getValue(constraintMap, "relative", false); + data.offsetRotation = this.getValue(constraintMap, "rotation", 0); + data.offsetX = this.getValue(constraintMap, "x", 0) * scale; + data.offsetY = this.getValue(constraintMap, "y", 0) * scale; + data.offsetScaleX = this.getValue(constraintMap, "scaleX", 0); + data.offsetScaleY = this.getValue(constraintMap, "scaleY", 0); + data.offsetShearY = this.getValue(constraintMap, "shearY", 0); + data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); + data.translateMix = this.getValue(constraintMap, "translateMix", 1); + data.scaleMix = this.getValue(constraintMap, "scaleMix", 1); + data.shearMix = this.getValue(constraintMap, "shearMix", 1); + skeletonData.transformConstraints.push(data); + } + } + // Path constraints. + if (root.path) { + for (var i = 0; i < root.path.length; i++) { + var constraintMap = root.path[i]; + var data = new PathConstraintData$1(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + for (var j = 0; j < constraintMap.bones.length; j++) { + var boneName = constraintMap.bones[j]; + var bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("Transform constraint bone not found: " + boneName); + data.bones.push(bone); + } + var targetName = constraintMap.target; + data.target = skeletonData.findSlot(targetName); + if (data.target == null) + throw new Error("Path target slot not found: " + targetName); + data.positionMode = SkeletonJson.positionModeFromString(this.getValue(constraintMap, "positionMode", "percent")); + data.spacingMode = SkeletonJson.spacingModeFromString(this.getValue(constraintMap, "spacingMode", "length")); + data.rotateMode = SkeletonJson.rotateModeFromString(this.getValue(constraintMap, "rotateMode", "tangent")); + data.offsetRotation = this.getValue(constraintMap, "rotation", 0); + data.position = this.getValue(constraintMap, "position", 0); + if (data.positionMode == exports.PositionMode.Fixed) + data.position *= scale; + data.spacing = this.getValue(constraintMap, "spacing", 0); + if (data.spacingMode == SpacingMode$1.Length || data.spacingMode == SpacingMode$1.Fixed) + data.spacing *= scale; + data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); + data.translateMix = this.getValue(constraintMap, "translateMix", 1); + skeletonData.pathConstraints.push(data); + } + } + // Skins. + if (root.skins) { + for (var skinName in root.skins) { + var skinMap = root.skins[skinName]; + var skin = new Skin$1(skinName); + for (var slotName in skinMap) { + var slotIndex = skeletonData.findSlotIndex(slotName); + if (slotIndex == -1) + throw new Error("Slot not found: " + slotName); + var slotMap = skinMap[slotName]; + for (var entryName in slotMap) { + var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData); + if (attachment != null) + skin.addAttachment(slotIndex, entryName, attachment); + } + } + skeletonData.skins.push(skin); + if (skin.name == "default") + skeletonData.defaultSkin = skin; + } + } + // Linked meshes. + for (var i = 0, n = this.linkedMeshes.length; i < n; i++) { + var linkedMesh = this.linkedMeshes[i]; + var skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); + if (skin == null) + throw new Error("Skin not found: " + linkedMesh.skin); + var parent_2 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (parent_2 == null) + throw new Error("Parent mesh not found: " + linkedMesh.parent); + linkedMesh.mesh.setParentMesh(parent_2); + //linkedMesh.mesh.updateUVs(); + } + this.linkedMeshes.length = 0; + // Events. + if (root.events) { + for (var eventName in root.events) { + var eventMap = root.events[eventName]; + var data = new EventData$1(eventName); + data.intValue = this.getValue(eventMap, "int", 0); + data.floatValue = this.getValue(eventMap, "float", 0); + data.stringValue = this.getValue(eventMap, "string", ""); + data.audioPath = this.getValue(eventMap, "audio", null); + if (data.audioPath != null) { + data.volume = this.getValue(eventMap, "volume", 1); + data.balance = this.getValue(eventMap, "balance", 0); + } + skeletonData.events.push(data); + } + } + // Animations. + if (root.animations) { + for (var animationName in root.animations) { + var animationMap = root.animations[animationName]; + this.readAnimation(animationMap, animationName, skeletonData); + } + } + return skeletonData; + }; + SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) { + var scale = this.scale; + name = this.getValue(map, "name", name); + var type = this.getValue(map, "type", "region"); + switch (type) { + case "region": { + var path = this.getValue(map, "path", name); + var region = this.attachmentLoader.newRegionAttachment(skin, name, path); + if (region == null) + return null; + region.path = path; + region.x = this.getValue(map, "x", 0) * scale; + region.y = this.getValue(map, "y", 0) * scale; + region.scaleX = this.getValue(map, "scaleX", 1); + region.scaleY = this.getValue(map, "scaleY", 1); + region.rotation = this.getValue(map, "rotation", 0); + region.width = map.width * scale; + region.height = map.height * scale; + var color = this.getValue(map, "color", null); + if (color != null) + region.color.setFromString(color); + //region.updateOffset(); + return region; + } + case "boundingbox": { + var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (box == null) + return null; + this.readVertices(map, box, map.vertexCount << 1); + var color = this.getValue(map, "color", null); + if (color != null) + box.color.setFromString(color); + return box; + } + case "mesh": + case "linkedmesh": { + var path = this.getValue(map, "path", name); + var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); + if (mesh == null) + return null; + mesh.path = path; + var color = this.getValue(map, "color", null); + if (color != null) + mesh.color.setFromString(color); + var parent_3 = this.getValue(map, "parent", null); + if (parent_3 != null) { + mesh.inheritDeform = this.getValue(map, "deform", true); + this.linkedMeshes.push(new LinkedMesh$2(mesh, this.getValue(map, "skin", null), slotIndex, parent_3)); + return mesh; + } + var uvs = map.uvs; + this.readVertices(map, mesh, uvs.length); + mesh.triangles = map.triangles; + mesh.regionUVs = new Float32Array(uvs); + //mesh.updateUVs(); + mesh.hullLength = this.getValue(map, "hull", 0) * 2; + return mesh; + } + case "path": { + var path = this.attachmentLoader.newPathAttachment(skin, name); + if (path == null) + return null; + path.closed = this.getValue(map, "closed", false); + path.constantSpeed = this.getValue(map, "constantSpeed", true); + var vertexCount = map.vertexCount; + this.readVertices(map, path, vertexCount << 1); + var lengths = Utils.newArray(vertexCount / 3, 0); + for (var i = 0; i < map.lengths.length; i++) + lengths[i] = map.lengths[i] * scale; + path.lengths = lengths; + var color = this.getValue(map, "color", null); + if (color != null) + path.color.setFromString(color); + return path; + } + case "point": { + var point = this.attachmentLoader.newPointAttachment(skin, name); + if (point == null) + return null; + point.x = this.getValue(map, "x", 0) * scale; + point.y = this.getValue(map, "y", 0) * scale; + point.rotation = this.getValue(map, "rotation", 0); + var color = this.getValue(map, "color", null); + if (color != null) + point.color.setFromString(color); + return point; + } + case "clipping": { + var clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (clip == null) + return null; + var end = this.getValue(map, "end", null); + if (end != null) { + var slot = skeletonData.findSlot(end); + if (slot == null) + throw new Error("Clipping end slot not found: " + end); + clip.endSlot = slot; + } + var vertexCount = map.vertexCount; + this.readVertices(map, clip, vertexCount << 1); + var color = this.getValue(map, "color", null); + if (color != null) + clip.color.setFromString(color); + return clip; + } + } + return null; + }; + SkeletonJson.prototype.readVertices = function (map, attachment, verticesLength) { + var scale = this.scale; + attachment.worldVerticesLength = verticesLength; + var vertices = map.vertices; + if (verticesLength == vertices.length) { + var scaledVertices = Utils.toFloatArray(vertices); + if (scale != 1) { + for (var i = 0, n = vertices.length; i < n; i++) + scaledVertices[i] *= scale; + } + attachment.vertices = scaledVertices; + return; + } + var weights = new Array(); + var bones = new Array(); + for (var i = 0, n = vertices.length; i < n;) { + var boneCount = vertices[i++]; + bones.push(boneCount); + for (var nn = i + boneCount * 4; i < nn; i += 4) { + bones.push(vertices[i]); + weights.push(vertices[i + 1] * scale); + weights.push(vertices[i + 2] * scale); + weights.push(vertices[i + 3]); + } + } + attachment.bones = bones; + attachment.vertices = Utils.toFloatArray(weights); + }; + SkeletonJson.prototype.readAnimation = function (map, name, skeletonData) { + var scale = this.scale; + var timelines = new Array(); + var duration = 0; + // Slot timelines. + if (map.slots) { + for (var slotName in map.slots) { + var slotMap = map.slots[slotName]; + var slotIndex = skeletonData.findSlotIndex(slotName); + if (slotIndex == -1) + throw new Error("Slot not found: " + slotName); + for (var timelineName in slotMap) { + var timelineMap = slotMap[timelineName]; + if (timelineName == "attachment") { + var timeline = new AttachmentTimeline$1(timelineMap.length); + timeline.slotIndex = slotIndex; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + timeline.setFrame(frameIndex++, valueMap.time, valueMap.name); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + else if (timelineName == "color") { + var timeline = new ColorTimeline(timelineMap.length); + timeline.slotIndex = slotIndex; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + var color = new Color(); + color.setFromString(valueMap.color || "ffffffff"); + timeline.setFrame(frameIndex, valueMap.time, color.r, color.g, color.b, color.a); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * ColorTimeline.ENTRIES]); + } + else if (timelineName == "twoColor") { + var timeline = new TwoColorTimeline(timelineMap.length); + timeline.slotIndex = slotIndex; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + var light = new Color(); + var dark = new Color(); + light.setFromString(valueMap.light); + dark.setFromString(valueMap.dark); + timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TwoColorTimeline.ENTRIES]); + } + else + throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); + } + } + } + // Bone timelines. + if (map.bones) { + for (var boneName in map.bones) { + var boneMap = map.bones[boneName]; + var boneIndex = skeletonData.findBoneIndex(boneName); + if (boneIndex == -1) + throw new Error("Bone not found: " + boneName); + for (var timelineName in boneMap) { + var timelineMap = boneMap[timelineName]; + if (timelineName === "rotate") { + var timeline = new RotateTimeline$1(timelineMap.length); + timeline.boneIndex = boneIndex; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, valueMap.time, valueMap.angle); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * RotateTimeline$1.ENTRIES]); + } + else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") { + var timeline = null; + var timelineScale = 1; + if (timelineName === "scale") + timeline = new ScaleTimeline$1(timelineMap.length); + else if (timelineName === "shear") + timeline = new ShearTimeline$1(timelineMap.length); + else { + timeline = new TranslateTimeline$1(timelineMap.length); + timelineScale = scale; + } + timeline.boneIndex = boneIndex; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + var x = this.getValue(valueMap, "x", 0), y = this.getValue(valueMap, "y", 0); + timeline.setFrame(frameIndex, valueMap.time, x * timelineScale, y * timelineScale); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TranslateTimeline$1.ENTRIES]); + } + else + throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); + } + } + } + // IK constraint timelines. + if (map.ik) { + for (var constraintName in map.ik) { + var constraintMap = map.ik[constraintName]; + var constraint = skeletonData.findIkConstraint(constraintName); + var timeline = new IkConstraintTimeline$1(constraintMap.length); + timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(constraint); + var frameIndex = 0; + for (var i = 0; i < constraintMap.length; i++) { + var valueMap = constraintMap[i]; + timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * IkConstraintTimeline$1.ENTRIES]); + } + } + // Transform constraint timelines. + if (map.transform) { + for (var constraintName in map.transform) { + var constraintMap = map.transform[constraintName]; + var constraint = skeletonData.findTransformConstraint(constraintName); + var timeline = new TransformConstraintTimeline$1(constraintMap.length); + timeline.transformConstraintIndex = skeletonData.transformConstraints.indexOf(constraint); + var frameIndex = 0; + for (var i = 0; i < constraintMap.length; i++) { + var valueMap = constraintMap[i]; + timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TransformConstraintTimeline$1.ENTRIES]); + } + } + // Path constraint timelines. + if (map.paths) { + for (var constraintName in map.paths) { + var constraintMap = map.paths[constraintName]; + var index = skeletonData.findPathConstraintIndex(constraintName); + if (index == -1) + throw new Error("Path constraint not found: " + constraintName); + var data = skeletonData.pathConstraints[index]; + for (var timelineName in constraintMap) { + var timelineMap = constraintMap[timelineName]; + if (timelineName === "position" || timelineName === "spacing") { + var timeline = null; + var timelineScale = 1; + if (timelineName === "spacing") { + timeline = new PathConstraintSpacingTimeline$1(timelineMap.length); + if (data.spacingMode == SpacingMode$1.Length || data.spacingMode == SpacingMode$1.Fixed) + timelineScale = scale; + } + else { + timeline = new PathConstraintPositionTimeline$1(timelineMap.length); + if (data.positionMode == exports.PositionMode.Fixed) + timelineScale = scale; + } + timeline.pathConstraintIndex = index; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, timelineName, 0) * timelineScale); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * PathConstraintPositionTimeline$1.ENTRIES]); + } + else if (timelineName === "mix") { + var timeline = new PathConstraintMixTimeline$1(timelineMap.length); + timeline.pathConstraintIndex = index; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * PathConstraintMixTimeline$1.ENTRIES]); + } + } + } + } + // Deform timelines. + if (map.deform) { + for (var deformName in map.deform) { + var deformMap = map.deform[deformName]; + var skin = skeletonData.findSkin(deformName); + if (skin == null) { + if (settings.FAIL_ON_NON_EXISTING_SKIN) { + throw new Error("Skin not found: " + deformName); + } + else { + continue; + } + } + for (var slotName in deformMap) { + var slotMap = deformMap[slotName]; + var slotIndex = skeletonData.findSlotIndex(slotName); + if (slotIndex == -1) + throw new Error("Slot not found: " + slotMap.name); + for (var timelineName in slotMap) { + var timelineMap = slotMap[timelineName]; + var attachment = skin.getAttachment(slotIndex, timelineName); + if (attachment == null) + throw new Error("Deform attachment not found: " + timelineMap.name); + var weighted = attachment.bones != null; + var vertices = attachment.vertices; + var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + var timeline = new DeformTimeline$1(timelineMap.length); + timeline.slotIndex = slotIndex; + timeline.attachment = attachment; + var frameIndex = 0; + for (var j = 0; j < timelineMap.length; j++) { + var valueMap = timelineMap[j]; + var deform = void 0; + var verticesValue = this.getValue(valueMap, "vertices", null); + if (verticesValue == null) + deform = weighted ? Utils.newFloatArray(deformLength) : vertices; + else { + deform = Utils.newFloatArray(deformLength); + var start = this.getValue(valueMap, "offset", 0); + Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); + if (scale != 1) { + for (var i = start, n = i + verticesValue.length; i < n; i++) + deform[i] *= scale; + } + if (!weighted) { + for (var i = 0; i < deformLength; i++) + deform[i] += vertices[i]; + } + } + timeline.setFrame(frameIndex, valueMap.time, deform); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + } + } + } + // Draw order timeline. + var drawOrderNode = map.drawOrder; + if (drawOrderNode == null) + drawOrderNode = map.draworder; + if (drawOrderNode != null) { + var timeline = new DrawOrderTimeline$1(drawOrderNode.length); + var slotCount = skeletonData.slots.length; + var frameIndex = 0; + for (var j = 0; j < drawOrderNode.length; j++) { + var drawOrderMap = drawOrderNode[j]; + var drawOrder = null; + var offsets = this.getValue(drawOrderMap, "offsets", null); + if (offsets != null) { + drawOrder = Utils.newArray(slotCount, -1); + var unchanged = Utils.newArray(slotCount - offsets.length, 0); + var originalIndex = 0, unchangedIndex = 0; + for (var i = 0; i < offsets.length; i++) { + var offsetMap = offsets[i]; + var slotIndex = skeletonData.findSlotIndex(offsetMap.slot); + if (slotIndex == -1) + throw new Error("Slot not found: " + offsetMap.slot); + // Collect unchanged items. + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + // Set changed items. + drawOrder[originalIndex + offsetMap.offset] = originalIndex++; + } + // Collect remaining unchanged items. + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + // Fill in unchanged items. + for (var i = slotCount - 1; i >= 0; i--) + if (drawOrder[i] == -1) + drawOrder[i] = unchanged[--unchangedIndex]; + } + timeline.setFrame(frameIndex++, drawOrderMap.time, drawOrder); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + // Event timeline. + if (map.events) { + var timeline = new EventTimeline$1(map.events.length); + var frameIndex = 0; + for (var i = 0; i < map.events.length; i++) { + var eventMap = map.events[i]; + var eventData = skeletonData.findEvent(eventMap.name); + if (eventData == null) + throw new Error("Event not found: " + eventMap.name); + var event_1 = new Event$1(Utils.toSinglePrecision(eventMap.time), eventData); + event_1.intValue = this.getValue(eventMap, "int", eventData.intValue); + event_1.floatValue = this.getValue(eventMap, "float", eventData.floatValue); + event_1.stringValue = this.getValue(eventMap, "string", eventData.stringValue); + if (event_1.data.audioPath != null) { + event_1.volume = this.getValue(eventMap, "volume", 1); + event_1.balance = this.getValue(eventMap, "balance", 0); + } + timeline.setFrame(frameIndex++, event_1); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + if (isNaN(duration)) { + throw new Error("Error while parsing animation, duration is NaN"); + } + skeletonData.animations.push(new Animation$1(name, timelines, duration)); + }; + SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) { + if (!map.curve) + return; + if (map.curve === "stepped") + timeline.setStepped(frameIndex); + else if (Object.prototype.toString.call(map.curve) === '[object Array]') { + var curve = map.curve; + timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]); + } + }; + SkeletonJson.prototype.getValue = function (map, prop, defaultValue) { + return map[prop] !== undefined ? map[prop] : defaultValue; + }; + SkeletonJson.blendModeFromString = function (str) { + str = str.toLowerCase(); + if (str == "normal") + return constants.BLEND_MODES.NORMAL; + if (str == "additive") + return constants.BLEND_MODES.ADD; + if (str == "multiply") + return constants.BLEND_MODES.MULTIPLY; + if (str == "screen") + return constants.BLEND_MODES.SCREEN; + throw new Error("Unknown blend mode: " + str); + }; + SkeletonJson.positionModeFromString = function (str) { + str = str.toLowerCase(); + if (str == "fixed") + return exports.PositionMode.Fixed; + if (str == "percent") + return exports.PositionMode.Percent; + throw new Error("Unknown position mode: " + str); + }; + SkeletonJson.spacingModeFromString = function (str) { + str = str.toLowerCase(); + if (str == "length") + return SpacingMode$1.Length; + if (str == "fixed") + return SpacingMode$1.Fixed; + if (str == "percent") + return SpacingMode$1.Percent; + throw new Error("Unknown position mode: " + str); + }; + SkeletonJson.rotateModeFromString = function (str) { + str = str.toLowerCase(); + if (str == "tangent") + return exports.RotateMode.Tangent; + if (str == "chain") + return exports.RotateMode.Chain; + if (str == "chainscale") + return exports.RotateMode.ChainScale; + throw new Error("Unknown rotate mode: " + str); + }; + SkeletonJson.transformModeFromString = function (str) { + str = str.toLowerCase(); + if (str == "normal") + return exports.TransformMode.Normal; + if (str == "onlytranslation") + return exports.TransformMode.OnlyTranslation; + if (str == "norotationorreflection") + return exports.TransformMode.NoRotationOrReflection; + if (str == "noscale") + return exports.TransformMode.NoScale; + if (str == "noscaleorreflection") + return exports.TransformMode.NoScaleOrReflection; + throw new Error("Unknown transform mode: " + str); + }; + return SkeletonJson; + }()); + var LinkedMesh$2 = /** @class */ (function () { + function LinkedMesh(mesh, skin, slotIndex, parent) { + this.mesh = mesh; + this.skin = skin; + this.slotIndex = slotIndex; + this.parent = parent; + } + return LinkedMesh; + }()); + + /** + * @public + */ + var Spine$2 = /** @class */ (function (_super) { + __extends$2(Spine, _super); + function Spine() { + return _super !== null && _super.apply(this, arguments) || this; + } + Spine.prototype.createSkeleton = function (spineData) { + this.skeleton = new Skeleton$1(spineData); + this.skeleton.updateWorldTransform(); + this.stateData = new AnimationStateData$1(spineData); + this.state = new AnimationState$1(this.stateData); + }; + return Spine; + }(SpineBase)); + + var spine37 = /*#__PURE__*/Object.freeze({ + __proto__: null, + Animation: Animation$1, + AnimationState: AnimationState$1, + AnimationStateAdapter2: AnimationStateAdapter2, + AnimationStateData: AnimationStateData$1, + AtlasAttachmentLoader: AtlasAttachmentLoader$1, + Attachment: Attachment$1, + AttachmentTimeline: AttachmentTimeline$1, + Bone: Bone$1, + BoneData: BoneData$1, + BoundingBoxAttachment: BoundingBoxAttachment$1, + ClippingAttachment: ClippingAttachment$1, + ColorTimeline: ColorTimeline, + CurveTimeline: CurveTimeline$1, + DeformTimeline: DeformTimeline$1, + DrawOrderTimeline: DrawOrderTimeline$1, + Event: Event$1, + EventData: EventData$1, + EventQueue: EventQueue$1, + EventTimeline: EventTimeline$1, + get EventType () { return EventType$1; }, + IkConstraint: IkConstraint$1, + IkConstraintData: IkConstraintData$1, + IkConstraintTimeline: IkConstraintTimeline$1, + JitterEffect: JitterEffect, + MeshAttachment: MeshAttachment$1, + PathAttachment: PathAttachment$1, + PathConstraint: PathConstraint$1, + PathConstraintData: PathConstraintData$1, + PathConstraintMixTimeline: PathConstraintMixTimeline$1, + PathConstraintPositionTimeline: PathConstraintPositionTimeline$1, + PathConstraintSpacingTimeline: PathConstraintSpacingTimeline$1, + PointAttachment: PointAttachment$1, + RegionAttachment: RegionAttachment$1, + RotateTimeline: RotateTimeline$1, + ScaleTimeline: ScaleTimeline$1, + ShearTimeline: ShearTimeline$1, + Skeleton: Skeleton$1, + SkeletonBounds: SkeletonBounds$1, + SkeletonData: SkeletonData$1, + SkeletonJson: SkeletonJson$1, + Skin: Skin$1, + Slot: Slot$1, + SlotData: SlotData$1, + get SpacingMode () { return SpacingMode$1; }, + Spine: Spine$2, + SwirlEffect: SwirlEffect, + get TimelineType () { return TimelineType; }, + TrackEntry: TrackEntry$1, + TransformConstraint: TransformConstraint$1, + TransformConstraintData: TransformConstraintData$1, + TransformConstraintTimeline: TransformConstraintTimeline$1, + TranslateTimeline: TranslateTimeline$1, + TwoColorTimeline: TwoColorTimeline, + VertexAttachment: VertexAttachment$1 + }); + + /* eslint-disable */ + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + var extendStatics$1 = function(d, b) { + extendStatics$1 = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics$1(d, b); + }; + + function __extends$1(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics$1(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + + /** + * The base class for all attachments. + * @public + */ + var Attachment = /** @class */ (function () { + function Attachment(name) { + if (!name) + throw new Error("name cannot be null."); + this.name = name; + } + return Attachment; + }()); + /** + * Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by a slot's + * {@link Slot#deform}. + * @public + */ + var VertexAttachment = /** @class */ (function (_super) { + __extends$1(VertexAttachment, _super); + function VertexAttachment(name) { + var _this = _super.call(this, name) || this; + /** The unique ID for this attachment. */ + _this.id = VertexAttachment.nextID++; + /** The bones which affect the {@link #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 {@link Skeleton#bones}. Will be null + * if this attachment has no weights. */ + _this.bones = null; + /** 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. */ + _this.vertices = []; + /** The maximum number of world vertex values that can be output by + * {@link #computeWorldVertices()} using the `count` parameter. */ + _this.worldVerticesLength = 0; + /** Timelines for the timeline attachment are also applied to this attachment. + * May be null if no attachment-specific timelines should be applied. */ + _this.timelineAttachment = _this; + return _this; + } + VertexAttachment.prototype.computeWorldVerticesOld = function (slot, worldVertices) { + this.computeWorldVertices(slot, 0, this.worldVerticesLength, worldVertices, 0, 2); + }; + /** Transforms the attachment's local {@link #vertices} to world coordinates. If the slot's {@link Slot#deform} 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. + * @param start The index of the first {@link #vertices} value to transform. Each vertex has 2 values, x and y. + * @param count The number of world vertex values to output. Must be <= {@link #worldVerticesLength} - `start`. + * @param worldVertices The output world vertices. Must have a length >= `offset` + `count` * + * `stride` / 2. + * @param offset The `worldVertices` index to begin writing values. + * @param stride The number of `worldVertices` entries between the value pairs written. */ + VertexAttachment.prototype.computeWorldVertices = function (slot, start, count, worldVertices, offset, stride) { + count = offset + (count >> 1) * stride; + var skeleton = slot.bone.skeleton; + var deformArray = slot.deform; + var vertices = this.vertices; + var bones = this.bones; + if (!bones) { + if (deformArray.length > 0) + vertices = deformArray; + var mat = slot.bone.matrix; + var x = mat.tx; + var y = mat.ty; + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + for (var v_1 = start, w = offset; w < count; v_1 += 2, w += stride) { + var vx = vertices[v_1], vy = vertices[v_1 + 1]; + worldVertices[w] = vx * a + vy * b + x; + worldVertices[w + 1] = vx * c + vy * d + y; + } + return; + } + var v = 0, skip = 0; + for (var i = 0; i < start; i += 2) { + var n = bones[v]; + v += n + 1; + skip += n; + } + var skeletonBones = skeleton.bones; + if (deformArray.length == 0) { + for (var w = offset, b = skip * 3; w < count; w += stride) { + var wx = 0, wy = 0; + var n = bones[v++]; + n += v; + for (; v < n; v++, b += 3) { + var mat = skeletonBones[bones[v]].matrix; + var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; + wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; + wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + else { + var deform = deformArray; + for (var w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { + var wx = 0, wy = 0; + var n = bones[v++]; + n += v; + for (; v < n; v++, b += 3, f += 2) { + var mat = skeletonBones[bones[v]].matrix; + var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; + wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; + wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + }; + /** Does not copy id (generated) or name (set on construction). **/ + VertexAttachment.prototype.copyTo = function (attachment) { + if (this.bones) { + attachment.bones = new Array(this.bones.length); + Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length); + } + else + attachment.bones = null; + if (this.vertices) { + attachment.vertices = Utils.newFloatArray(this.vertices.length); + Utils.arrayCopy(this.vertices, 0, attachment.vertices, 0, this.vertices.length); + } + attachment.worldVerticesLength = this.worldVerticesLength; + attachment.timelineAttachment = this.timelineAttachment; + }; + VertexAttachment.nextID = 0; + return VertexAttachment; + }(Attachment)); + + /** + * @public + */ + var BoundingBoxAttachment = /** @class */ (function (_super) { + __extends$1(BoundingBoxAttachment, _super); + function BoundingBoxAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.BoundingBox; + _this.color = new Color(1, 1, 1, 1); + return _this; + } + BoundingBoxAttachment.prototype.copy = function () { + var copy = new BoundingBoxAttachment(this.name); + this.copyTo(copy); + copy.color.setFromColor(this.color); + return copy; + }; + return BoundingBoxAttachment; + }(VertexAttachment)); + + /** + * @public + */ + var ClippingAttachment = /** @class */ (function (_super) { + __extends$1(ClippingAttachment, _super); + function ClippingAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Clipping; + /** Clipping is performed between the clipping polygon's slot and the end slot. Returns null if clipping is done until the end of + * the skeleton's rendering. */ + _this.endSlot = null; + // Nonessential. + /** The color of the clipping polygon as it was in Spine. Available only when nonessential data was exported. Clipping polygons + * are not usually rendered at runtime. */ + _this.color = new Color(0.2275, 0.2275, 0.8078, 1); // ce3a3aff + return _this; + } + ClippingAttachment.prototype.copy = function () { + var copy = new ClippingAttachment(this.name); + this.copyTo(copy); + copy.endSlot = this.endSlot; + copy.color.setFromColor(this.color); + return copy; + }; + return ClippingAttachment; + }(VertexAttachment)); + + /** + * @public + */ + var MeshAttachment = /** @class */ (function (_super) { + __extends$1(MeshAttachment, _super); + function MeshAttachment(name, path) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Mesh; + _this.region = null; + /** Triplets of vertex indices which describe the mesh's triangulation. */ + _this.triangles = []; + /** The color to tint the mesh. */ + _this.color = new Color(1, 1, 1, 1); + /** The width of the mesh's image. Available only when nonessential data was exported. */ + _this.width = 0; + /** The height of the mesh's image. Available only when nonessential data was exported. */ + _this.height = 0; + /** The number of entries at the beginning of {@link #vertices} that make up the mesh hull. */ + _this.hullLength = 0; + /** Vertex index pairs describing edges for controling triangulation. Mesh triangles will never cross edges. Only available if + * nonessential data was exported. Triangulation is not performed at runtime. */ + _this.edges = []; + _this.parentMesh = null; + _this.sequence = null; + _this.tempColor = new Color(0, 0, 0, 0); + _this.path = path; + return _this; + } + /** The parent mesh if this is a linked mesh, else null. A linked mesh shares the {@link #bones}, {@link #vertices}, + * {@link #regionUVs}, {@link #triangles}, {@link #hullLength}, {@link #edges}, {@link #width}, and {@link #height} with the + * parent mesh, but may have a different {@link #name} or {@link #path} (and therefore a different texture). */ + MeshAttachment.prototype.getParentMesh = function () { + return this.parentMesh; + }; + /** @param parentMesh May be null. */ + MeshAttachment.prototype.setParentMesh = function (parentMesh) { + this.parentMesh = parentMesh; + if (parentMesh) { + this.bones = parentMesh.bones; + this.vertices = parentMesh.vertices; + this.worldVerticesLength = parentMesh.worldVerticesLength; + this.regionUVs = parentMesh.regionUVs; + this.triangles = parentMesh.triangles; + this.hullLength = parentMesh.hullLength; + this.worldVerticesLength = parentMesh.worldVerticesLength; + } + }; + MeshAttachment.prototype.copy = function () { + if (this.parentMesh) + return this.newLinkedMesh(); + var copy = new MeshAttachment(this.name, this.path); + copy.region = this.region; + copy.color.setFromColor(this.color); + this.copyTo(copy); + copy.regionUVs = new Float32Array(this.regionUVs.length); + Utils.arrayCopy(this.regionUVs, 0, copy.regionUVs, 0, this.regionUVs.length); + copy.triangles = new Array(this.triangles.length); + Utils.arrayCopy(this.triangles, 0, copy.triangles, 0, this.triangles.length); + copy.hullLength = this.hullLength; + copy.sequence = this.sequence != null ? this.sequence.copy() : null; + // Nonessential. + if (this.edges) { + copy.edges = new Array(this.edges.length); + Utils.arrayCopy(this.edges, 0, copy.edges, 0, this.edges.length); + } + copy.width = this.width; + copy.height = this.height; + return copy; + }; + MeshAttachment.prototype.computeWorldVertices = function (slot, start, count, worldVertices, offset, stride) { + if (this.sequence != null) + this.sequence.apply(slot, this); + _super.prototype.computeWorldVertices.call(this, slot, start, count, worldVertices, offset, stride); + }; + /** Returns a new mesh with the {@link #parentMesh} set to this mesh's parent mesh, if any, else to this mesh. **/ + MeshAttachment.prototype.newLinkedMesh = function () { + var copy = new MeshAttachment(this.name, this.path); + copy.region = this.region; + copy.color.setFromColor(this.color); + copy.timelineAttachment = this.timelineAttachment; + copy.setParentMesh(this.parentMesh ? this.parentMesh : this); + // if (copy.region != null) copy.updateRegion(); + return copy; + }; + return MeshAttachment; + }(VertexAttachment)); + + /** + * @public + */ + var PathAttachment = /** @class */ (function (_super) { + __extends$1(PathAttachment, _super); + function PathAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Path; + /** The lengths along the path in the setup pose from the start of the path to the end of each Bezier curve. */ + _this.lengths = []; + /** If true, the start and end knots are connected. */ + _this.closed = false; + /** If true, additional calculations are performed to make calculating positions along the path more accurate. If false, fewer + * calculations are performed but calculating positions along the path is less accurate. */ + _this.constantSpeed = false; + /** The color of the path as it was in Spine. Available only when nonessential data was exported. Paths are not usually + * rendered at runtime. */ + _this.color = new Color(1, 1, 1, 1); + return _this; + } + PathAttachment.prototype.copy = function () { + var copy = new PathAttachment(this.name); + this.copyTo(copy); + copy.lengths = new Array(this.lengths.length); + Utils.arrayCopy(this.lengths, 0, copy.lengths, 0, this.lengths.length); + copy.closed = closed; + copy.constantSpeed = this.constantSpeed; + copy.color.setFromColor(this.color); + return copy; + }; + return PathAttachment; + }(VertexAttachment)); + + /** + * @public + */ + var PointAttachment = /** @class */ (function (_super) { + __extends$1(PointAttachment, _super); + function PointAttachment(name) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Point; + _this.x = 0; + _this.y = 0; + _this.rotation = 0; + /** The color of the point attachment as it was in Spine. Available only when nonessential data was exported. Point attachments + * are not usually rendered at runtime. */ + _this.color = new Color(0.38, 0.94, 0, 1); + return _this; + } + PointAttachment.prototype.computeWorldPosition = function (bone, point) { + var mat = bone.matrix; + point.x = this.x * mat.a + this.y * mat.c + bone.worldX; + point.y = this.x * mat.b + this.y * mat.d + bone.worldY; + return point; + }; + PointAttachment.prototype.computeWorldRotation = function (bone) { + var mat = bone.matrix; + var cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation); + var x = cos * mat.a + sin * mat.c; + var y = cos * mat.b + sin * mat.d; + return Math.atan2(y, x) * MathUtils.radDeg; + }; + PointAttachment.prototype.copy = function () { + var copy = new PointAttachment(this.name); + copy.x = this.x; + copy.y = this.y; + copy.rotation = this.rotation; + copy.color.setFromColor(this.color); + return copy; + }; + return PointAttachment; + }(VertexAttachment)); + + /** + * @public + */ + var RegionAttachment = /** @class */ (function (_super) { + __extends$1(RegionAttachment, _super); + function RegionAttachment(name, path) { + var _this = _super.call(this, name) || this; + _this.type = exports.AttachmentType.Region; + /** The local x translation. */ + _this.x = 0; + /** The local y translation. */ + _this.y = 0; + /** The local scaleX. */ + _this.scaleX = 1; + /** The local scaleY. */ + _this.scaleY = 1; + /** The local rotation. */ + _this.rotation = 0; + /** The width of the region attachment in Spine. */ + _this.width = 0; + /** The height of the region attachment in Spine. */ + _this.height = 0; + /** The color to tint the region attachment. */ + _this.color = new Color(1, 1, 1, 1); + _this.rendererObject = null; + _this.region = null; + _this.sequence = null; + /** For each of the 4 vertices, a pair of x,y values that is the local position of the vertex. + * + * See {@link #updateOffset()}. */ + _this.offset = Utils.newFloatArray(8); + _this.uvs = Utils.newFloatArray(8); + _this.tempColor = new Color(1, 1, 1, 1); + _this.path = path; + return _this; + } + /** Calculates the {@link #offset} using the region settings. Must be called after changing region settings. */ + RegionAttachment.prototype.updateRegion = function () { + if (!this.region) + throw new Error("Region not set."); + var region = this.region; + var regionScaleX = this.width / this.region.originalWidth * this.scaleX; + var regionScaleY = this.height / this.region.originalHeight * this.scaleY; + var localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; + var localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; + var localX2 = localX + this.region.width * regionScaleX; + var localY2 = localY + this.region.height * regionScaleY; + var radians = this.rotation * Math.PI / 180; + var cos = Math.cos(radians); + var sin = Math.sin(radians); + var x = this.x, y = this.y; + var localXCos = localX * cos + x; + var localXSin = localX * sin; + var localYCos = localY * cos + y; + var localYSin = localY * sin; + var localX2Cos = localX2 * cos + x; + var localX2Sin = localX2 * sin; + var localY2Cos = localY2 * cos + y; + var localY2Sin = localY2 * sin; + var offset = this.offset; + offset[0] = localXCos - localYSin; + offset[1] = localYCos + localXSin; + offset[2] = localXCos - localY2Sin; + offset[3] = localY2Cos + localXSin; + offset[4] = localX2Cos - localY2Sin; + offset[5] = localY2Cos + localX2Sin; + offset[6] = localX2Cos - localYSin; + offset[7] = localYCos + localX2Sin; + var uvs = this.uvs; + if (region.degrees == 90) { + uvs[2] = region.u; + uvs[3] = region.v2; + uvs[4] = region.u; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v; + uvs[0] = region.u2; + uvs[1] = region.v2; + } + else { + uvs[0] = region.u; + uvs[1] = region.v2; + uvs[2] = region.u; + uvs[3] = region.v; + uvs[4] = region.u2; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v2; + } + }; + /** Transforms the attachment's four vertices to world coordinates. If the attachment has a {@link #sequence}, the region may + * be changed. + *

+ * See World transforms in the Spine + * Runtimes Guide. + * @param worldVertices The output world vertices. Must have a length >= offset + 8. + * @param offset The worldVertices index to begin writing values. + * @param stride The number of worldVertices entries between the value pairs written. */ + RegionAttachment.prototype.computeWorldVertices = function (slot, worldVertices, offset, stride) { + if (this.sequence != null) + this.sequence.apply(slot, this); + var bone = slot.bone; + var vertexOffset = this.offset; + var mat = bone.matrix; + var x = mat.tx, y = mat.ty; + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var offsetX = 0, offsetY = 0; + offsetX = vertexOffset[0]; + offsetY = vertexOffset[1]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // br + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[2]; + offsetY = vertexOffset[3]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // bl + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[4]; + offsetY = vertexOffset[5]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // ul + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[6]; + offsetY = vertexOffset[7]; + worldVertices[offset] = offsetX * a + offsetY * b + x; // ur + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + }; + RegionAttachment.prototype.copy = function () { + var copy = new RegionAttachment(this.name, this.path); + copy.region = this.region; + copy.rendererObject = this.rendererObject; + copy.x = this.x; + copy.y = this.y; + copy.scaleX = this.scaleX; + copy.scaleY = this.scaleY; + copy.rotation = this.rotation; + copy.width = this.width; + copy.height = this.height; + Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, 8); + Utils.arrayCopy(this.offset, 0, copy.offset, 0, 8); + copy.color.setFromColor(this.color); + copy.sequence = this.sequence != null ? this.sequence.copy() : null; + return copy; + }; + RegionAttachment.X1 = 0; + RegionAttachment.Y1 = 1; + RegionAttachment.C1R = 2; + RegionAttachment.C1G = 3; + RegionAttachment.C1B = 4; + RegionAttachment.C1A = 5; + RegionAttachment.U1 = 6; + RegionAttachment.V1 = 7; + RegionAttachment.X2 = 8; + RegionAttachment.Y2 = 9; + RegionAttachment.C2R = 10; + RegionAttachment.C2G = 11; + RegionAttachment.C2B = 12; + RegionAttachment.C2A = 13; + RegionAttachment.U2 = 14; + RegionAttachment.V2 = 15; + RegionAttachment.X3 = 16; + RegionAttachment.Y3 = 17; + RegionAttachment.C3R = 18; + RegionAttachment.C3G = 19; + RegionAttachment.C3B = 20; + RegionAttachment.C3A = 21; + RegionAttachment.U3 = 22; + RegionAttachment.V3 = 23; + RegionAttachment.X4 = 24; + RegionAttachment.Y4 = 25; + RegionAttachment.C4R = 26; + RegionAttachment.C4G = 27; + RegionAttachment.C4B = 28; + RegionAttachment.C4A = 29; + RegionAttachment.U4 = 30; + RegionAttachment.V4 = 31; + return RegionAttachment; + }(Attachment)); + + /** + * @public + */ + var Sequence = /** @class */ (function () { + function Sequence(count) { + this.id = Sequence.nextID(); + this.start = 0; + this.digits = 0; + /** The index of the region to show for the setup pose. */ + this.setupIndex = 0; + this.regions = new Array(count); + } + Sequence.prototype.copy = function () { + var copy = new Sequence(this.regions.length); + Utils.arrayCopy(this.regions, 0, copy.regions, 0, this.regions.length); + copy.start = this.start; + copy.digits = this.digits; + copy.setupIndex = this.setupIndex; + return copy; + }; + Sequence.prototype.apply = function (slot, attachment) { + var index = slot.sequenceIndex; + if (index == -1) + index = this.setupIndex; + if (index >= this.regions.length) + index = this.regions.length - 1; + var region = this.regions[index]; + if (attachment.region != region) { + attachment.region = region; + // attachment.updateRegion(); + } + }; + Sequence.prototype.getPath = function (basePath, index) { + var result = basePath; + var frame = (this.start + index).toString(); + for (var i = this.digits - frame.length; i > 0; i--) + result += "0"; + result += frame; + return result; + }; + Sequence.nextID = function () { + return Sequence._nextID++; + }; + Sequence._nextID = 0; + return Sequence; + }()); + /** + * @public + */ + var SequenceMode; + (function (SequenceMode) { + SequenceMode[SequenceMode["hold"] = 0] = "hold"; + SequenceMode[SequenceMode["once"] = 1] = "once"; + SequenceMode[SequenceMode["loop"] = 2] = "loop"; + SequenceMode[SequenceMode["pingpong"] = 3] = "pingpong"; + SequenceMode[SequenceMode["onceReverse"] = 4] = "onceReverse"; + SequenceMode[SequenceMode["loopReverse"] = 5] = "loopReverse"; + SequenceMode[SequenceMode["pingpongReverse"] = 6] = "pingpongReverse"; + })(SequenceMode || (SequenceMode = {})); + /** + * @public + */ + var SequenceModeValues = [ + SequenceMode.hold, + SequenceMode.once, + SequenceMode.loop, + SequenceMode.pingpong, + SequenceMode.onceReverse, + SequenceMode.loopReverse, + SequenceMode.pingpongReverse + ]; + + /** + * A simple container for a list of timelines and a name. + * @public + * */ + var Animation = /** @class */ (function () { + function Animation(name, timelines, duration) { + this.timelines = []; + this.timelineIds = new StringSet(); + if (!name) + throw new Error("name cannot be null."); + this.name = name; + this.setTimelines(timelines); + this.duration = duration; + } + Animation.prototype.setTimelines = function (timelines) { + if (!timelines) + throw new Error("timelines cannot be null."); + this.timelines = timelines; + this.timelineIds.clear(); + for (var i = 0; i < timelines.length; i++) + this.timelineIds.addAll(timelines[i].getPropertyIds()); + }; + Animation.prototype.hasTimeline = function (ids) { + for (var i = 0; i < ids.length; i++) + if (this.timelineIds.contains(ids[i])) + return true; + return false; + }; + /** Applies all the animation's timelines to the specified skeleton. + * + * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. + * @param loop If true, the animation repeats after {@link #getDuration()}. + * @param events May be null to ignore fired events. */ + Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, blend, direction) { + if (!skeleton) + throw new Error("skeleton cannot be null."); + if (loop && this.duration != 0) { + time %= this.duration; + if (lastTime > 0) + lastTime %= this.duration; + } + var timelines = this.timelines; + for (var i = 0, n = timelines.length; i < n; i++) + timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction); + }; + return Animation; + }()); + var Property = { + rotate: 0, + x: 1, + y: 2, + scaleX: 3, + scaleY: 4, + shearX: 5, + shearY: 6, + rgb: 7, + alpha: 8, + rgb2: 9, + attachment: 10, + deform: 11, + event: 12, + drawOrder: 13, + ikConstraint: 14, + transformConstraint: 15, + pathConstraintPosition: 16, + pathConstraintSpacing: 17, + pathConstraintMix: 18, + sequence: 19 + }; + /** The interface for all timelines. + * @public + * */ + var Timeline = /** @class */ (function () { + function Timeline(frameCount, propertyIds) { + this.propertyIds = propertyIds; + this.frames = Utils.newFloatArray(frameCount * this.getFrameEntries()); + } + Timeline.prototype.getPropertyIds = function () { + return this.propertyIds; + }; + Timeline.prototype.getFrameEntries = function () { + return 1; + }; + Timeline.prototype.getFrameCount = function () { + return this.frames.length / this.getFrameEntries(); + }; + Timeline.prototype.getDuration = function () { + return this.frames[this.frames.length - this.getFrameEntries()]; + }; + Timeline.search1 = function (frames, time) { + var n = frames.length; + for (var i = 1; i < n; i++) + if (frames[i] > time) + return i - 1; + return n - 1; + }; + Timeline.search = function (frames, time, step) { + var n = frames.length; + for (var i = step; i < n; i += step) + if (frames[i] > time) + return i - step; + return n - step; + }; + return Timeline; + }()); + /** The base class for timelines that use interpolation between key frame values. + * @public + * */ + var CurveTimeline = /** @class */ (function (_super) { + __extends$1(CurveTimeline, _super); + function CurveTimeline(frameCount, bezierCount, propertyIds) { + var _this = _super.call(this, frameCount, propertyIds) || this; + _this.curves = Utils.newFloatArray(frameCount + bezierCount * 18 /*BEZIER_SIZE*/); + _this.curves[frameCount - 1] = 1 /*STEPPED*/; + return _this; + } + /** Sets the specified key frame to linear interpolation. */ + CurveTimeline.prototype.setLinear = function (frame) { + this.curves[frame] = 0 /*LINEAR*/; + }; + /** Sets the specified key frame to stepped interpolation. */ + CurveTimeline.prototype.setStepped = function (frame) { + this.curves[frame] = 1 /*STEPPED*/; + }; + /** Shrinks the storage for Bezier curves, for use when bezierCount (specified in the constructor) was larger + * than the actual number of Bezier curves. */ + CurveTimeline.prototype.shrink = function (bezierCount) { + var size = this.getFrameCount() + bezierCount * 18 /*BEZIER_SIZE*/; + if (this.curves.length > size) { + var newCurves = Utils.newFloatArray(size); + Utils.arrayCopy(this.curves, 0, newCurves, 0, size); + this.curves = newCurves; + } + }; + /** Stores the segments for the specified Bezier curve. For timelines that modify multiple values, there may be more than + * one curve per frame. + * @param bezier The ordinal of this Bezier curve for this timeline, between 0 and bezierCount - 1 (specified + * in the constructor), inclusive. + * @param frame Between 0 and frameCount - 1, inclusive. + * @param value The index of the value for this frame that this curve is used for. + * @param time1 The time for the first key. + * @param value1 The value for the first key. + * @param cx1 The time for the first Bezier handle. + * @param cy1 The value for the first Bezier handle. + * @param cx2 The time of the second Bezier handle. + * @param cy2 The value for the second Bezier handle. + * @param time2 The time for the second key. + * @param value2 The value for the second key. */ + CurveTimeline.prototype.setBezier = function (bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2) { + var curves = this.curves; + var i = this.getFrameCount() + bezier * 18 /*BEZIER_SIZE*/; + if (value == 0) + curves[frame] = 2 /*BEZIER*/ + i; + var tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = (value1 - cy1 * 2 + cy2) * 0.03; + var dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006, dddy = ((cy1 - cy2) * 3 - value1 + value2) * 0.006; + var ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy; + var dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = (cy1 - value1) * 0.3 + tmpy + dddy * 0.16666667; + var x = time1 + dx, y = value1 + dy; + for (var n = i + 18 /*BEZIER_SIZE*/; i < n; i += 2) { + curves[i] = x; + curves[i + 1] = y; + dx += ddx; + dy += ddy; + ddx += dddx; + ddy += dddy; + x += dx; + y += dy; + } + }; + /** Returns the Bezier interpolated value for the specified time. + * @param frameIndex The index into {@link #getFrames()} for the values of the frame before time. + * @param valueOffset The offset from frameIndex to the value this curve is used for. + * @param i The index of the Bezier segments. See {@link #getCurveType(int)}. */ + CurveTimeline.prototype.getBezierValue = function (time, frameIndex, valueOffset, i) { + var curves = this.curves; + if (curves[i] > time) { + var x_1 = this.frames[frameIndex], y_1 = this.frames[frameIndex + valueOffset]; + return y_1 + (time - x_1) / (curves[i] - x_1) * (curves[i + 1] - y_1); + } + var n = i + 18 /*BEZIER_SIZE*/; + for (i += 2; i < n; i += 2) { + if (curves[i] >= time) { + var x_2 = curves[i - 2], y_2 = curves[i - 1]; + return y_2 + (time - x_2) / (curves[i] - x_2) * (curves[i + 1] - y_2); + } + } + frameIndex += this.getFrameEntries(); + var x = curves[n - 2], y = curves[n - 1]; + return y + (time - x) / (this.frames[frameIndex] - x) * (this.frames[frameIndex + valueOffset] - y); + }; + return CurveTimeline; + }(Timeline)); + /** + * @public + */ + var CurveTimeline1 = /** @class */ (function (_super) { + __extends$1(CurveTimeline1, _super); + function CurveTimeline1(frameCount, bezierCount, propertyId) { + return _super.call(this, frameCount, bezierCount, [propertyId]) || this; + } + CurveTimeline1.prototype.getFrameEntries = function () { + return 2 /*ENTRIES*/; + }; + /** Sets the time and value for the specified frame. + * @param frame Between 0 and frameCount, inclusive. + * @param time The frame time in seconds. */ + CurveTimeline1.prototype.setFrame = function (frame, time, value) { + frame <<= 1; + this.frames[frame] = time; + this.frames[frame + 1 /*VALUE*/] = value; + }; + /** Returns the interpolated value for the specified time. */ + CurveTimeline1.prototype.getCurveValue = function (time) { + var frames = this.frames; + var i = frames.length - 2; + for (var ii = 2; ii <= i; ii += 2) { + if (frames[ii] > time) { + i = ii - 2; + break; + } + } + var curveType = this.curves[i >> 1]; + switch (curveType) { + case 0 /*LINEAR*/: + var before = frames[i], value = frames[i + 1 /*VALUE*/]; + return value + (time - before) / (frames[i + 2 /*ENTRIES*/] - before) * (frames[i + 2 /*ENTRIES*/ + 1 /*VALUE*/] - value); + case 1 /*STEPPED*/: + return frames[i + 1 /*VALUE*/]; + } + return this.getBezierValue(time, i, 1 /*VALUE*/, curveType - 2 /*BEZIER*/); + }; + return CurveTimeline1; + }(CurveTimeline)); + /** The base class for a {@link CurveTimeline} which sets two properties. + * @public + * */ + var CurveTimeline2 = /** @class */ (function (_super) { + __extends$1(CurveTimeline2, _super); + /** @param bezierCount The maximum number of Bezier curves. See {@link #shrink(int)}. + * @param propertyIds Unique identifiers for the properties the timeline modifies. */ + function CurveTimeline2(frameCount, bezierCount, propertyId1, propertyId2) { + return _super.call(this, frameCount, bezierCount, [propertyId1, propertyId2]) || this; + } + CurveTimeline2.prototype.getFrameEntries = function () { + return 3 /*ENTRIES*/; + }; + /** Sets the time and values for the specified frame. + * @param frame Between 0 and frameCount, inclusive. + * @param time The frame time in seconds. */ + CurveTimeline2.prototype.setFrame = function (frame, time, value1, value2) { + frame *= 3 /*ENTRIES*/; + this.frames[frame] = time; + this.frames[frame + 1 /*VALUE1*/] = value1; + this.frames[frame + 2 /*VALUE2*/] = value2; + }; + return CurveTimeline2; + }(CurveTimeline)); + /** Changes a bone's local {@link Bone#rotation}. + * @public + * */ + var RotateTimeline = /** @class */ (function (_super) { + __extends$1(RotateTimeline, _super); + function RotateTimeline(frameCount, bezierCount, boneIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.rotate + "|" + boneIndex) || this; + _this.boneIndex = 0; + _this.boneIndex = boneIndex; + return _this; + } + RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.rotation = bone.data.rotation; + return; + case exports.MixBlend.first: + bone.rotation += (bone.data.rotation - bone.rotation) * alpha; + } + return; + } + var r = this.getCurveValue(time); + switch (blend) { + case exports.MixBlend.setup: + bone.rotation = bone.data.rotation + r * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + r += bone.data.rotation - bone.rotation; + case exports.MixBlend.add: + bone.rotation += r * alpha; + } + }; + return RotateTimeline; + }(CurveTimeline1)); + /** Changes a bone's local {@link Bone#x} and {@link Bone#y}. + * @public + * */ + var TranslateTimeline = /** @class */ (function (_super) { + __extends$1(TranslateTimeline, _super); + function TranslateTimeline(frameCount, bezierCount, boneIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.x + "|" + boneIndex, Property.y + "|" + boneIndex) || this; + _this.boneIndex = 0; + _this.boneIndex = boneIndex; + return _this; + } + TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.x = bone.data.x; + bone.y = bone.data.y; + return; + case exports.MixBlend.first: + bone.x += (bone.data.x - bone.x) * alpha; + bone.y += (bone.data.y - bone.y) * alpha; + } + return; + } + var x = 0, y = 0; + var i = Timeline.search(frames, time, 3 /*ENTRIES*/); + var curveType = this.curves[i / 3 /*ENTRIES*/]; + switch (curveType) { + case 0 /*LINEAR*/: + var before = frames[i]; + x = frames[i + 1 /*VALUE1*/]; + y = frames[i + 2 /*VALUE2*/]; + var t = (time - before) / (frames[i + 3 /*ENTRIES*/] - before); + x += (frames[i + 3 /*ENTRIES*/ + 1 /*VALUE1*/] - x) * t; + y += (frames[i + 3 /*ENTRIES*/ + 2 /*VALUE2*/] - y) * t; + break; + case 1 /*STEPPED*/: + x = frames[i + 1 /*VALUE1*/]; + y = frames[i + 2 /*VALUE2*/]; + break; + default: + x = this.getBezierValue(time, i, 1 /*VALUE1*/, curveType - 2 /*BEZIER*/); + y = this.getBezierValue(time, i, 2 /*VALUE2*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); + } + switch (blend) { + case exports.MixBlend.setup: + bone.x = bone.data.x + x * alpha; + bone.y = bone.data.y + y * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bone.x += (bone.data.x + x - bone.x) * alpha; + bone.y += (bone.data.y + y - bone.y) * alpha; + break; + case exports.MixBlend.add: + bone.x += x * alpha; + bone.y += y * alpha; + } + }; + return TranslateTimeline; + }(CurveTimeline2)); + /** Changes a bone's local {@link Bone#x}. + * @public + * */ + var TranslateXTimeline = /** @class */ (function (_super) { + __extends$1(TranslateXTimeline, _super); + function TranslateXTimeline(frameCount, bezierCount, boneIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.x + "|" + boneIndex) || this; + _this.boneIndex = 0; + _this.boneIndex = boneIndex; + return _this; + } + TranslateXTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.x = bone.data.x; + return; + case exports.MixBlend.first: + bone.x += (bone.data.x - bone.x) * alpha; + } + return; + } + var x = this.getCurveValue(time); + switch (blend) { + case exports.MixBlend.setup: + bone.x = bone.data.x + x * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bone.x += (bone.data.x + x - bone.x) * alpha; + break; + case exports.MixBlend.add: + bone.x += x * alpha; + } + }; + return TranslateXTimeline; + }(CurveTimeline1)); + /** Changes a bone's local {@link Bone#x}. + * @public + * */ + var TranslateYTimeline = /** @class */ (function (_super) { + __extends$1(TranslateYTimeline, _super); + function TranslateYTimeline(frameCount, bezierCount, boneIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.y + "|" + boneIndex) || this; + _this.boneIndex = 0; + _this.boneIndex = boneIndex; + return _this; + } + TranslateYTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.y = bone.data.y; + return; + case exports.MixBlend.first: + bone.y += (bone.data.y - bone.y) * alpha; + } + return; + } + var y = this.getCurveValue(time); + switch (blend) { + case exports.MixBlend.setup: + bone.y = bone.data.y + y * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bone.y += (bone.data.y + y - bone.y) * alpha; + break; + case exports.MixBlend.add: + bone.y += y * alpha; + } + }; + return TranslateYTimeline; + }(CurveTimeline1)); + /** Changes a bone's local {@link Bone#scaleX)} and {@link Bone#scaleY}. + * @public + * */ + var ScaleTimeline = /** @class */ (function (_super) { + __extends$1(ScaleTimeline, _super); + function ScaleTimeline(frameCount, bezierCount, boneIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.scaleX + "|" + boneIndex, Property.scaleY + "|" + boneIndex) || this; + _this.boneIndex = 0; + _this.boneIndex = boneIndex; + return _this; + } + ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.scaleX = bone.data.scaleX; + bone.scaleY = bone.data.scaleY; + return; + case exports.MixBlend.first: + bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; + } + return; + } + var x, y; + var i = Timeline.search(frames, time, 3 /*ENTRIES*/); + var curveType = this.curves[i / 3 /*ENTRIES*/]; + switch (curveType) { + case 0 /*LINEAR*/: + var before = frames[i]; + x = frames[i + 1 /*VALUE1*/]; + y = frames[i + 2 /*VALUE2*/]; + var t = (time - before) / (frames[i + 3 /*ENTRIES*/] - before); + x += (frames[i + 3 /*ENTRIES*/ + 1 /*VALUE1*/] - x) * t; + y += (frames[i + 3 /*ENTRIES*/ + 2 /*VALUE2*/] - y) * t; + break; + case 1 /*STEPPED*/: + x = frames[i + 1 /*VALUE1*/]; + y = frames[i + 2 /*VALUE2*/]; + break; + default: + x = this.getBezierValue(time, i, 1 /*VALUE1*/, curveType - 2 /*BEZIER*/); + y = this.getBezierValue(time, i, 2 /*VALUE2*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); + } + x *= bone.data.scaleX; + y *= bone.data.scaleY; + if (alpha == 1) { + if (blend == exports.MixBlend.add) { + bone.scaleX += x - bone.data.scaleX; + bone.scaleY += y - bone.data.scaleY; + } + else { + bone.scaleX = x; + bone.scaleY = y; + } + } + else { + var bx = 0, by = 0; + if (direction == exports.MixDirection.mixOut) { + switch (blend) { + case exports.MixBlend.setup: + bx = bone.data.scaleX; + by = bone.data.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case exports.MixBlend.add: + bone.scaleX += (x - bone.data.scaleX) * alpha; + bone.scaleY += (y - bone.data.scaleY) * alpha; + } + } + else { + switch (blend) { + case exports.MixBlend.setup: + bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x); + by = Math.abs(bone.data.scaleY) * MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bx = Math.abs(bone.scaleX) * MathUtils.signum(x); + by = Math.abs(bone.scaleY) * MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case exports.MixBlend.add: + bone.scaleX += (x - bone.data.scaleX) * alpha; + bone.scaleY += (y - bone.data.scaleY) * alpha; + } + } + } + }; + return ScaleTimeline; + }(CurveTimeline2)); + /** Changes a bone's local {@link Bone#scaleX)} and {@link Bone#scaleY}. + * @public + * */ + var ScaleXTimeline = /** @class */ (function (_super) { + __extends$1(ScaleXTimeline, _super); + function ScaleXTimeline(frameCount, bezierCount, boneIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.scaleX + "|" + boneIndex) || this; + _this.boneIndex = 0; + _this.boneIndex = boneIndex; + return _this; + } + ScaleXTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.scaleX = bone.data.scaleX; + return; + case exports.MixBlend.first: + bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; + } + return; + } + var x = this.getCurveValue(time) * bone.data.scaleX; + if (alpha == 1) { + if (blend == exports.MixBlend.add) + bone.scaleX += x - bone.data.scaleX; + else + bone.scaleX = x; + } + else { + // Mixing out uses sign of setup or current pose, else use sign of key. + var bx = 0; + if (direction == exports.MixDirection.mixOut) { + switch (blend) { + case exports.MixBlend.setup: + bx = bone.data.scaleX; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bx = bone.scaleX; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + break; + case exports.MixBlend.add: + bone.scaleX += (x - bone.data.scaleX) * alpha; + } + } + else { + switch (blend) { + case exports.MixBlend.setup: + bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x); + bone.scaleX = bx + (x - bx) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bx = Math.abs(bone.scaleX) * MathUtils.signum(x); + bone.scaleX = bx + (x - bx) * alpha; + break; + case exports.MixBlend.add: + bone.scaleX += (x - bone.data.scaleX) * alpha; + } + } + } + }; + return ScaleXTimeline; + }(CurveTimeline1)); + /** Changes a bone's local {@link Bone#scaleX)} and {@link Bone#scaleY}. + * @public + * */ + var ScaleYTimeline = /** @class */ (function (_super) { + __extends$1(ScaleYTimeline, _super); + function ScaleYTimeline(frameCount, bezierCount, boneIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.scaleY + "|" + boneIndex) || this; + _this.boneIndex = 0; + _this.boneIndex = boneIndex; + return _this; + } + ScaleYTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.scaleY = bone.data.scaleY; + return; + case exports.MixBlend.first: + bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; + } + return; + } + var y = this.getCurveValue(time) * bone.data.scaleY; + if (alpha == 1) { + if (blend == exports.MixBlend.add) + bone.scaleY += y - bone.data.scaleY; + else + bone.scaleY = y; + } + else { + // Mixing out uses sign of setup or current pose, else use sign of key. + var by = 0; + if (direction == exports.MixDirection.mixOut) { + switch (blend) { + case exports.MixBlend.setup: + by = bone.data.scaleY; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + by = bone.scaleY; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case exports.MixBlend.add: + bone.scaleY += (y - bone.data.scaleY) * alpha; + } + } + else { + switch (blend) { + case exports.MixBlend.setup: + by = Math.abs(bone.data.scaleY) * MathUtils.signum(y); + bone.scaleY = by + (y - by) * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + by = Math.abs(bone.scaleY) * MathUtils.signum(y); + bone.scaleY = by + (y - by) * alpha; + break; + case exports.MixBlend.add: + bone.scaleY += (y - bone.data.scaleY) * alpha; + } + } + } + }; + return ScaleYTimeline; + }(CurveTimeline1)); + /** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. + * @public + * */ + var ShearTimeline = /** @class */ (function (_super) { + __extends$1(ShearTimeline, _super); + function ShearTimeline(frameCount, bezierCount, boneIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.shearX + "|" + boneIndex, Property.shearY + "|" + boneIndex) || this; + _this.boneIndex = 0; + _this.boneIndex = boneIndex; + return _this; + } + ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.shearX = bone.data.shearX; + bone.shearY = bone.data.shearY; + return; + case exports.MixBlend.first: + bone.shearX += (bone.data.shearX - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY - bone.shearY) * alpha; + } + return; + } + var x = 0, y = 0; + var i = Timeline.search(frames, time, 3 /*ENTRIES*/); + var curveType = this.curves[i / 3 /*ENTRIES*/]; + switch (curveType) { + case 0 /*LINEAR*/: + var before = frames[i]; + x = frames[i + 1 /*VALUE1*/]; + y = frames[i + 2 /*VALUE2*/]; + var t = (time - before) / (frames[i + 3 /*ENTRIES*/] - before); + x += (frames[i + 3 /*ENTRIES*/ + 1 /*VALUE1*/] - x) * t; + y += (frames[i + 3 /*ENTRIES*/ + 2 /*VALUE2*/] - y) * t; + break; + case 1 /*STEPPED*/: + x = frames[i + 1 /*VALUE1*/]; + y = frames[i + 2 /*VALUE2*/]; + break; + default: + x = this.getBezierValue(time, i, 1 /*VALUE1*/, curveType - 2 /*BEZIER*/); + y = this.getBezierValue(time, i, 2 /*VALUE2*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); + } + switch (blend) { + case exports.MixBlend.setup: + bone.shearX = bone.data.shearX + x * alpha; + bone.shearY = bone.data.shearY + y * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; + break; + case exports.MixBlend.add: + bone.shearX += x * alpha; + bone.shearY += y * alpha; + } + }; + return ShearTimeline; + }(CurveTimeline2)); + /** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. + * @public + * */ + var ShearXTimeline = /** @class */ (function (_super) { + __extends$1(ShearXTimeline, _super); + function ShearXTimeline(frameCount, bezierCount, boneIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.shearX + "|" + boneIndex) || this; + _this.boneIndex = 0; + _this.boneIndex = boneIndex; + return _this; + } + ShearXTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.shearX = bone.data.shearX; + return; + case exports.MixBlend.first: + bone.shearX += (bone.data.shearX - bone.shearX) * alpha; + } + return; + } + var x = this.getCurveValue(time); + switch (blend) { + case exports.MixBlend.setup: + bone.shearX = bone.data.shearX + x * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; + break; + case exports.MixBlend.add: + bone.shearX += x * alpha; + } + }; + return ShearXTimeline; + }(CurveTimeline1)); + /** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. + * @public + * */ + var ShearYTimeline = /** @class */ (function (_super) { + __extends$1(ShearYTimeline, _super); + function ShearYTimeline(frameCount, bezierCount, boneIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.shearY + "|" + boneIndex) || this; + _this.boneIndex = 0; + _this.boneIndex = boneIndex; + return _this; + } + ShearYTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.shearY = bone.data.shearY; + return; + case exports.MixBlend.first: + bone.shearY += (bone.data.shearY - bone.shearY) * alpha; + } + return; + } + var y = this.getCurveValue(time); + switch (blend) { + case exports.MixBlend.setup: + bone.shearY = bone.data.shearY + y * alpha; + break; + case exports.MixBlend.first: + case exports.MixBlend.replace: + bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; + break; + case exports.MixBlend.add: + bone.shearY += y * alpha; + } + }; + return ShearYTimeline; + }(CurveTimeline1)); + /** Changes a slot's {@link Slot#color}. + * @public + * */ + var RGBATimeline = /** @class */ (function (_super) { + __extends$1(RGBATimeline, _super); + function RGBATimeline(frameCount, bezierCount, slotIndex) { + var _this = _super.call(this, frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex, + Property.alpha + "|" + slotIndex + ]) || this; + _this.slotIndex = 0; + _this.slotIndex = slotIndex; + return _this; + } + RGBATimeline.prototype.getFrameEntries = function () { + return 5 /*ENTRIES*/; + }; + /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ + RGBATimeline.prototype.setFrame = function (frame, time, r, g, b, a) { + frame *= 5 /*ENTRIES*/; + this.frames[frame] = time; + this.frames[frame + 1 /*R*/] = r; + this.frames[frame + 2 /*G*/] = g; + this.frames[frame + 3 /*B*/] = b; + this.frames[frame + 4 /*A*/] = a; + }; + RGBATimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + var frames = this.frames; + var color = slot.color; + if (time < frames[0]) { + var setup = slot.data.color; + switch (blend) { + case exports.MixBlend.setup: + color.setFromColor(setup); + return; + case exports.MixBlend.first: + color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha); + } + return; + } + var r = 0, g = 0, b = 0, a = 0; + var i = Timeline.search(frames, time, 5 /*ENTRIES*/); + var curveType = this.curves[i / 5 /*ENTRIES*/]; + switch (curveType) { + case 0 /*LINEAR*/: + var before = frames[i]; + r = frames[i + 1 /*R*/]; + g = frames[i + 2 /*G*/]; + b = frames[i + 3 /*B*/]; + a = frames[i + 4 /*A*/]; + var t = (time - before) / (frames[i + 5 /*ENTRIES*/] - before); + r += (frames[i + 5 /*ENTRIES*/ + 1 /*R*/] - r) * t; + g += (frames[i + 5 /*ENTRIES*/ + 2 /*G*/] - g) * t; + b += (frames[i + 5 /*ENTRIES*/ + 3 /*B*/] - b) * t; + a += (frames[i + 5 /*ENTRIES*/ + 4 /*A*/] - a) * t; + break; + case 1 /*STEPPED*/: + r = frames[i + 1 /*R*/]; + g = frames[i + 2 /*G*/]; + b = frames[i + 3 /*B*/]; + a = frames[i + 4 /*A*/]; + break; + default: + r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/); + g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); + b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); + a = this.getBezierValue(time, i, 4 /*A*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/); + } + if (alpha == 1) + color.set(r, g, b, a); + else { + if (blend == exports.MixBlend.setup) + color.setFromColor(slot.data.color); + color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha); + } + }; + return RGBATimeline; + }(CurveTimeline)); + /** Changes a slot's {@link Slot#color}. + * @public + * */ + var RGBTimeline = /** @class */ (function (_super) { + __extends$1(RGBTimeline, _super); + function RGBTimeline(frameCount, bezierCount, slotIndex) { + var _this = _super.call(this, frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex + ]) || this; + _this.slotIndex = 0; + _this.slotIndex = slotIndex; + return _this; + } + RGBTimeline.prototype.getFrameEntries = function () { + return 4 /*ENTRIES*/; + }; + /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ + RGBTimeline.prototype.setFrame = function (frame, time, r, g, b) { + frame <<= 2; + this.frames[frame] = time; + this.frames[frame + 1 /*R*/] = r; + this.frames[frame + 2 /*G*/] = g; + this.frames[frame + 3 /*B*/] = b; + }; + RGBTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + var frames = this.frames; + var color = slot.color; + if (time < frames[0]) { + var setup = slot.data.color; + switch (blend) { + case exports.MixBlend.setup: + color.r = setup.r; + color.g = setup.g; + color.b = setup.b; + return; + case exports.MixBlend.first: + color.r += (setup.r - color.r) * alpha; + color.g += (setup.g - color.g) * alpha; + color.b += (setup.b - color.b) * alpha; + } + return; + } + var r = 0, g = 0, b = 0; + var i = Timeline.search(frames, time, 4 /*ENTRIES*/); + var curveType = this.curves[i >> 2]; + switch (curveType) { + case 0 /*LINEAR*/: + var before = frames[i]; + r = frames[i + 1 /*R*/]; + g = frames[i + 2 /*G*/]; + b = frames[i + 3 /*B*/]; + var t = (time - before) / (frames[i + 4 /*ENTRIES*/] - before); + r += (frames[i + 4 /*ENTRIES*/ + 1 /*R*/] - r) * t; + g += (frames[i + 4 /*ENTRIES*/ + 2 /*G*/] - g) * t; + b += (frames[i + 4 /*ENTRIES*/ + 3 /*B*/] - b) * t; + break; + case 1 /*STEPPED*/: + r = frames[i + 1 /*R*/]; + g = frames[i + 2 /*G*/]; + b = frames[i + 3 /*B*/]; + break; + default: + r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/); + g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); + b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); + } + if (alpha == 1) { + color.r = r; + color.g = g; + color.b = b; + } + else { + if (blend == exports.MixBlend.setup) { + var setup = slot.data.color; + color.r = setup.r; + color.g = setup.g; + color.b = setup.b; + } + color.r += (r - color.r) * alpha; + color.g += (g - color.g) * alpha; + color.b += (b - color.b) * alpha; + } + }; + return RGBTimeline; + }(CurveTimeline)); + /** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. + * @public + * */ + var AlphaTimeline = /** @class */ (function (_super) { + __extends$1(AlphaTimeline, _super); + function AlphaTimeline(frameCount, bezierCount, slotIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.alpha + "|" + slotIndex) || this; + _this.slotIndex = 0; + _this.slotIndex = slotIndex; + return _this; + } + AlphaTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + var color = slot.color; + if (time < this.frames[0]) { // Time is before first frame. + var setup = slot.data.color; + switch (blend) { + case exports.MixBlend.setup: + color.a = setup.a; + return; + case exports.MixBlend.first: + color.a += (setup.a - color.a) * alpha; + } + return; + } + var a = this.getCurveValue(time); + if (alpha == 1) + color.a = a; + else { + if (blend == exports.MixBlend.setup) + color.a = slot.data.color.a; + color.a += (a - color.a) * alpha; + } + }; + return AlphaTimeline; + }(CurveTimeline1)); + /** Changes a slot's {@link Slot#color} and {@link Slot#darkColor} for two color tinting. + * @public + * */ + var RGBA2Timeline = /** @class */ (function (_super) { + __extends$1(RGBA2Timeline, _super); + function RGBA2Timeline(frameCount, bezierCount, slotIndex) { + var _this = _super.call(this, frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex, + Property.alpha + "|" + slotIndex, + Property.rgb2 + "|" + slotIndex + ]) || this; + _this.slotIndex = 0; + _this.slotIndex = slotIndex; + return _this; + } + RGBA2Timeline.prototype.getFrameEntries = function () { + return 8 /*ENTRIES*/; + }; + /** Sets the time in seconds, light, and dark colors for the specified key frame. */ + RGBA2Timeline.prototype.setFrame = function (frame, time, r, g, b, a, r2, g2, b2) { + frame <<= 3; + this.frames[frame] = time; + this.frames[frame + 1 /*R*/] = r; + this.frames[frame + 2 /*G*/] = g; + this.frames[frame + 3 /*B*/] = b; + this.frames[frame + 4 /*A*/] = a; + this.frames[frame + 5 /*R2*/] = r2; + this.frames[frame + 6 /*G2*/] = g2; + this.frames[frame + 7 /*B2*/] = b2; + }; + RGBA2Timeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + var frames = this.frames; + var light = slot.color, dark = slot.darkColor; + if (time < frames[0]) { + var setupLight = slot.data.color, setupDark = slot.data.darkColor; + switch (blend) { + case exports.MixBlend.setup: + light.setFromColor(setupLight); + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + return; + case exports.MixBlend.first: + light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha); + dark.r += (setupDark.r - dark.r) * alpha; + dark.g += (setupDark.g - dark.g) * alpha; + dark.b += (setupDark.b - dark.b) * alpha; + } + return; + } + var r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; + var i = Timeline.search(frames, time, 8 /*ENTRIES*/); + var curveType = this.curves[i >> 3]; + switch (curveType) { + case 0 /*LINEAR*/: + var before = frames[i]; + r = frames[i + 1 /*R*/]; + g = frames[i + 2 /*G*/]; + b = frames[i + 3 /*B*/]; + a = frames[i + 4 /*A*/]; + r2 = frames[i + 5 /*R2*/]; + g2 = frames[i + 6 /*G2*/]; + b2 = frames[i + 7 /*B2*/]; + var t = (time - before) / (frames[i + 8 /*ENTRIES*/] - before); + r += (frames[i + 8 /*ENTRIES*/ + 1 /*R*/] - r) * t; + g += (frames[i + 8 /*ENTRIES*/ + 2 /*G*/] - g) * t; + b += (frames[i + 8 /*ENTRIES*/ + 3 /*B*/] - b) * t; + a += (frames[i + 8 /*ENTRIES*/ + 4 /*A*/] - a) * t; + r2 += (frames[i + 8 /*ENTRIES*/ + 5 /*R2*/] - r2) * t; + g2 += (frames[i + 8 /*ENTRIES*/ + 6 /*G2*/] - g2) * t; + b2 += (frames[i + 8 /*ENTRIES*/ + 7 /*B2*/] - b2) * t; + break; + case 1 /*STEPPED*/: + r = frames[i + 1 /*R*/]; + g = frames[i + 2 /*G*/]; + b = frames[i + 3 /*B*/]; + a = frames[i + 4 /*A*/]; + r2 = frames[i + 5 /*R2*/]; + g2 = frames[i + 6 /*G2*/]; + b2 = frames[i + 7 /*B2*/]; + break; + default: + r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/); + g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); + b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); + a = this.getBezierValue(time, i, 4 /*A*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/); + r2 = this.getBezierValue(time, i, 5 /*R2*/, curveType + 18 /*BEZIER_SIZE*/ * 4 - 2 /*BEZIER*/); + g2 = this.getBezierValue(time, i, 6 /*G2*/, curveType + 18 /*BEZIER_SIZE*/ * 5 - 2 /*BEZIER*/); + b2 = this.getBezierValue(time, i, 7 /*B2*/, curveType + 18 /*BEZIER_SIZE*/ * 6 - 2 /*BEZIER*/); + } + if (alpha == 1) { + light.set(r, g, b, a); + dark.r = r2; + dark.g = g2; + dark.b = b2; + } + else { + if (blend == exports.MixBlend.setup) { + light.setFromColor(slot.data.color); + var setupDark = slot.data.darkColor; + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + } + light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha); + dark.r += (r2 - dark.r) * alpha; + dark.g += (g2 - dark.g) * alpha; + dark.b += (b2 - dark.b) * alpha; + } + }; + return RGBA2Timeline; + }(CurveTimeline)); + /** Changes a slot's {@link Slot#color} and {@link Slot#darkColor} for two color tinting. + * @public + * */ + var RGB2Timeline = /** @class */ (function (_super) { + __extends$1(RGB2Timeline, _super); + function RGB2Timeline(frameCount, bezierCount, slotIndex) { + var _this = _super.call(this, frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex, + Property.rgb2 + "|" + slotIndex + ]) || this; + _this.slotIndex = 0; + _this.slotIndex = slotIndex; + return _this; + } + RGB2Timeline.prototype.getFrameEntries = function () { + return 7 /*ENTRIES*/; + }; + /** Sets the time in seconds, light, and dark colors for the specified key frame. */ + RGB2Timeline.prototype.setFrame = function (frame, time, r, g, b, r2, g2, b2) { + frame *= 7 /*ENTRIES*/; + this.frames[frame] = time; + this.frames[frame + 1 /*R*/] = r; + this.frames[frame + 2 /*G*/] = g; + this.frames[frame + 3 /*B*/] = b; + this.frames[frame + 4 /*R2*/] = r2; + this.frames[frame + 5 /*G2*/] = g2; + this.frames[frame + 6 /*B2*/] = b2; + }; + RGB2Timeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + var frames = this.frames; + var light = slot.color, dark = slot.darkColor; + if (time < frames[0]) { + var setupLight = slot.data.color, setupDark = slot.data.darkColor; + switch (blend) { + case exports.MixBlend.setup: + light.r = setupLight.r; + light.g = setupLight.g; + light.b = setupLight.b; + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + return; + case exports.MixBlend.first: + light.r += (setupLight.r - light.r) * alpha; + light.g += (setupLight.g - light.g) * alpha; + light.b += (setupLight.b - light.b) * alpha; + dark.r += (setupDark.r - dark.r) * alpha; + dark.g += (setupDark.g - dark.g) * alpha; + dark.b += (setupDark.b - dark.b) * alpha; + } + return; + } + var r = 0, g = 0, b = 0, r2 = 0, g2 = 0, b2 = 0; + var i = Timeline.search(frames, time, 7 /*ENTRIES*/); + var curveType = this.curves[i / 7 /*ENTRIES*/]; + switch (curveType) { + case 0 /*LINEAR*/: + var before = frames[i]; + r = frames[i + 1 /*R*/]; + g = frames[i + 2 /*G*/]; + b = frames[i + 3 /*B*/]; + r2 = frames[i + 4 /*R2*/]; + g2 = frames[i + 5 /*G2*/]; + b2 = frames[i + 6 /*B2*/]; + var t = (time - before) / (frames[i + 7 /*ENTRIES*/] - before); + r += (frames[i + 7 /*ENTRIES*/ + 1 /*R*/] - r) * t; + g += (frames[i + 7 /*ENTRIES*/ + 2 /*G*/] - g) * t; + b += (frames[i + 7 /*ENTRIES*/ + 3 /*B*/] - b) * t; + r2 += (frames[i + 7 /*ENTRIES*/ + 4 /*R2*/] - r2) * t; + g2 += (frames[i + 7 /*ENTRIES*/ + 5 /*G2*/] - g2) * t; + b2 += (frames[i + 7 /*ENTRIES*/ + 6 /*B2*/] - b2) * t; + break; + case 1 /*STEPPED*/: + r = frames[i + 1 /*R*/]; + g = frames[i + 2 /*G*/]; + b = frames[i + 3 /*B*/]; + r2 = frames[i + 4 /*R2*/]; + g2 = frames[i + 5 /*G2*/]; + b2 = frames[i + 6 /*B2*/]; + break; + default: + r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/); + g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); + b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); + r2 = this.getBezierValue(time, i, 4 /*R2*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/); + g2 = this.getBezierValue(time, i, 5 /*G2*/, curveType + 18 /*BEZIER_SIZE*/ * 4 - 2 /*BEZIER*/); + b2 = this.getBezierValue(time, i, 6 /*B2*/, curveType + 18 /*BEZIER_SIZE*/ * 5 - 2 /*BEZIER*/); + } + if (alpha == 1) { + light.r = r; + light.g = g; + light.b = b; + dark.r = r2; + dark.g = g2; + dark.b = b2; + } + else { + if (blend == exports.MixBlend.setup) { + var setupLight = slot.data.color, setupDark = slot.data.darkColor; + light.r = setupLight.r; + light.g = setupLight.g; + light.b = setupLight.b; + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + } + light.r += (r - light.r) * alpha; + light.g += (g - light.g) * alpha; + light.b += (b - light.b) * alpha; + dark.r += (r2 - dark.r) * alpha; + dark.g += (g2 - dark.g) * alpha; + dark.b += (b2 - dark.b) * alpha; + } + }; + return RGB2Timeline; + }(CurveTimeline)); + /** Changes a slot's {@link Slot#attachment}. + * @public + * */ + var AttachmentTimeline = /** @class */ (function (_super) { + __extends$1(AttachmentTimeline, _super); + function AttachmentTimeline(frameCount, slotIndex) { + var _this = _super.call(this, frameCount, [ + Property.attachment + "|" + slotIndex + ]) || this; + _this.slotIndex = 0; + _this.slotIndex = slotIndex; + _this.attachmentNames = new Array(frameCount); + return _this; + } + AttachmentTimeline.prototype.getFrameCount = function () { + return this.frames.length; + }; + /** Sets the time in seconds and the attachment name for the specified key frame. */ + AttachmentTimeline.prototype.setFrame = function (frame, time, attachmentName) { + this.frames[frame] = time; + this.attachmentNames[frame] = attachmentName; + }; + AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + if (direction == exports.MixDirection.mixOut) { + if (blend == exports.MixBlend.setup) + this.setAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + if (time < this.frames[0]) { + if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) + this.setAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + this.setAttachment(skeleton, slot, this.attachmentNames[Timeline.search1(this.frames, time)]); + }; + AttachmentTimeline.prototype.setAttachment = function (skeleton, slot, attachmentName) { + slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); + }; + return AttachmentTimeline; + }(Timeline)); + /** Changes a slot's {@link Slot#deform} to deform a {@link VertexAttachment}. + * @public + * */ + var DeformTimeline = /** @class */ (function (_super) { + __extends$1(DeformTimeline, _super); + function DeformTimeline(frameCount, bezierCount, slotIndex, attachment) { + var _this = _super.call(this, frameCount, bezierCount, [ + Property.deform + "|" + slotIndex + "|" + attachment.id + ]) || this; + _this.slotIndex = 0; + _this.slotIndex = slotIndex; + _this.attachment = attachment; + _this.vertices = new Array(frameCount); + return _this; + } + DeformTimeline.prototype.getFrameCount = function () { + return this.frames.length; + }; + /** Sets the time in seconds and the vertices for the specified key frame. + * @param vertices Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */ + DeformTimeline.prototype.setFrame = function (frame, time, vertices) { + this.frames[frame] = time; + this.vertices[frame] = vertices; + }; + /** @param value1 Ignored (0 is used for a deform timeline). + * @param value2 Ignored (1 is used for a deform timeline). */ + DeformTimeline.prototype.setBezier = function (bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2) { + var curves = this.curves; + var i = this.getFrameCount() + bezier * 18 /*BEZIER_SIZE*/; + if (value == 0) + curves[frame] = 2 /*BEZIER*/ + i; + var tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = cy2 * 0.03 - cy1 * 0.06; + var dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006, dddy = (cy1 - cy2 + 0.33333333) * 0.018; + var ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy; + var dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = cy1 * 0.3 + tmpy + dddy * 0.16666667; + var x = time1 + dx, y = dy; + for (var n = i + 18 /*BEZIER_SIZE*/; i < n; i += 2) { + curves[i] = x; + curves[i + 1] = y; + dx += ddx; + dy += ddy; + ddx += dddx; + ddy += dddy; + x += dx; + y += dy; + } + }; + DeformTimeline.prototype.getCurvePercent = function (time, frame) { + var curves = this.curves; + var i = curves[frame]; + switch (i) { + case 0 /*LINEAR*/: + var x_3 = this.frames[frame]; + return (time - x_3) / (this.frames[frame + this.getFrameEntries()] - x_3); + case 1 /*STEPPED*/: + return 0; + } + i -= 2 /*BEZIER*/; + if (curves[i] > time) { + var x_4 = this.frames[frame]; + return curves[i + 1] * (time - x_4) / (curves[i] - x_4); + } + var n = i + 18 /*BEZIER_SIZE*/; + for (i += 2; i < n; i += 2) { + if (curves[i] >= time) { + var x_5 = curves[i - 2], y_3 = curves[i - 1]; + return y_3 + (time - x_5) / (curves[i] - x_5) * (curves[i + 1] - y_3); + } + } + var x = curves[n - 2], y = curves[n - 1]; + return y + (1 - y) * (time - x) / (this.frames[frame + this.getFrameEntries()] - x); + }; + DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + var slotAttachment = slot.getAttachment(); + if (!slotAttachment) + return; + if (!(slotAttachment instanceof VertexAttachment) || slotAttachment.timelineAttachment != this.attachment) + return; + var deform = slot.deform; + if (deform.length == 0) + blend = exports.MixBlend.setup; + var vertices = this.vertices; + var vertexCount = vertices[0].length; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + deform.length = 0; + return; + case exports.MixBlend.first: + if (alpha == 1) { + deform.length = 0; + return; + } + deform.length = vertexCount; + var vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + // Unweighted vertex positions. + var setupVertices = vertexAttachment.vertices; + for (var i = 0; i < vertexCount; i++) + deform[i] += (setupVertices[i] - deform[i]) * alpha; + } + else { + // Weighted deform offsets. + alpha = 1 - alpha; + for (var i = 0; i < vertexCount; i++) + deform[i] *= alpha; + } + } + return; + } + deform.length = vertexCount; + if (time >= frames[frames.length - 1]) { // Time is after last frame. + var lastVertices = vertices[frames.length - 1]; + if (alpha == 1) { + if (blend == exports.MixBlend.add) { + var vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i_1 = 0; i_1 < vertexCount; i_1++) + deform[i_1] += lastVertices[i_1] - setupVertices[i_1]; + } + else { + // Weighted deform offsets, with alpha. + for (var i_2 = 0; i_2 < vertexCount; i_2++) + deform[i_2] += lastVertices[i_2]; + } + } + else + Utils.arrayCopy(lastVertices, 0, deform, 0, vertexCount); + } + else { + switch (blend) { + case exports.MixBlend.setup: { + var vertexAttachment_1 = slotAttachment; + if (!vertexAttachment_1.bones) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment_1.vertices; + for (var i_3 = 0; i_3 < vertexCount; i_3++) { + var setup = setupVertices[i_3]; + deform[i_3] = setup + (lastVertices[i_3] - setup) * alpha; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i_4 = 0; i_4 < vertexCount; i_4++) + deform[i_4] = lastVertices[i_4] * alpha; + } + break; + } + case exports.MixBlend.first: + case exports.MixBlend.replace: + for (var i_5 = 0; i_5 < vertexCount; i_5++) + deform[i_5] += (lastVertices[i_5] - deform[i_5]) * alpha; + break; + case exports.MixBlend.add: + var vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i_6 = 0; i_6 < vertexCount; i_6++) + deform[i_6] += (lastVertices[i_6] - setupVertices[i_6]) * alpha; + } + else { + // Weighted deform offsets, with alpha. + for (var i_7 = 0; i_7 < vertexCount; i_7++) + deform[i_7] += lastVertices[i_7] * alpha; + } + } + } + return; + } + // Interpolate between the previous frame and the current frame. + var frame = Timeline.search1(frames, time); + var percent = this.getCurvePercent(time, frame); + var prevVertices = vertices[frame]; + var nextVertices = vertices[frame + 1]; + if (alpha == 1) { + if (blend == exports.MixBlend.add) { + var vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i_8 = 0; i_8 < vertexCount; i_8++) { + var prev = prevVertices[i_8]; + deform[i_8] += prev + (nextVertices[i_8] - prev) * percent - setupVertices[i_8]; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i_9 = 0; i_9 < vertexCount; i_9++) { + var prev = prevVertices[i_9]; + deform[i_9] += prev + (nextVertices[i_9] - prev) * percent; + } + } + } + else { + for (var i_10 = 0; i_10 < vertexCount; i_10++) { + var prev = prevVertices[i_10]; + deform[i_10] = prev + (nextVertices[i_10] - prev) * percent; + } + } + } + else { + switch (blend) { + case exports.MixBlend.setup: { + var vertexAttachment_2 = slotAttachment; + if (!vertexAttachment_2.bones) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment_2.vertices; + for (var i_11 = 0; i_11 < vertexCount; i_11++) { + var prev = prevVertices[i_11], setup = setupVertices[i_11]; + deform[i_11] = setup + (prev + (nextVertices[i_11] - prev) * percent - setup) * alpha; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i_12 = 0; i_12 < vertexCount; i_12++) { + var prev = prevVertices[i_12]; + deform[i_12] = (prev + (nextVertices[i_12] - prev) * percent) * alpha; + } + } + break; + } + case exports.MixBlend.first: + case exports.MixBlend.replace: + for (var i_13 = 0; i_13 < vertexCount; i_13++) { + var prev = prevVertices[i_13]; + deform[i_13] += (prev + (nextVertices[i_13] - prev) * percent - deform[i_13]) * alpha; + } + break; + case exports.MixBlend.add: + var vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + // Unweighted vertex positions, with alpha. + var setupVertices = vertexAttachment.vertices; + for (var i_14 = 0; i_14 < vertexCount; i_14++) { + var prev = prevVertices[i_14]; + deform[i_14] += (prev + (nextVertices[i_14] - prev) * percent - setupVertices[i_14]) * alpha; + } + } + else { + // Weighted deform offsets, with alpha. + for (var i_15 = 0; i_15 < vertexCount; i_15++) { + var prev = prevVertices[i_15]; + deform[i_15] += (prev + (nextVertices[i_15] - prev) * percent) * alpha; + } + } + } + } + }; + return DeformTimeline; + }(CurveTimeline)); + /** Fires an {@link Event} when specific animation times are reached. + * @public + * */ + var EventTimeline = /** @class */ (function (_super) { + __extends$1(EventTimeline, _super); + function EventTimeline(frameCount) { + var _this = _super.call(this, frameCount, EventTimeline.propertyIds) || this; + _this.events = new Array(frameCount); + return _this; + } + EventTimeline.prototype.getFrameCount = function () { + return this.frames.length; + }; + /** Sets the time in seconds and the event for the specified key frame. */ + EventTimeline.prototype.setFrame = function (frame, event) { + this.frames[frame] = event.time; + this.events[frame] = event; + }; + /** Fires events for frames > `lastTime` and <= `time`. */ + EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + if (!firedEvents) + return; + var frames = this.frames; + var frameCount = this.frames.length; + if (lastTime > time) { // Fire events after last time for looped animations. + this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction); + lastTime = -1; + } + else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame. + return; + if (time < frames[0]) + return; // Time is before first frame. + var i = 0; + if (lastTime < frames[0]) + i = 0; + else { + i = Timeline.search1(frames, lastTime) + 1; + var frameTime = frames[i]; + while (i > 0) { // Fire multiple events with the same frame. + if (frames[i - 1] != frameTime) + break; + i--; + } + } + for (; i < frameCount && time >= frames[i]; i++) + firedEvents.push(this.events[i]); + }; + EventTimeline.propertyIds = ["" + Property.event]; + return EventTimeline; + }(Timeline)); + /** Changes a skeleton's {@link Skeleton#drawOrder}. + * @public + * */ + var DrawOrderTimeline = /** @class */ (function (_super) { + __extends$1(DrawOrderTimeline, _super); + function DrawOrderTimeline(frameCount) { + var _this = _super.call(this, frameCount, DrawOrderTimeline.propertyIds) || this; + _this.drawOrders = new Array(frameCount); + return _this; + } + DrawOrderTimeline.prototype.getFrameCount = function () { + return this.frames.length; + }; + /** Sets the time in seconds and the draw order for the specified key frame. + * @param drawOrder For each slot in {@link Skeleton#slots}, the index of the new draw order. May be null to use setup pose + * draw order. */ + DrawOrderTimeline.prototype.setFrame = function (frame, time, drawOrder) { + this.frames[frame] = time; + this.drawOrders[frame] = drawOrder; + }; + DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + if (direction == exports.MixDirection.mixOut) { + if (blend == exports.MixBlend.setup) + Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + if (time < this.frames[0]) { + if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) + Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + var idx = Timeline.search1(this.frames, time); + var drawOrderToSetupIndex = this.drawOrders[idx]; + if (!drawOrderToSetupIndex) + Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + else { + var drawOrder = skeleton.drawOrder; + var slots = skeleton.slots; + for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++) + drawOrder[i] = slots[drawOrderToSetupIndex[i]]; + } + }; + DrawOrderTimeline.propertyIds = ["" + Property.drawOrder]; + return DrawOrderTimeline; + }(Timeline)); + /** Changes an IK constraint's {@link IkConstraint#mix}, {@link IkConstraint#softness}, + * {@link IkConstraint#bendDirection}, {@link IkConstraint#stretch}, and {@link IkConstraint#compress}. + * @public + * */ + var IkConstraintTimeline = /** @class */ (function (_super) { + __extends$1(IkConstraintTimeline, _super); + function IkConstraintTimeline(frameCount, bezierCount, ikConstraintIndex) { + var _this = _super.call(this, frameCount, bezierCount, [ + Property.ikConstraint + "|" + ikConstraintIndex + ]) || this; + /** The index of the IK constraint slot in {@link Skeleton#ikConstraints} that will be changed. */ + _this.ikConstraintIndex = 0; + _this.ikConstraintIndex = ikConstraintIndex; + return _this; + } + IkConstraintTimeline.prototype.getFrameEntries = function () { + return 6 /*ENTRIES*/; + }; + /** Sets the time in seconds, mix, softness, bend direction, compress, and stretch for the specified key frame. */ + IkConstraintTimeline.prototype.setFrame = function (frame, time, mix, softness, bendDirection, compress, stretch) { + frame *= 6 /*ENTRIES*/; + this.frames[frame] = time; + this.frames[frame + 1 /*MIX*/] = mix; + this.frames[frame + 2 /*SOFTNESS*/] = softness; + this.frames[frame + 3 /*BEND_DIRECTION*/] = bendDirection; + this.frames[frame + 4 /*COMPRESS*/] = compress ? 1 : 0; + this.frames[frame + 5 /*STRETCH*/] = stretch ? 1 : 0; + }; + IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var constraint = skeleton.ikConstraints[this.ikConstraintIndex]; + if (!constraint.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.mix = constraint.data.mix; + constraint.softness = constraint.data.softness; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + return; + case exports.MixBlend.first: + constraint.mix += (constraint.data.mix - constraint.mix) * alpha; + constraint.softness += (constraint.data.softness - constraint.softness) * alpha; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + return; + } + var mix = 0, softness = 0; + var i = Timeline.search(frames, time, 6 /*ENTRIES*/); + var curveType = this.curves[i / 6 /*ENTRIES*/]; + switch (curveType) { + case 0 /*LINEAR*/: + var before = frames[i]; + mix = frames[i + 1 /*MIX*/]; + softness = frames[i + 2 /*SOFTNESS*/]; + var t = (time - before) / (frames[i + 6 /*ENTRIES*/] - before); + mix += (frames[i + 6 /*ENTRIES*/ + 1 /*MIX*/] - mix) * t; + softness += (frames[i + 6 /*ENTRIES*/ + 2 /*SOFTNESS*/] - softness) * t; + break; + case 1 /*STEPPED*/: + mix = frames[i + 1 /*MIX*/]; + softness = frames[i + 2 /*SOFTNESS*/]; + break; + default: + mix = this.getBezierValue(time, i, 1 /*MIX*/, curveType - 2 /*BEZIER*/); + softness = this.getBezierValue(time, i, 2 /*SOFTNESS*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); + } + if (blend == exports.MixBlend.setup) { + constraint.mix = constraint.data.mix + (mix - constraint.data.mix) * alpha; + constraint.softness = constraint.data.softness + (softness - constraint.data.softness) * alpha; + if (direction == exports.MixDirection.mixOut) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + else { + constraint.bendDirection = frames[i + 3 /*BEND_DIRECTION*/]; + constraint.compress = frames[i + 4 /*COMPRESS*/] != 0; + constraint.stretch = frames[i + 5 /*STRETCH*/] != 0; + } + } + else { + constraint.mix += (mix - constraint.mix) * alpha; + constraint.softness += (softness - constraint.softness) * alpha; + if (direction == exports.MixDirection.mixIn) { + constraint.bendDirection = frames[i + 3 /*BEND_DIRECTION*/]; + constraint.compress = frames[i + 4 /*COMPRESS*/] != 0; + constraint.stretch = frames[i + 5 /*STRETCH*/] != 0; + } + } + }; + return IkConstraintTimeline; + }(CurveTimeline)); + /** Changes a transform constraint's {@link TransformConstraint#rotateMix}, {@link TransformConstraint#translateMix}, + * {@link TransformConstraint#scaleMix}, and {@link TransformConstraint#shearMix}. + * @public + * */ + var TransformConstraintTimeline = /** @class */ (function (_super) { + __extends$1(TransformConstraintTimeline, _super); + function TransformConstraintTimeline(frameCount, bezierCount, transformConstraintIndex) { + var _this = _super.call(this, frameCount, bezierCount, [ + Property.transformConstraint + "|" + transformConstraintIndex + ]) || this; + /** The index of the transform constraint slot in {@link Skeleton#transformConstraints} that will be changed. */ + _this.transformConstraintIndex = 0; + _this.transformConstraintIndex = transformConstraintIndex; + return _this; + } + TransformConstraintTimeline.prototype.getFrameEntries = function () { + return 7 /*ENTRIES*/; + }; + /** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. */ + TransformConstraintTimeline.prototype.setFrame = function (frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY) { + var frames = this.frames; + frame *= 7 /*ENTRIES*/; + frames[frame] = time; + frames[frame + 1 /*ROTATE*/] = mixRotate; + frames[frame + 2 /*X*/] = mixX; + frames[frame + 3 /*Y*/] = mixY; + frames[frame + 4 /*SCALEX*/] = mixScaleX; + frames[frame + 5 /*SCALEY*/] = mixScaleY; + frames[frame + 6 /*SHEARY*/] = mixShearY; + }; + TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var constraint = skeleton.transformConstraints[this.transformConstraintIndex]; + if (!constraint.active) + return; + var frames = this.frames; + if (time < frames[0]) { + var data = constraint.data; + switch (blend) { + case exports.MixBlend.setup: + constraint.mixRotate = data.mixRotate; + constraint.mixX = data.mixX; + constraint.mixY = data.mixY; + constraint.mixScaleX = data.mixScaleX; + constraint.mixScaleY = data.mixScaleY; + constraint.mixShearY = data.mixShearY; + return; + case exports.MixBlend.first: + constraint.mixRotate += (data.mixRotate - constraint.mixRotate) * alpha; + constraint.mixX += (data.mixX - constraint.mixX) * alpha; + constraint.mixY += (data.mixY - constraint.mixY) * alpha; + constraint.mixScaleX += (data.mixScaleX - constraint.mixScaleX) * alpha; + constraint.mixScaleY += (data.mixScaleY - constraint.mixScaleY) * alpha; + constraint.mixShearY += (data.mixShearY - constraint.mixShearY) * alpha; + } + return; + } + var rotate, x, y, scaleX, scaleY, shearY; + var i = Timeline.search(frames, time, 7 /*ENTRIES*/); + var curveType = this.curves[i / 7 /*ENTRIES*/]; + switch (curveType) { + case 0 /*LINEAR*/: + var before = frames[i]; + rotate = frames[i + 1 /*ROTATE*/]; + x = frames[i + 2 /*X*/]; + y = frames[i + 3 /*Y*/]; + scaleX = frames[i + 4 /*SCALEX*/]; + scaleY = frames[i + 5 /*SCALEY*/]; + shearY = frames[i + 6 /*SHEARY*/]; + var t = (time - before) / (frames[i + 7 /*ENTRIES*/] - before); + rotate += (frames[i + 7 /*ENTRIES*/ + 1 /*ROTATE*/] - rotate) * t; + x += (frames[i + 7 /*ENTRIES*/ + 2 /*X*/] - x) * t; + y += (frames[i + 7 /*ENTRIES*/ + 3 /*Y*/] - y) * t; + scaleX += (frames[i + 7 /*ENTRIES*/ + 4 /*SCALEX*/] - scaleX) * t; + scaleY += (frames[i + 7 /*ENTRIES*/ + 5 /*SCALEY*/] - scaleY) * t; + shearY += (frames[i + 7 /*ENTRIES*/ + 6 /*SHEARY*/] - shearY) * t; + break; + case 1 /*STEPPED*/: + rotate = frames[i + 1 /*ROTATE*/]; + x = frames[i + 2 /*X*/]; + y = frames[i + 3 /*Y*/]; + scaleX = frames[i + 4 /*SCALEX*/]; + scaleY = frames[i + 5 /*SCALEY*/]; + shearY = frames[i + 6 /*SHEARY*/]; + break; + default: + rotate = this.getBezierValue(time, i, 1 /*ROTATE*/, curveType - 2 /*BEZIER*/); + x = this.getBezierValue(time, i, 2 /*X*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); + y = this.getBezierValue(time, i, 3 /*Y*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); + scaleX = this.getBezierValue(time, i, 4 /*SCALEX*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/); + scaleY = this.getBezierValue(time, i, 5 /*SCALEY*/, curveType + 18 /*BEZIER_SIZE*/ * 4 - 2 /*BEZIER*/); + shearY = this.getBezierValue(time, i, 6 /*SHEARY*/, curveType + 18 /*BEZIER_SIZE*/ * 5 - 2 /*BEZIER*/); + } + if (blend == exports.MixBlend.setup) { + var data = constraint.data; + constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha; + constraint.mixX = data.mixX + (x - data.mixX) * alpha; + constraint.mixY = data.mixY + (y - data.mixY) * alpha; + constraint.mixScaleX = data.mixScaleX + (scaleX - data.mixScaleX) * alpha; + constraint.mixScaleY = data.mixScaleY + (scaleY - data.mixScaleY) * alpha; + constraint.mixShearY = data.mixShearY + (shearY - data.mixShearY) * alpha; + } + else { + constraint.mixRotate += (rotate - constraint.mixRotate) * alpha; + constraint.mixX += (x - constraint.mixX) * alpha; + constraint.mixY += (y - constraint.mixY) * alpha; + constraint.mixScaleX += (scaleX - constraint.mixScaleX) * alpha; + constraint.mixScaleY += (scaleY - constraint.mixScaleY) * alpha; + constraint.mixShearY += (shearY - constraint.mixShearY) * alpha; + } + }; + return TransformConstraintTimeline; + }(CurveTimeline)); + /** Changes a path constraint's {@link PathConstraint#position}. + * @public + * */ + var PathConstraintPositionTimeline = /** @class */ (function (_super) { + __extends$1(PathConstraintPositionTimeline, _super); + function PathConstraintPositionTimeline(frameCount, bezierCount, pathConstraintIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.pathConstraintPosition + "|" + pathConstraintIndex) || this; + /** The index of the path constraint slot in {@link Skeleton#pathConstraints} that will be changed. */ + _this.pathConstraintIndex = 0; + _this.pathConstraintIndex = pathConstraintIndex; + return _this; + } + PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (!constraint.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.position = constraint.data.position; + return; + case exports.MixBlend.first: + constraint.position += (constraint.data.position - constraint.position) * alpha; + } + return; + } + var position = this.getCurveValue(time); + if (blend == exports.MixBlend.setup) + constraint.position = constraint.data.position + (position - constraint.data.position) * alpha; + else + constraint.position += (position - constraint.position) * alpha; + }; + return PathConstraintPositionTimeline; + }(CurveTimeline1)); + /** Changes a path constraint's {@link PathConstraint#spacing}. + * @public + * */ + var PathConstraintSpacingTimeline = /** @class */ (function (_super) { + __extends$1(PathConstraintSpacingTimeline, _super); + function PathConstraintSpacingTimeline(frameCount, bezierCount, pathConstraintIndex) { + var _this = _super.call(this, frameCount, bezierCount, Property.pathConstraintSpacing + "|" + pathConstraintIndex) || this; + /** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */ + _this.pathConstraintIndex = 0; + _this.pathConstraintIndex = pathConstraintIndex; + return _this; + } + PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (!constraint.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.spacing = constraint.data.spacing; + return; + case exports.MixBlend.first: + constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha; + } + return; + } + var spacing = this.getCurveValue(time); + if (blend == exports.MixBlend.setup) + constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha; + else + constraint.spacing += (spacing - constraint.spacing) * alpha; + }; + return PathConstraintSpacingTimeline; + }(CurveTimeline1)); + /** Changes a transform constraint's {@link PathConstraint#getMixRotate()}, {@link PathConstraint#getMixX()}, and + * {@link PathConstraint#getMixY()}. + * @public + * */ + var PathConstraintMixTimeline = /** @class */ (function (_super) { + __extends$1(PathConstraintMixTimeline, _super); + function PathConstraintMixTimeline(frameCount, bezierCount, pathConstraintIndex) { + var _this = _super.call(this, frameCount, bezierCount, [ + Property.pathConstraintMix + "|" + pathConstraintIndex + ]) || this; + /** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */ + _this.pathConstraintIndex = 0; + _this.pathConstraintIndex = pathConstraintIndex; + return _this; + } + PathConstraintMixTimeline.prototype.getFrameEntries = function () { + return 4 /*ENTRIES*/; + }; + PathConstraintMixTimeline.prototype.setFrame = function (frame, time, mixRotate, mixX, mixY) { + var frames = this.frames; + frame <<= 2; + frames[frame] = time; + frames[frame + 1 /*ROTATE*/] = mixRotate; + frames[frame + 2 /*X*/] = mixX; + frames[frame + 3 /*Y*/] = mixY; + }; + PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (!constraint.active) + return; + var frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + constraint.mixRotate = constraint.data.mixRotate; + constraint.mixX = constraint.data.mixX; + constraint.mixY = constraint.data.mixY; + return; + case exports.MixBlend.first: + constraint.mixRotate += (constraint.data.mixRotate - constraint.mixRotate) * alpha; + constraint.mixX += (constraint.data.mixX - constraint.mixX) * alpha; + constraint.mixY += (constraint.data.mixY - constraint.mixY) * alpha; + } + return; + } + var rotate, x, y; + var i = Timeline.search(frames, time, 4 /*ENTRIES*/); + var curveType = this.curves[i >> 2]; + switch (curveType) { + case 0 /*LINEAR*/: + var before = frames[i]; + rotate = frames[i + 1 /*ROTATE*/]; + x = frames[i + 2 /*X*/]; + y = frames[i + 3 /*Y*/]; + var t = (time - before) / (frames[i + 4 /*ENTRIES*/] - before); + rotate += (frames[i + 4 /*ENTRIES*/ + 1 /*ROTATE*/] - rotate) * t; + x += (frames[i + 4 /*ENTRIES*/ + 2 /*X*/] - x) * t; + y += (frames[i + 4 /*ENTRIES*/ + 3 /*Y*/] - y) * t; + break; + case 1 /*STEPPED*/: + rotate = frames[i + 1 /*ROTATE*/]; + x = frames[i + 2 /*X*/]; + y = frames[i + 3 /*Y*/]; + break; + default: + rotate = this.getBezierValue(time, i, 1 /*ROTATE*/, curveType - 2 /*BEZIER*/); + x = this.getBezierValue(time, i, 2 /*X*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); + y = this.getBezierValue(time, i, 3 /*Y*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); + } + if (blend == exports.MixBlend.setup) { + var data = constraint.data; + constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha; + constraint.mixX = data.mixX + (x - data.mixX) * alpha; + constraint.mixY = data.mixY + (y - data.mixY) * alpha; + } + else { + constraint.mixRotate += (rotate - constraint.mixRotate) * alpha; + constraint.mixX += (x - constraint.mixX) * alpha; + constraint.mixY += (y - constraint.mixY) * alpha; + } + }; + return PathConstraintMixTimeline; + }(CurveTimeline)); + /** Changes a slot's {@link Slot#getSequenceIndex()} for an attachment's {@link Sequence}. + * @public + * */ + var SequenceTimeline = /** @class */ (function (_super) { + __extends$1(SequenceTimeline, _super); + function SequenceTimeline(frameCount, slotIndex, attachment) { + var _this = _super.call(this, frameCount, [ + Property.sequence + "|" + slotIndex + "|" + attachment.sequence.id + ]) || this; + _this.slotIndex = slotIndex; + _this.attachment = attachment; + return _this; + } + SequenceTimeline.prototype.getFrameEntries = function () { + return SequenceTimeline.ENTRIES; + }; + SequenceTimeline.prototype.getSlotIndex = function () { + return this.slotIndex; + }; + SequenceTimeline.prototype.getAttachment = function () { + return this.attachment; + }; + /** Sets the time, mode, index, and frame time for the specified frame. + * @param frame Between 0 and frameCount, inclusive. + * @param time Seconds between frames. */ + SequenceTimeline.prototype.setFrame = function (frame, time, mode, index, delay) { + var frames = this.frames; + frame *= SequenceTimeline.ENTRIES; + frames[frame] = time; + frames[frame + SequenceTimeline.MODE] = mode | (index << 4); + frames[frame + SequenceTimeline.DELAY] = delay; + }; + SequenceTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { + var slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + var slotAttachment = slot.attachment; + var attachment = this.attachment; + if (slotAttachment != attachment) { + if (!(slotAttachment instanceof VertexAttachment) + || slotAttachment.timelineAttachment != attachment) + return; + } + var frames = this.frames; + if (time < frames[0]) { // Time is before first frame. + if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) + slot.sequenceIndex = -1; + return; + } + var i = Timeline.search(frames, time, SequenceTimeline.ENTRIES); + var before = frames[i]; + var modeAndIndex = frames[i + SequenceTimeline.MODE]; + var delay = frames[i + SequenceTimeline.DELAY]; + if (!this.attachment.sequence) + return; + var index = modeAndIndex >> 4, count = this.attachment.sequence.regions.length; + var mode = SequenceModeValues[modeAndIndex & 0xf]; + if (mode != SequenceMode.hold) { + index += (((time - before) / delay + 0.00001) | 0); + switch (mode) { + case SequenceMode.once: + index = Math.min(count - 1, index); + break; + case SequenceMode.loop: + index %= count; + break; + case SequenceMode.pingpong: { + var n = (count << 1) - 2; + index = n == 0 ? 0 : index % n; + if (index >= count) + index = n - index; + break; + } + case SequenceMode.onceReverse: + index = Math.max(count - 1 - index, 0); + break; + case SequenceMode.loopReverse: + index = count - 1 - (index % count); + break; + case SequenceMode.pingpongReverse: { + var n = (count << 1) - 2; + index = n == 0 ? 0 : (index + count - 1) % n; + if (index >= count) + index = n - index; + } + } + } + slot.sequenceIndex = index; + }; + SequenceTimeline.ENTRIES = 3; + SequenceTimeline.MODE = 1; + SequenceTimeline.DELAY = 2; + return SequenceTimeline; + }(Timeline)); + + /** Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies + * multiple animations on top of each other (layering). + * + * See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. + * @public + * */ + var AnimationState = /** @class */ (function () { + function AnimationState(data) { + /** The list of tracks that currently have animations, which may contain null entries. */ + this.tracks = new Array(); + /** Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower + * or faster. Defaults to 1. + * + * See TrackEntry {@link TrackEntry#timeScale} for affecting a single animation. */ + this.timeScale = 1; + this.unkeyedState = 0; + this.events = new Array(); + this.listeners = new Array(); + this.queue = new EventQueue(this); + this.propertyIDs = new StringSet(); + this.animationsChanged = false; + this.trackEntryPool = new Pool(function () { return new TrackEntry(); }); + this.data = data; + } + AnimationState.emptyAnimation = function () { + return AnimationState._emptyAnimation; + }; + /** Increments each track entry {@link TrackEntry#trackTime()}, setting queued animations as current if needed. */ + AnimationState.prototype.update = function (delta) { + delta *= this.timeScale; + var tracks = this.tracks; + for (var i = 0, n = tracks.length; i < n; i++) { + var current = tracks[i]; + if (!current) + continue; + current.animationLast = current.nextAnimationLast; + current.trackLast = current.nextTrackLast; + var currentDelta = delta * current.timeScale; + if (current.delay > 0) { + current.delay -= currentDelta; + if (current.delay > 0) + continue; + currentDelta = -current.delay; + current.delay = 0; + } + var next = current.next; + if (next) { + // When the next entry's delay is passed, change to the next entry, preserving leftover time. + var nextTime = current.trackLast - next.delay; + if (nextTime >= 0) { + next.delay = 0; + next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale; + current.trackTime += currentDelta; + this.setCurrent(i, next, true); + while (next.mixingFrom) { + next.mixTime += delta; + next = next.mixingFrom; + } + continue; + } + } + else if (current.trackLast >= current.trackEnd && !current.mixingFrom) { + tracks[i] = null; + this.queue.end(current); + this.clearNext(current); + continue; + } + if (current.mixingFrom && this.updateMixingFrom(current, delta)) { + // End mixing from entries once all have completed. + var from = current.mixingFrom; + current.mixingFrom = null; + if (from) + from.mixingTo = null; + while (from) { + this.queue.end(from); + from = from.mixingFrom; + } + } + current.trackTime += currentDelta; + } + this.queue.drain(); + }; + /** Returns true when all mixing from entries are complete. */ + AnimationState.prototype.updateMixingFrom = function (to, delta) { + var from = to.mixingFrom; + if (!from) + return true; + var finished = this.updateMixingFrom(from, delta); + from.animationLast = from.nextAnimationLast; + from.trackLast = from.nextTrackLast; + // Require mixTime > 0 to ensure the mixing from entry was applied at least once. + if (to.mixTime > 0 && to.mixTime >= to.mixDuration) { + // Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame). + if (from.totalAlpha == 0 || to.mixDuration == 0) { + to.mixingFrom = from.mixingFrom; + if (from.mixingFrom) + from.mixingFrom.mixingTo = to; + to.interruptAlpha = from.interruptAlpha; + this.queue.end(from); + } + return finished; + } + from.trackTime += delta * from.timeScale; + to.mixTime += delta; + return false; + }; + /** Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the + * animation state can be applied to multiple skeletons to pose them identically. + * @returns True if any animations were applied. */ + AnimationState.prototype.apply = function (skeleton) { + if (!skeleton) + throw new Error("skeleton cannot be null."); + if (this.animationsChanged) + this._animationsChanged(); + var events = this.events; + var tracks = this.tracks; + var applied = false; + for (var i_1 = 0, n_1 = tracks.length; i_1 < n_1; i_1++) { + var current = tracks[i_1]; + if (!current || current.delay > 0) + continue; + applied = true; + var blend = i_1 == 0 ? exports.MixBlend.first : current.mixBlend; + // Apply mixing from entries first. + var mix = current.alpha; + if (current.mixingFrom) + mix *= this.applyMixingFrom(current, skeleton, blend); + else if (current.trackTime >= current.trackEnd && !current.next) + mix = 0; + // Apply current entry. + var animationLast = current.animationLast, animationTime = current.getAnimationTime(), applyTime = animationTime; + var applyEvents = events; + if (current.reverse) { + applyTime = current.animation.duration - applyTime; + applyEvents = null; + } + var timelines = current.animation.timelines; + var timelineCount = timelines.length; + if ((i_1 == 0 && mix == 1) || blend == exports.MixBlend.add) { + for (var ii = 0; ii < timelineCount; ii++) { + // Fixes issue #302 on IOS9 where mix, blend sometimes became undefined and caused assets + // to sometimes stop rendering when using color correction, as their RGBA values become NaN. + // (https://github.com/pixijs/pixi-spine/issues/302) + Utils.webkit602BugfixHelper(mix, blend); + var timeline = timelines[ii]; + if (timeline instanceof AttachmentTimeline) + this.applyAttachmentTimeline(timeline, skeleton, applyTime, blend, true); + else + timeline.apply(skeleton, animationLast, applyTime, applyEvents, mix, blend, exports.MixDirection.mixIn); + } + } + else { + var timelineMode = current.timelineMode; + var shortestRotation = current.shortestRotation; + var firstFrame = !shortestRotation && current.timelinesRotation.length != timelineCount << 1; + if (firstFrame) + current.timelinesRotation.length = timelineCount << 1; + for (var ii = 0; ii < timelineCount; ii++) { + var timeline_1 = timelines[ii]; + var timelineBlend = timelineMode[ii] == SUBSEQUENT ? blend : exports.MixBlend.setup; + if (!shortestRotation && timeline_1 instanceof RotateTimeline) { + this.applyRotateTimeline(timeline_1, skeleton, applyTime, mix, timelineBlend, current.timelinesRotation, ii << 1, firstFrame); + } + else if (timeline_1 instanceof AttachmentTimeline) { + this.applyAttachmentTimeline(timeline_1, skeleton, applyTime, blend, true); + } + else { + // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 + Utils.webkit602BugfixHelper(mix, blend); + timeline_1.apply(skeleton, animationLast, applyTime, applyEvents, mix, timelineBlend, exports.MixDirection.mixIn); + } + } + } + this.queueEvents(current, animationTime); + events.length = 0; + current.nextAnimationLast = animationTime; + current.nextTrackLast = current.trackTime; + } + // Set slots attachments to the setup pose, if needed. This occurs if an animation that is mixing out sets attachments so + // subsequent timelines see any deform, but the subsequent timelines don't set an attachment (eg they are also mixing out or + // the time is before the first key). + var setupState = this.unkeyedState + SETUP; + var slots = skeleton.slots; + for (var i = 0, n = skeleton.slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.attachmentState == setupState) { + var attachmentName = slot.data.attachmentName; + slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName)); + } + } + this.unkeyedState += 2; // Increasing after each use avoids the need to reset attachmentState for every slot. + this.queue.drain(); + return applied; + }; + AnimationState.prototype.applyMixingFrom = function (to, skeleton, blend) { + var from = to.mixingFrom; + if (from.mixingFrom) + this.applyMixingFrom(from, skeleton, blend); + var mix = 0; + if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. + mix = 1; + if (blend == exports.MixBlend.first) + blend = exports.MixBlend.setup; + } + else { + mix = to.mixTime / to.mixDuration; + if (mix > 1) + mix = 1; + if (blend != exports.MixBlend.first) + blend = from.mixBlend; + } + var attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold; + var timelines = from.animation.timelines; + var timelineCount = timelines.length; + var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); + var animationLast = from.animationLast, animationTime = from.getAnimationTime(), applyTime = animationTime; + var events = null; + if (from.reverse) + applyTime = from.animation.duration - applyTime; + else if (mix < from.eventThreshold) + events = this.events; + if (blend == exports.MixBlend.add) { + for (var i = 0; i < timelineCount; i++) + timelines[i].apply(skeleton, animationLast, applyTime, events, alphaMix, blend, exports.MixDirection.mixOut); + } + else { + var timelineMode = from.timelineMode; + var timelineHoldMix = from.timelineHoldMix; + var shortestRotation = from.shortestRotation; + var firstFrame = !shortestRotation && from.timelinesRotation.length != timelineCount << 1; + if (firstFrame) + from.timelinesRotation.length = timelineCount << 1; + from.totalAlpha = 0; + for (var i = 0; i < timelineCount; i++) { + var timeline = timelines[i]; + var direction = exports.MixDirection.mixOut; + var timelineBlend = void 0; + var alpha = 0; + switch (timelineMode[i]) { + case SUBSEQUENT: + if (!drawOrder && timeline instanceof DrawOrderTimeline) + continue; + timelineBlend = blend; + alpha = alphaMix; + break; + case FIRST: + timelineBlend = exports.MixBlend.setup; + alpha = alphaMix; + break; + case HOLD_SUBSEQUENT: + timelineBlend = blend; + alpha = alphaHold; + break; + case HOLD_FIRST: + timelineBlend = exports.MixBlend.setup; + alpha = alphaHold; + break; + default: + timelineBlend = exports.MixBlend.setup; + var holdMix = timelineHoldMix[i]; + alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration); + break; + } + from.totalAlpha += alpha; + if (!shortestRotation && timeline instanceof RotateTimeline) + this.applyRotateTimeline(timeline, skeleton, applyTime, alpha, timelineBlend, from.timelinesRotation, i << 1, firstFrame); + else if (timeline instanceof AttachmentTimeline) + this.applyAttachmentTimeline(timeline, skeleton, applyTime, timelineBlend, attachments); + else { + // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 + Utils.webkit602BugfixHelper(alpha, blend); + if (drawOrder && timeline instanceof DrawOrderTimeline && timelineBlend == exports.MixBlend.setup) + direction = exports.MixDirection.mixIn; + timeline.apply(skeleton, animationLast, applyTime, events, alpha, timelineBlend, direction); + } + } + } + if (to.mixDuration > 0) + this.queueEvents(from, animationTime); + this.events.length = 0; + from.nextAnimationLast = animationTime; + from.nextTrackLast = from.trackTime; + return mix; + }; + AnimationState.prototype.applyAttachmentTimeline = function (timeline, skeleton, time, blend, attachments) { + var slot = skeleton.slots[timeline.slotIndex]; + if (!slot.bone.active) + return; + if (time < timeline.frames[0]) { // Time is before first frame. + if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) + this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments); + } + else + this.setAttachment(skeleton, slot, timeline.attachmentNames[Timeline.search1(timeline.frames, time)], attachments); + // If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later. + if (slot.attachmentState <= this.unkeyedState) + slot.attachmentState = this.unkeyedState + SETUP; + }; + AnimationState.prototype.setAttachment = function (skeleton, slot, attachmentName, attachments) { + slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName)); + if (attachments) + slot.attachmentState = this.unkeyedState + CURRENT; + }; + AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) { + if (firstFrame) + timelinesRotation[i] = 0; + if (alpha == 1) { + timeline.apply(skeleton, 0, time, null, 1, blend, exports.MixDirection.mixIn); + return; + } + var bone = skeleton.bones[timeline.boneIndex]; + if (!bone.active) + return; + var frames = timeline.frames; + var r1 = 0, r2 = 0; + if (time < frames[0]) { + switch (blend) { + case exports.MixBlend.setup: + bone.rotation = bone.data.rotation; + default: + return; + case exports.MixBlend.first: + r1 = bone.rotation; + r2 = bone.data.rotation; + } + } + else { + r1 = blend == exports.MixBlend.setup ? bone.data.rotation : bone.rotation; + r2 = bone.data.rotation + timeline.getCurveValue(time); + } + // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. + var total = 0, diff = r2 - r1; + diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360; + if (diff == 0) { + total = timelinesRotation[i]; + } + else { + var lastTotal = 0, lastDiff = 0; + if (firstFrame) { + lastTotal = 0; + lastDiff = diff; + } + else { + lastTotal = timelinesRotation[i]; // Angle and direction of mix, including loops. + lastDiff = timelinesRotation[i + 1]; // Difference between bones. + } + var current = diff > 0, dir = lastTotal >= 0; + // Detect cross at 0 (not 180). + if (MathUtils.signum(lastDiff) != MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) { + // A cross after a 360 rotation is a loop. + if (Math.abs(lastTotal) > 180) + lastTotal += 360 * MathUtils.signum(lastTotal); + dir = current; + } + total = diff + lastTotal - lastTotal % 360; // Store loops as part of lastTotal. + if (dir != current) + total += 360 * MathUtils.signum(lastTotal); + timelinesRotation[i] = total; + } + timelinesRotation[i + 1] = diff; + bone.rotation = r1 + total * alpha; + }; + AnimationState.prototype.queueEvents = function (entry, animationTime) { + var animationStart = entry.animationStart, animationEnd = entry.animationEnd; + var duration = animationEnd - animationStart; + var trackLastWrapped = entry.trackLast % duration; + // Queue events before complete. + var events = this.events; + var i = 0, n = events.length; + for (; i < n; i++) { + var event_1 = events[i]; + if (event_1.time < trackLastWrapped) + break; + if (event_1.time > animationEnd) + continue; // Discard events outside animation start/end. + this.queue.event(entry, event_1); + } + // Queue complete if completed a loop iteration or the animation. + var complete = false; + if (entry.loop) + complete = duration == 0 || trackLastWrapped > entry.trackTime % duration; + else + complete = animationTime >= animationEnd && entry.animationLast < animationEnd; + if (complete) + this.queue.complete(entry); + // Queue events after complete. + for (; i < n; i++) { + var event_2 = events[i]; + if (event_2.time < animationStart) + continue; // Discard events outside animation start/end. + this.queue.event(entry, event_2); + } + }; + /** Removes all animations from all tracks, leaving skeletons in their current pose. + * + * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, + * rather than leaving them in their current pose. */ + AnimationState.prototype.clearTracks = function () { + var oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (var i = 0, n = this.tracks.length; i < n; i++) + this.clearTrack(i); + this.tracks.length = 0; + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + }; + /** Removes all animations from the track, leaving skeletons in their current pose. + * + * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, + * rather than leaving them in their current pose. */ + AnimationState.prototype.clearTrack = function (trackIndex) { + if (trackIndex >= this.tracks.length) + return; + var current = this.tracks[trackIndex]; + if (!current) + return; + this.queue.end(current); + this.clearNext(current); + var entry = current; + while (true) { + var from = entry.mixingFrom; + if (!from) + break; + this.queue.end(from); + entry.mixingFrom = null; + entry.mixingTo = null; + entry = from; + } + this.tracks[current.trackIndex] = null; + this.queue.drain(); + }; + AnimationState.prototype.setCurrent = function (index, current, interrupt) { + var from = this.expandToIndex(index); + this.tracks[index] = current; + current.previous = null; + if (from) { + if (interrupt) + this.queue.interrupt(from); + current.mixingFrom = from; + from.mixingTo = current; + current.mixTime = 0; + // Store the interrupted mix percentage. + if (from.mixingFrom && from.mixDuration > 0) + current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration); + from.timelinesRotation.length = 0; // Reset rotation for mixing out, in case entry was mixed in. + } + this.queue.start(current); + }; + /** Sets an animation by name. + * + * See {@link #setAnimationWith()}. */ + AnimationState.prototype.setAnimation = function (trackIndex, animationName, loop) { + if (loop === void 0) { loop = false; } + var animation = this.data.skeletonData.findAnimation(animationName); + if (!animation) + throw new Error("Animation not found: " + animationName); + return this.setAnimationWith(trackIndex, animation, loop); + }; + /** Sets the current animation for a track, discarding any queued animations. If the formerly current track entry was never + * applied to a skeleton, it is replaced (not mixed from). + * @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its + * duration. In either case {@link TrackEntry#trackEnd} determines when the track is cleared. + * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + AnimationState.prototype.setAnimationWith = function (trackIndex, animation, loop) { + if (loop === void 0) { loop = false; } + if (!animation) + throw new Error("animation cannot be null."); + var interrupt = true; + var current = this.expandToIndex(trackIndex); + if (current) { + if (current.nextTrackLast == -1) { + // Don't mix from an entry that was never applied. + this.tracks[trackIndex] = current.mixingFrom; + this.queue.interrupt(current); + this.queue.end(current); + this.clearNext(current); + current = current.mixingFrom; + interrupt = false; + } + else + this.clearNext(current); + } + var entry = this.trackEntry(trackIndex, animation, loop, current); + this.setCurrent(trackIndex, entry, interrupt); + this.queue.drain(); + return entry; + }; + /** Queues an animation by name. + * + * See {@link #addAnimationWith()}. */ + AnimationState.prototype.addAnimation = function (trackIndex, animationName, loop, delay) { + if (loop === void 0) { loop = false; } + if (delay === void 0) { delay = 0; } + var animation = this.data.skeletonData.findAnimation(animationName); + if (!animation) + throw new Error("Animation not found: " + animationName); + return this.addAnimationWith(trackIndex, animation, loop, delay); + }; + /** Adds an animation to be played after the current or last queued animation for a track. If the track is empty, it is + * equivalent to calling {@link #setAnimationWith()}. + * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry + * minus any mix duration (from the {@link AnimationStateData}) plus the specified `delay` (ie the mix + * ends at (`delay` = 0) or before (`delay` < 0) the previous track entry duration). If the + * previous entry is looping, its next loop completion is used instead of its duration. + * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + AnimationState.prototype.addAnimationWith = function (trackIndex, animation, loop, delay) { + if (loop === void 0) { loop = false; } + if (delay === void 0) { delay = 0; } + if (!animation) + throw new Error("animation cannot be null."); + var last = this.expandToIndex(trackIndex); + if (last) { + while (last.next) + last = last.next; + } + var entry = this.trackEntry(trackIndex, animation, loop, last); + if (!last) { + this.setCurrent(trackIndex, entry, true); + this.queue.drain(); + } + else { + last.next = entry; + entry.previous = last; + if (delay <= 0) + delay += last.getTrackComplete() - entry.mixDuration; + } + entry.delay = delay; + return entry; + }; + /** Sets an empty animation for a track, discarding any queued animations, and sets the track entry's + * {@link TrackEntry#mixduration}. An empty animation has no timelines and serves as a placeholder for mixing in or out. + * + * Mixing out is done by setting an empty animation with a mix duration using either {@link #setEmptyAnimation()}, + * {@link #setEmptyAnimations()}, or {@link #addEmptyAnimation()}. Mixing to an empty animation causes + * the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation + * transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of + * 0 still mixes out over one frame. + * + * Mixing in is done by first setting an empty animation, then adding an animation using + * {@link #addAnimation()} and on the returned track entry, set the + * {@link TrackEntry#setMixDuration()}. Mixing from an empty animation causes the new animation to be applied more and + * more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the + * setup pose value if no lower tracks key the property to the value keyed in the new animation. */ + AnimationState.prototype.setEmptyAnimation = function (trackIndex, mixDuration) { + if (mixDuration === void 0) { mixDuration = 0; } + var entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation(), false); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + }; + /** Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's + * {@link TrackEntry#mixDuration}. If the track is empty, it is equivalent to calling + * {@link #setEmptyAnimation()}. + * + * See {@link #setEmptyAnimation()}. + * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry + * minus any mix duration plus the specified `delay` (ie the mix ends at (`delay` = 0) or + * before (`delay` < 0) the previous track entry duration). If the previous entry is looping, its next + * loop completion is used instead of its duration. + * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + AnimationState.prototype.addEmptyAnimation = function (trackIndex, mixDuration, delay) { + if (mixDuration === void 0) { mixDuration = 0; } + if (delay === void 0) { delay = 0; } + var entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation(), false, delay); + if (delay <= 0) + entry.delay += entry.mixDuration - mixDuration; + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + }; + /** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix + * duration. */ + AnimationState.prototype.setEmptyAnimations = function (mixDuration) { + if (mixDuration === void 0) { mixDuration = 0; } + var oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (var i = 0, n = this.tracks.length; i < n; i++) { + var current = this.tracks[i]; + if (current) + this.setEmptyAnimation(current.trackIndex, mixDuration); + } + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + }; + AnimationState.prototype.expandToIndex = function (index) { + if (index < this.tracks.length) + return this.tracks[index]; + Utils.ensureArrayCapacity(this.tracks, index + 1, null); + this.tracks.length = index + 1; + return null; + }; + /** @param last May be null. */ + AnimationState.prototype.trackEntry = function (trackIndex, animation, loop, last) { + var entry = this.trackEntryPool.obtain(); + entry.reset(); + entry.trackIndex = trackIndex; + entry.animation = animation; + entry.loop = loop; + entry.holdPrevious = false; + entry.reverse = false; + entry.shortestRotation = false; + entry.eventThreshold = 0; + entry.attachmentThreshold = 0; + entry.drawOrderThreshold = 0; + entry.animationStart = 0; + entry.animationEnd = animation.duration; + entry.animationLast = -1; + entry.nextAnimationLast = -1; + entry.delay = 0; + entry.trackTime = 0; + entry.trackLast = -1; + entry.nextTrackLast = -1; + entry.trackEnd = Number.MAX_VALUE; + entry.timeScale = 1; + entry.alpha = 1; + entry.mixTime = 0; + entry.mixDuration = !last ? 0 : this.data.getMix(last.animation, animation); + entry.interruptAlpha = 1; + entry.totalAlpha = 0; + entry.mixBlend = exports.MixBlend.replace; + return entry; + }; + /** Removes the {@link TrackEntry#getNext() next entry} and all entries after it for the specified entry. */ + AnimationState.prototype.clearNext = function (entry) { + var next = entry.next; + while (next) { + this.queue.dispose(next); + next = next.next; + } + entry.next = null; + }; + AnimationState.prototype._animationsChanged = function () { + this.animationsChanged = false; + this.propertyIDs.clear(); + var tracks = this.tracks; + for (var i = 0, n = tracks.length; i < n; i++) { + var entry = tracks[i]; + if (!entry) + continue; + while (entry.mixingFrom) + entry = entry.mixingFrom; + do { + if (!entry.mixingTo || entry.mixBlend != exports.MixBlend.add) + this.computeHold(entry); + entry = entry.mixingTo; + } while (entry); + } + }; + AnimationState.prototype.computeHold = function (entry) { + var to = entry.mixingTo; + var timelines = entry.animation.timelines; + var timelinesCount = entry.animation.timelines.length; + var timelineMode = entry.timelineMode; + timelineMode.length = timelinesCount; + var timelineHoldMix = entry.timelineHoldMix; + timelineHoldMix.length = 0; + var propertyIDs = this.propertyIDs; + if (to && to.holdPrevious) { + for (var i = 0; i < timelinesCount; i++) + timelineMode[i] = propertyIDs.addAll(timelines[i].getPropertyIds()) ? HOLD_FIRST : HOLD_SUBSEQUENT; + return; + } + outer: for (var i = 0; i < timelinesCount; i++) { + var timeline = timelines[i]; + var ids = timeline.getPropertyIds(); + if (!propertyIDs.addAll(ids)) + timelineMode[i] = SUBSEQUENT; + else if (!to || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline + || timeline instanceof EventTimeline || !to.animation.hasTimeline(ids)) { + timelineMode[i] = FIRST; + } + else { + for (var next = to.mixingTo; next; next = next.mixingTo) { + if (next.animation.hasTimeline(ids)) + continue; + if (entry.mixDuration > 0) { + timelineMode[i] = HOLD_MIX; + timelineHoldMix[i] = next; + continue outer; + } + break; + } + timelineMode[i] = HOLD_FIRST; + } + } + }; + /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */ + AnimationState.prototype.getCurrent = function (trackIndex) { + if (trackIndex >= this.tracks.length) + return null; + return this.tracks[trackIndex]; + }; + /** Adds a listener to receive events for all track entries. */ + AnimationState.prototype.addListener = function (listener) { + if (!listener) + throw new Error("listener cannot be null."); + this.listeners.push(listener); + }; + /** Removes the listener added with {@link #addListener()}. */ + AnimationState.prototype.removeListener = function (listener) { + var index = this.listeners.indexOf(listener); + if (index >= 0) + this.listeners.splice(index, 1); + }; + /** Removes all listeners added with {@link #addListener()}. */ + AnimationState.prototype.clearListeners = function () { + this.listeners.length = 0; + }; + /** Discards all listener notifications that have not yet been delivered. This can be useful to call from an + * {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery + * are not wanted because new animations are being set. */ + AnimationState.prototype.clearListenerNotifications = function () { + this.queue.clear(); + }; + AnimationState.prototype.setAnimationByName = function (trackIndex, animationName, loop) { + if (!AnimationState.deprecatedWarning1) { + AnimationState.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on."); + } + this.setAnimation(trackIndex, animationName, loop); + }; + AnimationState.prototype.addAnimationByName = function (trackIndex, animationName, loop, delay) { + if (!AnimationState.deprecatedWarning2) { + AnimationState.deprecatedWarning2 = true; + console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on."); + } + this.addAnimation(trackIndex, animationName, loop, delay); + }; + AnimationState.prototype.hasAnimation = function (animationName) { + var animation = this.data.skeletonData.findAnimation(animationName); + return animation !== null; + }; + AnimationState.prototype.hasAnimationByName = function (animationName) { + if (!AnimationState.deprecatedWarning3) { + AnimationState.deprecatedWarning3 = true; + console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on."); + } + return this.hasAnimation(animationName); + }; + AnimationState._emptyAnimation = new Animation("", [], 0); + AnimationState.deprecatedWarning1 = false; + AnimationState.deprecatedWarning2 = false; + AnimationState.deprecatedWarning3 = false; + return AnimationState; + }()); + /** Stores settings and other state for the playback of an animation on an {@link AnimationState} track. + * + * References to a track entry must not be kept after the {@link AnimationStateListener#dispose()} event occurs. + * @public + * */ + var TrackEntry = /** @class */ (function () { + function TrackEntry() { + /** The animation to apply for this track entry. */ + this.animation = null; + this.previous = null; + /** The animation queued to start after this animation, or null. `next` makes up a linked list. */ + this.next = null; + /** The track entry for the previous animation when mixing from the previous animation to this animation, or null if no + * mixing is currently occuring. When mixing from multiple animations, `mixingFrom` makes up a linked list. */ + this.mixingFrom = null; + /** The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is + * currently occuring. When mixing to multiple animations, `mixingTo` makes up a linked list. */ + this.mixingTo = null; + /** The listener for events generated by this track entry, or null. + * + * A track entry returned from {@link AnimationState#setAnimation()} is already the current animation + * for the track, so the track entry listener {@link AnimationStateListener#start()} will not be called. */ + this.listener = null; + /** The index of the track where this track entry is either current or queued. + * + * See {@link AnimationState#getCurrent()}. */ + this.trackIndex = 0; + /** If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its + * duration. */ + this.loop = false; + /** If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead + * of being mixed out. + * + * When mixing between animations that key the same property, if a lower track also keys that property then the value will + * briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0% + * while the second animation mixes from 0% to 100%. Setting `holdPrevious` to true applies the first animation + * at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which + * keys the property, only when a higher track also keys the property. + * + * Snapping will occur if `holdPrevious` is true and this animation does not key all the same properties as the + * previous animation. */ + this.holdPrevious = false; + this.reverse = false; + this.shortestRotation = false; + /** When the mix percentage ({@link #mixTime} / {@link #mixDuration}) is less than the + * `eventThreshold`, event timelines are applied while this animation is being mixed out. Defaults to 0, so event + * timelines are not applied while this animation is being mixed out. */ + this.eventThreshold = 0; + /** When the mix percentage ({@link #mixtime} / {@link #mixDuration}) is less than the + * `attachmentThreshold`, attachment timelines are applied while this animation is being mixed out. Defaults to + * 0, so attachment timelines are not applied while this animation is being mixed out. */ + this.attachmentThreshold = 0; + /** When the mix percentage ({@link #mixTime} / {@link #mixDuration}) is less than the + * `drawOrderThreshold`, draw order timelines are applied while this animation is being mixed out. Defaults to 0, + * so draw order timelines are not applied while this animation is being mixed out. */ + this.drawOrderThreshold = 0; + /** Seconds when this animation starts, both initially and after looping. Defaults to 0. + * + * When changing the `animationStart` time, it often makes sense to set {@link #animationLast} to the same + * value to prevent timeline keys before the start time from triggering. */ + this.animationStart = 0; + /** Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will + * loop back to {@link #animationStart} at this time. Defaults to the animation {@link Animation#duration}. */ + this.animationEnd = 0; + /** The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this + * animation is applied, event timelines will fire all events between the `animationLast` time (exclusive) and + * `animationTime` (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation + * is applied. */ + this.animationLast = 0; + this.nextAnimationLast = 0; + /** Seconds to postpone playing the animation. When this track entry is the current track entry, `delay` + * postpones incrementing the {@link #trackTime}. When this track entry is queued, `delay` is the time from + * the start of the previous animation to when this track entry will become the current track entry (ie when the previous + * track entry {@link TrackEntry#trackTime} >= this track entry's `delay`). + * + * {@link #timeScale} affects the delay. */ + this.delay = 0; + /** Current time in seconds this track entry has been the current track entry. The track time determines + * {@link #animationTime}. The track time can be set to start the animation at a time other than 0, without affecting + * looping. */ + this.trackTime = 0; + this.trackLast = 0; + this.nextTrackLast = 0; + /** The track time in seconds when this animation will be removed from the track. Defaults to the highest possible float + * value, meaning the animation will be applied until a new animation is set or the track is cleared. If the track end time + * is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the + * properties keyed by the animation are set to the setup pose and the track is cleared. + * + * It may be desired to use {@link AnimationState#addEmptyAnimation()} rather than have the animation + * abruptly cease being applied. */ + this.trackEnd = 0; + /** Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or + * faster. Defaults to 1. + * + * {@link #mixTime} is not affected by track entry time scale, so {@link #mixDuration} may need to be adjusted to + * match the animation speed. + * + * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the + * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, assuming time scale to be 1. If + * the time scale is not 1, the delay may need to be adjusted. + * + * See AnimationState {@link AnimationState#timeScale} for affecting all animations. */ + this.timeScale = 0; + /** Values < 1 mix this animation with the skeleton's current pose (usually the pose resulting from lower tracks). Defaults + * to 1, which overwrites the skeleton's current pose with this animation. + * + * Typically track 0 is used to completely pose the skeleton, then alpha is used on higher tracks. It doesn't make sense to + * use alpha on track 0 if the skeleton pose is from the last frame render. */ + this.alpha = 0; + /** Seconds from 0 to the {@link #getMixDuration()} when mixing from the previous animation to this animation. May be + * slightly more than `mixDuration` when the mix is complete. */ + this.mixTime = 0; + /** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData + * {@link AnimationStateData#getMix()} based on the animation before this animation (if any). + * + * A mix duration of 0 still mixes out over one frame to provide the track entry being mixed out a chance to revert the + * properties it was animating. + * + * The `mixDuration` can be set manually rather than use the value from + * {@link AnimationStateData#getMix()}. In that case, the `mixDuration` can be set for a new + * track entry only before {@link AnimationState#update(float)} is first called. + * + * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the + * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, not a mix duration set + * afterward. */ + this.mixDuration = 0; + this.interruptAlpha = 0; + this.totalAlpha = 0; + /** Controls how properties keyed in the animation are mixed with lower tracks. Defaults to {@link MixBlend#replace}, which + * replaces the values from the lower tracks with the animation values. {@link MixBlend#add} adds the animation values to + * the values from the lower tracks. + * + * The `mixBlend` can be set for a new track entry only before {@link AnimationState#apply()} is first + * called. */ + this.mixBlend = exports.MixBlend.replace; + this.timelineMode = new Array(); + this.timelineHoldMix = new Array(); + this.timelinesRotation = new Array(); + } + TrackEntry.prototype.reset = function () { + this.next = null; + this.previous = null; + this.mixingFrom = null; + this.mixingTo = null; + this.animation = null; + this.listener = null; + this.timelineMode.length = 0; + this.timelineHoldMix.length = 0; + this.timelinesRotation.length = 0; + }; + /** Uses {@link #trackTime} to compute the `animationTime`, which is between {@link #animationStart} + * and {@link #animationEnd}. When the `trackTime` is 0, the `animationTime` is equal to the + * `animationStart` time. */ + TrackEntry.prototype.getAnimationTime = function () { + if (this.loop) { + var duration = this.animationEnd - this.animationStart; + if (duration == 0) + return this.animationStart; + return (this.trackTime % duration) + this.animationStart; + } + return Math.min(this.trackTime + this.animationStart, this.animationEnd); + }; + TrackEntry.prototype.setAnimationLast = function (animationLast) { + this.animationLast = animationLast; + this.nextAnimationLast = animationLast; + }; + /** Returns true if at least one loop has been completed. + * + * See {@link AnimationStateListener#complete()}. */ + TrackEntry.prototype.isComplete = function () { + return this.trackTime >= this.animationEnd - this.animationStart; + }; + /** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the + * long way around when using {@link #alpha} and starting animations on other tracks. + * + * Mixing with {@link MixBlend#replace} involves finding a rotation between two others, which has two possible solutions: + * the short way or the long way around. The two rotations likely change over time, so which direction is the short or long + * way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the + * long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. */ + TrackEntry.prototype.resetRotationDirections = function () { + this.timelinesRotation.length = 0; + }; + TrackEntry.prototype.getTrackComplete = function () { + var duration = this.animationEnd - this.animationStart; + if (duration != 0) { + if (this.loop) + return duration * (1 + ((this.trackTime / duration) | 0)); // Completion of next loop. + if (this.trackTime < duration) + return duration; // Before duration. + } + return this.trackTime; // Next update. + }; + Object.defineProperty(TrackEntry.prototype, "time", { + get: function () { + if (!TrackEntry.deprecatedWarning1) { + TrackEntry.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); + } + return this.trackTime; + }, + set: function (value) { + if (!TrackEntry.deprecatedWarning1) { + TrackEntry.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); + } + this.trackTime = value; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(TrackEntry.prototype, "endTime", { + get: function () { + if (!TrackEntry.deprecatedWarning2) { + TrackEntry.deprecatedWarning2 = true; + console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); + } + return this.trackTime; + }, + set: function (value) { + if (!TrackEntry.deprecatedWarning2) { + TrackEntry.deprecatedWarning2 = true; + console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); + } + this.trackTime = value; + }, + enumerable: false, + configurable: true + }); + TrackEntry.prototype.loopsCount = function () { + return Math.floor(this.trackTime / this.trackEnd); + }; + TrackEntry.deprecatedWarning1 = false; + TrackEntry.deprecatedWarning2 = false; + return TrackEntry; + }()); + /** + * @public + */ + var EventQueue = /** @class */ (function () { + function EventQueue(animState) { + this.objects = []; + this.drainDisabled = false; + this.animState = animState; + } + EventQueue.prototype.start = function (entry) { + this.objects.push(EventType.start); + this.objects.push(entry); + this.animState.animationsChanged = true; + }; + EventQueue.prototype.interrupt = function (entry) { + this.objects.push(EventType.interrupt); + this.objects.push(entry); + }; + EventQueue.prototype.end = function (entry) { + this.objects.push(EventType.end); + this.objects.push(entry); + this.animState.animationsChanged = true; + }; + EventQueue.prototype.dispose = function (entry) { + this.objects.push(EventType.dispose); + this.objects.push(entry); + }; + EventQueue.prototype.complete = function (entry) { + this.objects.push(EventType.complete); + this.objects.push(entry); + }; + EventQueue.prototype.event = function (entry, event) { + this.objects.push(EventType.event); + this.objects.push(entry); + this.objects.push(event); + }; + EventQueue.prototype.drain = function () { + if (this.drainDisabled) + return; + this.drainDisabled = true; + var objects = this.objects; + var listeners = this.animState.listeners; + for (var i = 0; i < objects.length; i += 2) { + var type = objects[i]; + var entry = objects[i + 1]; + switch (type) { + case EventType.start: + if (entry.listener && entry.listener.start) + entry.listener.start(entry); + for (var ii = 0; ii < listeners.length; ii++) { + var listener = listeners[ii]; + if (listener.start) + listener.start(entry); + } + break; + case EventType.interrupt: + if (entry.listener && entry.listener.interrupt) + entry.listener.interrupt(entry); + for (var ii = 0; ii < listeners.length; ii++) { + var listener = listeners[ii]; + if (listener.interrupt) + listener.interrupt(entry); + } + break; + case EventType.end: + if (entry.listener && entry.listener.end) + entry.listener.end(entry); + for (var ii = 0; ii < listeners.length; ii++) { + var listener = listeners[ii]; + if (listener.end) + listener.end(entry); + } + // Fall through. + case EventType.dispose: + if (entry.listener && entry.listener.dispose) + entry.listener.dispose(entry); + for (var ii = 0; ii < listeners.length; ii++) { + var listener = listeners[ii]; + if (listener.dispose) + listener.dispose(entry); + } + this.animState.trackEntryPool.free(entry); + break; + case EventType.complete: + if (entry.listener && entry.listener.complete) + entry.listener.complete(entry); + for (var ii = 0; ii < listeners.length; ii++) { + var listener = listeners[ii]; + if (listener.complete) + listener.complete(entry); + } + break; + case EventType.event: + var event_3 = objects[i++ + 2]; + if (entry.listener && entry.listener.event) + entry.listener.event(entry, event_3); + for (var ii = 0; ii < listeners.length; ii++) { + var listener = listeners[ii]; + if (listener.event) + listener.event(entry, event_3); + } + break; + } + } + this.clear(); + this.drainDisabled = false; + }; + EventQueue.prototype.clear = function () { + this.objects.length = 0; + }; + return EventQueue; + }()); + /** + * @public + */ + var EventType; + (function (EventType) { + EventType[EventType["start"] = 0] = "start"; + EventType[EventType["interrupt"] = 1] = "interrupt"; + EventType[EventType["end"] = 2] = "end"; + EventType[EventType["dispose"] = 3] = "dispose"; + EventType[EventType["complete"] = 4] = "complete"; + EventType[EventType["event"] = 5] = "event"; + })(EventType || (EventType = {})); + /** + * @public + */ + var AnimationStateAdapter = /** @class */ (function () { + function AnimationStateAdapter() { + } + AnimationStateAdapter.prototype.start = function (entry) { + }; + AnimationStateAdapter.prototype.interrupt = function (entry) { + }; + AnimationStateAdapter.prototype.end = function (entry) { + }; + AnimationStateAdapter.prototype.dispose = function (entry) { + }; + AnimationStateAdapter.prototype.complete = function (entry) { + }; + AnimationStateAdapter.prototype.event = function (entry, event) { + }; + return AnimationStateAdapter; + }()); + /** 1. A previously applied timeline has set this property. + * + * Result: Mix from the current pose to the timeline pose. */ + var SUBSEQUENT = 0; + /** 1. This is the first timeline to set this property. + * 2. The next track entry applied after this one does not have a timeline to set this property. + * + * Result: Mix from the setup pose to the timeline pose. */ + var FIRST = 1; + /** 1) A previously applied timeline has set this property.
+ * 2) The next track entry to be applied does have a timeline to set this property.
+ * 3) The next track entry after that one does not have a timeline to set this property.
+ * Result: Mix from the current pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading + * animations that key the same property. A subsequent timeline will set this property using a mix. */ + var HOLD_SUBSEQUENT = 2; + /** 1) This is the first timeline to set this property.
+ * 2) The next track entry to be applied does have a timeline to set this property.
+ * 3) The next track entry after that one does not have a timeline to set this property.
+ * Result: Mix from the setup pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading animations + * that key the same property. A subsequent timeline will set this property using a mix. */ + var HOLD_FIRST = 3; + /** 1. This is the first timeline to set this property. + * 2. The next track entry to be applied does have a timeline to set this property. + * 3. The next track entry after that one does have a timeline to set this property. + * 4. timelineHoldMix stores the first subsequent track entry that does not have a timeline to set this property. + * + * Result: The same as HOLD except the mix percentage from the timelineHoldMix track entry is used. This handles when more than + * 2 track entries in a row have a timeline that sets the same property. + * + * Eg, A -> B -> C -> D where A, B, and C have a timeline setting same property, but D does not. When A is applied, to avoid + * "dipping" A is not mixed out, however D (the first entry that doesn't set the property) mixing in is used to mix out A + * (which affects B and C). Without using D to mix out, A would be applied fully until mixing completes, then snap into + * place. */ + var HOLD_MIX = 4; + var SETUP = 1; + var CURRENT = 2; + + /** Stores mix (crossfade) durations to be applied when {@link AnimationState} animations are changed. + * @public + * */ + var AnimationStateData = /** @class */ (function () { + function AnimationStateData(skeletonData) { + this.animationToMixTime = {}; + /** The mix duration to use when no mix duration has been defined between two animations. */ + this.defaultMix = 0; + if (!skeletonData) + throw new Error("skeletonData cannot be null."); + this.skeletonData = skeletonData; + } + /** Sets a mix duration by animation name. + * + * See {@link #setMixWith()}. */ + AnimationStateData.prototype.setMix = function (fromName, toName, duration) { + var from = this.skeletonData.findAnimation(fromName); + if (!from) + throw new Error("Animation not found: " + fromName); + var to = this.skeletonData.findAnimation(toName); + if (!to) + throw new Error("Animation not found: " + toName); + this.setMixWith(from, to, duration); + }; + /** Sets the mix duration when changing from the specified animation to the other. + * + * See {@link TrackEntry#mixDuration}. */ + AnimationStateData.prototype.setMixWith = function (from, to, duration) { + if (!from) + throw new Error("from cannot be null."); + if (!to) + throw new Error("to cannot be null."); + var key = from.name + "." + to.name; + this.animationToMixTime[key] = duration; + }; + /** Returns the mix duration to use when changing from the specified animation to the other, or the {@link #defaultMix} if + * no mix duration has been set. */ + AnimationStateData.prototype.getMix = function (from, to) { + var key = from.name + "." + to.name; + var value = this.animationToMixTime[key]; + return value === undefined ? this.defaultMix : value; + }; + return AnimationStateData; + }()); + + /** + * @public + */ + var AtlasAttachmentLoader = /** @class */ (function () { + function AtlasAttachmentLoader(atlas) { + this.atlas = atlas; + } + AtlasAttachmentLoader.prototype.loadSequence = function (name, basePath, sequence) { + var regions = sequence.regions; + for (var i = 0, n = regions.length; i < n; i++) { + var path = sequence.getPath(basePath, i); + var region = this.atlas.findRegion(path); + if (region == null) + throw new Error("Region not found in atlas: " + path + " (sequence: " + name + ")"); + regions[i] = region; + regions[i].renderObject = regions[i]; + } + }; + AtlasAttachmentLoader.prototype.newRegionAttachment = function (skin, name, path, sequence) { + var attachment = new RegionAttachment(name, path); + if (sequence != null) { + this.loadSequence(name, path, sequence); + } + else { + var region = this.atlas.findRegion(path); + if (!region) + throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); + region.renderObject = region; + attachment.region = region; + } + return attachment; + }; + AtlasAttachmentLoader.prototype.newMeshAttachment = function (skin, name, path, sequence) { + var attachment = new MeshAttachment(name, path); + if (sequence != null) { + this.loadSequence(name, path, sequence); + } + else { + var region = this.atlas.findRegion(path); + if (!region) + throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); + region.renderObject = region; + attachment.region = region; + } + return attachment; + }; + AtlasAttachmentLoader.prototype.newBoundingBoxAttachment = function (skin, name) { + return new BoundingBoxAttachment(name); + }; + AtlasAttachmentLoader.prototype.newPathAttachment = function (skin, name) { + return new PathAttachment(name); + }; + AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) { + return new PointAttachment(name); + }; + AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) { + return new ClippingAttachment(name); + }; + return AtlasAttachmentLoader; + }()); + + /** 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. + * @public + * */ + var Bone = /** @class */ (function () { + /** @param parent May be null. */ + function Bone(data, skeleton, parent) { + //be careful! Spine b,c is c,b in pixi matrix + this.matrix = new math.Matrix(); + /** The parent bone, or null if this is the root bone. */ + this.parent = null; + /** The immediate children of this bone. */ + this.children = new Array(); + /** The local x translation. */ + this.x = 0; + /** The local y translation. */ + this.y = 0; + /** The local rotation in degrees, counter clockwise. */ + this.rotation = 0; + /** The local scaleX. */ + this.scaleX = 0; + /** The local scaleY. */ + this.scaleY = 0; + /** The local shearX. */ + this.shearX = 0; + /** The local shearY. */ + this.shearY = 0; + /** The applied local x translation. */ + this.ax = 0; + /** The applied local y translation. */ + this.ay = 0; + /** The applied local rotation in degrees, counter clockwise. */ + this.arotation = 0; + /** The applied local scaleX. */ + this.ascaleX = 0; + /** The applied local scaleY. */ + this.ascaleY = 0; + /** The applied local shearX. */ + this.ashearX = 0; + /** The applied local shearY. */ + this.ashearY = 0; + this.sorted = false; + this.active = false; + if (!data) + throw new Error("data cannot be null."); + if (!skeleton) + throw new Error("skeleton cannot be null."); + this.data = data; + this.skeleton = skeleton; + this.parent = parent; + this.setToSetupPose(); + } + Object.defineProperty(Bone.prototype, "worldX", { + get: function () { + return this.matrix.tx; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Bone.prototype, "worldY", { + get: function () { + return this.matrix.ty; + }, + enumerable: false, + configurable: true + }); + /** Returns false when the bone has not been computed because {@link BoneData#skinRequired} is true and the + * {@link Skeleton#skin active skin} does not {@link Skin#bones contain} this bone. */ + Bone.prototype.isActive = function () { + return this.active; + }; + /** Computes the world transform using the parent bone and this bone's local applied transform. */ + Bone.prototype.update = function () { + this.updateWorldTransformWith(this.ax, this.ay, this.arotation, this.ascaleX, this.ascaleY, this.ashearX, this.ashearY); + }; + /** Computes the world transform using the parent bone and this bone's local transform. + * + * See {@link #updateWorldTransformWith()}. */ + Bone.prototype.updateWorldTransform = function () { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + }; + /** 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 transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + * Runtimes Guide. */ + Bone.prototype.updateWorldTransformWith = function (x, y, rotation, scaleX, scaleY, shearX, shearY) { + this.ax = x; + this.ay = y; + this.arotation = rotation; + this.ascaleX = scaleX; + this.ascaleY = scaleY; + this.ashearX = shearX; + this.ashearY = shearY; + var parent = this.parent; + var m = this.matrix; + var sx = this.skeleton.scaleX; + var sy = settings.yDown ? -this.skeleton.scaleY : this.skeleton.scaleY; + if (!parent) { // Root bone. + var skeleton = this.skeleton; + var rotationY = rotation + 90 + shearY; + m.a = MathUtils.cosDeg(rotation + shearX) * scaleX * sx; + m.c = MathUtils.cosDeg(rotationY) * scaleY * sx; + m.b = MathUtils.sinDeg(rotation + shearX) * scaleX * sy; + m.d = MathUtils.sinDeg(rotationY) * scaleY * sy; + m.tx = x * sx + skeleton.x; + m.ty = y * sy + skeleton.y; + return; + } + var pa = parent.matrix.a, pb = parent.matrix.c, pc = parent.matrix.b, pd = parent.matrix.d; + m.tx = pa * x + pb * y + parent.matrix.tx; + m.ty = pc * x + pd * y + parent.matrix.ty; + switch (this.data.transformMode) { + case exports.TransformMode.Normal: { + var rotationY = rotation + 90 + shearY; + var la = MathUtils.cosDeg(rotation + shearX) * scaleX; + var lb = MathUtils.cosDeg(rotationY) * scaleY; + var lc = MathUtils.sinDeg(rotation + shearX) * scaleX; + var ld = MathUtils.sinDeg(rotationY) * scaleY; + m.a = pa * la + pb * lc; + m.c = pa * lb + pb * ld; + m.b = pc * la + pd * lc; + m.d = pc * lb + pd * ld; + return; + } + case exports.TransformMode.OnlyTranslation: { + var rotationY = rotation + 90 + shearY; + m.a = MathUtils.cosDeg(rotation + shearX) * scaleX; + m.c = MathUtils.cosDeg(rotationY) * scaleY; + m.b = MathUtils.sinDeg(rotation + shearX) * scaleX; + m.d = MathUtils.sinDeg(rotationY) * scaleY; + break; + } + case exports.TransformMode.NoRotationOrReflection: { + var s = pa * pa + pc * pc; + var prx = 0; + if (s > 0.0001) { + s = Math.abs(pa * pd - pb * pc) / s; + pa /= sx; + pc /= sy; + pb = pc * s; + pd = pa * s; + prx = Math.atan2(pc, pa) * MathUtils.radDeg; + } + else { + pa = 0; + pc = 0; + prx = 90 - Math.atan2(pd, pb) * MathUtils.radDeg; + } + var rx = rotation + shearX - prx; + var ry = rotation + shearY - prx + 90; + var la = MathUtils.cosDeg(rx) * scaleX; + var lb = MathUtils.cosDeg(ry) * scaleY; + var lc = MathUtils.sinDeg(rx) * scaleX; + var ld = MathUtils.sinDeg(ry) * scaleY; + m.a = pa * la - pb * lc; + m.c = pa * lb - pb * ld; + m.b = pc * la + pd * lc; + m.d = pc * lb + pd * ld; + break; + } + case exports.TransformMode.NoScale: + case exports.TransformMode.NoScaleOrReflection: { + var cos = MathUtils.cosDeg(rotation); + var sin = MathUtils.sinDeg(rotation); + var za = (pa * cos + pb * sin) / sx; + var zc = (pc * cos + pd * sin) / sy; + var s = Math.sqrt(za * za + zc * zc); + if (s > 0.00001) + s = 1 / s; + za *= s; + zc *= s; + s = Math.sqrt(za * za + zc * zc); + if (this.data.transformMode == exports.TransformMode.NoScale + && (pa * pd - pb * pc < 0) != (sx < 0 != sy < 0)) + s = -s; + var r = Math.PI / 2 + Math.atan2(zc, za); + var zb = Math.cos(r) * s; + var zd = Math.sin(r) * s; + var la = MathUtils.cosDeg(shearX) * scaleX; + var lb = MathUtils.cosDeg(90 + shearY) * scaleY; + var lc = MathUtils.sinDeg(shearX) * scaleX; + var ld = MathUtils.sinDeg(90 + shearY) * scaleY; + m.a = za * la + zb * lc; + m.c = za * lb + zb * ld; + m.b = zc * la + zd * lc; + m.d = zc * lb + zd * ld; + break; + } + } + m.a *= sx; + m.c *= sx; + m.b *= sy; + m.d *= sy; + }; + /** Sets this bone's local transform to the setup pose. */ + Bone.prototype.setToSetupPose = function () { + var data = this.data; + this.x = data.x; + this.y = data.y; + this.rotation = data.rotation; + this.scaleX = data.scaleX; + this.scaleY = data.scaleY; + this.shearX = data.shearX; + this.shearY = data.shearY; + }; + /** The world rotation for the X axis, calculated using {@link #a} and {@link #c}. */ + Bone.prototype.getWorldRotationX = function () { + return Math.atan2(this.matrix.b, this.matrix.a) * MathUtils.radDeg; + }; + /** The world rotation for the Y axis, calculated using {@link #b} and {@link #d}. */ + Bone.prototype.getWorldRotationY = function () { + return Math.atan2(this.matrix.d, this.matrix.c) * MathUtils.radDeg; + }; + /** The magnitude (always positive) of the world scale X, calculated using {@link #a} and {@link #c}. */ + Bone.prototype.getWorldScaleX = function () { + var m = this.matrix; + return Math.sqrt(m.a * m.a + m.b * m.b); + }; + /** The magnitude (always positive) of the world scale Y, calculated using {@link #b} and {@link #d}. */ + Bone.prototype.getWorldScaleY = function () { + var m = this.matrix; + return Math.sqrt(m.c * m.c + m.d * m.d); + }; + /** Computes the applied transform values from the world transform. + * + * If the world transform is modified (by a constraint, {@link #rotateWorld(float)}, 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 other + * constraints). + * + * 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. */ + Bone.prototype.updateAppliedTransform = function () { + var parent = this.parent; + var m = this.matrix; + if (!parent) { + this.ax = m.tx - this.skeleton.x; + this.ay = m.ty - this.skeleton.y; + this.arotation = Math.atan2(m.b, m.a) * MathUtils.radDeg; + this.ascaleX = Math.sqrt(m.a * m.a + m.b * m.b); + this.ascaleY = Math.sqrt(m.c * m.c + m.d * m.d); + this.ashearX = 0; + this.ashearY = Math.atan2(m.a * m.c + m.b * m.d, m.a * m.d - m.b * m.c) * MathUtils.radDeg; + return; + } + var pm = parent.matrix; + var pid = 1 / (pm.a * pm.d - pm.b * pm.c); + var dx = m.tx - pm.tx, dy = m.ty - pm.ty; + this.ax = (dx * pm.d * pid - dy * pm.c * pid); + this.ay = (dy * pm.a * pid - dx * pm.b * pid); + var ia = pid * pm.d; + var id = pid * pm.a; + var ib = pid * pm.c; + var ic = pid * pm.b; + var ra = ia * m.a - ib * m.b; + var rb = ia * m.c - ib * m.d; + var rc = id * m.b - ic * m.a; + var rd = id * m.d - ic * m.c; + this.ashearX = 0; + this.ascaleX = Math.sqrt(ra * ra + rc * rc); + if (this.ascaleX > 0.0001) { + var det = ra * rd - rb * rc; + this.ascaleY = det / this.ascaleX; + this.ashearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg; + this.arotation = Math.atan2(rc, ra) * MathUtils.radDeg; + } + else { + this.ascaleX = 0; + this.ascaleY = Math.sqrt(rb * rb + rd * rd); + this.ashearY = 0; + this.arotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg; + } + }; + /** Transforms a point from world coordinates to the bone's local coordinates. */ + Bone.prototype.worldToLocal = function (world) { + var m = this.matrix; + var a = m.a, b = m.c, c = m.b, d = m.d; + var invDet = 1 / (a * d - b * c); + var x = world.x - m.tx, y = world.y - m.ty; + world.x = (x * d * invDet - y * b * invDet); + world.y = (y * a * invDet - x * c * invDet); + return world; + }; + /** Transforms a point from the bone's local coordinates to world coordinates. */ + Bone.prototype.localToWorld = function (local) { + var m = this.matrix; + var x = local.x, y = local.y; + local.x = x * m.a + y * m.c + m.tx; + local.y = x * m.b + y * m.d + m.ty; + return local; + }; + /** Transforms a world rotation to a local rotation. */ + Bone.prototype.worldToLocalRotation = function (worldRotation) { + var sin = MathUtils.sinDeg(worldRotation), cos = MathUtils.cosDeg(worldRotation); + var mat = this.matrix; + return Math.atan2(mat.a * sin - mat.b * cos, mat.d * cos - mat.c * sin) * MathUtils.radDeg; + }; + /** Transforms a local rotation to a world rotation. */ + Bone.prototype.localToWorldRotation = function (localRotation) { + localRotation -= this.rotation - this.shearX; + var sin = MathUtils.sinDeg(localRotation), cos = MathUtils.cosDeg(localRotation); + var mat = this.matrix; + return Math.atan2(cos * mat.b + sin * mat.d, cos * mat.a + sin * mat.c) * MathUtils.radDeg; + }; + /** Rotates the world transform the specified amount. + *

+ * After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and {@link #update()} will + * need to be called on any child bones, recursively. */ + Bone.prototype.rotateWorld = function (degrees) { + var mat = this.matrix; + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var cos = MathUtils.cosDeg(degrees), sin = MathUtils.sinDeg(degrees); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + }; + return Bone; + }()); + + /** Stores the setup pose for a {@link Bone}. + * @public + * */ + var BoneData = /** @class */ (function () { + function BoneData(index, name, parent) { + /** The index of the bone in {@link Skeleton#getBones()}. */ + this.index = 0; + /** @returns May be null. */ + this.parent = null; + /** The bone's length. */ + this.length = 0; + /** The local x translation. */ + this.x = 0; + /** The local y translation. */ + this.y = 0; + /** The local rotation. */ + this.rotation = 0; + /** The local scaleX. */ + this.scaleX = 1; + /** The local scaleY. */ + this.scaleY = 1; + /** The local shearX. */ + this.shearX = 0; + /** The local shearX. */ + this.shearY = 0; + /** The transform mode for how parent world transforms affect this bone. */ + this.transformMode = exports.TransformMode.Normal; + /** When true, {@link Skeleton#updateWorldTransform()} only updates this bone if the {@link Skeleton#skin} contains this + * bone. + * @see Skin#bones */ + this.skinRequired = false; + /** The color of the bone as it was in Spine. Available only when nonessential data was exported. Bones are not usually + * rendered at runtime. */ + this.color = new Color(); + if (index < 0) + throw new Error("index must be >= 0."); + if (!name) + throw new Error("name cannot be null."); + this.index = index; + this.name = name; + this.parent = parent; + } + return BoneData; + }()); + + /** The base class for all constraint datas. + * @public + * */ + var ConstraintData = /** @class */ (function () { + function ConstraintData(name, order, skinRequired) { + this.name = name; + this.order = order; + this.skinRequired = skinRequired; + } + return ConstraintData; + }()); + + /** Stores the current pose values for an {@link Event}. + * + * See Timeline {@link Timeline#apply()}, + * AnimationStateListener {@link AnimationStateListener#event()}, and + * [Events](http://esotericsoftware.com/spine-events) in the Spine User Guide. + * @public + * */ + var Event = /** @class */ (function () { + function Event(time, data) { + this.intValue = 0; + this.floatValue = 0; + this.stringValue = null; + this.time = 0; + this.volume = 0; + this.balance = 0; + if (!data) + throw new Error("data cannot be null."); + this.time = time; + this.data = data; + } + return Event; + }()); + + /** Stores the setup pose values for an {@link Event}. + * + * See [Events](http://esotericsoftware.com/spine-events) in the Spine User Guide. + * @public + * */ + var EventData = /** @class */ (function () { + function EventData(name) { + this.intValue = 0; + this.floatValue = 0; + this.stringValue = null; + this.audioPath = null; + this.volume = 0; + this.balance = 0; + this.name = name; + } + return EventData; + }()); + + /** Stores the current pose for an IK constraint. An IK constraint adjusts the rotation of 1 or 2 constrained bones so the tip of + * the last bone is as close to the target bone as possible. + * + * See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. + * @public + * */ + var IkConstraint = /** @class */ (function () { + function IkConstraint(data, skeleton) { + /** Controls the bend direction of the IK bones, either 1 or -1. */ + this.bendDirection = 0; + /** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */ + this.compress = false; + /** When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained + * and the parent bone has local nonuniform scale, stretch is not applied. */ + this.stretch = false; + /** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */ + this.mix = 1; + /** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */ + this.softness = 0; + this.active = false; + if (!data) + throw new Error("data cannot be null."); + if (!skeleton) + throw new Error("skeleton cannot be null."); + this.data = data; + this.mix = data.mix; + this.softness = data.softness; + this.bendDirection = data.bendDirection; + this.compress = data.compress; + this.stretch = data.stretch; + this.bones = new Array(); + for (var i = 0; i < data.bones.length; i++) { + var bone = skeleton.findBone(data.bones[i].name); + if (!bone) + throw new Error("Couldn't find bone " + data.bones[i].name); + this.bones.push(bone); + } + var target = skeleton.findBone(data.target.name); + if (!target) + throw new Error("Couldn't find bone " + data.target.name); + this.target = target; + } + IkConstraint.prototype.isActive = function () { + return this.active; + }; + IkConstraint.prototype.update = function () { + if (this.mix == 0) + return; + var target = this.target; + var bones = this.bones; + switch (bones.length) { + case 1: + this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix); + break; + case 2: + this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.data.uniform, this.softness, this.mix); + break; + } + }; + /** Applies 1 bone IK. The target is specified in the world coordinate system. */ + IkConstraint.prototype.apply1 = function (bone, targetX, targetY, compress, stretch, uniform, alpha) { + var p = bone.parent.matrix; + if (!p) + throw new Error("IK bone must have parent."); + var pa = p.a, pb = p.c, pc = p.b, pd = p.d; + var rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0; + var skelX = bone.skeleton.scaleX; + var skelY = settings.yDown ? -bone.skeleton.scaleY : bone.skeleton.scaleY; + switch (bone.data.transformMode) { + case exports.TransformMode.OnlyTranslation: + tx = targetX - bone.worldX; + ty = targetY - bone.worldY; + //TODO: possible bug in spine-ts runtime! + if (settings.yDown) { + ty = -ty; + } + break; + case exports.TransformMode.NoRotationOrReflection: + var s = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc); + var sa = pa / skelX; + var sc = pc / skelY; + pb = -sc * s * skelX; + pd = sa * s * skelY; + rotationIK += Math.atan2(sc, sa) * MathUtils.radDeg; + // Fall through + default: + var x = targetX - p.tx, y = targetY - p.ty; + var d = pa * pd - pb * pc; + tx = (x * pd - y * pb) / d - bone.ax; + ty = (y * pa - x * pc) / d - bone.ay; + } + rotationIK += Math.atan2(ty, tx) * MathUtils.radDeg; + if (bone.ascaleX < 0) + rotationIK += 180; + if (rotationIK > 180) + rotationIK -= 360; + else if (rotationIK < -180) + rotationIK += 360; + var sx = bone.ascaleX, sy = bone.ascaleY; + if (compress || stretch) { + switch (bone.data.transformMode) { + case exports.TransformMode.NoScale: + case exports.TransformMode.NoScaleOrReflection: + tx = targetX - bone.worldX; + ty = targetY - bone.worldY; + } + var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty); + if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001) { + var s = (dd / b - 1) * alpha + 1; + sx *= s; + if (uniform) + sy *= s; + } + } + bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY); + }; + /** Applies 2 bone IK. The target is specified in the world coordinate system. + * @param child A direct descendant of the parent bone. */ + IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, uniform, softness, alpha) { + var px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, sx = psx, sy = psy, csx = child.ascaleX; + var pmat = parent.matrix; + var os1 = 0, os2 = 0, s2 = 0; + if (psx < 0) { + psx = -psx; + os1 = 180; + s2 = -1; + } + else { + os1 = 0; + s2 = 1; + } + if (psy < 0) { + psy = -psy; + s2 = -s2; + } + if (csx < 0) { + csx = -csx; + os2 = 180; + } + else + os2 = 0; + var cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = pmat.a, b = pmat.c, c = pmat.b, d = pmat.d; + var u = Math.abs(psx - psy) <= 0.0001; + if (!u || stretch) { + cy = 0; + cwx = a * cx + pmat.tx; + cwy = c * cx + pmat.ty; + } + else { + cy = child.ay; + cwx = a * cx + b * cy + pmat.tx; + cwy = c * cx + d * cy + pmat.ty; + } + var pp = parent.parent.matrix; + if (!pp) + throw new Error("IK parent must itself have a parent."); + a = pp.a; + b = pp.c; + c = pp.b; + d = pp.d; + var id = 1 / (a * d - b * c), x = cwx - pp.tx, y = cwy - pp.ty; + var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; + var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2; + if (l1 < 0.0001) { + this.apply1(parent, targetX, targetY, false, stretch, false, alpha); + child.updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + return; + } + x = targetX - pp.tx; + y = targetY - pp.ty; + var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; + var dd = tx * tx + ty * ty; + if (softness != 0) { + softness *= psx * (csx + 1) * 0.5; + var td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness; + if (sd > 0) { + var p = Math.min(1, sd / (softness * 2)) - 1; + p = (sd - softness * (1 - p * p)) / td; + tx -= p * tx; + ty -= p * ty; + dd = tx * tx + ty * ty; + } + } + outer: if (u) { + l2 *= psx; + var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2); + if (cos < -1) { + cos = -1; + a2 = Math.PI * bendDir; + } + else if (cos > 1) { + cos = 1; + a2 = 0; + if (stretch) { + a = (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1; + sx *= a; + if (uniform) + sy *= a; + } + } + else + a2 = Math.acos(cos) * bendDir; + a = l1 + l2 * cos; + b = l2 * Math.sin(a2); + a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b); + } + else { + a = psx * l2; + b = psy * l2; + var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx); + c = bb * l1 * l1 + aa * dd - aa * bb; + var c1 = -2 * bb * l1, c2 = bb - aa; + d = c1 * c1 - 4 * c2 * c; + if (d >= 0) { + var q = Math.sqrt(d); + if (c1 < 0) + q = -q; + q = -(c1 + q) * 0.5; + var r0 = q / c2, r1 = c / q; + var r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; + if (r * r <= dd) { + y = Math.sqrt(dd - r * r) * bendDir; + a1 = ta - Math.atan2(y, r); + a2 = Math.atan2(y / psy, (r - l1) / psx); + break outer; + } + } + var minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; + var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; + c = -a * l1 / (aa - bb); + if (c >= -1 && c <= 1) { + c = Math.acos(c); + x = a * Math.cos(c) + l1; + y = b * Math.sin(c); + d = x * x + y * y; + if (d < minDist) { + minAngle = c; + minDist = d; + minX = x; + minY = y; + } + if (d > maxDist) { + maxAngle = c; + maxDist = d; + maxX = x; + maxY = y; + } + } + if (dd <= (minDist + maxDist) * 0.5) { + a1 = ta - Math.atan2(minY * bendDir, minX); + a2 = minAngle * bendDir; + } + else { + a1 = ta - Math.atan2(maxY * bendDir, maxX); + a2 = maxAngle * bendDir; + } + } + var os = Math.atan2(cy, cx) * s2; + var rotation = parent.arotation; + a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation; + if (a1 > 180) + a1 -= 360; + else if (a1 < -180) // + a1 += 360; + parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, sy, 0, 0); + rotation = child.arotation; + a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; + if (a2 > 180) + a2 -= 360; + else if (a2 < -180) // + a2 += 360; + child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + }; + return IkConstraint; + }()); + + /** Stores the setup pose for an {@link IkConstraint}. + *

+ * See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. + * @public + * */ + var IkConstraintData = /** @class */ (function (_super) { + __extends$1(IkConstraintData, _super); + function IkConstraintData(name) { + var _this = _super.call(this, name, 0, false) || this; + /** The bones that are constrained by this IK constraint. */ + _this.bones = new Array(); + /** The bone that is the IK target. */ + _this._target = null; + /** Controls the bend direction of the IK bones, either 1 or -1. */ + _this.bendDirection = 1; + /** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */ + _this.compress = false; + /** When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained + * and the parent bone has local nonuniform scale, stretch is not applied. */ + _this.stretch = false; + /** When true, only a single bone is being constrained, and {@link #getCompress()} or {@link #getStretch()} is used, the bone + * is scaled on both the X and Y axes. */ + _this.uniform = false; + /** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */ + _this.mix = 1; + /** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */ + _this.softness = 0; + return _this; + } + Object.defineProperty(IkConstraintData.prototype, "target", { + get: function () { + if (!this._target) + throw new Error("BoneData not set."); + else + return this._target; + }, + set: function (boneData) { this._target = boneData; }, + enumerable: false, + configurable: true + }); + return IkConstraintData; + }(ConstraintData)); + + /** Stores the setup pose for a {@link PathConstraint}. + * + * See [Path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. + * @public + * */ + var PathConstraintData = /** @class */ (function (_super) { + __extends$1(PathConstraintData, _super); + function PathConstraintData(name) { + var _this = _super.call(this, name, 0, false) || this; + /** The bones that will be modified by this path constraint. */ + _this.bones = new Array(); + /** The slot whose path attachment will be used to constrained the bones. */ + _this._target = null; + /** The mode for positioning the first bone on the path. */ + _this.positionMode = exports.PositionMode.Fixed; + /** The mode for positioning the bones after the first bone on the path. */ + _this.spacingMode = SpacingMode.Fixed; + /** The mode for adjusting the rotation of the bones. */ + _this.rotateMode = exports.RotateMode.Chain; + /** An offset added to the constrained bone rotation. */ + _this.offsetRotation = 0; + /** The position along the path. */ + _this.position = 0; + /** The spacing between bones. */ + _this.spacing = 0; + _this.mixRotate = 0; + _this.mixX = 0; + _this.mixY = 0; + return _this; + } + Object.defineProperty(PathConstraintData.prototype, "target", { + get: function () { + if (!this._target) + throw new Error("SlotData not set."); + else + return this._target; + }, + set: function (slotData) { this._target = slotData; }, + enumerable: false, + configurable: true + }); + return PathConstraintData; + }(ConstraintData)); + /** Controls how bones after the first bone are positioned along the path. + * + * [Spacing mode](http://esotericsoftware.com/spine-path-constraints#Spacing-mode) in the Spine User Guide. + * @public + * */ + var SpacingMode; + (function (SpacingMode) { + SpacingMode[SpacingMode["Length"] = 0] = "Length"; + SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed"; + SpacingMode[SpacingMode["Percent"] = 2] = "Percent"; + SpacingMode[SpacingMode["Proportional"] = 3] = "Proportional"; + })(SpacingMode || (SpacingMode = {})); + + /** Stores the current pose for a path constraint. A path constraint adjusts the rotation, translation, and scale of the + * constrained bones so they follow a {@link PathAttachment}. + * + * See [Path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. + * @public + * */ + var PathConstraint = /** @class */ (function () { + function PathConstraint(data, skeleton) { + /** The position along the path. */ + this.position = 0; + /** The spacing between bones. */ + this.spacing = 0; + this.mixRotate = 0; + this.mixX = 0; + this.mixY = 0; + this.spaces = new Array(); + this.positions = new Array(); + this.world = new Array(); + this.curves = new Array(); + this.lengths = new Array(); + this.segments = new Array(); + this.active = false; + if (!data) + throw new Error("data cannot be null."); + if (!skeleton) + throw new Error("skeleton cannot be null."); + this.data = data; + this.bones = new Array(); + for (var i = 0, n = data.bones.length; i < n; i++) { + var bone = skeleton.findBone(data.bones[i].name); + if (!bone) + throw new Error("Couldn't find bone " + data.bones[i].name + "."); + this.bones.push(bone); + } + var target = skeleton.findSlot(data.target.name); + if (!target) + throw new Error("Couldn't find target bone " + data.target.name); + this.target = target; + this.position = data.position; + this.spacing = data.spacing; + this.mixRotate = data.mixRotate; + this.mixX = data.mixX; + this.mixY = data.mixY; + } + PathConstraint.prototype.isActive = function () { + return this.active; + }; + PathConstraint.prototype.update = function () { + var attachment = this.target.getAttachment(); + if (!(attachment instanceof PathAttachment)) + return; + var mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY; + if (mixRotate == 0 && mixX == 0 && mixY == 0) + return; + var data = this.data; + var tangents = data.rotateMode == exports.RotateMode.Tangent, scale = data.rotateMode == exports.RotateMode.ChainScale; + var bones = this.bones; + var boneCount = bones.length, spacesCount = tangents ? boneCount : boneCount + 1; + var spaces = Utils.setArraySize(this.spaces, spacesCount), lengths = scale ? this.lengths = Utils.setArraySize(this.lengths, boneCount) : []; + var spacing = this.spacing; + switch (data.spacingMode) { + case SpacingMode.Percent: + if (scale) { + for (var i = 0, n = spacesCount - 1; i < n; i++) { + var bone = bones[i]; + var setupLength = bone.data.length; + if (setupLength < PathConstraint.epsilon) + lengths[i] = 0; + else { + var x = setupLength * bone.matrix.a, y = setupLength * bone.matrix.b; + lengths[i] = Math.sqrt(x * x + y * y); + } + } + } + Utils.arrayFill(spaces, 1, spacesCount, spacing); + break; + case SpacingMode.Proportional: + var sum = 0; + for (var i = 0, n = spacesCount - 1; i < n;) { + var bone = bones[i]; + var setupLength = bone.data.length; + if (setupLength < PathConstraint.epsilon) { + if (scale) + lengths[i] = 0; + spaces[++i] = spacing; + } + else { + var x = setupLength * bone.matrix.a, y = setupLength * bone.matrix.b; + var length_1 = Math.sqrt(x * x + y * y); + if (scale) + lengths[i] = length_1; + spaces[++i] = length_1; + sum += length_1; + } + } + if (sum > 0) { + sum = spacesCount / sum * spacing; + for (var i = 1; i < spacesCount; i++) + spaces[i] *= sum; + } + break; + default: + var lengthSpacing = data.spacingMode == SpacingMode.Length; + for (var i = 0, n = spacesCount - 1; i < n;) { + var bone = bones[i]; + var setupLength = bone.data.length; + if (setupLength < PathConstraint.epsilon) { + if (scale) + lengths[i] = 0; + spaces[++i] = spacing; + } + else { + var x = setupLength * bone.matrix.a, y = setupLength * bone.matrix.b; + var length_2 = Math.sqrt(x * x + y * y); + if (scale) + lengths[i] = length_2; + spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length_2 / setupLength; + } + } + } + var positions = this.computeWorldPositions(attachment, spacesCount, tangents); + var boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; + var tip = false; + if (offsetRotation == 0) + tip = data.rotateMode == exports.RotateMode.Chain; + else { + tip = false; + var p = this.target.bone.matrix; + offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.degRad : -MathUtils.degRad; + } + for (var i = 0, p = 3; i < boneCount; i++, p += 3) { + var bone = bones[i]; + var mat = bone.matrix; + mat.tx += (boneX - mat.tx) * mixX; + mat.ty += (boneY - mat.ty) * mixY; + var x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; + if (scale) { + var length_3 = lengths[i]; + if (length_3 != 0) { + var s = (Math.sqrt(dx * dx + dy * dy) / length_3 - 1) * mixRotate + 1; + mat.a *= s; + mat.b *= s; + } + } + boneX = x; + boneY = y; + if (mixRotate > 0) { + var a = mat.a, b = mat.c, c = mat.b, d = mat.d, r = 0, cos = 0, sin = 0; + if (tangents) + r = positions[p - 1]; + else if (spaces[i + 1] == 0) + r = positions[p + 2]; + else + r = Math.atan2(dy, dx); + r -= Math.atan2(c, a); + if (tip) { + cos = Math.cos(r); + sin = Math.sin(r); + var length_4 = bone.data.length; + boneX += (length_4 * (cos * a - sin * c) - dx) * mixRotate; + boneY += (length_4 * (sin * a + cos * c) - dy) * mixRotate; + } + else { + r += offsetRotation; + } + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; + r *= mixRotate; + cos = Math.cos(r); + sin = Math.sin(r); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + } + bone.updateAppliedTransform(); + } + }; + PathConstraint.prototype.computeWorldPositions = function (path, spacesCount, tangents) { + var target = this.target; + var position = this.position; + var spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = this.world; + var closed = path.closed; + var verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE; + if (!path.constantSpeed) { + var lengths = path.lengths; + curveCount -= closed ? 1 : 2; + var pathLength_1 = lengths[curveCount]; + if (this.data.positionMode == exports.PositionMode.Percent) + position *= pathLength_1; + var multiplier_1; + switch (this.data.spacingMode) { + case SpacingMode.Percent: + multiplier_1 = pathLength_1; + break; + case SpacingMode.Proportional: + multiplier_1 = pathLength_1 / spacesCount; + break; + default: + multiplier_1 = 1; + } + world = Utils.setArraySize(this.world, 8); + for (var i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { + var space = spaces[i] * multiplier_1; + position += space; + var p = position; + if (closed) { + p %= pathLength_1; + if (p < 0) + p += pathLength_1; + curve = 0; + } + else if (p < 0) { + if (prevCurve != PathConstraint.BEFORE) { + prevCurve = PathConstraint.BEFORE; + path.computeWorldVertices(target, 2, 4, world, 0, 2); + } + this.addBeforePosition(p, world, 0, out, o); + continue; + } + else if (p > pathLength_1) { + if (prevCurve != PathConstraint.AFTER) { + prevCurve = PathConstraint.AFTER; + path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); + } + this.addAfterPosition(p - pathLength_1, world, 0, out, o); + continue; + } + // Determine curve containing position. + for (;; curve++) { + var length_5 = lengths[curve]; + if (p > length_5) + continue; + if (curve == 0) + p /= length_5; + else { + var prev = lengths[curve - 1]; + p = (p - prev) / (length_5 - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + if (closed && curve == curveCount) { + path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); + path.computeWorldVertices(target, 0, 4, world, 4, 2); + } + else + path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); + } + this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0)); + } + return out; + } + // World vertices. + if (closed) { + verticesLength += 2; + world = Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); + path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); + world[verticesLength - 2] = world[0]; + world[verticesLength - 1] = world[1]; + } + else { + curveCount--; + verticesLength -= 4; + world = Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); + } + // Curve lengths. + var curves = Utils.setArraySize(this.curves, curveCount); + var pathLength = 0; + var x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; + var tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0; + for (var i = 0, w = 2; i < curveCount; i++, w += 6) { + cx1 = world[w]; + cy1 = world[w + 1]; + cx2 = world[w + 2]; + cy2 = world[w + 3]; + x2 = world[w + 4]; + y2 = world[w + 5]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.1875; + tmpy = (y1 - cy1 * 2 + cy2) * 0.1875; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + curves[i] = pathLength; + x1 = x2; + y1 = y2; + } + if (this.data.positionMode == exports.PositionMode.Percent) + position *= pathLength; + var multiplier; + switch (this.data.spacingMode) { + case SpacingMode.Percent: + multiplier = pathLength; + break; + case SpacingMode.Proportional: + multiplier = pathLength / spacesCount; + break; + default: + multiplier = 1; + } + var segments = this.segments; + var curveLength = 0; + for (var i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { + var space = spaces[i] * multiplier; + position += space; + var p = position; + if (closed) { + p %= pathLength; + if (p < 0) + p += pathLength; + curve = 0; + } + else if (p < 0) { + this.addBeforePosition(p, world, 0, out, o); + continue; + } + else if (p > pathLength) { + this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o); + continue; + } + // Determine curve containing position. + for (;; curve++) { + var length_6 = curves[curve]; + if (p > length_6) + continue; + if (curve == 0) + p /= length_6; + else { + var prev = curves[curve - 1]; + p = (p - prev) / (length_6 - prev); + } + break; + } + // Curve segment lengths. + if (curve != prevCurve) { + prevCurve = curve; + var ii = curve * 6; + x1 = world[ii]; + y1 = world[ii + 1]; + cx1 = world[ii + 2]; + cy1 = world[ii + 3]; + cx2 = world[ii + 4]; + cy2 = world[ii + 5]; + x2 = world[ii + 6]; + y2 = world[ii + 7]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.03; + tmpy = (y1 - cy1 * 2 + cy2) * 0.03; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667; + curveLength = Math.sqrt(dfx * dfx + dfy * dfy); + segments[0] = curveLength; + for (ii = 1; ii < 8; ii++) { + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[ii] = curveLength; + } + dfx += ddfx; + dfy += ddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[8] = curveLength; + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[9] = curveLength; + segment = 0; + } + // Weight by segment length. + p *= curveLength; + for (;; segment++) { + var length_7 = segments[segment]; + if (p > length_7) + continue; + if (segment == 0) + p /= length_7; + else { + var prev = segments[segment - 1]; + p = segment + (p - prev) / (length_7 - prev); + } + break; + } + this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0)); + } + return out; + }; + PathConstraint.prototype.addBeforePosition = function (p, temp, i, out, o) { + var x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + }; + PathConstraint.prototype.addAfterPosition = function (p, temp, i, out, o) { + var x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + }; + PathConstraint.prototype.addCurvePosition = function (p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) { + if (p == 0 || isNaN(p)) { + out[o] = x1; + out[o + 1] = y1; + out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); + return; + } + var tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; + var ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; + var x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; + out[o] = x; + out[o + 1] = y; + if (tangents) { + if (p < 0.001) + out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); + else + out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); + } + }; + PathConstraint.NONE = -1; + PathConstraint.BEFORE = -2; + PathConstraint.AFTER = -3; + PathConstraint.epsilon = 0.00001; + return PathConstraint; + }()); + + /** Stores a slot's current pose. Slots organize attachments for {@link Skeleton#drawOrder} 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. + * @public + * */ + var Slot = /** @class */ (function () { + function Slot(data, bone) { + /** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark + * color's alpha is not used. */ + this.darkColor = null; + this.attachment = null; + this.attachmentState = 0; + /** The index of the texture region to display when the slot's attachment has a {@link Sequence}. -1 represents the + * {@link Sequence#getSetupIndex()}. */ + this.sequenceIndex = -1; + /** Values to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a + * weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions. + * + * See {@link VertexAttachment#computeWorldVertices()} and {@link DeformTimeline}. */ + this.deform = new Array(); + if (!data) + throw new Error("data cannot be null."); + if (!bone) + throw new Error("bone cannot be null."); + this.data = data; + this.bone = bone; + this.color = new Color(); + this.darkColor = !data.darkColor ? null : new Color(); + this.setToSetupPose(); + this.blendMode = this.data.blendMode; + } + /** The skeleton this slot belongs to. */ + Slot.prototype.getSkeleton = function () { + return this.bone.skeleton; + }; + /** The current attachment for the slot, or null if the slot has no attachment. */ + Slot.prototype.getAttachment = function () { + return this.attachment; + }; + /** Sets the slot's attachment and, if the attachment changed, resets {@link #sequenceIndex} and clears the {@link #deform}. + * The deform is not cleared if the old attachment has the same {@link VertexAttachment#getTimelineAttachment()} as the + * specified attachment. */ + Slot.prototype.setAttachment = function (attachment) { + if (this.attachment == attachment) + return; + if (!(attachment instanceof VertexAttachment) || !(this.attachment instanceof VertexAttachment) + || attachment.timelineAttachment != this.attachment.timelineAttachment) { + this.deform.length = 0; + } + this.attachment = attachment; + this.sequenceIndex = -1; + }; + /** Sets this slot to the setup pose. */ + Slot.prototype.setToSetupPose = function () { + this.color.setFromColor(this.data.color); + if (this.darkColor) + this.darkColor.setFromColor(this.data.darkColor); + if (!this.data.attachmentName) + this.attachment = null; + else { + this.attachment = null; + this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName)); + } + }; + return Slot; + }()); + + /** Stores the current pose for a transform constraint. A transform constraint adjusts the world transform of the constrained + * bones to match that of the target bone. + * + * See [Transform constraints](http://esotericsoftware.com/spine-transform-constraints) in the Spine User Guide. + * @public + * */ + var TransformConstraint = /** @class */ (function () { + function TransformConstraint(data, skeleton) { + this.mixRotate = 0; + this.mixX = 0; + this.mixY = 0; + this.mixScaleX = 0; + this.mixScaleY = 0; + this.mixShearY = 0; + this.temp = new Vector2(); + this.active = false; + if (!data) + throw new Error("data cannot be null."); + if (!skeleton) + throw new Error("skeleton cannot be null."); + this.data = data; + this.mixRotate = data.mixRotate; + this.mixX = data.mixX; + this.mixY = data.mixY; + this.mixScaleX = data.mixScaleX; + this.mixScaleY = data.mixScaleY; + this.mixShearY = data.mixShearY; + this.bones = new Array(); + for (var i = 0; i < data.bones.length; i++) { + var bone = skeleton.findBone(data.bones[i].name); + if (!bone) + throw new Error("Couldn't find bone " + data.bones[i].name + "."); + this.bones.push(bone); + } + var target = skeleton.findBone(data.target.name); + if (!target) + throw new Error("Couldn't find target bone " + data.target.name + "."); + this.target = target; + } + TransformConstraint.prototype.isActive = function () { + return this.active; + }; + TransformConstraint.prototype.update = function () { + if (this.mixRotate == 0 && this.mixX == 0 && this.mixY == 0 && this.mixScaleX == 0 && this.mixScaleX == 0 && this.mixShearY == 0) + return; + if (this.data.local) { + if (this.data.relative) + this.applyRelativeLocal(); + else + this.applyAbsoluteLocal(); + } + else { + if (this.data.relative) + this.applyRelativeWorld(); + else + this.applyAbsoluteWorld(); + } + }; + TransformConstraint.prototype.applyAbsoluteWorld = function () { + var mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + var translate = mixX != 0 || mixY != 0; + var target = this.target; + var targetMat = target.matrix; + var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; + var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; + var offsetRotation = this.data.offsetRotation * degRadReflect; + var offsetShearY = this.data.offsetShearY * degRadReflect; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + var mat = bone.matrix; + if (mixRotate != 0) { + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; + r *= mixRotate; + var cos = Math.cos(r), sin = Math.sin(r); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + } + if (translate) { + var temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + mat.tx += (temp.x - mat.tx) * mixX; + mat.ty += (temp.y - mat.ty) * mixY; + } + if (mixScaleX != 0) { + var s = Math.sqrt(mat.a * mat.a + mat.b * mat.b); + if (s != 0) + s = (s + (Math.sqrt(ta * ta + tc * tc) - s + this.data.offsetScaleX) * mixScaleX) / s; + mat.a *= s; + mat.b *= s; + } + if (mixScaleY != 0) { + var s = Math.sqrt(mat.c * mat.c + mat.d * mat.d); + if (s != 0) + s = (s + (Math.sqrt(tb * tb + td * td) - s + this.data.offsetScaleY) * mixScaleY) / s; + mat.c *= s; + mat.d *= s; + } + if (mixShearY > 0) { + var b = mat.c, d = mat.d; + var by = Math.atan2(d, b); + var r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(mat.b, mat.a)); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; + r = by + (r + offsetShearY) * mixShearY; + var s = Math.sqrt(b * b + d * d); + mat.c = Math.cos(r) * s; + mat.d = Math.sin(r) * s; + } + bone.updateAppliedTransform(); + } + }; + TransformConstraint.prototype.applyRelativeWorld = function () { + var mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + var translate = mixX != 0 || mixY != 0; + var target = this.target; + var targetMat = target.matrix; + var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; + var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; + var offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + var mat = bone.matrix; + if (mixRotate != 0) { + var a = mat.a, b = mat.c, c = mat.b, d = mat.d; + var r = Math.atan2(tc, ta) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; + r *= mixRotate; + var cos = Math.cos(r), sin = Math.sin(r); + mat.a = cos * a - sin * c; + mat.c = cos * b - sin * d; + mat.b = sin * a + cos * c; + mat.d = sin * b + cos * d; + } + if (translate) { + var temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + mat.tx += temp.x * mixX; + mat.ty += temp.y * mixY; + } + if (mixScaleX != 0) { + var s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * mixScaleX + 1; + mat.a *= s; + mat.b *= s; + } + if (mixScaleY != 0) { + var s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * mixScaleY + 1; + mat.c *= s; + mat.d *= s; + } + if (mixShearY > 0) { + var r = Math.atan2(td, tb) - Math.atan2(tc, ta); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; + var b = mat.c, d = mat.d; + r = Math.atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * mixShearY; + var s = Math.sqrt(b * b + d * d); + mat.c = Math.cos(r) * s; + mat.d = Math.sin(r) * s; + } + bone.updateAppliedTransform(); + } + }; + TransformConstraint.prototype.applyAbsoluteLocal = function () { + var mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + var target = this.target; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + var rotation = bone.arotation; + if (mixRotate != 0) { + var r = target.arotation - rotation + this.data.offsetRotation; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + rotation += r * mixRotate; + } + var x = bone.ax, y = bone.ay; + x += (target.ax - x + this.data.offsetX) * mixX; + y += (target.ay - y + this.data.offsetY) * mixY; + var scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (mixScaleX != 0 && scaleX != 0) + scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * mixScaleX) / scaleX; + if (mixScaleY != 0 && scaleY != 0) + scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * mixScaleY) / scaleY; + var shearY = bone.ashearY; + if (mixShearY != 0) { + var r = target.ashearY - shearY + this.data.offsetShearY; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + shearY += r * mixShearY; + } + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + }; + TransformConstraint.prototype.applyRelativeLocal = function () { + var mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + var target = this.target; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + var rotation = bone.arotation + (target.arotation + this.data.offsetRotation) * mixRotate; + var x = bone.ax + (target.ax + this.data.offsetX) * mixX; + var y = bone.ay + (target.ay + this.data.offsetY) * mixY; + var scaleX = bone.ascaleX * (((target.ascaleX - 1 + this.data.offsetScaleX) * mixScaleX) + 1); + var scaleY = bone.ascaleY * (((target.ascaleY - 1 + this.data.offsetScaleY) * mixScaleY) + 1); + var shearY = bone.ashearY + (target.ashearY + this.data.offsetShearY) * mixShearY; + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + }; + return TransformConstraint; + }()); + + /** Stores the current pose for a skeleton. + * + * See [Instance objects](http://esotericsoftware.com/spine-runtime-architecture#Instance-objects) in the Spine Runtimes Guide. + * @public + * */ + var Skeleton = /** @class */ (function () { + function Skeleton(data) { + /** The list of bones and constraints, sorted in the order they should be updated, as computed by {@link #updateCache()}. */ + this._updateCache = new Array(); + /** The skeleton's current skin. May be null. */ + this.skin = null; + /** Scales the entire skeleton on the X axis. This affects all bones, even if the bone's transform mode disallows scale + * inheritance. */ + this.scaleX = 1; + /** Scales the entire skeleton on the Y axis. This affects all bones, even if the bone's transform mode disallows scale + * inheritance. */ + this.scaleY = 1; + /** Sets the skeleton X position, which is added to the root bone worldX position. */ + this.x = 0; + /** Sets the skeleton Y position, which is added to the root bone worldY position. */ + this.y = 0; + if (!data) + throw new Error("data cannot be null."); + this.data = data; + this.bones = new Array(); + for (var i = 0; i < data.bones.length; i++) { + var boneData = data.bones[i]; + var bone = void 0; + if (!boneData.parent) + bone = new Bone(boneData, this, null); + else { + var parent_1 = this.bones[boneData.parent.index]; + bone = new Bone(boneData, this, parent_1); + parent_1.children.push(bone); + } + this.bones.push(bone); + } + this.slots = new Array(); + this.drawOrder = new Array(); + for (var i = 0; i < data.slots.length; i++) { + var slotData = data.slots[i]; + var bone = this.bones[slotData.boneData.index]; + var slot = new Slot(slotData, bone); + this.slots.push(slot); + this.drawOrder.push(slot); + } + this.ikConstraints = new Array(); + for (var i = 0; i < data.ikConstraints.length; i++) { + var ikConstraintData = data.ikConstraints[i]; + this.ikConstraints.push(new IkConstraint(ikConstraintData, this)); + } + this.transformConstraints = new Array(); + for (var i = 0; i < data.transformConstraints.length; i++) { + var transformConstraintData = data.transformConstraints[i]; + this.transformConstraints.push(new TransformConstraint(transformConstraintData, this)); + } + this.pathConstraints = new Array(); + for (var i = 0; i < data.pathConstraints.length; i++) { + var pathConstraintData = data.pathConstraints[i]; + this.pathConstraints.push(new PathConstraint(pathConstraintData, this)); + } + this.color = new Color(1, 1, 1, 1); + this.updateCache(); + } + /** Caches information about bones and constraints. Must be called if the {@link #getSkin()} is modified or if bones, + * constraints, or weighted path attachments are added or removed. */ + Skeleton.prototype.updateCache = function () { + var updateCache = this._updateCache; + updateCache.length = 0; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + bone.sorted = bone.data.skinRequired; + bone.active = !bone.sorted; + } + if (this.skin) { + var skinBones = this.skin.bones; + for (var i = 0, n = this.skin.bones.length; i < n; i++) { + var bone = this.bones[skinBones[i].index]; + do { + bone.sorted = false; + bone.active = true; + bone = bone.parent; + } while (bone); + } + } + // IK first, lowest hierarchy depth first. + var ikConstraints = this.ikConstraints; + var transformConstraints = this.transformConstraints; + var pathConstraints = this.pathConstraints; + var ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length; + var constraintCount = ikCount + transformCount + pathCount; + outer: for (var i = 0; i < constraintCount; i++) { + for (var ii = 0; ii < ikCount; ii++) { + var constraint = ikConstraints[ii]; + if (constraint.data.order == i) { + this.sortIkConstraint(constraint); + continue outer; + } + } + for (var ii = 0; ii < transformCount; ii++) { + var constraint = transformConstraints[ii]; + if (constraint.data.order == i) { + this.sortTransformConstraint(constraint); + continue outer; + } + } + for (var ii = 0; ii < pathCount; ii++) { + var constraint = pathConstraints[ii]; + if (constraint.data.order == i) { + this.sortPathConstraint(constraint); + continue outer; + } + } + } + for (var i = 0, n = bones.length; i < n; i++) + this.sortBone(bones[i]); + }; + Skeleton.prototype.sortIkConstraint = function (constraint) { + constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true))); + if (!constraint.active) + return; + var target = constraint.target; + this.sortBone(target); + var constrained = constraint.bones; + var parent = constrained[0]; + this.sortBone(parent); + if (constrained.length == 1) { + this._updateCache.push(constraint); + this.sortReset(parent.children); + } + else { + var child = constrained[constrained.length - 1]; + this.sortBone(child); + this._updateCache.push(constraint); + this.sortReset(parent.children); + child.sorted = true; + } + }; + Skeleton.prototype.sortPathConstraint = function (constraint) { + constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true))); + if (!constraint.active) + return; + var slot = constraint.target; + var slotIndex = slot.data.index; + var slotBone = slot.bone; + if (this.skin) + this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone); + if (this.data.defaultSkin && this.data.defaultSkin != this.skin) + this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone); + for (var i = 0, n = this.data.skins.length; i < n; i++) + this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone); + var attachment = slot.getAttachment(); + if (attachment instanceof PathAttachment) + this.sortPathConstraintAttachmentWith(attachment, slotBone); + var constrained = constraint.bones; + var boneCount = constrained.length; + for (var i = 0; i < boneCount; i++) + this.sortBone(constrained[i]); + this._updateCache.push(constraint); + for (var i = 0; i < boneCount; i++) + this.sortReset(constrained[i].children); + for (var i = 0; i < boneCount; i++) + constrained[i].sorted = true; + }; + Skeleton.prototype.sortTransformConstraint = function (constraint) { + constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true))); + if (!constraint.active) + return; + this.sortBone(constraint.target); + var constrained = constraint.bones; + var boneCount = constrained.length; + if (constraint.data.local) { + for (var i = 0; i < boneCount; i++) { + var child = constrained[i]; + this.sortBone(child.parent); + this.sortBone(child); + } + } + else { + for (var i = 0; i < boneCount; i++) { + this.sortBone(constrained[i]); + } + } + this._updateCache.push(constraint); + for (var i = 0; i < boneCount; i++) + this.sortReset(constrained[i].children); + for (var i = 0; i < boneCount; i++) + constrained[i].sorted = true; + }; + Skeleton.prototype.sortPathConstraintAttachment = function (skin, slotIndex, slotBone) { + var attachments = skin.attachments[slotIndex]; + if (!attachments) + return; + for (var key in attachments) { + this.sortPathConstraintAttachmentWith(attachments[key], slotBone); + } + }; + Skeleton.prototype.sortPathConstraintAttachmentWith = function (attachment, slotBone) { + if (!(attachment instanceof PathAttachment)) + return; + var pathBones = attachment.bones; + if (!pathBones) + this.sortBone(slotBone); + else { + var bones = this.bones; + for (var i = 0, n = pathBones.length; i < n;) { + var nn = pathBones[i++]; + nn += i; + while (i < nn) + this.sortBone(bones[pathBones[i++]]); + } + } + }; + Skeleton.prototype.sortBone = function (bone) { + if (!bone) + return; + if (bone.sorted) + return; + var parent = bone.parent; + if (parent) + this.sortBone(parent); + bone.sorted = true; + this._updateCache.push(bone); + }; + Skeleton.prototype.sortReset = function (bones) { + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (!bone.active) + continue; + if (bone.sorted) + this.sortReset(bone.children); + bone.sorted = false; + } + }; + /** Updates the world transform for each bone and applies all constraints. + * + * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + * Runtimes Guide. */ + Skeleton.prototype.updateWorldTransform = function () { + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + } + var updateCache = this._updateCache; + for (var i = 0, n = updateCache.length; i < n; i++) + updateCache[i].update(); + }; + Skeleton.prototype.updateWorldTransformWith = function (parent) { + // Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection. + var rootBone = this.getRootBone(); + var pa = parent.matrix.a, pb = parent.matrix.c, pc = parent.matrix.b, pd = parent.matrix.d; + rootBone.matrix.tx = pa * this.x + pb * this.y + parent.worldX; + rootBone.matrix.ty = pc * this.x + pd * this.y + parent.worldY; + var rotationY = rootBone.rotation + 90 + rootBone.shearY; + var la = MathUtils.cosDeg(rootBone.rotation + rootBone.shearX) * rootBone.scaleX; + var lb = MathUtils.cosDeg(rotationY) * rootBone.scaleY; + var lc = MathUtils.sinDeg(rootBone.rotation + rootBone.shearX) * rootBone.scaleX; + var ld = MathUtils.sinDeg(rotationY) * rootBone.scaleY; + var sx = this.scaleX; + var sy = settings.yDown ? -this.scaleY : this.scaleY; + rootBone.matrix.a = (pa * la + pb * lc) * sx; + rootBone.matrix.c = (pa * lb + pb * ld) * sx; + rootBone.matrix.b = (pc * la + pd * lc) * sy; + rootBone.matrix.d = (pc * lb + pd * ld) * sy; + // Update everything except root bone. + var updateCache = this._updateCache; + for (var i = 0, n = updateCache.length; i < n; i++) { + var updatable = updateCache[i]; + if (updatable != rootBone) + updatable.update(); + } + }; + /** Sets the bones, constraints, and slots to their setup pose values. */ + Skeleton.prototype.setToSetupPose = function () { + this.setBonesToSetupPose(); + this.setSlotsToSetupPose(); + }; + /** Sets the bones and constraints to their setup pose values. */ + Skeleton.prototype.setBonesToSetupPose = function () { + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + bones[i].setToSetupPose(); + var ikConstraints = this.ikConstraints; + for (var i = 0, n = ikConstraints.length; i < n; i++) { + var constraint = ikConstraints[i]; + constraint.mix = constraint.data.mix; + constraint.softness = constraint.data.softness; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + var transformConstraints = this.transformConstraints; + for (var i = 0, n = transformConstraints.length; i < n; i++) { + var constraint = transformConstraints[i]; + var data = constraint.data; + constraint.mixRotate = data.mixRotate; + constraint.mixX = data.mixX; + constraint.mixY = data.mixY; + constraint.mixScaleX = data.mixScaleX; + constraint.mixScaleY = data.mixScaleY; + constraint.mixShearY = data.mixShearY; + } + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) { + var constraint = pathConstraints[i]; + var data = constraint.data; + constraint.position = data.position; + constraint.spacing = data.spacing; + constraint.mixRotate = data.mixRotate; + constraint.mixX = data.mixX; + constraint.mixY = data.mixY; + } + }; + /** Sets the slots and draw order to their setup pose values. */ + Skeleton.prototype.setSlotsToSetupPose = function () { + var slots = this.slots; + Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length); + for (var i = 0, n = slots.length; i < n; i++) + slots[i].setToSetupPose(); + }; + /** @returns May return null. */ + Skeleton.prototype.getRootBone = function () { + if (this.bones.length == 0) + return null; + return this.bones[0]; + }; + /** @returns May be null. */ + Skeleton.prototype.findBone = function (boneName) { + if (!boneName) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (bone.data.name == boneName) + return bone; + } + return null; + }; + /** @returns -1 if the bone was not found. */ + Skeleton.prototype.findBoneIndex = function (boneName) { + if (!boneName) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + if (bones[i].data.name == boneName) + return i; + return -1; + }; + /** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it + * repeatedly. + * @returns May be null. */ + Skeleton.prototype.findSlot = function (slotName) { + if (!slotName) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.data.name == slotName) + return slot; + } + return null; + }; + /** @returns -1 if the bone was not found. */ + Skeleton.prototype.findSlotIndex = function (slotName) { + if (!slotName) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) + if (slots[i].data.name == slotName) + return i; + return -1; + }; + /** Sets a skin by name. + * + * See {@link #setSkin()}. */ + Skeleton.prototype.setSkinByName = function (skinName) { + var skin = this.data.findSkin(skinName); + if (!skin) + throw new Error("Skin not found: " + skinName); + this.setSkin(skin); + }; + /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#defaultSkin default skin}. If the + * skin is changed, {@link #updateCache()} is called. + * + * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no + * old skin, each slot's setup mode attachment is attached from the new skin. + * + * After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling + * {@link #setSlotsToSetupPose()}. Also, often {@link AnimationState#apply()} is called before the next time the + * skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin. + * @param newSkin May be null. */ + Skeleton.prototype.setSkin = function (newSkin) { + if (newSkin == this.skin) + return; + if (newSkin) { + if (this.skin) + newSkin.attachAll(this, this.skin); + else { + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + var name_1 = slot.data.attachmentName; + if (name_1) { + var attachment = newSkin.getAttachment(i, name_1); + if (attachment) + slot.setAttachment(attachment); + } + } + } + } + this.skin = newSkin; + this.updateCache(); + }; + /** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot name and attachment + * name. + * + * See {@link #getAttachment()}. + * @returns May be null. */ + Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) { + var slot = this.data.findSlot(slotName); + if (!slot) + throw new Error("Can't find slot with name " + slotName); + return this.getAttachment(slot.index, attachmentName); + }; + /** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot index and + * attachment name. First the skin is checked and if the attachment was not found, the default skin is checked. + * + * See [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide. + * @returns May be null. */ + Skeleton.prototype.getAttachment = function (slotIndex, attachmentName) { + if (!attachmentName) + throw new Error("attachmentName cannot be null."); + if (this.skin) { + var attachment = this.skin.getAttachment(slotIndex, attachmentName); + if (attachment) + return attachment; + } + if (this.data.defaultSkin) + return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); + return null; + }; + /** A convenience method to set an attachment by finding the slot with {@link #findSlot()}, finding the attachment with + * {@link #getAttachment()}, then setting the slot's {@link Slot#attachment}. + * @param attachmentName May be null to clear the slot's attachment. */ + Skeleton.prototype.setAttachment = function (slotName, attachmentName) { + if (!slotName) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.data.name == slotName) { + var attachment = null; + if (attachmentName) { + attachment = this.getAttachment(i, attachmentName); + if (!attachment) + throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName); + } + slot.setAttachment(attachment); + return; + } + } + throw new Error("Slot not found: " + slotName); + }; + /** 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 repeatedly. + * @return May be null. */ + Skeleton.prototype.findIkConstraint = function (constraintName) { + if (!constraintName) + throw new Error("constraintName cannot be null."); + var ikConstraints = this.ikConstraints; + for (var i = 0, n = ikConstraints.length; i < n; i++) { + var ikConstraint = ikConstraints[i]; + if (ikConstraint.data.name == constraintName) + return ikConstraint; + } + return null; + }; + /** 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 repeatedly. + * @return May be null. */ + Skeleton.prototype.findTransformConstraint = function (constraintName) { + if (!constraintName) + throw new Error("constraintName cannot be null."); + var transformConstraints = this.transformConstraints; + for (var i = 0, n = transformConstraints.length; i < n; i++) { + var constraint = transformConstraints[i]; + if (constraint.data.name == constraintName) + return constraint; + } + return null; + }; + /** 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 repeatedly. + * @return May be null. */ + Skeleton.prototype.findPathConstraint = function (constraintName) { + if (!constraintName) + throw new Error("constraintName cannot be null."); + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) { + var constraint = pathConstraints[i]; + if (constraint.data.name == constraintName) + return constraint; + } + return null; + }; + /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose as `{ x: number, y: number, width: number, height: number }`. + * Note that this method will create temporary objects which can add to garbage collection pressure. Use `getBounds()` if garbage collection is a concern. */ + Skeleton.prototype.getBoundsRect = function () { + var offset = new Vector2(); + var size = new Vector2(); + this.getBounds(offset, size); + return { x: offset.x, y: offset.y, width: size.x, height: size.y }; + }; + /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. + * @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB. + * @param size An output value, the width and height of the AABB. + * @param temp Working memory to temporarily store attachments' computed world vertices. */ + Skeleton.prototype.getBounds = function (offset, size, temp) { + if (temp === void 0) { temp = new Array(2); } + if (!offset) + throw new Error("offset cannot be null."); + if (!size) + throw new Error("size cannot be null."); + var drawOrder = this.drawOrder; + var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + for (var i = 0, n = drawOrder.length; i < n; i++) { + var slot = drawOrder[i]; + if (!slot.bone.active) + continue; + var verticesLength = 0; + var vertices = null; + var attachment = slot.getAttachment(); + if (attachment instanceof RegionAttachment) { + verticesLength = 8; + vertices = Utils.setArraySize(temp, verticesLength, 0); + attachment.computeWorldVertices(slot, vertices, 0, 2); + } + else if (attachment instanceof MeshAttachment) { + var mesh = attachment; + verticesLength = mesh.worldVerticesLength; + vertices = Utils.setArraySize(temp, verticesLength, 0); + mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2); + } + if (vertices) { + for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) { + var x = vertices[ii], y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + } + offset.set(minX, minY); + size.set(maxX - minX, maxY - minY); + }; + Object.defineProperty(Skeleton.prototype, "flipX", { + get: function () { + return this.scaleX == -1; + }, + set: function (value) { + if (!Skeleton.deprecatedWarning1) { + Skeleton.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); + } + this.scaleX = value ? 1.0 : -1.0; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Skeleton.prototype, "flipY", { + get: function () { + return this.scaleY == -1; + }, + set: function (value) { + if (!Skeleton.deprecatedWarning1) { + Skeleton.deprecatedWarning1 = true; + console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); + } + this.scaleY = value ? 1.0 : -1.0; + }, + enumerable: false, + configurable: true + }); + Skeleton.deprecatedWarning1 = false; + return Skeleton; + }()); + + /** Stores the setup pose and all of the stateless data for a skeleton. + * + * See [Data objects](http://esotericsoftware.com/spine-runtime-architecture#Data-objects) in the Spine Runtimes + * Guide. + * @public + * */ + var SkeletonData = /** @class */ (function () { + function SkeletonData() { + /** The skeleton's name, which by default is the name of the skeleton data file, if possible. May be null. */ + this.name = null; + /** The skeleton's bones, sorted parent first. The root bone is always the first bone. */ + this.bones = new Array(); // Ordered parents first. + /** The skeleton's slots. */ + this.slots = new Array(); // Setup pose draw order. + this.skins = new Array(); + /** The skeleton's default skin. By default this skin contains all attachments that were not in a skin in Spine. + * + * See {@link Skeleton#getAttachmentByName()}. + * May be null. */ + this.defaultSkin = null; + /** The skeleton's events. */ + this.events = new Array(); + /** The skeleton's animations. */ + this.animations = new Array(); + /** The skeleton's IK constraints. */ + this.ikConstraints = new Array(); + /** The skeleton's transform constraints. */ + this.transformConstraints = new Array(); + /** The skeleton's path constraints. */ + this.pathConstraints = new Array(); + /** The X coordinate of the skeleton's axis aligned bounding box in the setup pose. */ + this.x = 0; + /** The Y coordinate of the skeleton's axis aligned bounding box in the setup pose. */ + this.y = 0; + /** The width of the skeleton's axis aligned bounding box in the setup pose. */ + this.width = 0; + /** The height of the skeleton's axis aligned bounding box in the setup pose. */ + this.height = 0; + /** The Spine version used to export the skeleton data, or null. */ + this.version = null; + /** The skeleton data hash. This value will change if any of the skeleton data has changed. May be null. */ + this.hash = null; + // Nonessential + /** The dopesheet FPS in Spine. Available only when nonessential data was exported. */ + this.fps = 0; + /** The path to the images directory as defined in Spine. Available only when nonessential data was exported. May be null. */ + this.imagesPath = null; + /** The path to the audio directory as defined in Spine. Available only when nonessential data was exported. May be null. */ + this.audioPath = null; + } + /** 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. + * @returns May be null. */ + SkeletonData.prototype.findBone = function (boneName) { + if (!boneName) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (bone.name == boneName) + return bone; + } + return null; + }; + /** removed from spine-ts runtime **/ + SkeletonData.prototype.findBoneIndex = function (boneName) { + if (!boneName) + throw new Error("boneName cannot be null."); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + if (bones[i].name == boneName) + return i; + return -1; + }; + /** 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. + * @returns May be null. */ + SkeletonData.prototype.findSlot = function (slotName) { + if (!slotName) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.name == slotName) + return slot; + } + return null; + }; + /** removed from spine-ts runtime **/ + SkeletonData.prototype.findSlotIndex = function (slotName) { + if (!slotName) + throw new Error("slotName cannot be null."); + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) + if (slots[i].name == slotName) + return i; + return -1; + }; + /** 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. + * @returns May be null. */ + SkeletonData.prototype.findSkin = function (skinName) { + if (!skinName) + throw new Error("skinName cannot be null."); + var skins = this.skins; + for (var i = 0, n = skins.length; i < n; i++) { + var skin = skins[i]; + if (skin.name == skinName) + return skin; + } + return null; + }; + /** 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. + * @returns May be null. */ + SkeletonData.prototype.findEvent = function (eventDataName) { + if (!eventDataName) + throw new Error("eventDataName cannot be null."); + var events = this.events; + for (var i = 0, n = events.length; i < n; i++) { + var event_1 = events[i]; + if (event_1.name == eventDataName) + return event_1; + } + return null; + }; + /** 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. + * @returns May be null. */ + SkeletonData.prototype.findAnimation = function (animationName) { + if (!animationName) + throw new Error("animationName cannot be null."); + var animations = this.animations; + for (var i = 0, n = animations.length; i < n; i++) { + var animation = animations[i]; + if (animation.name == animationName) + return animation; + } + return null; + }; + /** 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. + * @return May be null. */ + SkeletonData.prototype.findIkConstraint = function (constraintName) { + if (!constraintName) + throw new Error("constraintName cannot be null."); + var ikConstraints = this.ikConstraints; + for (var i = 0, n = ikConstraints.length; i < n; i++) { + var constraint = ikConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + }; + /** 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. + * @return May be null. */ + SkeletonData.prototype.findTransformConstraint = function (constraintName) { + if (!constraintName) + throw new Error("constraintName cannot be null."); + var transformConstraints = this.transformConstraints; + for (var i = 0, n = transformConstraints.length; i < n; i++) { + var constraint = transformConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + }; + /** 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. + * @return May be null. */ + SkeletonData.prototype.findPathConstraint = function (constraintName) { + if (!constraintName) + throw new Error("constraintName cannot be null."); + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) { + var constraint = pathConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + }; + /** removed from spine-ts runtime **/ SkeletonData.prototype.findPathConstraintIndex = function (pathConstraintName) { + if (pathConstraintName == null) + throw new Error("pathConstraintName cannot be null."); + var pathConstraints = this.pathConstraints; + for (var i = 0, n = pathConstraints.length; i < n; i++) + if (pathConstraints[i].name == pathConstraintName) + return i; + return -1; + }; + return SkeletonData; + }()); + + /** Stores the setup pose for a {@link Slot}. + * @public + * */ + var SlotData = /** @class */ (function () { + function SlotData(index, name, boneData) { + /** The index of the slot in {@link Skeleton#getSlots()}. */ + this.index = 0; + /** The color used to tint the slot's attachment. If {@link #getDarkColor()} is set, this is used as the light color for two + * color tinting. */ + this.color = new Color(1, 1, 1, 1); + /** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark + * color's alpha is not used. */ + this.darkColor = null; + /** The name of the attachment that is visible for this slot in the setup pose, or null if no attachment is visible. */ + this.attachmentName = null; + /** The blend mode for drawing the slot's attachment. */ + this.blendMode = constants.BLEND_MODES.NORMAL; + if (index < 0) + throw new Error("index must be >= 0."); + if (!name) + throw new Error("name cannot be null."); + if (!boneData) + throw new Error("boneData cannot be null."); + this.index = index; + this.name = name; + this.boneData = boneData; + } + return SlotData; + }()); + + /** Stores the setup pose for a {@link TransformConstraint}. + * + * See [Transform constraints](http://esotericsoftware.com/spine-transform-constraints) in the Spine User Guide. + * @public + * */ + var TransformConstraintData = /** @class */ (function (_super) { + __extends$1(TransformConstraintData, _super); + function TransformConstraintData(name) { + var _this = _super.call(this, name, 0, false) || this; + /** The bones that will be modified by this transform constraint. */ + _this.bones = new Array(); + /** The target bone whose world transform will be copied to the constrained bones. */ + _this._target = null; + _this.mixRotate = 0; + _this.mixX = 0; + _this.mixY = 0; + _this.mixScaleX = 0; + _this.mixScaleY = 0; + _this.mixShearY = 0; + /** An offset added to the constrained bone rotation. */ + _this.offsetRotation = 0; + /** An offset added to the constrained bone X translation. */ + _this.offsetX = 0; + /** An offset added to the constrained bone Y translation. */ + _this.offsetY = 0; + /** An offset added to the constrained bone scaleX. */ + _this.offsetScaleX = 0; + /** An offset added to the constrained bone scaleY. */ + _this.offsetScaleY = 0; + /** An offset added to the constrained bone shearY. */ + _this.offsetShearY = 0; + _this.relative = false; + _this.local = false; + return _this; + } + Object.defineProperty(TransformConstraintData.prototype, "target", { + get: function () { + if (!this._target) + throw new Error("BoneData not set."); + else + return this._target; + }, + set: function (boneData) { this._target = boneData; }, + enumerable: false, + configurable: true + }); + return TransformConstraintData; + }(ConstraintData)); + + /** Stores an entry in the skin consisting of the slot index, name, and attachment + * @public + * **/ + var SkinEntry = /** @class */ (function () { + function SkinEntry(slotIndex, name, attachment) { + this.slotIndex = slotIndex; + this.name = name; + this.attachment = attachment; + } + return SkinEntry; + }()); + /** Stores attachments by slot index and attachment name. + * + * See SkeletonData {@link SkeletonData#defaultSkin}, Skeleton {@link Skeleton#skin}, and + * [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide. + * @public + * */ + var Skin = /** @class */ (function () { + function Skin(name) { + this.attachments = new Array(); + this.bones = Array(); + this.constraints = new Array(); + if (!name) + throw new Error("name cannot be null."); + this.name = name; + } + /** Adds an attachment to the skin for the specified slot index and name. */ + Skin.prototype.setAttachment = function (slotIndex, name, attachment) { + if (!attachment) + throw new Error("attachment cannot be null."); + var attachments = this.attachments; + if (slotIndex >= attachments.length) + attachments.length = slotIndex + 1; + if (!attachments[slotIndex]) + attachments[slotIndex] = {}; + attachments[slotIndex][name] = attachment; + }; + /** Adds all attachments, bones, and constraints from the specified skin to this skin. */ + Skin.prototype.addSkin = function (skin) { + for (var i = 0; i < skin.bones.length; i++) { + var bone = skin.bones[i]; + var contained = false; + for (var ii = 0; ii < this.bones.length; ii++) { + if (this.bones[ii] == bone) { + contained = true; + break; + } + } + if (!contained) + this.bones.push(bone); + } + for (var i = 0; i < skin.constraints.length; i++) { + var constraint = skin.constraints[i]; + var contained = false; + for (var ii = 0; ii < this.constraints.length; ii++) { + if (this.constraints[ii] == constraint) { + contained = true; + break; + } + } + if (!contained) + this.constraints.push(constraint); + } + var attachments = skin.getAttachments(); + for (var i = 0; i < attachments.length; i++) { + var attachment = attachments[i]; + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + }; + /** 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. */ + Skin.prototype.copySkin = function (skin) { + for (var i = 0; i < skin.bones.length; i++) { + var bone = skin.bones[i]; + var contained = false; + for (var ii = 0; ii < this.bones.length; ii++) { + if (this.bones[ii] == bone) { + contained = true; + break; + } + } + if (!contained) + this.bones.push(bone); + } + for (var i = 0; i < skin.constraints.length; i++) { + var constraint = skin.constraints[i]; + var contained = false; + for (var ii = 0; ii < this.constraints.length; ii++) { + if (this.constraints[ii] == constraint) { + contained = true; + break; + } + } + if (!contained) + this.constraints.push(constraint); + } + var attachments = skin.getAttachments(); + for (var i = 0; i < attachments.length; i++) { + var attachment = attachments[i]; + if (!attachment.attachment) + continue; + if (attachment.attachment instanceof MeshAttachment) { + attachment.attachment = attachment.attachment.newLinkedMesh(); + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + else { + attachment.attachment = attachment.attachment.copy(); + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + } + }; + /** Returns the attachment for the specified slot index and name, or null. */ + Skin.prototype.getAttachment = function (slotIndex, name) { + var dictionary = this.attachments[slotIndex]; + return dictionary ? dictionary[name] : null; + }; + /** Removes the attachment in the skin for the specified slot index and name, if any. */ + Skin.prototype.removeAttachment = function (slotIndex, name) { + var dictionary = this.attachments[slotIndex]; + if (dictionary) + delete dictionary[name]; + }; + /** Returns all attachments in this skin. */ + Skin.prototype.getAttachments = function () { + var entries = new Array(); + for (var i = 0; i < this.attachments.length; i++) { + var slotAttachments = this.attachments[i]; + if (slotAttachments) { + for (var name_1 in slotAttachments) { + var attachment = slotAttachments[name_1]; + if (attachment) + entries.push(new SkinEntry(i, name_1, attachment)); + } + } + } + return entries; + }; + /** Returns all attachments in this skin for the specified slot index. */ + Skin.prototype.getAttachmentsForSlot = function (slotIndex, attachments) { + var slotAttachments = this.attachments[slotIndex]; + if (slotAttachments) { + for (var name_2 in slotAttachments) { + var attachment = slotAttachments[name_2]; + if (attachment) + attachments.push(new SkinEntry(slotIndex, name_2, attachment)); + } + } + }; + /** Clears all attachments, bones, and constraints. */ + Skin.prototype.clear = function () { + this.attachments.length = 0; + this.bones.length = 0; + this.constraints.length = 0; + }; + /** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */ + Skin.prototype.attachAll = function (skeleton, oldSkin) { + var slotIndex = 0; + for (var i = 0; i < skeleton.slots.length; i++) { + var slot = skeleton.slots[i]; + var slotAttachment = slot.getAttachment(); + if (slotAttachment && slotIndex < oldSkin.attachments.length) { + var dictionary = oldSkin.attachments[slotIndex]; + for (var key in dictionary) { + var skinAttachment = dictionary[key]; + if (slotAttachment == skinAttachment) { + var attachment = this.getAttachment(slotIndex, key); + if (attachment) + slot.setAttachment(attachment); + break; + } + } + } + slotIndex++; + } + }; + return Skin; + }()); + + /** Loads skeleton data in the Spine binary format. + * + * See [Spine binary format](http://esotericsoftware.com/spine-binary-format) and + * [JSON and binary data](http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data) in the Spine + * Runtimes Guide. + * @public + * */ + var SkeletonBinary = /** @class */ (function () { + function SkeletonBinary(attachmentLoader) { + this.ver40 = false; + /** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at + * runtime than were used in Spine. + * + * See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */ + this.scale = 1; + this.linkedMeshes = new Array(); + this.attachmentLoader = attachmentLoader; + } + SkeletonBinary.prototype.readSkeletonData = function (binary) { + var scale = this.scale; + var skeletonData = new SkeletonData(); + skeletonData.name = ""; // BOZO + var input = new BinaryInput(binary); + var lowHash = input.readInt32(); + var highHash = input.readInt32(); + skeletonData.hash = highHash == 0 && lowHash == 0 ? null : highHash.toString(16) + lowHash.toString(16); + skeletonData.version = input.readString(); + var verShort = skeletonData.version.substr(0, 3); + if (verShort !== '4.0' && verShort !== '4.1') { + var error = "Spine 4.1 loader cant load version " + skeletonData.version + ". Please configure your pixi-spine bundle"; + console.error(error); + } + this.ver40 = verShort === '4.0'; + skeletonData.x = input.readFloat(); + skeletonData.y = input.readFloat(); + skeletonData.width = input.readFloat(); + skeletonData.height = input.readFloat(); + var nonessential = input.readBoolean(); + if (nonessential) { + skeletonData.fps = input.readFloat(); + skeletonData.imagesPath = input.readString(); + skeletonData.audioPath = input.readString(); + } + var n = 0; + // Strings. + n = input.readInt(true); + for (var i = 0; i < n; i++) { + var str = input.readString(); + if (!str) + throw new Error("String in string table must not be null."); + input.strings.push(str); + } + // Bones. + n = input.readInt(true); + for (var i = 0; i < n; i++) { + var name_1 = input.readString(); + if (!name_1) + throw new Error("Bone name must not be null."); + var parent_1 = i == 0 ? null : skeletonData.bones[input.readInt(true)]; + var data = new BoneData(i, name_1, parent_1); + data.rotation = input.readFloat(); + data.x = input.readFloat() * scale; + data.y = input.readFloat() * scale; + data.scaleX = input.readFloat(); + data.scaleY = input.readFloat(); + data.shearX = input.readFloat(); + data.shearY = input.readFloat(); + data.length = input.readFloat() * scale; + data.transformMode = input.readInt(true); + data.skinRequired = input.readBoolean(); + if (nonessential) + Color.rgba8888ToColor(data.color, input.readInt32()); + skeletonData.bones.push(data); + } + // Slots. + n = input.readInt(true); + for (var i = 0; i < n; i++) { + var slotName = input.readString(); + if (!slotName) + throw new Error("Slot name must not be null."); + var boneData = skeletonData.bones[input.readInt(true)]; + var data = new SlotData(i, slotName, boneData); + Color.rgba8888ToColor(data.color, input.readInt32()); + var darkColor = input.readInt32(); + if (darkColor != -1) + Color.rgb888ToColor(data.darkColor = new Color(), darkColor); + data.attachmentName = input.readStringRef(); + data.blendMode = input.readInt(true); + skeletonData.slots.push(data); + } + // IK constraints. + n = input.readInt(true); + for (var i = 0, nn = void 0; i < n; i++) { + var name_2 = input.readString(); + if (!name_2) + throw new Error("IK constraint data name must not be null."); + var data = new IkConstraintData(name_2); + data.order = input.readInt(true); + data.skinRequired = input.readBoolean(); + nn = input.readInt(true); + for (var ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.bones[input.readInt(true)]; + data.mix = input.readFloat(); + data.softness = input.readFloat() * scale; + data.bendDirection = input.readByte(); + data.compress = input.readBoolean(); + data.stretch = input.readBoolean(); + data.uniform = input.readBoolean(); + skeletonData.ikConstraints.push(data); + } + // Transform constraints. + n = input.readInt(true); + for (var i = 0, nn = void 0; i < n; i++) { + var name_3 = input.readString(); + if (!name_3) + throw new Error("Transform constraint data name must not be null."); + var data = new TransformConstraintData(name_3); + data.order = input.readInt(true); + data.skinRequired = input.readBoolean(); + nn = input.readInt(true); + for (var ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.bones[input.readInt(true)]; + data.local = input.readBoolean(); + data.relative = input.readBoolean(); + data.offsetRotation = input.readFloat(); + data.offsetX = input.readFloat() * scale; + data.offsetY = input.readFloat() * scale; + data.offsetScaleX = input.readFloat(); + data.offsetScaleY = input.readFloat(); + data.offsetShearY = input.readFloat(); + data.mixRotate = input.readFloat(); + data.mixX = input.readFloat(); + data.mixY = input.readFloat(); + data.mixScaleX = input.readFloat(); + data.mixScaleY = input.readFloat(); + data.mixShearY = input.readFloat(); + skeletonData.transformConstraints.push(data); + } + // Path constraints. + n = input.readInt(true); + for (var i = 0, nn = void 0; i < n; i++) { + var name_4 = input.readString(); + if (!name_4) + throw new Error("Path constraint data name must not be null."); + var data = new PathConstraintData(name_4); + data.order = input.readInt(true); + data.skinRequired = input.readBoolean(); + nn = input.readInt(true); + for (var ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.slots[input.readInt(true)]; + data.positionMode = input.readInt(true); + data.spacingMode = input.readInt(true); + data.rotateMode = input.readInt(true); + data.offsetRotation = input.readFloat(); + data.position = input.readFloat(); + if (data.positionMode == exports.PositionMode.Fixed) + data.position *= scale; + data.spacing = input.readFloat(); + if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) + data.spacing *= scale; + data.mixRotate = input.readFloat(); + data.mixX = input.readFloat(); + data.mixY = input.readFloat(); + skeletonData.pathConstraints.push(data); + } + // Default skin. + var defaultSkin = this.readSkin(input, skeletonData, true, nonessential); + if (defaultSkin) { + skeletonData.defaultSkin = defaultSkin; + skeletonData.skins.push(defaultSkin); + } + // Skins. + { + var i = skeletonData.skins.length; + Utils.setArraySize(skeletonData.skins, n = i + input.readInt(true)); + for (; i < n; i++) { + var skin = this.readSkin(input, skeletonData, false, nonessential); + if (!skin) + throw new Error("readSkin() should not have returned null."); + skeletonData.skins[i] = skin; + } + } + // Linked meshes. + n = this.linkedMeshes.length; + for (var i = 0; i < n; i++) { + var linkedMesh = this.linkedMeshes[i]; + var skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); + if (!skin) + throw new Error("Not skin found for linked mesh."); + if (!linkedMesh.parent) + throw new Error("Linked mesh parent must not be null"); + var parent_2 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (!parent_2) + throw new Error("Parent mesh not found: " + linkedMesh.parent); + linkedMesh.mesh.timelineAttachment = linkedMesh.inheritTimeline ? parent_2 : linkedMesh.mesh; + linkedMesh.mesh.setParentMesh(parent_2); + // if (linkedMesh.mesh.region != null) linkedMesh.mesh.updateRegion(); + } + this.linkedMeshes.length = 0; + // Events. + n = input.readInt(true); + for (var i = 0; i < n; i++) { + var eventName = input.readStringRef(); + if (!eventName) + throw new Error; + var data = new EventData(eventName); + data.intValue = input.readInt(false); + data.floatValue = input.readFloat(); + data.stringValue = input.readString(); + data.audioPath = input.readString(); + if (data.audioPath) { + data.volume = input.readFloat(); + data.balance = input.readFloat(); + } + skeletonData.events.push(data); + } + // Animations. + n = input.readInt(true); + for (var i = 0; i < n; i++) { + var animationName = input.readString(); + if (!animationName) + throw new Error("Animatio name must not be null."); + skeletonData.animations.push(this.readAnimation(input, animationName, skeletonData)); + } + return skeletonData; + }; + SkeletonBinary.prototype.readSkin = function (input, skeletonData, defaultSkin, nonessential) { + var skin = null; + var slotCount = 0; + if (defaultSkin) { + slotCount = input.readInt(true); + if (slotCount == 0) + return null; + skin = new Skin("default"); + } + else { + var skinName = input.readStringRef(); + if (!skinName) + throw new Error("Skin name must not be null."); + skin = new Skin(skinName); + skin.bones.length = input.readInt(true); + for (var i = 0, n = skin.bones.length; i < n; i++) + skin.bones[i] = skeletonData.bones[input.readInt(true)]; + for (var i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.ikConstraints[input.readInt(true)]); + for (var i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.transformConstraints[input.readInt(true)]); + for (var i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.pathConstraints[input.readInt(true)]); + slotCount = input.readInt(true); + } + for (var i = 0; i < slotCount; i++) { + var slotIndex = input.readInt(true); + for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { + var name_5 = input.readStringRef(); + if (!name_5) + throw new Error("Attachment name must not be null"); + var attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name_5, nonessential); + if (attachment) + skin.setAttachment(slotIndex, name_5, attachment); + } + } + return skin; + }; + SkeletonBinary.prototype.readAttachment = function (input, skeletonData, skin, slotIndex, attachmentName, nonessential) { + var scale = this.scale; + var name = input.readStringRef(); + if (!name) + name = attachmentName; + switch (input.readByte()) { + case exports.AttachmentType.Region: { + var path = input.readStringRef(); + var rotation = input.readFloat(); + var x = input.readFloat(); + var y = input.readFloat(); + var scaleX = input.readFloat(); + var scaleY = input.readFloat(); + var width = input.readFloat(); + var height = input.readFloat(); + var color = input.readInt32(); + var sequence = this.readSequence(input); + if (!path) + path = name; + var region = this.attachmentLoader.newRegionAttachment(skin, name, path, sequence); + if (!region) + return null; + region.path = path; + region.x = x * scale; + region.y = y * scale; + region.scaleX = scaleX; + region.scaleY = scaleY; + region.rotation = rotation; + region.width = width * scale; + region.height = height * scale; + Color.rgba8888ToColor(region.color, color); + region.sequence = sequence; + if (sequence == null) + region.updateRegion(); + return region; + } + case exports.AttachmentType.BoundingBox: { + var vertexCount = input.readInt(true); + var vertices = this.readVertices(input, vertexCount); + var color = nonessential ? input.readInt32() : 0; + var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (!box) + return null; + box.worldVerticesLength = vertexCount << 1; + box.vertices = vertices.vertices; + box.bones = vertices.bones; + if (nonessential) + Color.rgba8888ToColor(box.color, color); + return box; + } + case exports.AttachmentType.Mesh: { + var path = input.readStringRef(); + var color = input.readInt32(); + var vertexCount = input.readInt(true); + var uvs = this.readFloatArray(input, vertexCount << 1, 1); + var triangles = this.readShortArray(input); + var vertices = this.readVertices(input, vertexCount); + var hullLength = input.readInt(true); + var sequence = this.readSequence(input); + var edges = []; + var width = 0, height = 0; + if (nonessential) { + edges = this.readShortArray(input); + width = input.readFloat(); + height = input.readFloat(); + } + if (!path) + path = name; + var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); + if (!mesh) + return null; + mesh.path = path; + Color.rgba8888ToColor(mesh.color, color); + mesh.bones = vertices.bones; + mesh.vertices = vertices.vertices; + mesh.worldVerticesLength = vertexCount << 1; + mesh.triangles = triangles; + mesh.regionUVs = new Float32Array(uvs); + // if (sequence == null) mesh.updateRegion(); + mesh.hullLength = hullLength << 1; + mesh.sequence = sequence; + if (nonessential) { + mesh.edges = edges; + mesh.width = width * scale; + mesh.height = height * scale; + } + return mesh; + } + case exports.AttachmentType.LinkedMesh: { + var path = input.readStringRef(); + var color = input.readInt32(); + var skinName = input.readStringRef(); + var parent_3 = input.readStringRef(); + var inheritTimelines = input.readBoolean(); + var sequence = this.readSequence(input); + var width = 0, height = 0; + if (nonessential) { + width = input.readFloat(); + height = input.readFloat(); + } + if (!path) + path = name; + var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); + if (!mesh) + return null; + mesh.path = path; + Color.rgba8888ToColor(mesh.color, color); + mesh.sequence = sequence; + if (nonessential) { + mesh.width = width * scale; + mesh.height = height * scale; + } + this.linkedMeshes.push(new LinkedMesh$1(mesh, skinName, slotIndex, parent_3, inheritTimelines)); + return mesh; + } + case exports.AttachmentType.Path: { + var closed_1 = input.readBoolean(); + var constantSpeed = input.readBoolean(); + var vertexCount = input.readInt(true); + var vertices = this.readVertices(input, vertexCount); + var lengths = Utils.newArray(vertexCount / 3, 0); + for (var i = 0, n = lengths.length; i < n; i++) + lengths[i] = input.readFloat() * scale; + var color = nonessential ? input.readInt32() : 0; + var path = this.attachmentLoader.newPathAttachment(skin, name); + if (!path) + return null; + path.closed = closed_1; + path.constantSpeed = constantSpeed; + path.worldVerticesLength = vertexCount << 1; + path.vertices = vertices.vertices; + path.bones = vertices.bones; + path.lengths = lengths; + if (nonessential) + Color.rgba8888ToColor(path.color, color); + return path; + } + case exports.AttachmentType.Point: { + var rotation = input.readFloat(); + var x = input.readFloat(); + var y = input.readFloat(); + var color = nonessential ? input.readInt32() : 0; + var point = this.attachmentLoader.newPointAttachment(skin, name); + if (!point) + return null; + point.x = x * scale; + point.y = y * scale; + point.rotation = rotation; + if (nonessential) + Color.rgba8888ToColor(point.color, color); + return point; + } + case exports.AttachmentType.Clipping: { + var endSlotIndex = input.readInt(true); + var vertexCount = input.readInt(true); + var vertices = this.readVertices(input, vertexCount); + var color = nonessential ? input.readInt32() : 0; + var clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (!clip) + return null; + clip.endSlot = skeletonData.slots[endSlotIndex]; + clip.worldVerticesLength = vertexCount << 1; + clip.vertices = vertices.vertices; + clip.bones = vertices.bones; + if (nonessential) + Color.rgba8888ToColor(clip.color, color); + return clip; + } + } + return null; + }; + SkeletonBinary.prototype.readSequence = function (input) { + if (this.ver40 || !input.readBoolean()) + return null; + var sequence = new Sequence(input.readInt(true)); + sequence.start = input.readInt(true); + sequence.digits = input.readInt(true); + sequence.setupIndex = input.readInt(true); + return sequence; + }; + SkeletonBinary.prototype.readDeformTimelineType = function (input) { + if (this.ver40) + return ATTACHMENT_DEFORM; + return input.readByte(); + }; + SkeletonBinary.prototype.readVertices = function (input, vertexCount) { + var scale = this.scale; + var verticesLength = vertexCount << 1; + var vertices = new Vertices(); + if (!input.readBoolean()) { + vertices.vertices = this.readFloatArray(input, verticesLength, scale); + return vertices; + } + var weights = new Array(); + var bonesArray = new Array(); + for (var i = 0; i < vertexCount; i++) { + var boneCount = input.readInt(true); + bonesArray.push(boneCount); + for (var ii = 0; ii < boneCount; ii++) { + bonesArray.push(input.readInt(true)); + weights.push(input.readFloat() * scale); + weights.push(input.readFloat() * scale); + weights.push(input.readFloat()); + } + } + vertices.vertices = Utils.toFloatArray(weights); + vertices.bones = bonesArray; + return vertices; + }; + SkeletonBinary.prototype.readFloatArray = function (input, n, scale) { + var array = new Array(n); + if (scale == 1) { + for (var i = 0; i < n; i++) + array[i] = input.readFloat(); + } + else { + for (var i = 0; i < n; i++) + array[i] = input.readFloat() * scale; + } + return array; + }; + SkeletonBinary.prototype.readShortArray = function (input) { + var n = input.readInt(true); + var array = new Array(n); + for (var i = 0; i < n; i++) + array[i] = input.readShort(); + return array; + }; + SkeletonBinary.prototype.readAnimation = function (input, name, skeletonData) { + input.readInt(true); // Number of timelines. + var timelines = new Array(); + var scale = this.scale; + // Slot timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var slotIndex = input.readInt(true); + for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { + var timelineType = input.readByte(); + var frameCount = input.readInt(true); + var frameLast = frameCount - 1; + switch (timelineType) { + case SLOT_ATTACHMENT: { + var timeline = new AttachmentTimeline(frameCount, slotIndex); + for (var frame = 0; frame < frameCount; frame++) + timeline.setFrame(frame, input.readFloat(), input.readStringRef()); + timelines.push(timeline); + break; + } + case SLOT_RGBA: { + var bezierCount = input.readInt(true); + var timeline = new RGBATimeline(frameCount, bezierCount, slotIndex); + var time = input.readFloat(); + var r = input.readUnsignedByte() / 255.0; + var g = input.readUnsignedByte() / 255.0; + var b = input.readUnsignedByte() / 255.0; + var a = input.readUnsignedByte() / 255.0; + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, r, g, b, a); + if (frame == frameLast) + break; + var time2 = input.readFloat(); + var r2 = input.readUnsignedByte() / 255.0; + var g2 = input.readUnsignedByte() / 255.0; + var b2 = input.readUnsignedByte() / 255.0; + var a2 = input.readUnsignedByte() / 255.0; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, a, a2, 1); + } + time = time2; + r = r2; + g = g2; + b = b2; + a = a2; + } + timelines.push(timeline); + break; + } + case SLOT_RGB: { + var bezierCount = input.readInt(true); + var timeline = new RGBTimeline(frameCount, bezierCount, slotIndex); + var time = input.readFloat(); + var r = input.readUnsignedByte() / 255.0; + var g = input.readUnsignedByte() / 255.0; + var b = input.readUnsignedByte() / 255.0; + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, r, g, b); + if (frame == frameLast) + break; + var time2 = input.readFloat(); + var r2 = input.readUnsignedByte() / 255.0; + var g2 = input.readUnsignedByte() / 255.0; + var b2 = input.readUnsignedByte() / 255.0; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1); + } + time = time2; + r = r2; + g = g2; + b = b2; + } + timelines.push(timeline); + break; + } + case SLOT_RGBA2: { + var bezierCount = input.readInt(true); + var timeline = new RGBA2Timeline(frameCount, bezierCount, slotIndex); + var time = input.readFloat(); + var r = input.readUnsignedByte() / 255.0; + var g = input.readUnsignedByte() / 255.0; + var b = input.readUnsignedByte() / 255.0; + var a = input.readUnsignedByte() / 255.0; + var r2 = input.readUnsignedByte() / 255.0; + var g2 = input.readUnsignedByte() / 255.0; + var b2 = input.readUnsignedByte() / 255.0; + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, r, g, b, a, r2, g2, b2); + if (frame == frameLast) + break; + var time2 = input.readFloat(); + var nr = input.readUnsignedByte() / 255.0; + var ng = input.readUnsignedByte() / 255.0; + var nb = input.readUnsignedByte() / 255.0; + var na = input.readUnsignedByte() / 255.0; + var nr2 = input.readUnsignedByte() / 255.0; + var ng2 = input.readUnsignedByte() / 255.0; + var nb2 = input.readUnsignedByte() / 255.0; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, a, na, 1); + setBezier(input, timeline, bezier++, frame, 4, time, time2, r2, nr2, 1); + setBezier(input, timeline, bezier++, frame, 5, time, time2, g2, ng2, 1); + setBezier(input, timeline, bezier++, frame, 6, time, time2, b2, nb2, 1); + } + time = time2; + r = nr; + g = ng; + b = nb; + a = na; + r2 = nr2; + g2 = ng2; + b2 = nb2; + } + timelines.push(timeline); + break; + } + case SLOT_RGB2: { + var bezierCount = input.readInt(true); + var timeline = new RGB2Timeline(frameCount, bezierCount, slotIndex); + var time = input.readFloat(); + var r = input.readUnsignedByte() / 255.0; + var g = input.readUnsignedByte() / 255.0; + var b = input.readUnsignedByte() / 255.0; + var r2 = input.readUnsignedByte() / 255.0; + var g2 = input.readUnsignedByte() / 255.0; + var b2 = input.readUnsignedByte() / 255.0; + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, r, g, b, r2, g2, b2); + if (frame == frameLast) + break; + var time2 = input.readFloat(); + var nr = input.readUnsignedByte() / 255.0; + var ng = input.readUnsignedByte() / 255.0; + var nb = input.readUnsignedByte() / 255.0; + var nr2 = input.readUnsignedByte() / 255.0; + var ng2 = input.readUnsignedByte() / 255.0; + var nb2 = input.readUnsignedByte() / 255.0; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, r2, nr2, 1); + setBezier(input, timeline, bezier++, frame, 4, time, time2, g2, ng2, 1); + setBezier(input, timeline, bezier++, frame, 5, time, time2, b2, nb2, 1); + } + time = time2; + r = nr; + g = ng; + b = nb; + r2 = nr2; + g2 = ng2; + b2 = nb2; + } + timelines.push(timeline); + break; + } + case SLOT_ALPHA: { + var timeline = new AlphaTimeline(frameCount, input.readInt(true), slotIndex); + var time = input.readFloat(), a = input.readUnsignedByte() / 255; + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, a); + if (frame == frameLast) + break; + var time2 = input.readFloat(); + var a2 = input.readUnsignedByte() / 255; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, a, a2, 1); + } + time = time2; + a = a2; + } + timelines.push(timeline); + } + } + } + } + // Bone timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var boneIndex = input.readInt(true); + for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { + var type = input.readByte(), frameCount = input.readInt(true), bezierCount = input.readInt(true); + switch (type) { + case BONE_ROTATE: + timelines.push(readTimeline1$1(input, new RotateTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_TRANSLATE: + timelines.push(readTimeline2$1(input, new TranslateTimeline(frameCount, bezierCount, boneIndex), scale)); + break; + case BONE_TRANSLATEX: + timelines.push(readTimeline1$1(input, new TranslateXTimeline(frameCount, bezierCount, boneIndex), scale)); + break; + case BONE_TRANSLATEY: + timelines.push(readTimeline1$1(input, new TranslateYTimeline(frameCount, bezierCount, boneIndex), scale)); + break; + case BONE_SCALE: + timelines.push(readTimeline2$1(input, new ScaleTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SCALEX: + timelines.push(readTimeline1$1(input, new ScaleXTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SCALEY: + timelines.push(readTimeline1$1(input, new ScaleYTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SHEAR: + timelines.push(readTimeline2$1(input, new ShearTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SHEARX: + timelines.push(readTimeline1$1(input, new ShearXTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SHEARY: + timelines.push(readTimeline1$1(input, new ShearYTimeline(frameCount, bezierCount, boneIndex), 1)); + } + } + } + // IK constraint timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1; + var timeline = new IkConstraintTimeline(frameCount, input.readInt(true), index); + var time = input.readFloat(), mix = input.readFloat(), softness = input.readFloat() * scale; + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, mix, softness, input.readByte(), input.readBoolean(), input.readBoolean()); + if (frame == frameLast) + break; + var time2 = input.readFloat(), mix2 = input.readFloat(), softness2 = input.readFloat() * scale; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2, scale); + } + time = time2; + mix = mix2; + softness = softness2; + } + timelines.push(timeline); + } + // Transform constraint timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1; + var timeline = new TransformConstraintTimeline(frameCount, input.readInt(true), index); + var time = input.readFloat(), mixRotate = input.readFloat(), mixX = input.readFloat(), mixY = input.readFloat(), mixScaleX = input.readFloat(), mixScaleY = input.readFloat(), mixShearY = input.readFloat(); + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY); + if (frame == frameLast) + break; + var time2 = input.readFloat(), mixRotate2 = input.readFloat(), mixX2 = input.readFloat(), mixY2 = input.readFloat(), mixScaleX2 = input.readFloat(), mixScaleY2 = input.readFloat(), mixShearY2 = input.readFloat(); + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, mixScaleX, mixScaleX2, 1); + setBezier(input, timeline, bezier++, frame, 4, time, time2, mixScaleY, mixScaleY2, 1); + setBezier(input, timeline, bezier++, frame, 5, time, time2, mixShearY, mixShearY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + mixScaleX = mixScaleX2; + mixScaleY = mixScaleY2; + mixShearY = mixShearY2; + } + timelines.push(timeline); + } + // Path constraint timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var index = input.readInt(true); + var data = skeletonData.pathConstraints[index]; + for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { + switch (input.readByte()) { + case PATH_POSITION: + timelines + .push(readTimeline1$1(input, new PathConstraintPositionTimeline(input.readInt(true), input.readInt(true), index), data.positionMode == exports.PositionMode.Fixed ? scale : 1)); + break; + case PATH_SPACING: + timelines + .push(readTimeline1$1(input, new PathConstraintSpacingTimeline(input.readInt(true), input.readInt(true), index), data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1)); + break; + case PATH_MIX: + var timeline = new PathConstraintMixTimeline(input.readInt(true), input.readInt(true), index); + var time = input.readFloat(), mixRotate = input.readFloat(), mixX = input.readFloat(), mixY = input.readFloat(); + for (var frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1;; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY); + if (frame == frameLast) + break; + var time2 = input.readFloat(), mixRotate2 = input.readFloat(), mixX2 = input.readFloat(), mixY2 = input.readFloat(); + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + } + timelines.push(timeline); + } + } + } + // Deform timelines. + for (var i = 0, n = input.readInt(true); i < n; i++) { + var skin = skeletonData.skins[input.readInt(true)]; + for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { + var slotIndex = input.readInt(true); + for (var iii = 0, nnn = input.readInt(true); iii < nnn; iii++) { + var attachmentName = input.readStringRef(); + if (!attachmentName) + throw new Error("attachmentName must not be null."); + var attachment = skin.getAttachment(slotIndex, attachmentName); + var timelineType = this.readDeformTimelineType(input); + var frameCount = input.readInt(true); + var frameLast = frameCount - 1; + switch (timelineType) { + case ATTACHMENT_DEFORM: { + var vertexAttachment = attachment; + var weighted = vertexAttachment.bones; + var vertices = vertexAttachment.vertices; + var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + var bezierCount = input.readInt(true); + var timeline = new DeformTimeline(frameCount, bezierCount, slotIndex, vertexAttachment); + var time = input.readFloat(); + for (var frame = 0, bezier = 0;; frame++) { + var deform = void 0; + var end = input.readInt(true); + if (end == 0) + deform = weighted ? Utils.newFloatArray(deformLength) : vertices; + else { + deform = Utils.newFloatArray(deformLength); + var start = input.readInt(true); + end += start; + if (scale == 1) { + for (var v = start; v < end; v++) + deform[v] = input.readFloat(); + } + else { + for (var v = start; v < end; v++) + deform[v] = input.readFloat() * scale; + } + if (!weighted) { + for (var v = 0, vn = deform.length; v < vn; v++) + deform[v] += vertices[v]; + } + } + timeline.setFrame(frame, time, deform); + if (frame == frameLast) + break; + var time2 = input.readFloat(); + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1); + } + time = time2; + } + timelines.push(timeline); + break; + } + case ATTACHMENT_SEQUENCE: { + var timeline = new SequenceTimeline(frameCount, slotIndex, attachment); + for (var frame = 0; frame < frameCount; frame++) { + var time = input.readFloat(); + var modeAndIndex = input.readInt32(); + timeline.setFrame(frame, time, SequenceModeValues[modeAndIndex & 0xf], modeAndIndex >> 4, input.readFloat()); + } + timelines.push(timeline); + break; + } + } + } + } + } + // Draw order timeline. + var drawOrderCount = input.readInt(true); + if (drawOrderCount > 0) { + var timeline = new DrawOrderTimeline(drawOrderCount); + var slotCount = skeletonData.slots.length; + for (var i = 0; i < drawOrderCount; i++) { + var time = input.readFloat(); + var offsetCount = input.readInt(true); + var drawOrder = Utils.newArray(slotCount, 0); + for (var ii = slotCount - 1; ii >= 0; ii--) + drawOrder[ii] = -1; + var unchanged = Utils.newArray(slotCount - offsetCount, 0); + var originalIndex = 0, unchangedIndex = 0; + for (var ii = 0; ii < offsetCount; ii++) { + var slotIndex = input.readInt(true); + // Collect unchanged items. + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + // Set changed items. + drawOrder[originalIndex + input.readInt(true)] = originalIndex++; + } + // Collect remaining unchanged items. + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + // Fill in unchanged items. + for (var ii = slotCount - 1; ii >= 0; ii--) + if (drawOrder[ii] == -1) + drawOrder[ii] = unchanged[--unchangedIndex]; + timeline.setFrame(i, time, drawOrder); + } + timelines.push(timeline); + } + // Event timeline. + var eventCount = input.readInt(true); + if (eventCount > 0) { + var timeline = new EventTimeline(eventCount); + for (var i = 0; i < eventCount; i++) { + var time = input.readFloat(); + var eventData = skeletonData.events[input.readInt(true)]; + var event_1 = new Event(time, eventData); + event_1.intValue = input.readInt(false); + event_1.floatValue = input.readFloat(); + event_1.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue; + if (event_1.data.audioPath) { + event_1.volume = input.readFloat(); + event_1.balance = input.readFloat(); + } + timeline.setFrame(i, event_1); + } + timelines.push(timeline); + } + var duration = 0; + for (var i = 0, n = timelines.length; i < n; i++) + duration = Math.max(duration, timelines[i].getDuration()); + return new Animation(name, timelines, duration); + }; + SkeletonBinary.BlendModeValues = [constants.BLEND_MODES.NORMAL, constants.BLEND_MODES.ADD, constants.BLEND_MODES.MULTIPLY, constants.BLEND_MODES.SCREEN]; + return SkeletonBinary; + }()); + var LinkedMesh$1 = /** @class */ (function () { + function LinkedMesh(mesh, skin, slotIndex, parent, inheritDeform) { + this.mesh = mesh; + this.skin = skin; + this.slotIndex = slotIndex; + this.parent = parent; + this.inheritTimeline = inheritDeform; + } + return LinkedMesh; + }()); + var Vertices = /** @class */ (function () { + function Vertices(bones, vertices) { + if (bones === void 0) { bones = null; } + if (vertices === void 0) { vertices = null; } + this.bones = bones; + this.vertices = vertices; + } + return Vertices; + }()); + function readTimeline1$1(input, timeline, scale) { + var time = input.readFloat(), value = input.readFloat() * scale; + for (var frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1;; frame++) { + timeline.setFrame(frame, time, value); + if (frame == frameLast) + break; + var time2 = input.readFloat(), value2 = input.readFloat() * scale; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, value, value2, scale); + } + time = time2; + value = value2; + } + return timeline; + } + function readTimeline2$1(input, timeline, scale) { + var time = input.readFloat(), value1 = input.readFloat() * scale, value2 = input.readFloat() * scale; + for (var frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1;; frame++) { + timeline.setFrame(frame, time, value1, value2); + if (frame == frameLast) + break; + var time2 = input.readFloat(), nvalue1 = input.readFloat() * scale, nvalue2 = input.readFloat() * scale; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, value1, nvalue1, scale); + setBezier(input, timeline, bezier++, frame, 1, time, time2, value2, nvalue2, scale); + } + time = time2; + value1 = nvalue1; + value2 = nvalue2; + } + return timeline; + } + function setBezier(input, timeline, bezier, frame, value, time1, time2, value1, value2, scale) { + timeline.setBezier(bezier, frame, value, time1, value1, input.readFloat(), input.readFloat() * scale, input.readFloat(), input.readFloat() * scale, time2, value2); + } + var BONE_ROTATE = 0; + var BONE_TRANSLATE = 1; + var BONE_TRANSLATEX = 2; + var BONE_TRANSLATEY = 3; + var BONE_SCALE = 4; + var BONE_SCALEX = 5; + var BONE_SCALEY = 6; + var BONE_SHEAR = 7; + var BONE_SHEARX = 8; + var BONE_SHEARY = 9; + var SLOT_ATTACHMENT = 0; + var SLOT_RGBA = 1; + var SLOT_RGB = 2; + var SLOT_RGBA2 = 3; + var SLOT_RGB2 = 4; + var SLOT_ALPHA = 5; + var ATTACHMENT_DEFORM = 0; + var ATTACHMENT_SEQUENCE = 1; + var PATH_POSITION = 0; + var PATH_SPACING = 1; + var PATH_MIX = 2; + // const CURVE_LINEAR = 0; + var CURVE_STEPPED = 1; + var CURVE_BEZIER = 2; + + /** Collects each visible {@link BoundingBoxAttachment} and computes the world vertices for its polygon. The polygon vertices are + * provided along with convenience methods for doing hit detection. + * @public + * */ + var SkeletonBounds = /** @class */ (function (_super) { + __extends$1(SkeletonBounds, _super); + function SkeletonBounds() { + return _super !== null && _super.apply(this, arguments) || this; + } + return SkeletonBounds; + }(SkeletonBoundsBase)); + + /** Loads skeleton data in the Spine JSON format. + * + * See [Spine JSON format](http://esotericsoftware.com/spine-json-format) and + * [JSON and binary data](http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data) in the Spine + * Runtimes Guide. + * @public + * */ + var SkeletonJson = /** @class */ (function () { + function SkeletonJson(attachmentLoader) { + /** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at + * runtime than were used in Spine. + * + * See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */ + this.scale = 1; + this.linkedMeshes = new Array(); + this.attachmentLoader = attachmentLoader; + } + SkeletonJson.prototype.readSkeletonData = function (json) { + var scale = this.scale; + var skeletonData = new SkeletonData(); + var root = typeof (json) === "string" ? JSON.parse(json) : json; + // Skeleton + var skeletonMap = root.skeleton; + if (skeletonMap) { + skeletonData.hash = skeletonMap.hash; + skeletonData.version = skeletonMap.spine; + var verShort = skeletonData.version.substr(0, 3); + if (verShort !== '4.0' && verShort !== '4.1') { + var error = "Spine 4.1 loader cant load version " + skeletonMap.spine + ". Please configure your pixi-spine bundle"; + console.error(error); + } + skeletonData.x = skeletonMap.x; + skeletonData.y = skeletonMap.y; + skeletonData.width = skeletonMap.width; + skeletonData.height = skeletonMap.height; + skeletonData.fps = skeletonMap.fps; + skeletonData.imagesPath = skeletonMap.images; + } + // Bones + if (root.bones) { + for (var i = 0; i < root.bones.length; i++) { + var boneMap = root.bones[i]; + var parent_1 = null; + var parentName = getValue(boneMap, "parent", null); + if (parentName != null) { + parent_1 = skeletonData.findBone(parentName); + if (parent_1 == null) + throw new Error("Parent bone not found: " + parentName); + } + var data = new BoneData(skeletonData.bones.length, boneMap.name, parent_1); + data.length = getValue(boneMap, "length", 0) * scale; + data.x = getValue(boneMap, "x", 0) * scale; + data.y = getValue(boneMap, "y", 0) * scale; + data.rotation = getValue(boneMap, "rotation", 0); + data.scaleX = getValue(boneMap, "scaleX", 1); + data.scaleY = getValue(boneMap, "scaleY", 1); + data.shearX = getValue(boneMap, "shearX", 0); + data.shearY = getValue(boneMap, "shearY", 0); + data.transformMode = Utils.enumValue(exports.TransformMode, getValue(boneMap, "transform", "Normal")); + data.skinRequired = getValue(boneMap, "skin", false); + var color = getValue(boneMap, "color", null); + if (color) + data.color.setFromString(color); + skeletonData.bones.push(data); + } + } + // Slots. + if (root.slots) { + for (var i = 0; i < root.slots.length; i++) { + var slotMap = root.slots[i]; + var boneData = skeletonData.findBone(slotMap.bone); + if (!boneData) + throw new Error("Couldn't find bone " + slotMap.bone + " for slot " + slotMap.name); + var data = new SlotData(skeletonData.slots.length, slotMap.name, boneData); + var color = getValue(slotMap, "color", null); + if (color) + data.color.setFromString(color); + var dark = getValue(slotMap, "dark", null); + if (dark) + data.darkColor = Color.fromString(dark); + data.attachmentName = getValue(slotMap, "attachment", null); + data.blendMode = SkeletonJson.blendModeFromString(getValue(slotMap, "blend", "normal")); + skeletonData.slots.push(data); + } + } + // IK constraints + if (root.ik) { + for (var i = 0; i < root.ik.length; i++) { + var constraintMap = root.ik[i]; + var data = new IkConstraintData(constraintMap.name); + data.order = getValue(constraintMap, "order", 0); + data.skinRequired = getValue(constraintMap, "skin", false); + for (var ii = 0; ii < constraintMap.bones.length; ii++) { + var boneName = constraintMap.bones[ii]; + var bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("IK bone not found: " + boneName); + data.bones.push(bone); + } + data.target = skeletonData.findBone(constraintMap.target); + data.mix = getValue(constraintMap, "mix", 1); + data.softness = getValue(constraintMap, "softness", 0) * scale; + data.bendDirection = getValue(constraintMap, "bendPositive", true) ? 1 : -1; + data.compress = getValue(constraintMap, "compress", false); + data.stretch = getValue(constraintMap, "stretch", false); + data.uniform = getValue(constraintMap, "uniform", false); + skeletonData.ikConstraints.push(data); + } + } + // Transform constraints. + if (root.transform) { + for (var i = 0; i < root.transform.length; i++) { + var constraintMap = root.transform[i]; + var data = new TransformConstraintData(constraintMap.name); + data.order = getValue(constraintMap, "order", 0); + data.skinRequired = getValue(constraintMap, "skin", false); + for (var ii = 0; ii < constraintMap.bones.length; ii++) { + var boneName = constraintMap.bones[ii]; + var bone = skeletonData.findBone(boneName); + if (!bone) + throw new Error("Couldn't find bone " + boneName + " for transform constraint " + constraintMap.name + "."); + data.bones.push(bone); + } + var targetName = constraintMap.target; + var target = skeletonData.findBone(targetName); + if (!target) + throw new Error("Couldn't find target bone " + targetName + " for transform constraint " + constraintMap.name + "."); + data.target = target; + data.local = getValue(constraintMap, "local", false); + data.relative = getValue(constraintMap, "relative", false); + data.offsetRotation = getValue(constraintMap, "rotation", 0); + data.offsetX = getValue(constraintMap, "x", 0) * scale; + data.offsetY = getValue(constraintMap, "y", 0) * scale; + data.offsetScaleX = getValue(constraintMap, "scaleX", 0); + data.offsetScaleY = getValue(constraintMap, "scaleY", 0); + data.offsetShearY = getValue(constraintMap, "shearY", 0); + data.mixRotate = getValue(constraintMap, "mixRotate", 1); + data.mixX = getValue(constraintMap, "mixX", 1); + data.mixY = getValue(constraintMap, "mixY", data.mixX); + data.mixScaleX = getValue(constraintMap, "mixScaleX", 1); + data.mixScaleY = getValue(constraintMap, "mixScaleY", data.mixScaleX); + data.mixShearY = getValue(constraintMap, "mixShearY", 1); + skeletonData.transformConstraints.push(data); + } + } + // Path constraints. + if (root.path) { + for (var i = 0; i < root.path.length; i++) { + var constraintMap = root.path[i]; + var data = new PathConstraintData(constraintMap.name); + data.order = getValue(constraintMap, "order", 0); + data.skinRequired = getValue(constraintMap, "skin", false); + for (var ii = 0; ii < constraintMap.bones.length; ii++) { + var boneName = constraintMap.bones[ii]; + var bone = skeletonData.findBone(boneName); + if (!bone) + throw new Error("Couldn't find bone " + boneName + " for path constraint " + constraintMap.name + "."); + data.bones.push(bone); + } + var targetName = constraintMap.target; + var target = skeletonData.findSlot(targetName); + if (!target) + throw new Error("Couldn't find target slot " + targetName + " for path constraint " + constraintMap.name + "."); + data.target = target; + data.positionMode = Utils.enumValue(exports.PositionMode, getValue(constraintMap, "positionMode", "Percent")); + data.spacingMode = Utils.enumValue(SpacingMode, getValue(constraintMap, "spacingMode", "Length")); + data.rotateMode = Utils.enumValue(exports.RotateMode, getValue(constraintMap, "rotateMode", "Tangent")); + data.offsetRotation = getValue(constraintMap, "rotation", 0); + data.position = getValue(constraintMap, "position", 0); + if (data.positionMode == exports.PositionMode.Fixed) + data.position *= scale; + data.spacing = getValue(constraintMap, "spacing", 0); + if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) + data.spacing *= scale; + data.mixRotate = getValue(constraintMap, "mixRotate", 1); + data.mixX = getValue(constraintMap, "mixX", 1); + data.mixY = getValue(constraintMap, "mixY", data.mixX); + skeletonData.pathConstraints.push(data); + } + } + // Skins. + if (root.skins) { + for (var i = 0; i < root.skins.length; i++) { + var skinMap = root.skins[i]; + var skin = new Skin(skinMap.name); + if (skinMap.bones) { + for (var ii = 0; ii < skinMap.bones.length; ii++) { + var boneName = skinMap.bones[ii]; + var bone = skeletonData.findBone(boneName); + if (!bone) + throw new Error("Couldn't find bone " + boneName + " for skin " + skinMap.name + "."); + skin.bones.push(bone); + } + } + if (skinMap.ik) { + for (var ii = 0; ii < skinMap.ik.length; ii++) { + var constraintName = skinMap.ik[ii]; + var constraint = skeletonData.findIkConstraint(constraintName); + if (!constraint) + throw new Error("Couldn't find IK constraint " + constraintName + " for skin " + skinMap.name + "."); + skin.constraints.push(constraint); + } + } + if (skinMap.transform) { + for (var ii = 0; ii < skinMap.transform.length; ii++) { + var constraintName = skinMap.transform[ii]; + var constraint = skeletonData.findTransformConstraint(constraintName); + if (!constraint) + throw new Error("Couldn't find transform constraint " + constraintName + " for skin " + skinMap.name + "."); + skin.constraints.push(constraint); + } + } + if (skinMap.path) { + for (var ii = 0; ii < skinMap.path.length; ii++) { + var constraintName = skinMap.path[ii]; + var constraint = skeletonData.findPathConstraint(constraintName); + if (!constraint) + throw new Error("Couldn't find path constraint " + constraintName + " for skin " + skinMap.name + "."); + skin.constraints.push(constraint); + } + } + for (var slotName in skinMap.attachments) { + var slot = skeletonData.findSlot(slotName); + if (!slot) + throw new Error("Couldn't find slot " + slotName + " for skin " + skinMap.name + "."); + var slotMap = skinMap.attachments[slotName]; + for (var entryName in slotMap) { + var attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData); + if (attachment) + skin.setAttachment(slot.index, entryName, attachment); + } + } + skeletonData.skins.push(skin); + if (skin.name == "default") + skeletonData.defaultSkin = skin; + } + } + // Linked meshes. + for (var i = 0, n = this.linkedMeshes.length; i < n; i++) { + var linkedMesh = this.linkedMeshes[i]; + var skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); + if (!skin) + throw new Error("Skin not found: " + linkedMesh.skin); + var parent_2 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (!parent_2) + throw new Error("Parent mesh not found: " + linkedMesh.parent); + linkedMesh.mesh.timelineAttachment = linkedMesh.inheritTimeline ? parent_2 : linkedMesh.mesh; + linkedMesh.mesh.setParentMesh(parent_2); + // if (linkedMesh.mesh.region != null) linkedMesh.mesh.updateRegion(); + } + this.linkedMeshes.length = 0; + // Events. + if (root.events) { + for (var eventName in root.events) { + var eventMap = root.events[eventName]; + var data = new EventData(eventName); + data.intValue = getValue(eventMap, "int", 0); + data.floatValue = getValue(eventMap, "float", 0); + data.stringValue = getValue(eventMap, "string", ""); + data.audioPath = getValue(eventMap, "audio", null); + if (data.audioPath) { + data.volume = getValue(eventMap, "volume", 1); + data.balance = getValue(eventMap, "balance", 0); + } + skeletonData.events.push(data); + } + } + // Animations. + if (root.animations) { + for (var animationName in root.animations) { + var animationMap = root.animations[animationName]; + this.readAnimation(animationMap, animationName, skeletonData); + } + } + return skeletonData; + }; + SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) { + var scale = this.scale; + name = getValue(map, "name", name); + switch (getValue(map, "type", "region")) { + case "region": { + var path = getValue(map, "path", name); + var sequence = this.readSequence(getValue(map, "sequence", null)); + var region = this.attachmentLoader.newRegionAttachment(skin, name, path, sequence); + if (!region) + return null; + region.path = path; + region.x = getValue(map, "x", 0) * scale; + region.y = getValue(map, "y", 0) * scale; + region.scaleX = getValue(map, "scaleX", 1); + region.scaleY = getValue(map, "scaleY", 1); + region.rotation = getValue(map, "rotation", 0); + region.width = map.width * scale; + region.height = map.height * scale; + region.sequence = sequence; + var color = getValue(map, "color", null); + if (color) + region.color.setFromString(color); + // if (region.region != null) region.updateRegion(); + return region; + } + case "boundingbox": { + var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (!box) + return null; + this.readVertices(map, box, map.vertexCount << 1); + var color = getValue(map, "color", null); + if (color) + box.color.setFromString(color); + return box; + } + case "mesh": + case "linkedmesh": { + var path = getValue(map, "path", name); + var sequence = this.readSequence(getValue(map, "sequence", null)); + var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); + if (!mesh) + return null; + mesh.path = path; + var color = getValue(map, "color", null); + if (color) + mesh.color.setFromString(color); + mesh.width = getValue(map, "width", 0) * scale; + mesh.height = getValue(map, "height", 0) * scale; + mesh.sequence = sequence; + var parent_3 = getValue(map, "parent", null); + if (parent_3) { + this.linkedMeshes.push(new LinkedMesh(mesh, getValue(map, "skin", null), slotIndex, parent_3, getValue(map, "timelines", true))); + return mesh; + } + var uvs = map.uvs; + this.readVertices(map, mesh, uvs.length); + mesh.triangles = map.triangles; + mesh.regionUVs = new Float32Array(uvs); + // if (mesh.region != null) mesh.updateRegion(); + mesh.edges = getValue(map, "edges", null); + mesh.hullLength = getValue(map, "hull", 0) * 2; + return mesh; + } + case "path": { + var path = this.attachmentLoader.newPathAttachment(skin, name); + if (!path) + return null; + path.closed = getValue(map, "closed", false); + path.constantSpeed = getValue(map, "constantSpeed", true); + var vertexCount = map.vertexCount; + this.readVertices(map, path, vertexCount << 1); + var lengths = Utils.newArray(vertexCount / 3, 0); + for (var i = 0; i < map.lengths.length; i++) + lengths[i] = map.lengths[i] * scale; + path.lengths = lengths; + var color = getValue(map, "color", null); + if (color) + path.color.setFromString(color); + return path; + } + case "point": { + var point = this.attachmentLoader.newPointAttachment(skin, name); + if (!point) + return null; + point.x = getValue(map, "x", 0) * scale; + point.y = getValue(map, "y", 0) * scale; + point.rotation = getValue(map, "rotation", 0); + var color = getValue(map, "color", null); + if (color) + point.color.setFromString(color); + return point; + } + case "clipping": { + var clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (!clip) + return null; + var end = getValue(map, "end", null); + if (end != null) { + var slot = skeletonData.findSlot(end); + if (slot == null) + throw new Error("Clipping end slot not found: " + end); + clip.endSlot = slot; + } + var vertexCount = map.vertexCount; + this.readVertices(map, clip, vertexCount << 1); + var color = getValue(map, "color", null); + if (color) + clip.color.setFromString(color); + return clip; + } + } + return null; + }; + SkeletonJson.prototype.readSequence = function (map) { + if (map == null) + return null; + var sequence = new Sequence(getValue(map, "count", 0)); + sequence.start = getValue(map, "start", 1); + sequence.digits = getValue(map, "digits", 0); + sequence.setupIndex = getValue(map, "setup", 0); + return sequence; + }; + SkeletonJson.prototype.readVertices = function (map, attachment, verticesLength) { + var scale = this.scale; + attachment.worldVerticesLength = verticesLength; + var vertices = map.vertices; + if (verticesLength == vertices.length) { + var scaledVertices = Utils.toFloatArray(vertices); + if (scale != 1) { + for (var i = 0, n = vertices.length; i < n; i++) + scaledVertices[i] *= scale; + } + attachment.vertices = scaledVertices; + return; + } + var weights = new Array(); + var bones = new Array(); + for (var i = 0, n = vertices.length; i < n;) { + var boneCount = vertices[i++]; + bones.push(boneCount); + for (var nn = i + boneCount * 4; i < nn; i += 4) { + bones.push(vertices[i]); + weights.push(vertices[i + 1] * scale); + weights.push(vertices[i + 2] * scale); + weights.push(vertices[i + 3]); + } + } + attachment.bones = bones; + attachment.vertices = Utils.toFloatArray(weights); + }; + SkeletonJson.prototype.readAnimation = function (map, name, skeletonData) { + var scale = this.scale; + var timelines = new Array(); + // Slot timelines. + if (map.slots) { + for (var slotName in map.slots) { + var slotMap = map.slots[slotName]; + var slot = skeletonData.findSlot(slotName); + if (!slot) + throw new Error("Slot not found: " + slotName); + var slotIndex = slot.index; + for (var timelineName in slotMap) { + var timelineMap = slotMap[timelineName]; + if (!timelineMap) + continue; + var frames_1 = timelineMap.length; + if (timelineName == "attachment") { + var timeline = new AttachmentTimeline(frames_1, slotIndex); + for (var frame = 0; frame < frames_1; frame++) { + var keyMap = timelineMap[frame]; + timeline.setFrame(frame, getValue(keyMap, "time", 0), getValue(keyMap, "name", null)); + } + timelines.push(timeline); + } + else if (timelineName == "rgba") { + var timeline = new RGBATimeline(frames_1, frames_1 << 2, slotIndex); + var keyMap = timelineMap[0]; + var time = getValue(keyMap, "time", 0); + var color = Color.fromString(keyMap.color); + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b, color.a); + var nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + var time2 = getValue(nextMap, "time", 0); + var newColor = Color.fromString(nextMap.color); + var curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1); + } + time = time2; + color = newColor; + keyMap = nextMap; + } + timelines.push(timeline); + } + else if (timelineName == "rgb") { + var timeline = new RGBTimeline(frames_1, frames_1 * 3, slotIndex); + var keyMap = timelineMap[0]; + var time = getValue(keyMap, "time", 0); + var color = Color.fromString(keyMap.color); + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b); + var nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + var time2 = getValue(nextMap, "time", 0); + var newColor = Color.fromString(nextMap.color); + var curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + } + time = time2; + color = newColor; + keyMap = nextMap; + } + timelines.push(timeline); + } + else if (timelineName == "alpha") { + timelines.push(readTimeline1(timelineMap, new AlphaTimeline(frames_1, frames_1, slotIndex), 0, 1)); + } + else if (timelineName == "rgba2") { + var timeline = new RGBA2Timeline(frames_1, frames_1 * 7, slotIndex); + var keyMap = timelineMap[0]; + var time = getValue(keyMap, "time", 0); + var color = Color.fromString(keyMap.light); + var color2 = Color.fromString(keyMap.dark); + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b, color.a, color2.r, color2.g, color2.b); + var nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + var time2 = getValue(nextMap, "time", 0); + var newColor = Color.fromString(nextMap.light); + var newColor2 = Color.fromString(nextMap.dark); + var curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1); + bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.r, newColor2.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.g, newColor2.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 6, time, time2, color2.b, newColor2.b, 1); + } + time = time2; + color = newColor; + color2 = newColor2; + keyMap = nextMap; + } + timelines.push(timeline); + } + else if (timelineName == "rgb2") { + var timeline = new RGB2Timeline(frames_1, frames_1 * 6, slotIndex); + var keyMap = timelineMap[0]; + var time = getValue(keyMap, "time", 0); + var color = Color.fromString(keyMap.light); + var color2 = Color.fromString(keyMap.dark); + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b, color2.r, color2.g, color2.b); + var nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + var time2 = getValue(nextMap, "time", 0); + var newColor = Color.fromString(nextMap.light); + var newColor2 = Color.fromString(nextMap.dark); + var curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color2.r, newColor2.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.g, newColor2.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.b, newColor2.b, 1); + } + time = time2; + color = newColor; + color2 = newColor2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + } + } + // Bone timelines. + if (map.bones) { + for (var boneName in map.bones) { + var boneMap = map.bones[boneName]; + var bone = skeletonData.findBone(boneName); + if (!bone) + throw new Error("Bone not found: " + boneName); + var boneIndex = bone.index; + for (var timelineName in boneMap) { + var timelineMap = boneMap[timelineName]; + var frames_2 = timelineMap.length; + if (frames_2 == 0) + continue; + if (timelineName === "rotate") { + timelines.push(readTimeline1(timelineMap, new RotateTimeline(frames_2, frames_2, boneIndex), 0, 1)); + } + else if (timelineName === "translate") { + var timeline = new TranslateTimeline(frames_2, frames_2 << 1, boneIndex); + timelines.push(readTimeline2(timelineMap, timeline, "x", "y", 0, scale)); + } + else if (timelineName === "translatex") { + var timeline = new TranslateXTimeline(frames_2, frames_2, boneIndex); + timelines.push(readTimeline1(timelineMap, timeline, 0, scale)); + } + else if (timelineName === "translatey") { + var timeline = new TranslateYTimeline(frames_2, frames_2, boneIndex); + timelines.push(readTimeline1(timelineMap, timeline, 0, scale)); + } + else if (timelineName === "scale") { + var timeline = new ScaleTimeline(frames_2, frames_2 << 1, boneIndex); + timelines.push(readTimeline2(timelineMap, timeline, "x", "y", 1, 1)); + } + else if (timelineName === "scalex") { + var timeline = new ScaleXTimeline(frames_2, frames_2, boneIndex); + timelines.push(readTimeline1(timelineMap, timeline, 1, 1)); + } + else if (timelineName === "scaley") { + var timeline = new ScaleYTimeline(frames_2, frames_2, boneIndex); + timelines.push(readTimeline1(timelineMap, timeline, 1, 1)); + } + else if (timelineName === "shear") { + var timeline = new ShearTimeline(frames_2, frames_2 << 1, boneIndex); + timelines.push(readTimeline2(timelineMap, timeline, "x", "y", 0, 1)); + } + else if (timelineName === "shearx") { + var timeline = new ShearXTimeline(frames_2, frames_2, boneIndex); + timelines.push(readTimeline1(timelineMap, timeline, 0, 1)); + } + else if (timelineName === "sheary") { + var timeline = new ShearYTimeline(frames_2, frames_2, boneIndex); + timelines.push(readTimeline1(timelineMap, timeline, 0, 1)); + } + } + } + } + // IK constraint timelines. + if (map.ik) { + for (var constraintName in map.ik) { + var constraintMap = map.ik[constraintName]; + var keyMap = constraintMap[0]; + if (!keyMap) + continue; + var constraint = skeletonData.findIkConstraint(constraintName); + if (!constraint) + throw new Error("IK Constraint not found: " + constraintName); + var constraintIndex = skeletonData.ikConstraints.indexOf(constraint); + var timeline = new IkConstraintTimeline(constraintMap.length, constraintMap.length << 1, constraintIndex); + var time = getValue(keyMap, "time", 0); + var mix = getValue(keyMap, "mix", 1); + var softness = getValue(keyMap, "softness", 0) * scale; + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, mix, softness, getValue(keyMap, "bendPositive", true) ? 1 : -1, getValue(keyMap, "compress", false), getValue(keyMap, "stretch", false)); + var nextMap = constraintMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + var time2 = getValue(nextMap, "time", 0); + var mix2 = getValue(nextMap, "mix", 1); + var softness2 = getValue(nextMap, "softness", 0) * scale; + var curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mix, mix2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, softness, softness2, scale); + } + time = time2; + mix = mix2; + softness = softness2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + // Transform constraint timelines. + if (map.transform) { + for (var constraintName in map.transform) { + var timelineMap = map.transform[constraintName]; + var keyMap = timelineMap[0]; + if (!keyMap) + continue; + var constraint = skeletonData.findTransformConstraint(constraintName); + if (!constraint) + throw new Error("Transform constraint not found: " + constraintName); + var constraintIndex = skeletonData.transformConstraints.indexOf(constraint); + var timeline = new TransformConstraintTimeline(timelineMap.length, timelineMap.length * 6, constraintIndex); + var time = getValue(keyMap, "time", 0); + var mixRotate = getValue(keyMap, "mixRotate", 1); + var mixX = getValue(keyMap, "mixX", 1); + var mixY = getValue(keyMap, "mixY", mixX); + var mixScaleX = getValue(keyMap, "mixScaleX", 1); + var mixScaleY = getValue(keyMap, "mixScaleY", mixScaleX); + var mixShearY = getValue(keyMap, "mixShearY", 1); + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY); + var nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + var time2 = getValue(nextMap, "time", 0); + var mixRotate2 = getValue(nextMap, "mixRotate", 1); + var mixX2 = getValue(nextMap, "mixX", 1); + var mixY2 = getValue(nextMap, "mixY", mixX2); + var mixScaleX2 = getValue(nextMap, "mixScaleX", 1); + var mixScaleY2 = getValue(nextMap, "mixScaleY", mixScaleX2); + var mixShearY2 = getValue(nextMap, "mixShearY", 1); + var curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, mixScaleX, mixScaleX2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, mixScaleY, mixScaleY2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, mixShearY, mixShearY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + mixScaleX = mixScaleX2; + mixScaleY = mixScaleY2; + mixScaleX = mixScaleX2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + // Path constraint timelines. + if (map.path) { + for (var constraintName in map.path) { + var constraintMap = map.path[constraintName]; + var constraint = skeletonData.findPathConstraint(constraintName); + if (!constraint) + throw new Error("Path constraint not found: " + constraintName); + var constraintIndex = skeletonData.pathConstraints.indexOf(constraint); + for (var timelineName in constraintMap) { + var timelineMap = constraintMap[timelineName]; + var keyMap = timelineMap[0]; + if (!keyMap) + continue; + var frames_3 = timelineMap.length; + if (timelineName === "position") { + var timeline = new PathConstraintPositionTimeline(frames_3, frames_3, constraintIndex); + timelines.push(readTimeline1(timelineMap, timeline, 0, constraint.positionMode == exports.PositionMode.Fixed ? scale : 1)); + } + else if (timelineName === "spacing") { + var timeline = new PathConstraintSpacingTimeline(frames_3, frames_3, constraintIndex); + timelines.push(readTimeline1(timelineMap, timeline, 0, constraint.spacingMode == SpacingMode.Length || constraint.spacingMode == SpacingMode.Fixed ? scale : 1)); + } + else if (timelineName === "mix") { + var timeline = new PathConstraintMixTimeline(frames_3, frames_3 * 3, constraintIndex); + var time = getValue(keyMap, "time", 0); + var mixRotate = getValue(keyMap, "mixRotate", 1); + var mixX = getValue(keyMap, "mixX", 1); + var mixY = getValue(keyMap, "mixY", mixX); + for (var frame = 0, bezier = 0;; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY); + var nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + var time2 = getValue(nextMap, "time", 0); + var mixRotate2 = getValue(nextMap, "mixRotate", 1); + var mixX2 = getValue(nextMap, "mixX", 1); + var mixY2 = getValue(nextMap, "mixY", mixX2); + var curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + } + } + // ver40 compatibility + if (map.deform) { + map.attachments = {}; + for (var deformName in map.deform) { + var deformMap = map.deform[deformName]; + var outMap = map.attachments[deformName] = {}; + for (var slotName in deformMap) { + var slotMap = deformMap[slotName]; + var outMap2 = outMap[slotName] = {}; + for (var innerMapName in slotMap) { + outMap2[innerMapName] = { + deform: slotMap[innerMapName] + }; + } + } + } + } + // Attachment timelines. + if (map.attachments) { + for (var attachmentsName in map.attachments) { + var attachmentsMap = map.attachments[attachmentsName]; + var skin = skeletonData.findSkin(attachmentsName); + if (skin == null) { + if (settings.FAIL_ON_NON_EXISTING_SKIN) { + throw new Error("Skin not found: " + attachmentsName); + } + else { + continue; + } + } + for (var slotMapName in attachmentsMap) { + var slotMap = attachmentsMap[slotMapName]; + var slot = skeletonData.findSlot(slotMapName); + if (!slot) + throw new Error("Slot not found: " + slotMapName); + var slotIndex = slot.index; + for (var attachmentMapName in slotMap) { + var attachmentMap = slotMap[attachmentMapName]; + var attachment = skin.getAttachment(slotIndex, attachmentMapName); + for (var timelineMapName in attachmentMap) { + var timelineMap = attachmentMap[timelineMapName]; + var keyMap = timelineMap[0]; + if (!keyMap) + continue; + if (timelineMapName == "deform") { + var weighted = attachment.bones; + var vertices = attachment.vertices; + var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + var timeline = new DeformTimeline(timelineMap.length, timelineMap.length, slotIndex, attachment); + var time = getValue(keyMap, "time", 0); + for (var frame = 0, bezier = 0;; frame++) { + var deform = void 0; + var verticesValue = getValue(keyMap, "vertices", null); + if (!verticesValue) + deform = weighted ? Utils.newFloatArray(deformLength) : vertices; + else { + deform = Utils.newFloatArray(deformLength); + var start = getValue(keyMap, "offset", 0); + Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); + if (scale != 1) { + for (var i = start, n = i + verticesValue.length; i < n; i++) + deform[i] *= scale; + } + if (!weighted) { + for (var i = 0; i < deformLength; i++) + deform[i] += vertices[i]; + } + } + timeline.setFrame(frame, time, deform); + var nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + var time2 = getValue(nextMap, "time", 0); + var curve = keyMap.curve; + if (curve) + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1); + time = time2; + keyMap = nextMap; + } + timelines.push(timeline); + } + else if (timelineMapName == "sequence") { + var timeline = new SequenceTimeline(timelineMap.length, slotIndex, attachment); + var lastDelay = 0; + for (var frame = 0; frame < timelineMap.length; frame++) { + var delay = getValue(keyMap, "delay", lastDelay); + var time = getValue(keyMap, "time", 0); + var mode = SequenceMode[getValue(keyMap, "mode", "hold")]; + var index = getValue(keyMap, "index", 0); + timeline.setFrame(frame, time, mode, index, delay); + lastDelay = delay; + keyMap = timelineMap[frame + 1]; + } + timelines.push(timeline); + } + } + } + } + } + } + // Draw order timelines. + if (map.drawOrder) { + var timeline = new DrawOrderTimeline(map.drawOrder.length); + var slotCount = skeletonData.slots.length; + var frame = 0; + for (var i = 0; i < map.drawOrder.length; i++, frame++) { + var drawOrderMap = map.drawOrder[i]; + var drawOrder = null; + var offsets = getValue(drawOrderMap, "offsets", null); + if (offsets) { + drawOrder = Utils.newArray(slotCount, -1); + var unchanged = Utils.newArray(slotCount - offsets.length, 0); + var originalIndex = 0, unchangedIndex = 0; + for (var ii = 0; ii < offsets.length; ii++) { + var offsetMap = offsets[ii]; + var slot = skeletonData.findSlot(offsetMap.slot); + if (!slot) + throw new Error("Slot not found: " + slot); + var slotIndex = slot.index; + // Collect unchanged items. + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + // Set changed items. + drawOrder[originalIndex + offsetMap.offset] = originalIndex++; + } + // Collect remaining unchanged items. + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + // Fill in unchanged items. + for (var ii = slotCount - 1; ii >= 0; ii--) + if (drawOrder[ii] == -1) + drawOrder[ii] = unchanged[--unchangedIndex]; + } + timeline.setFrame(frame, getValue(drawOrderMap, "time", 0), drawOrder); + } + timelines.push(timeline); + } + // Event timelines. + if (map.events) { + var timeline = new EventTimeline(map.events.length); + var frame = 0; + for (var i = 0; i < map.events.length; i++, frame++) { + var eventMap = map.events[i]; + var eventData = skeletonData.findEvent(eventMap.name); + if (!eventData) + throw new Error("Event not found: " + eventMap.name); + var event_1 = new Event(Utils.toSinglePrecision(getValue(eventMap, "time", 0)), eventData); + event_1.intValue = getValue(eventMap, "int", eventData.intValue); + event_1.floatValue = getValue(eventMap, "float", eventData.floatValue); + event_1.stringValue = getValue(eventMap, "string", eventData.stringValue); + if (event_1.data.audioPath) { + event_1.volume = getValue(eventMap, "volume", 1); + event_1.balance = getValue(eventMap, "balance", 0); + } + timeline.setFrame(frame, event_1); + } + timelines.push(timeline); + } + var duration = 0; + for (var i = 0, n = timelines.length; i < n; i++) + duration = Math.max(duration, timelines[i].getDuration()); + if (isNaN(duration)) { + throw new Error("Error while parsing animation, duration is NaN"); + } + skeletonData.animations.push(new Animation(name, timelines, duration)); + }; + SkeletonJson.blendModeFromString = function (str) { + str = str.toLowerCase(); + if (str == "normal") + return constants.BLEND_MODES.NORMAL; + if (str == "additive") + return constants.BLEND_MODES.ADD; + if (str == "multiply") + return constants.BLEND_MODES.MULTIPLY; + if (str == "screen") + return constants.BLEND_MODES.SCREEN; + throw new Error("Unknown blend mode: " + str); + }; + return SkeletonJson; + }()); + var LinkedMesh = /** @class */ (function () { + function LinkedMesh(mesh, skin, slotIndex, parent, inheritDeform) { + this.mesh = mesh; + this.skin = skin; + this.slotIndex = slotIndex; + this.parent = parent; + this.inheritTimeline = inheritDeform; + } + return LinkedMesh; + }()); + function readTimeline1(keys, timeline, defaultValue, scale) { + var keyMap = keys[0]; + var time = getValue(keyMap, "time", 0); + var value = getValue(keyMap, "value", defaultValue) * scale; + var bezier = 0; + for (var frame = 0;; frame++) { + timeline.setFrame(frame, time, value); + var nextMap = keys[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + return timeline; + } + var time2 = getValue(nextMap, "time", 0); + var value2 = getValue(nextMap, "value", defaultValue) * scale; + if (keyMap.curve) + bezier = readCurve(keyMap.curve, timeline, bezier, frame, 0, time, time2, value, value2, scale); + time = time2; + value = value2; + keyMap = nextMap; + } + } + function readTimeline2(keys, timeline, name1, name2, defaultValue, scale) { + var keyMap = keys[0]; + var time = getValue(keyMap, "time", 0); + var value1 = getValue(keyMap, name1, defaultValue) * scale; + var value2 = getValue(keyMap, name2, defaultValue) * scale; + var bezier = 0; + for (var frame = 0;; frame++) { + timeline.setFrame(frame, time, value1, value2); + var nextMap = keys[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + return timeline; + } + var time2 = getValue(nextMap, "time", 0); + var nvalue1 = getValue(nextMap, name1, defaultValue) * scale; + var nvalue2 = getValue(nextMap, name2, defaultValue) * scale; + var curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value1, nvalue1, scale); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, value2, nvalue2, scale); + } + time = time2; + value1 = nvalue1; + value2 = nvalue2; + keyMap = nextMap; + } + } + function readCurve(curve, timeline, bezier, frame, value, time1, time2, value1, value2, scale) { + if (curve == "stepped") { + timeline.setStepped(frame); + return bezier; + } + var i = value << 2; + var cx1 = curve[i]; + var cy1 = curve[i + 1] * scale; + var cx2 = curve[i + 2]; + var cy2 = curve[i + 3] * scale; + timeline.setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2); + return bezier + 1; + } + function getValue(map, property, defaultValue) { + return map[property] !== undefined ? map[property] : defaultValue; + } + + /** + * @public + */ + var Spine$1 = /** @class */ (function (_super) { + __extends$1(Spine, _super); + function Spine() { + return _super !== null && _super.apply(this, arguments) || this; + } + Spine.prototype.createSkeleton = function (spineData) { + this.skeleton = new Skeleton(spineData); + this.skeleton.updateWorldTransform(); + this.stateData = new AnimationStateData(spineData); + this.state = new AnimationState(this.stateData); + }; + return Spine; + }(SpineBase)); + + var spine41 = /*#__PURE__*/Object.freeze({ + __proto__: null, + AlphaTimeline: AlphaTimeline, + Animation: Animation, + AnimationState: AnimationState, + AnimationStateAdapter: AnimationStateAdapter, + AnimationStateData: AnimationStateData, + AtlasAttachmentLoader: AtlasAttachmentLoader, + Attachment: Attachment, + AttachmentTimeline: AttachmentTimeline, + Bone: Bone, + BoneData: BoneData, + BoundingBoxAttachment: BoundingBoxAttachment, + ClippingAttachment: ClippingAttachment, + ConstraintData: ConstraintData, + CurveTimeline: CurveTimeline, + CurveTimeline1: CurveTimeline1, + CurveTimeline2: CurveTimeline2, + DeformTimeline: DeformTimeline, + DrawOrderTimeline: DrawOrderTimeline, + Event: Event, + EventData: EventData, + EventQueue: EventQueue, + EventTimeline: EventTimeline, + get EventType () { return EventType; }, + IkConstraint: IkConstraint, + IkConstraintData: IkConstraintData, + IkConstraintTimeline: IkConstraintTimeline, + MeshAttachment: MeshAttachment, + PathAttachment: PathAttachment, + PathConstraint: PathConstraint, + PathConstraintData: PathConstraintData, + PathConstraintMixTimeline: PathConstraintMixTimeline, + PathConstraintPositionTimeline: PathConstraintPositionTimeline, + PathConstraintSpacingTimeline: PathConstraintSpacingTimeline, + PointAttachment: PointAttachment, + RGB2Timeline: RGB2Timeline, + RGBA2Timeline: RGBA2Timeline, + RGBATimeline: RGBATimeline, + RGBTimeline: RGBTimeline, + RegionAttachment: RegionAttachment, + RotateTimeline: RotateTimeline, + ScaleTimeline: ScaleTimeline, + ScaleXTimeline: ScaleXTimeline, + ScaleYTimeline: ScaleYTimeline, + Sequence: Sequence, + get SequenceMode () { return SequenceMode; }, + SequenceModeValues: SequenceModeValues, + SequenceTimeline: SequenceTimeline, + ShearTimeline: ShearTimeline, + ShearXTimeline: ShearXTimeline, + ShearYTimeline: ShearYTimeline, + Skeleton: Skeleton, + SkeletonBinary: SkeletonBinary, + SkeletonBounds: SkeletonBounds, + SkeletonData: SkeletonData, + SkeletonJson: SkeletonJson, + Skin: Skin, + SkinEntry: SkinEntry, + Slot: Slot, + SlotData: SlotData, + get SpacingMode () { return SpacingMode; }, + Spine: Spine$1, + Timeline: Timeline, + TrackEntry: TrackEntry, + TransformConstraint: TransformConstraint, + TransformConstraintData: TransformConstraintData, + TransformConstraintTimeline: TransformConstraintTimeline, + TranslateTimeline: TranslateTimeline, + TranslateXTimeline: TranslateXTimeline, + TranslateYTimeline: TranslateYTimeline, + VertexAttachment: VertexAttachment + }); + + /* eslint-disable */ + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + + function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + + /** + * @public + */ + var SPINE_VERSION; + (function (SPINE_VERSION) { + SPINE_VERSION[SPINE_VERSION["UNKNOWN"] = 0] = "UNKNOWN"; + SPINE_VERSION[SPINE_VERSION["VER37"] = 37] = "VER37"; + SPINE_VERSION[SPINE_VERSION["VER38"] = 38] = "VER38"; + SPINE_VERSION[SPINE_VERSION["VER40"] = 40] = "VER40"; + SPINE_VERSION[SPINE_VERSION["VER41"] = 41] = "VER41"; + })(SPINE_VERSION || (SPINE_VERSION = {})); + /** + * @public + */ + function detectSpineVersion(version) { + var ver3 = version.substr(0, 3); + var verNum = Math.floor(+ver3 * 10 + 1e-3); + if (ver3 === '3.7') { + return SPINE_VERSION.VER37; + } + if (ver3 === '3.8') { + return SPINE_VERSION.VER38; + } + if (ver3 === '4.0') { + return SPINE_VERSION.VER40; + } + if (ver3 === '4.1') { + return SPINE_VERSION.VER41; + } + // try parse old versions with 3.7 + if (verNum < SPINE_VERSION.VER37) { + return SPINE_VERSION.VER37; + } + return SPINE_VERSION.UNKNOWN; + } + + var UniBinaryParser = /** @class */ (function () { + function UniBinaryParser() { + this.scale = 1; + } + UniBinaryParser.prototype.readSkeletonData = function (atlas, dataToParse) { + var parser = null; + var version = this.readVersionOldFormat(dataToParse); + var ver = detectSpineVersion(version); + if (ver === SPINE_VERSION.VER38) { + parser = new SkeletonBinary$1(new AtlasAttachmentLoader$2(atlas)); + } + version = this.readVersionNewFormat(dataToParse); + ver = detectSpineVersion(version); + if (ver === SPINE_VERSION.VER40 || ver === SPINE_VERSION.VER41) { + parser = new SkeletonBinary(new AtlasAttachmentLoader(atlas)); + } + if (!parser) { + var error = "Unsupported version of spine model " + version + ", please update pixi-spine"; + console.error(error); + } + parser.scale = this.scale; + return parser.readSkeletonData(dataToParse); + }; + UniBinaryParser.prototype.readVersionOldFormat = function (dataToParse) { + var input = new BinaryInput(dataToParse); + var version; + try { + input.readString(); + version = input.readString(); + } + catch (e) { + version = ""; + } + return version || ""; + }; + UniBinaryParser.prototype.readVersionNewFormat = function (dataToParse) { + var input = new BinaryInput(dataToParse); + input.readInt32(); + input.readInt32(); + var version; + try { + version = input.readString(); + } + catch (e) { + version = ""; + } + return version || ""; + }; + return UniBinaryParser; + }()); + var UniJsonParser = /** @class */ (function () { + function UniJsonParser() { + this.scale = 1; + } + UniJsonParser.prototype.readSkeletonData = function (atlas, dataToParse) { + var version = dataToParse.skeleton.spine; + var ver = detectSpineVersion(version); + var parser = null; + if (ver === SPINE_VERSION.VER37) { + parser = new SkeletonJson$1(new AtlasAttachmentLoader$1(atlas)); + } + if (ver === SPINE_VERSION.VER38) { + parser = new SkeletonJson$2(new AtlasAttachmentLoader$2(atlas)); + } + if (ver === SPINE_VERSION.VER40 || ver === SPINE_VERSION.VER41) { + parser = new SkeletonJson(new AtlasAttachmentLoader(atlas)); + } + if (!parser) { + var error = "Unsupported version of spine model " + version + ", please update pixi-spine"; + console.error(error); + } + parser.scale = this.scale; + return parser.readSkeletonData(dataToParse); + }; + return UniJsonParser; + }()); + /** + * @public + */ + var SpineParser = /** @class */ (function (_super) { + __extends(SpineParser, _super); + function SpineParser() { + return _super !== null && _super.apply(this, arguments) || this; + } + SpineParser.prototype.createBinaryParser = function () { + return new UniBinaryParser(); + }; + SpineParser.prototype.createJsonParser = function () { + return new UniJsonParser(); + }; + SpineParser.prototype.parseData = function (resource, parser, atlas, dataToParse) { + var parserCast = parser; + resource.spineData = parserCast.readSkeletonData(atlas, dataToParse); + resource.spineAtlas = atlas; + }; + SpineParser.registerLoaderPlugin = function () { + loaders.Loader.registerPlugin(SpineParser); + }; + SpineParser.use = new SpineParser().genMiddleware().use; + return SpineParser; + }(AbstractSpineParser)); + + /** + * @public + */ + var Spine = /** @class */ (function (_super) { + __extends(Spine, _super); + function Spine() { + return _super !== null && _super.apply(this, arguments) || this; + } + Spine.prototype.createSkeleton = function (spineData) { + var ver = detectSpineVersion(spineData.version); + var spine = null; + if (ver === SPINE_VERSION.VER37) { + spine = spine37; + } + if (ver === SPINE_VERSION.VER38) { + spine = spine38; + } + if (ver === SPINE_VERSION.VER40 || ver === SPINE_VERSION.VER41) { + spine = spine41; + } + if (!spine) { + var error = "Cant detect version of spine model " + spineData.version; + console.error(error); + } + this.skeleton = new spine.Skeleton(spineData); + this.skeleton.updateWorldTransform(); + this.stateData = new spine.AnimationStateData(spineData); + this.state = new spine.AnimationState(this.stateData); + }; + return Spine; + }(SpineBase)); + + SpineParser.registerLoaderPlugin(); + + exports.BinaryInput = BinaryInput; + exports.Color = Color; + exports.DebugUtils = DebugUtils; + exports.IntSet = IntSet; + exports.Interpolation = Interpolation; + exports.MathUtils = MathUtils; + exports.Pool = Pool; + exports.Pow = Pow; + exports.PowOut = PowOut; + exports.SkeletonBounds = SkeletonBounds; + exports.SkeletonBoundsBase = SkeletonBoundsBase; + exports.Spine = Spine; + exports.SpineBase = SpineBase; + exports.SpineDebugRenderer = SpineDebugRenderer; + exports.SpineMesh = SpineMesh; + exports.SpineParser = SpineParser; + exports.SpineSprite = SpineSprite; + exports.StringSet = StringSet; + exports.TextureAtlas = TextureAtlas; + exports.TextureAtlasPage = TextureAtlasPage; + exports.TextureAtlasRegion = TextureAtlasRegion; + exports.TextureRegion = TextureRegion; + exports.TimeKeeper = TimeKeeper; + exports.Utils = Utils; + exports.Vector2 = Vector2; + exports.WindowedMean = WindowedMean; + exports.filterFromString = filterFromString; + exports.settings = settings; + exports.wrapFromString = wrapFromString; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); +if (typeof pixi_spine !== 'undefined') { Object.assign(this.PIXI.spine, pixi_spine); } +var GlobalPIXIModule = Object.assign(GlobalPIXIModule || {}, { PIXI_SPINE: this.PIXI.spine }); +//# sourceMappingURL=pixi-spine.umd.js.map diff --git a/GDJS/Runtime/runtimegame.ts b/GDJS/Runtime/runtimegame.ts index f31e4c68ac98..6e7cb86c68fe 100644 --- a/GDJS/Runtime/runtimegame.ts +++ b/GDJS/Runtime/runtimegame.ts @@ -140,6 +140,7 @@ namespace gdjs { _soundManager: SoundManager; _fontManager: FontManager; _jsonManager: JsonManager; + _textManager: TextManager; _model3DManager: Model3DManager; _effectsManager: EffectsManager; _bitmapFontManager: BitmapFontManager; @@ -227,6 +228,10 @@ namespace gdjs { this._data.resources.resources, this._resourcesLoader ); + this._textManager = new gdjs.TextManager( + this._data.resources.resources, + this._resourcesLoader + ) this._bitmapFontManager = new gdjs.BitmapFontManager( this._data.resources.resources, this._resourcesLoader, @@ -312,13 +317,18 @@ namespace gdjs { * @param projectData The object (usually stored in data.json) containing the full project data */ setProjectData(projectData: ProjectData): void { + const { resources } = projectData.resources; + this._data = projectData; - this._imageManager.setResources(this._data.resources.resources); - this._soundManager.setResources(this._data.resources.resources); - this._fontManager.setResources(this._data.resources.resources); - this._jsonManager.setResources(this._data.resources.resources); - this._bitmapFontManager.setResources(this._data.resources.resources); - this._model3DManager.setResources(this._data.resources.resources); + [ + this._imageManager, + this._soundManager, + this._fontManager, + this._jsonManager, + this._textManager, + this._bitmapFontManager, + this._model3DManager, + ].forEach((manager) => manager.setResources(resources)); } /** @@ -392,6 +402,15 @@ namespace gdjs { return this._jsonManager; } + /** + * Get the text manager of the game, used to load text from game + * resources. + * @return The text manager for the game + */ + getTextManager(): gdjs.TextManager { + return this._textManager; + } + /** * Get the 3D model manager of the game, used to load 3D model from game * resources. @@ -759,9 +778,9 @@ namespace gdjs { } }, function (model3DTotalCount) { - that._bitmapFontManager - .loadBitmapFontData((count) => { - var percent = Math.floor( + that._textManager.preload( + function (count, total) { + const percent = Math.floor( ((texturesTotalCount + audioTotalCount + fontTotalCount + @@ -772,15 +791,36 @@ namespace gdjs { 100 ); loadingScreen.setPercent(percent); - if (progressCallback) progressCallback(percent); - }) - .then(() => loadingScreen.unload()) - .then(() => - gdjs.getAllAsynchronouslyLoadingLibraryPromise() - ) - .then(() => { - callback(); - }); + if (progressCallback) { + progressCallback(percent); + } + }, + function (textsTotalCount) { + that._bitmapFontManager + .loadBitmapFontData((count) => { + var percent = Math.floor( + ((texturesTotalCount + + audioTotalCount + + fontTotalCount + + jsonTotalCount + + model3DTotalCount + + textsTotalCount + + count) / + allAssetsTotal) * + 100 + ); + loadingScreen.setPercent(percent); + if (progressCallback) progressCallback(percent); + }) + .then(() => loadingScreen.unload()) + .then(() => + gdjs.getAllAsynchronouslyLoadingLibraryPromise() + ) + .then(() => { + callback(); + }); + } + ) } ); } diff --git a/GDJS/Runtime/textmanager.ts b/GDJS/Runtime/textmanager.ts new file mode 100644 index 000000000000..5a254cf5159e --- /dev/null +++ b/GDJS/Runtime/textmanager.ts @@ -0,0 +1,169 @@ +/* + * GDevelop JS Platform + * Copyright 2013-present Florian Rival (Florian.Rival@gmail.com). All rights reserved. + * This project is released under the MIT License. + */ +namespace gdjs { + const logger = new gdjs.Logger('Text Manager'); + type TextManagerOnProgressCallback = ( + loadedCount: integer, + totalCount: integer + ) => void; + type TextManagerOnCompleteCallback = (totalCount: integer) => void; + + /** The callback called when a text that was requested is loaded (or an error occurred). */ + export type TextManagerRequestCallback = ( + error: Error | null, + content: Object | null + ) => void; + + const textKinds: ReadonlyArray = ['atlas']; + const isTextResource = (resource: ResourceData) => textKinds.includes(resource.kind); + + /** + * TextManager loads text files (using `XMLHttpRequest`), using the "atlas" resources + * registered in the game resources. + * + * Contrary to audio/fonts, text files are loaded asynchronously, when requested. + * You should properly handle errors, and give the developer/player a way to know + * that loading failed. + */ + export class TextManager { + _resourcesLoader: RuntimeGameResourcesLoader; + _resources: ResourceData[]; + + _loadedTexts: { [key: string]: string } = {}; + _callbacks: { [key: string]: Array } = {}; + + /** + * @param resources The resources data of the game. + * @param resourcesLoader The resources loader of the game. + */ + constructor( + resources: ResourceData[], + resourcesLoader: RuntimeGameResourcesLoader + ) { + this._resources = resources; + this._resourcesLoader = resourcesLoader; + } + + /** + * Update the resources data of the game. Useful for hot-reloading, should not be used otherwise. + * + * @param resources The resources data of the game. + */ + setResources(resources: ResourceData[]): void { + this._resources = resources; + } + + /** + * Request all the text resources to be preloaded (unless they are marked as not preloaded). + * + * Note that even if a text is already loaded, it will be reloaded (useful for hot-reloading, + * as text files can have been modified without the editor knowing). + * + * @param onProgress The function called after each texts is loaded. + * @param onComplete The function called when all texts are loaded. + */ + preload( + onProgress: TextManagerOnProgressCallback, + onComplete: TextManagerOnCompleteCallback + ): void { + const resources = this._resources; + const textResources = resources.filter((resource) => isTextResource(resource) && !resource.disablePreload); + if (!textResources.length) { return onComplete(0); } + let loaded = 0; + + const onLoad: TextManagerRequestCallback = (error) => { + if (error) { + logger.error('Error while preloading a text resource:' + error); + } + if (++loaded === textResources.length) { + onComplete(textResources.length); + } else { + onProgress(loaded, textResources.length); + } + }; + for (let i = 0; i < textResources.length; ++i) { + this.load(textResources[i].name, onLoad); + } + } + + /** + * Request the text file from the given resource name. + * This method is asynchronous. When loaded, the `callback` is called with the error + * (null if none) and the loaded test (a string). + * + * @param resourceName The resource pointing to the json file to load. + * @param callback The callback function called when json is loaded (or an error occurred). + */ + load(resourceName: string, callback: TextManagerRequestCallback): void { + const resource = this._resources.find((resource) => isTextResource(resource) && resource.name === resourceName); + if (!resource) { + return callback(new Error(`Can't find resource with name: "${resourceName}" (or is not a text resource).`), null); + } + + // Don't fetch again an object that is already in memory + if (this.isLoaded(resourceName)) { + return callback(null, this._loadedTexts[resourceName]); + } + + // Don't fetch again an object that is already being fetched. + const callbacks = this._callbacks[resourceName]; + if (callbacks) { + callbacks.push(callback); + return; + } + + this._callbacks[resourceName] = [callback]; + const xhr = new XMLHttpRequest(); + xhr.responseType = 'text'; + xhr.withCredentials = this._resourcesLoader.checkIfCredentialsRequired(resource.file); + xhr.open('GET', this._resourcesLoader.getFullUrl(resource.file)); + xhr.onload = () => { + if (xhr.status !== 200) { + this.callCallback(resourceName, `HTTP error: ${xhr.status} (${xhr.statusText })`, null); + } else { + this._loadedTexts[resourceName] = xhr.response; + this.callCallback(resourceName, null, xhr.response); + } + }; + xhr.onerror = () => this.callCallback(resourceName, 'Network error', null); + xhr.onabort = () => this.callCallback(resourceName, 'Request aborted', null); + xhr.send(); + } + + protected callCallback(resourceName: string, errorMessage: string, text: null): void + protected callCallback(resourceName: string, errorMessage: null, text: string): void + protected callCallback(resourceName: string, errorMessage: string | null, text: string | null): void { + if (!this._callbacks[resourceName]) { return; } + + for (const callback of this._callbacks[resourceName]) { + const error = typeof errorMessage === 'string' ? new Error(errorMessage) : null; + callback(error, text); + } + + delete this._callbacks[resourceName]; + } + + /** + * Check if the given text resource was loaded (preloaded or loaded with `loadText`). + * @param resourceName The name of the text resource. + * @returns true if the content of the text resource is loaded. false otherwise. + */ + isLoaded(resourceName: string): boolean { + return typeof this._loadedTexts[resourceName] === 'string'; + } + + /** + * Get the object for the given resource that is already loaded (preloaded or loaded with `load`). + * If the resource is not loaded, `null` will be returned. + * + * @param resourceName The name of the text resource. + * @returns the content of the text resource, if loaded. `null` otherwise. + */ + get(resourceName: string): string | null { + return this._loadedTexts[resourceName] || null; + } + } +} diff --git a/GDJS/Runtime/types/global-pixi.d.ts b/GDJS/Runtime/types/global-pixi.d.ts index 26720ca2f234..aed690000953 100644 --- a/GDJS/Runtime/types/global-pixi.d.ts +++ b/GDJS/Runtime/types/global-pixi.d.ts @@ -1,4 +1,5 @@ import * as PixiModule from 'pixi.js'; +import * as PixiSpineModule from 'pixi-spine'; declare global { /** @@ -18,5 +19,6 @@ declare global { */ namespace GlobalPIXIModule { export import PIXI = PixiModule; + export import PIXI_SPINE = PixiSpineModule; } } diff --git a/GDJS/package-lock.json b/GDJS/package-lock.json index 0e51fa2149fd..7b387ef585ce 100644 --- a/GDJS/package-lock.json +++ b/GDJS/package-lock.json @@ -29,6 +29,92 @@ "typescript": "4.3.2" } }, + "node_modules/@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", + "dev": true, + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/core": "^6.1.0", + "@pixi/display": "^6.1.0", + "@pixi/graphics": "^6.1.0", + "@pixi/math": "^6.1.0", + "@pixi/mesh": "^6.1.0", + "@pixi/mesh-extras": "^6.1.0", + "@pixi/sprite": "^6.1.0", + "@pixi/utils": "^6.1.0" + } + }, + "node_modules/@pixi-spine/loader-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-base/-/loader-base-3.1.2.tgz", + "integrity": "sha512-llg0RuuWiqVkyoQA+ceORV0sfUtrWGJj4jQ6erDFn2hMnob+QGzh+qwHSTMAnTNZTINEMfiUxmcwbmUYwTd8Ag==", + "dev": true, + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/core": "^6.1.0", + "@pixi/loaders": "^6.1.0" + } + }, + "node_modules/@pixi-spine/loader-uni": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-uni/-/loader-uni-3.1.2.tgz", + "integrity": "sha512-5th9gXqNQWMSuOu3euMw2kHETlncxU7LIFvOYqTMsKnwrOAIsPjHSF/4Sat1d3EAvvdMrYm4LmhHklgrAfk6UA==", + "dev": true, + "dependencies": { + "@pixi-spine/base": "~3.1.2", + "@pixi-spine/loader-base": "~3.1.2", + "@pixi-spine/runtime-3.7": "~3.1.2", + "@pixi-spine/runtime-3.8": "~3.1.2", + "@pixi-spine/runtime-4.1": "~3.1.2" + }, + "peerDependencies": { + "@pixi/loaders": "^6.1.0" + } + }, + "node_modules/@pixi-spine/runtime-3.7": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.7/-/runtime-3.7-3.1.2.tgz", + "integrity": "sha512-dMcw5x9jG+0itzzbPsJUn8hvhxzRXRzbm/kCUQ51iyFfLZQIK1LoPck4XPVuXckwFjU1qCT+tDZSEGBMYs5//A==", + "dev": true, + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/math": "^6.1.0" + } + }, + "node_modules/@pixi-spine/runtime-3.8": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.8/-/runtime-3.8-3.1.2.tgz", + "integrity": "sha512-AgS3mUC+5HQ/ehJO5Wo4oBoLg8F+tssF5WXi3FnnjqOaMcO+Ag232ForoL2iYHW40TKx0xMi5MpXsSafgS1i1A==", + "dev": true, + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/math": "^6.1.0" + } + }, + "node_modules/@pixi-spine/runtime-4.1": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-4.1/-/runtime-4.1-3.1.2.tgz", + "integrity": "sha512-XtaKAuLTtJ3o3llcUTr0d94dnRTyYHlss+x4VsYm1H38r4DUmQTBS13nisW0pgS3fY60D8AbEJkYVW7mwokxag==", + "dev": true, + "dependencies": { + "@pixi-spine/base": "~3.1.2" + }, + "peerDependencies": { + "@pixi/constants": "^6.1.0", + "@pixi/math": "^6.1.0" + } + }, "node_modules/@pixi/accessibility": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-6.1.2.tgz", @@ -1919,6 +2005,62 @@ } }, "dependencies": { + "@pixi-spine/base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/base/-/base-3.1.2.tgz", + "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", + "dev": true, + "requires": {} + }, + "@pixi-spine/loader-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-base/-/loader-base-3.1.2.tgz", + "integrity": "sha512-llg0RuuWiqVkyoQA+ceORV0sfUtrWGJj4jQ6erDFn2hMnob+QGzh+qwHSTMAnTNZTINEMfiUxmcwbmUYwTd8Ag==", + "dev": true, + "requires": { + "@pixi-spine/base": "~3.1.2" + } + }, + "@pixi-spine/loader-uni": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/loader-uni/-/loader-uni-3.1.2.tgz", + "integrity": "sha512-5th9gXqNQWMSuOu3euMw2kHETlncxU7LIFvOYqTMsKnwrOAIsPjHSF/4Sat1d3EAvvdMrYm4LmhHklgrAfk6UA==", + "dev": true, + "requires": { + "@pixi-spine/base": "~3.1.2", + "@pixi-spine/loader-base": "~3.1.2", + "@pixi-spine/runtime-3.7": "~3.1.2", + "@pixi-spine/runtime-3.8": "~3.1.2", + "@pixi-spine/runtime-4.1": "~3.1.2" + } + }, + "@pixi-spine/runtime-3.7": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.7/-/runtime-3.7-3.1.2.tgz", + "integrity": "sha512-dMcw5x9jG+0itzzbPsJUn8hvhxzRXRzbm/kCUQ51iyFfLZQIK1LoPck4XPVuXckwFjU1qCT+tDZSEGBMYs5//A==", + "dev": true, + "requires": { + "@pixi-spine/base": "~3.1.2" + } + }, + "@pixi-spine/runtime-3.8": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.8/-/runtime-3.8-3.1.2.tgz", + "integrity": "sha512-AgS3mUC+5HQ/ehJO5Wo4oBoLg8F+tssF5WXi3FnnjqOaMcO+Ag232ForoL2iYHW40TKx0xMi5MpXsSafgS1i1A==", + "dev": true, + "requires": { + "@pixi-spine/base": "~3.1.2" + } + }, + "@pixi-spine/runtime-4.1": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-4.1/-/runtime-4.1-3.1.2.tgz", + "integrity": "sha512-XtaKAuLTtJ3o3llcUTr0d94dnRTyYHlss+x4VsYm1H38r4DUmQTBS13nisW0pgS3fY60D8AbEJkYVW7mwokxag==", + "dev": true, + "requires": { + "@pixi-spine/base": "~3.1.2" + } + }, "@pixi/accessibility": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-6.1.2.tgz", diff --git a/GDJS/scripts/lib/runtime-files-list.js b/GDJS/scripts/lib/runtime-files-list.js index aae1a610bc86..8568e6d925ae 100644 --- a/GDJS/scripts/lib/runtime-files-list.js +++ b/GDJS/scripts/lib/runtime-files-list.js @@ -23,6 +23,7 @@ const transformExcludedExtensions = ['.min.js', '.d.ts']; const untransformedPaths = [ // GDJS prebuilt files: 'GDJS/Runtime/pixi-renderers/pixi.js', + 'GDJS/Runtime/pixi-renderers/pixi-spine.umd.js', 'GDJS/Runtime/pixi-renderers/three.js', 'GDJS/Runtime/pixi-renderers/ThreeAddons.js', 'GDJS/Runtime/pixi-renderers/draco/gltf/draco_wasm_wrapper.js', diff --git a/GDJS/tests/karma.conf.js b/GDJS/tests/karma.conf.js index e9b964b32041..730b441e7b75 100644 --- a/GDJS/tests/karma.conf.js +++ b/GDJS/tests/karma.conf.js @@ -41,6 +41,7 @@ module.exports = function (config) { './newIDE/app/resources/GDJS/Runtime/AsyncTasksManager.js', './newIDE/app/resources/GDJS/Runtime/libs/rbush.js', './newIDE/app/resources/GDJS/Runtime/pixi-renderers/pixi.js', + './newIDE/app/resources/GDJS/Runtime/pixi-renderers/pixi-spine.umd.js', './newIDE/app/resources/GDJS/Runtime/pixi-renderers/three.js', './newIDE/app/resources/GDJS/Runtime/pixi-renderers/*.js', './newIDE/app/resources/GDJS/Runtime/howler-sound-manager/howler.min.js', @@ -48,6 +49,7 @@ module.exports = function (config) { './newIDE/app/resources/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver.js', './newIDE/app/resources/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js', './newIDE/app/resources/GDJS/Runtime/jsonmanager.js', + './newIDE/app/resources/GDJS/Runtime/textmanager.js', './newIDE/app/resources/GDJS/Runtime/Model3DManager.js', './newIDE/app/resources/GDJS/Runtime/timemanager.js', './newIDE/app/resources/GDJS/Runtime/polygon.js', diff --git a/GDevelop.js/Bindings/Bindings.idl b/GDevelop.js/Bindings/Bindings.idl index 1b61dcc2cef0..c58c420ed51f 100644 --- a/GDevelop.js/Bindings/Bindings.idl +++ b/GDevelop.js/Bindings/Bindings.idl @@ -3063,6 +3063,35 @@ interface Model3DObjectConfiguration { }; Model3DObjectConfiguration implements ObjectConfiguration; + +interface SpineAnimation { + void SpineAnimation(); + + void SetName([Const] DOMString name); + [Const, Ref] DOMString GetName(); + + void SetSource([Const] DOMString name); + [Const, Ref] DOMString GetSource(); + + void SetShouldLoop(boolean shouldLoop); + boolean ShouldLoop(); +}; + +interface SpineObjectConfiguration { + void SpineObjectConfiguration(); + + void AddAnimation([Const, Ref] SpineAnimation animation); + [Ref] SpineAnimation GetAnimation(unsigned long index); + boolean HasAnimationNamed([Const] DOMString name); + unsigned long GetAnimationsCount(); + void RemoveAnimation(unsigned long index); + void RemoveAllAnimations(); + boolean HasNoAnimations(); + void SwapAnimations(unsigned long first, unsigned long second); + void MoveAnimation(unsigned long oldIndex, unsigned long newIndex); +}; +SpineObjectConfiguration implements ObjectConfiguration; + interface Vector2f { void Vector2f(); diff --git a/GDevelop.js/Bindings/Wrapper.cpp b/GDevelop.js/Bindings/Wrapper.cpp index b08c4a424dae..33e9bfdd11d2 100644 --- a/GDevelop.js/Bindings/Wrapper.cpp +++ b/GDevelop.js/Bindings/Wrapper.cpp @@ -103,6 +103,7 @@ #include "../../Extensions/TextObject/TextObject.h" #include "../../Extensions/TiledSpriteObject/TiledSpriteObject.h" #include "../../Extensions/3D/Model3DObjectConfiguration.h" +#include "../../Extensions/Spine/SpineObjectConfiguration.h" #include "BehaviorJsImplementation.h" #include "BehaviorSharedDataJsImplementation.h" #include "ObjectJsImplementation.h" diff --git a/GDevelop.js/Bindings/postjs.js b/GDevelop.js/Bindings/postjs.js index e9cdfd0a69f5..84237da18337 100644 --- a/GDevelop.js/Bindings/postjs.js +++ b/GDevelop.js/Bindings/postjs.js @@ -150,6 +150,9 @@ var adaptNamingConventions = function (gd) { gd.asModel3DConfiguration = function (evt) { return gd.castObject(evt, gd.Model3DObjectConfiguration); }; + gd.asSpineConfiguration = function (evt) { + return gd.castObject(evt, gd.SpineObjectConfiguration); + }; gd.asImageResource = function (evt) { return gd.castObject(evt, gd.ImageResource); diff --git a/GDevelop.js/CMakeLists.txt b/GDevelop.js/CMakeLists.txt index 70d3d148a15b..cc3b00e67c4d 100644 --- a/GDevelop.js/CMakeLists.txt +++ b/GDevelop.js/CMakeLists.txt @@ -100,3 +100,4 @@ target_link_libraries(GD PathfindingBehavior) target_link_libraries(GD PhysicsBehavior) target_link_libraries(GD ParticleSystem) target_link_libraries(GD Scene3D) +target_link_libraries(GD SpineObject) diff --git a/GDevelop.js/scripts/generate-types.js b/GDevelop.js/scripts/generate-types.js index 3b245947940f..bb431cd547e5 100644 --- a/GDevelop.js/scripts/generate-types.js +++ b/GDevelop.js/scripts/generate-types.js @@ -189,6 +189,7 @@ type ParticleEmitterObject_RendererType = 0 | 1 | 2` ` asObjectJsImplementation(gdObjectConfiguration): gdObjectJsImplementation;`, ` asCustomObjectConfiguration(gdObjectConfiguration): gdCustomObjectConfiguration;`, ` asModel3DConfiguration(gdObjectConfiguration): gdModel3DObjectConfiguration;`, + ` asSpineConfiguration(gdObjectConfiguration): gdSpineObjectConfiguration;`, '', ` asImageResource(gdResource): gdImageResource;`, '', diff --git a/GDevelop.js/types/gdspineanimation.js b/GDevelop.js/types/gdspineanimation.js new file mode 100644 index 000000000000..dc0be15cc35e --- /dev/null +++ b/GDevelop.js/types/gdspineanimation.js @@ -0,0 +1,12 @@ +// Automatically generated by GDevelop.js/scripts/generate-types.js +declare class gdSpineAnimation { + constructor(): void; + setName(name: string): void; + getName(): string; + setSource(name: string): void; + getSource(): string; + setShouldLoop(shouldLoop: boolean): void; + shouldLoop(): boolean; + delete(): void; + ptr: number; +}; \ No newline at end of file diff --git a/GDevelop.js/types/gdspineobjectconfiguration.js b/GDevelop.js/types/gdspineobjectconfiguration.js new file mode 100644 index 000000000000..9fa82f9b33ca --- /dev/null +++ b/GDevelop.js/types/gdspineobjectconfiguration.js @@ -0,0 +1,15 @@ +// Automatically generated by GDevelop.js/scripts/generate-types.js +declare class gdSpineObjectConfiguration extends gdObjectConfiguration { + constructor(): void; + addAnimation(animation: gdSpineAnimation): void; + getAnimation(index: number): gdSpineAnimation; + hasAnimationNamed(name: string): boolean; + getAnimationsCount(): number; + removeAnimation(index: number): void; + removeAllAnimations(): void; + hasNoAnimations(): boolean; + swapAnimations(first: number, second: number): void; + moveAnimation(oldIndex: number, newIndex: number): void; + delete(): void; + ptr: number; +}; \ No newline at end of file diff --git a/GDevelop.js/types/libgdevelop.js b/GDevelop.js/types/libgdevelop.js index f8575e6266b6..7ddde7bc5d21 100644 --- a/GDevelop.js/types/libgdevelop.js +++ b/GDevelop.js/types/libgdevelop.js @@ -33,6 +33,7 @@ declare class libGDevelop { asObjectJsImplementation(gdObjectConfiguration): gdObjectJsImplementation; asCustomObjectConfiguration(gdObjectConfiguration): gdCustomObjectConfiguration; asModel3DConfiguration(gdObjectConfiguration): gdModel3DObjectConfiguration; + asSpineConfiguration(gdObjectConfiguration): gdSpineObjectConfiguration; asImageResource(gdResource): gdImageResource; @@ -218,6 +219,8 @@ declare class libGDevelop { SpriteObject: Class; Model3DAnimation: Class; Model3DObjectConfiguration: Class; + SpineAnimation: Class; + SpineObjectConfiguration: Class; Vector2f: Class; VectorVector2f: Class; TextObject: Class; diff --git a/newIDE/app/package-lock.json b/newIDE/app/package-lock.json index 59fa3314106d..050f439a040c 100644 --- a/newIDE/app/package-lock.json +++ b/newIDE/app/package-lock.json @@ -16,6 +16,10 @@ "@material-ui/core": "4.11.0", "@material-ui/icons": "4.9.1", "@material-ui/lab": "4.0.0-alpha.56", + "@pixi/core": "^6.5.10", + "@pixi/display": "^6.5.10", + "@pixi/extensions": "^6.5.10", + "@pixi/utils": "^6.5.10", "@supercharge/promise-pool": "^1.6.0", "algoliasearch": "3.33.0", "axios": "^0.18.1", @@ -30,6 +34,7 @@ "jss-rtl": "^0.3.0", "lodash": "4.17.4", "node-require-function": "^1.2.0", + "path-browserify": "^1.0.1", "pixi-simple-gesture": "github:4ian/pixi-simple-gesture#v0.3.3", "pixi-spine": "^3.0.0", "pixi.js-legacy": "6.1.2", @@ -80,7 +85,6 @@ "iso-639-1": "^2.0.3", "minimist": "1.2.5", "patch-package": "^6.4.7", - "path-browserify": "^1.0.1", "prettier": "1.15.3", "react-scripts": "5.0.1", "recursive-copy": "^2.0.14", @@ -6085,40 +6089,6 @@ "@pixi/utils": "^6.1.0" } }, - "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/core": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", - "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", - "peer": true, - "dependencies": { - "@types/offscreencanvas": "^2019.6.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/pixijs" - }, - "peerDependencies": { - "@pixi/constants": "6.5.10", - "@pixi/extensions": "6.5.10", - "@pixi/math": "6.5.10", - "@pixi/runner": "6.5.10", - "@pixi/settings": "6.5.10", - "@pixi/ticker": "6.5.10", - "@pixi/utils": "6.5.10" - } - }, - "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/display": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", - "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", - "peer": true, - "peerDependencies": { - "@pixi/constants": "6.5.10", - "@pixi/math": "6.5.10", - "@pixi/settings": "6.5.10", - "@pixi/utils": "6.5.10" - } - }, "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/graphics": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", @@ -6160,21 +6130,6 @@ "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/runner": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", - "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", - "peer": true - }, - "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/settings": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", - "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", - "peer": true, - "peerDependencies": { - "@pixi/constants": "6.5.10" - } - }, "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/sprite": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", @@ -6189,38 +6144,6 @@ "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/ticker": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", - "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", - "peer": true, - "peerDependencies": { - "@pixi/extensions": "6.5.10", - "@pixi/settings": "6.5.10" - } - }, - "node_modules/@pixi-spine/runtime-3.7/node_modules/@pixi/utils": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", - "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", - "peer": true, - "dependencies": { - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^3.1.0", - "url": "^0.11.0" - }, - "peerDependencies": { - "@pixi/constants": "6.5.10", - "@pixi/settings": "6.5.10" - } - }, - "node_modules/@pixi-spine/runtime-3.7/node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "peer": true - }, "node_modules/@pixi-spine/runtime-3.8": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-3.8/-/runtime-3.8-3.1.2.tgz", @@ -6249,40 +6172,6 @@ "@pixi/utils": "^6.1.0" } }, - "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/core": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", - "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", - "peer": true, - "dependencies": { - "@types/offscreencanvas": "^2019.6.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/pixijs" - }, - "peerDependencies": { - "@pixi/constants": "6.5.10", - "@pixi/extensions": "6.5.10", - "@pixi/math": "6.5.10", - "@pixi/runner": "6.5.10", - "@pixi/settings": "6.5.10", - "@pixi/ticker": "6.5.10", - "@pixi/utils": "6.5.10" - } - }, - "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/display": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", - "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", - "peer": true, - "peerDependencies": { - "@pixi/constants": "6.5.10", - "@pixi/math": "6.5.10", - "@pixi/settings": "6.5.10", - "@pixi/utils": "6.5.10" - } - }, "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/graphics": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", @@ -6324,21 +6213,6 @@ "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/runner": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", - "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", - "peer": true - }, - "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/settings": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", - "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", - "peer": true, - "peerDependencies": { - "@pixi/constants": "6.5.10" - } - }, "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/sprite": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", @@ -6353,38 +6227,6 @@ "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/ticker": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", - "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", - "peer": true, - "peerDependencies": { - "@pixi/extensions": "6.5.10", - "@pixi/settings": "6.5.10" - } - }, - "node_modules/@pixi-spine/runtime-3.8/node_modules/@pixi/utils": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", - "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", - "peer": true, - "dependencies": { - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^3.1.0", - "url": "^0.11.0" - }, - "peerDependencies": { - "@pixi/constants": "6.5.10", - "@pixi/settings": "6.5.10" - } - }, - "node_modules/@pixi-spine/runtime-3.8/node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "peer": true - }, "node_modules/@pixi-spine/runtime-4.1": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@pixi-spine/runtime-4.1/-/runtime-4.1-3.1.2.tgz", @@ -6413,40 +6255,6 @@ "@pixi/utils": "^6.1.0" } }, - "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/core": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", - "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", - "peer": true, - "dependencies": { - "@types/offscreencanvas": "^2019.6.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/pixijs" - }, - "peerDependencies": { - "@pixi/constants": "6.5.10", - "@pixi/extensions": "6.5.10", - "@pixi/math": "6.5.10", - "@pixi/runner": "6.5.10", - "@pixi/settings": "6.5.10", - "@pixi/ticker": "6.5.10", - "@pixi/utils": "6.5.10" - } - }, - "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/display": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", - "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", - "peer": true, - "peerDependencies": { - "@pixi/constants": "6.5.10", - "@pixi/math": "6.5.10", - "@pixi/settings": "6.5.10", - "@pixi/utils": "6.5.10" - } - }, "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/graphics": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", @@ -6488,21 +6296,6 @@ "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/runner": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", - "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", - "peer": true - }, - "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/settings": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", - "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", - "peer": true, - "peerDependencies": { - "@pixi/constants": "6.5.10" - } - }, "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/sprite": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", @@ -6517,49 +6310,48 @@ "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/ticker": { + "node_modules/@pixi/constants": { "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", - "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", - "peer": true, - "peerDependencies": { - "@pixi/extensions": "6.5.10", - "@pixi/settings": "6.5.10" - } + "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.5.10.tgz", + "integrity": "sha512-PUF2Y9YISRu5eVrVVHhHCWpc/KmxQTg3UH8rIUs8UI9dCK41/wsPd3pEahzf7H47v7x1HCohVZcFO3XQc1bUDw==", + "peer": true }, - "node_modules/@pixi-spine/runtime-4.1/node_modules/@pixi/utils": { + "node_modules/@pixi/core": { "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", - "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", - "peer": true, + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", + "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", "dependencies": { - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^3.1.0", - "url": "^0.11.0" + "@types/offscreencanvas": "^2019.6.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/pixijs" }, "peerDependencies": { "@pixi/constants": "6.5.10", - "@pixi/settings": "6.5.10" + "@pixi/extensions": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/runner": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/ticker": "6.5.10", + "@pixi/utils": "6.5.10" } }, - "node_modules/@pixi-spine/runtime-4.1/node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "peer": true - }, - "node_modules/@pixi/constants": { + "node_modules/@pixi/display": { "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.5.10.tgz", - "integrity": "sha512-PUF2Y9YISRu5eVrVVHhHCWpc/KmxQTg3UH8rIUs8UI9dCK41/wsPd3pEahzf7H47v7x1HCohVZcFO3XQc1bUDw==", - "peer": true + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", + "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/math": "6.5.10", + "@pixi/settings": "6.5.10", + "@pixi/utils": "6.5.10" + } }, "node_modules/@pixi/extensions": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/extensions/-/extensions-6.5.10.tgz", - "integrity": "sha512-EIUGza+E+sCy3dupuIjvRK/WyVyfSzHb5XsxRaxNrPwvG1iIUIqNqZ3owLYCo4h17fJWrj/yXVufNNtUKQccWQ==", - "peer": true + "integrity": "sha512-EIUGza+E+sCy3dupuIjvRK/WyVyfSzHb5XsxRaxNrPwvG1iIUIqNqZ3owLYCo4h17fJWrj/yXVufNNtUKQccWQ==" }, "node_modules/@pixi/math": { "version": "6.5.10", @@ -6576,23 +6368,50 @@ } }, "node_modules/@pixi/runner": { - "version": "6.1.2", - "license": "MIT" + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", + "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", + "peer": true }, "node_modules/@pixi/settings": { - "version": "6.1.2", - "license": "MIT", - "dependencies": { - "ismobilejs": "^1.1.0" + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", + "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", + "peer": true, + "peerDependencies": { + "@pixi/constants": "6.5.10" } }, "node_modules/@pixi/ticker": { - "version": "6.1.2", - "license": "MIT", + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", + "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", + "peer": true, "peerDependencies": { - "@pixi/settings": "6.1.2" + "@pixi/extensions": "6.5.10", + "@pixi/settings": "6.5.10" } }, + "node_modules/@pixi/utils": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", + "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "dependencies": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.4", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + }, + "peerDependencies": { + "@pixi/constants": "6.5.10", + "@pixi/settings": "6.5.10" + } + }, + "node_modules/@pixi/utils/node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", @@ -15962,8 +15781,7 @@ "node_modules/@types/offscreencanvas": { "version": "2019.7.0", "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz", - "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==", - "peer": true + "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==" }, "node_modules/@types/overlayscrollbars": { "version": "1.12.1", @@ -26691,7 +26509,8 @@ }, "node_modules/ismobilejs": { "version": "1.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz", + "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==" }, "node_modules/iso-639-1": { "version": "2.1.4", @@ -34264,8 +34083,7 @@ "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" }, "node_modules/path-dirname": { "version": "1.0.2", @@ -34445,40 +34263,6 @@ "@pixi/loaders": "^6.1.0" } }, - "node_modules/pixi-spine/node_modules/@pixi/core": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", - "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", - "peer": true, - "dependencies": { - "@types/offscreencanvas": "^2019.6.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/pixijs" - }, - "peerDependencies": { - "@pixi/constants": "6.5.10", - "@pixi/extensions": "6.5.10", - "@pixi/math": "6.5.10", - "@pixi/runner": "6.5.10", - "@pixi/settings": "6.5.10", - "@pixi/ticker": "6.5.10", - "@pixi/utils": "6.5.10" - } - }, - "node_modules/pixi-spine/node_modules/@pixi/display": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", - "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", - "peer": true, - "peerDependencies": { - "@pixi/constants": "6.5.10", - "@pixi/math": "6.5.10", - "@pixi/settings": "6.5.10", - "@pixi/utils": "6.5.10" - } - }, "node_modules/pixi-spine/node_modules/@pixi/graphics": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", @@ -34531,21 +34315,6 @@ "@pixi/utils": "6.5.10" } }, - "node_modules/pixi-spine/node_modules/@pixi/runner": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", - "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", - "peer": true - }, - "node_modules/pixi-spine/node_modules/@pixi/settings": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", - "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", - "peer": true, - "peerDependencies": { - "@pixi/constants": "6.5.10" - } - }, "node_modules/pixi-spine/node_modules/@pixi/sprite": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", @@ -34560,38 +34329,6 @@ "@pixi/utils": "6.5.10" } }, - "node_modules/pixi-spine/node_modules/@pixi/ticker": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", - "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", - "peer": true, - "peerDependencies": { - "@pixi/extensions": "6.5.10", - "@pixi/settings": "6.5.10" - } - }, - "node_modules/pixi-spine/node_modules/@pixi/utils": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", - "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", - "peer": true, - "dependencies": { - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^3.1.0", - "url": "^0.11.0" - }, - "peerDependencies": { - "@pixi/constants": "6.5.10", - "@pixi/settings": "6.5.10" - } - }, - "node_modules/pixi-spine/node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "peer": true - }, "node_modules/pixi.js": { "version": "6.1.2", "license": "MIT", @@ -34878,6 +34615,21 @@ "@pixi/ticker": "6.1.2" } }, + "node_modules/pixi.js-legacy/node_modules/@pixi/runner": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.1.2.tgz", + "integrity": "sha512-OKFnW2qrjgUB/O7i15vvS3YRv49aV1Ny22uoYkWGJZ46y3wg6SWuMfHDOK2HIDMefToNRFhWCxcZJCqT5A7XmQ==", + "peer": true + }, + "node_modules/pixi.js-legacy/node_modules/@pixi/settings": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.1.2.tgz", + "integrity": "sha512-ZulDFSejh475/YOaTsYpOZNWKhfdN93FnojsaLYX4OXcuscF3Ncq4AE8wNwGFraMd0+ZZY9VXHdepU+rjIhF4g==", + "peer": true, + "dependencies": { + "ismobilejs": "^1.1.0" + } + }, "node_modules/pixi.js-legacy/node_modules/@pixi/sprite": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.1.2.tgz", @@ -34919,6 +34671,15 @@ "@pixi/utils": "6.1.2" } }, + "node_modules/pixi.js-legacy/node_modules/@pixi/ticker": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.1.2.tgz", + "integrity": "sha512-E0S7wzcPPd+hOTghwZeozuXgMvKGa8Zg4+DhlkqBchHt2HDdDzxgy2ZbcyLczBBkuidEx+JRt+BUWBGv4hqZUA==", + "peer": true, + "peerDependencies": { + "@pixi/settings": "6.1.2" + } + }, "node_modules/pixi.js-legacy/node_modules/@pixi/utils": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.1.2.tgz", @@ -35183,6 +34944,19 @@ "@pixi/ticker": "6.1.2" } }, + "node_modules/pixi.js/node_modules/@pixi/runner": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.1.2.tgz", + "integrity": "sha512-OKFnW2qrjgUB/O7i15vvS3YRv49aV1Ny22uoYkWGJZ46y3wg6SWuMfHDOK2HIDMefToNRFhWCxcZJCqT5A7XmQ==" + }, + "node_modules/pixi.js/node_modules/@pixi/settings": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.1.2.tgz", + "integrity": "sha512-ZulDFSejh475/YOaTsYpOZNWKhfdN93FnojsaLYX4OXcuscF3Ncq4AE8wNwGFraMd0+ZZY9VXHdepU+rjIhF4g==", + "dependencies": { + "ismobilejs": "^1.1.0" + } + }, "node_modules/pixi.js/node_modules/@pixi/sprite": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.1.2.tgz", @@ -35257,6 +35031,14 @@ "@pixi/utils": "6.1.2" } }, + "node_modules/pixi.js/node_modules/@pixi/ticker": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.1.2.tgz", + "integrity": "sha512-E0S7wzcPPd+hOTghwZeozuXgMvKGa8Zg4+DhlkqBchHt2HDdDzxgy2ZbcyLczBBkuidEx+JRt+BUWBGv4hqZUA==", + "peerDependencies": { + "@pixi/settings": "6.1.2" + } + }, "node_modules/pixi.js/node_modules/@pixi/utils": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.1.2.tgz", @@ -51014,22 +50796,6 @@ "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", "requires": {} }, - "@pixi/core": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", - "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", - "peer": true, - "requires": { - "@types/offscreencanvas": "^2019.6.4" - } - }, - "@pixi/display": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", - "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", - "peer": true, - "requires": {} - }, "@pixi/graphics": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", @@ -51051,50 +50817,12 @@ "peer": true, "requires": {} }, - "@pixi/runner": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", - "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", - "peer": true - }, - "@pixi/settings": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", - "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", - "peer": true, - "requires": {} - }, "@pixi/sprite": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", "peer": true, "requires": {} - }, - "@pixi/ticker": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", - "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", - "peer": true, - "requires": {} - }, - "@pixi/utils": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", - "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", - "peer": true, - "requires": { - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^3.1.0", - "url": "^0.11.0" - } - }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "peer": true } } }, @@ -51112,22 +50840,6 @@ "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", "requires": {} }, - "@pixi/core": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", - "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", - "peer": true, - "requires": { - "@types/offscreencanvas": "^2019.6.4" - } - }, - "@pixi/display": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", - "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", - "peer": true, - "requires": {} - }, "@pixi/graphics": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", @@ -51149,50 +50861,12 @@ "peer": true, "requires": {} }, - "@pixi/runner": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", - "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", - "peer": true - }, - "@pixi/settings": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", - "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", - "peer": true, - "requires": {} - }, "@pixi/sprite": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", "peer": true, "requires": {} - }, - "@pixi/ticker": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", - "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", - "peer": true, - "requires": {} - }, - "@pixi/utils": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", - "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", - "peer": true, - "requires": { - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^3.1.0", - "url": "^0.11.0" - } - }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "peer": true } } }, @@ -51210,22 +50884,6 @@ "integrity": "sha512-sMOZsCJQW4O11QR7afuHcuu8cSUgJv3paSNzZOh+imxvYB/cOcyG7K+f5sWqlGe+z3J2CLEYCX2WfXeeJi6pHg==", "requires": {} }, - "@pixi/core": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", - "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", - "peer": true, - "requires": { - "@types/offscreencanvas": "^2019.6.4" - } - }, - "@pixi/display": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", - "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", - "peer": true, - "requires": {} - }, "@pixi/graphics": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", @@ -51247,50 +50905,12 @@ "peer": true, "requires": {} }, - "@pixi/runner": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", - "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", - "peer": true - }, - "@pixi/settings": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", - "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", - "peer": true, - "requires": {} - }, "@pixi/sprite": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", "peer": true, "requires": {} - }, - "@pixi/ticker": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", - "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", - "peer": true, - "requires": {} - }, - "@pixi/utils": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", - "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", - "peer": true, - "requires": { - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^3.1.0", - "url": "^0.11.0" - } - }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "peer": true } } }, @@ -51300,11 +50920,24 @@ "integrity": "sha512-PUF2Y9YISRu5eVrVVHhHCWpc/KmxQTg3UH8rIUs8UI9dCK41/wsPd3pEahzf7H47v7x1HCohVZcFO3XQc1bUDw==", "peer": true }, + "@pixi/core": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", + "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", + "requires": { + "@types/offscreencanvas": "^2019.6.4" + } + }, + "@pixi/display": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", + "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "requires": {} + }, "@pixi/extensions": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/extensions/-/extensions-6.5.10.tgz", - "integrity": "sha512-EIUGza+E+sCy3dupuIjvRK/WyVyfSzHb5XsxRaxNrPwvG1iIUIqNqZ3owLYCo4h17fJWrj/yXVufNNtUKQccWQ==", - "peer": true + "integrity": "sha512-EIUGza+E+sCy3dupuIjvRK/WyVyfSzHb5XsxRaxNrPwvG1iIUIqNqZ3owLYCo4h17fJWrj/yXVufNNtUKQccWQ==" }, "@pixi/math": { "version": "6.5.10", @@ -51320,18 +50953,43 @@ } }, "@pixi/runner": { - "version": "6.1.2" + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", + "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", + "peer": true }, "@pixi/settings": { - "version": "6.1.2", - "requires": { - "ismobilejs": "^1.1.0" - } + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", + "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", + "peer": true, + "requires": {} }, "@pixi/ticker": { - "version": "6.1.2", + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", + "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", + "peer": true, "requires": {} }, + "@pixi/utils": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", + "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "requires": { + "@types/earcut": "^2.1.0", + "earcut": "^2.2.4", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + }, + "dependencies": { + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + } + } + }, "@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", @@ -57384,8 +57042,7 @@ "@types/offscreencanvas": { "version": "2019.7.0", "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz", - "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==", - "peer": true + "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==" }, "@types/overlayscrollbars": { "version": "1.12.1", @@ -64910,7 +64567,9 @@ "dev": true }, "ismobilejs": { - "version": "1.1.1" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz", + "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==" }, "iso-639-1": { "version": "2.1.4", @@ -70375,8 +70034,7 @@ "path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" }, "path-dirname": { "version": "1.0.2", @@ -70489,22 +70147,6 @@ "@pixi-spine/runtime-4.1": "~3.1.2" } }, - "@pixi/core": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", - "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", - "peer": true, - "requires": { - "@types/offscreencanvas": "^2019.6.4" - } - }, - "@pixi/display": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", - "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", - "peer": true, - "requires": {} - }, "@pixi/graphics": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.5.10.tgz", @@ -70533,50 +70175,12 @@ "peer": true, "requires": {} }, - "@pixi/runner": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.5.10.tgz", - "integrity": "sha512-4HiHp6diCmigJT/DSbnqQP62OfWKmZB7zPWMdV1AEdr4YT1QxzXAW1wHg7dkoEfyTHqZKl0tm/zcqKq/iH7tMA==", - "peer": true - }, - "@pixi/settings": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.5.10.tgz", - "integrity": "sha512-ypAS5L7pQ2Qb88yQK72bXtc7sD8OrtLWNXdZ/gnw5kwSWCFaOSoqhKqJCXrR5DQtN98+RQefwbEAmMvqobhFyw==", - "peer": true, - "requires": {} - }, "@pixi/sprite": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.5.10.tgz", "integrity": "sha512-UiK+8LgM9XQ/SBDKjRgZ8WggdOSlFRXqiWjEZVmNkiyU8HvXeFzWPRhpc8RR1zDwAUhZWKtMhF8X/ba9m+z2lg==", "peer": true, "requires": {} - }, - "@pixi/ticker": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.5.10.tgz", - "integrity": "sha512-UqX1XYtzqFSirmTOy8QAK4Ccg4KkIZztrBdRPKwFSOEiKAJoGDCSBmyQBo/9aYQKGObbNnrJ7Hxv3/ucg3/1GA==", - "peer": true, - "requires": {} - }, - "@pixi/utils": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", - "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", - "peer": true, - "requires": { - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^3.1.0", - "url": "^0.11.0" - } - }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "peer": true } } }, @@ -70762,6 +70366,19 @@ "integrity": "sha512-qHoS/knfchT7ZvpV1MwJQaS5zb8uvlO2paKRLN76aZR4dHKCpRzVWHJ+5EuSEacbbzX8ElBMTCI0iV1V7L1Jiw==", "requires": {} }, + "@pixi/runner": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.1.2.tgz", + "integrity": "sha512-OKFnW2qrjgUB/O7i15vvS3YRv49aV1Ny22uoYkWGJZ46y3wg6SWuMfHDOK2HIDMefToNRFhWCxcZJCqT5A7XmQ==" + }, + "@pixi/settings": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.1.2.tgz", + "integrity": "sha512-ZulDFSejh475/YOaTsYpOZNWKhfdN93FnojsaLYX4OXcuscF3Ncq4AE8wNwGFraMd0+ZZY9VXHdepU+rjIhF4g==", + "requires": { + "ismobilejs": "^1.1.0" + } + }, "@pixi/sprite": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.1.2.tgz", @@ -70798,6 +70415,12 @@ "integrity": "sha512-QpvFC9izghqVo4zkj5mS6PmqKVtd8ArdapYxbxOVystE+gI8IKq7ZJgvvPuaj+9aqCUy20jiMPoLvfSyVGIhUg==", "requires": {} }, + "@pixi/ticker": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.1.2.tgz", + "integrity": "sha512-E0S7wzcPPd+hOTghwZeozuXgMvKGa8Zg4+DhlkqBchHt2HDdDzxgy2ZbcyLczBBkuidEx+JRt+BUWBGv4hqZUA==", + "requires": {} + }, "@pixi/utils": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.1.2.tgz", @@ -70953,6 +70576,21 @@ "peer": true, "requires": {} }, + "@pixi/runner": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.1.2.tgz", + "integrity": "sha512-OKFnW2qrjgUB/O7i15vvS3YRv49aV1Ny22uoYkWGJZ46y3wg6SWuMfHDOK2HIDMefToNRFhWCxcZJCqT5A7XmQ==", + "peer": true + }, + "@pixi/settings": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.1.2.tgz", + "integrity": "sha512-ZulDFSejh475/YOaTsYpOZNWKhfdN93FnojsaLYX4OXcuscF3Ncq4AE8wNwGFraMd0+ZZY9VXHdepU+rjIhF4g==", + "peer": true, + "requires": { + "ismobilejs": "^1.1.0" + } + }, "@pixi/sprite": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.1.2.tgz", @@ -70974,6 +70612,13 @@ "peer": true, "requires": {} }, + "@pixi/ticker": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.1.2.tgz", + "integrity": "sha512-E0S7wzcPPd+hOTghwZeozuXgMvKGa8Zg4+DhlkqBchHt2HDdDzxgy2ZbcyLczBBkuidEx+JRt+BUWBGv4hqZUA==", + "peer": true, + "requires": {} + }, "@pixi/utils": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.1.2.tgz", diff --git a/newIDE/app/package.json b/newIDE/app/package.json index 301a6a5bf6d8..ab630f1f67fb 100644 --- a/newIDE/app/package.json +++ b/newIDE/app/package.json @@ -51,10 +51,14 @@ "jss-rtl": "^0.3.0", "lodash": "4.17.4", "node-require-function": "^1.2.0", + "path-browserify": "^1.0.1", "pixi-simple-gesture": "github:4ian/pixi-simple-gesture#v0.3.3", "pixi-spine": "^3.0.0", - "path-browserify": "^1.0.1", "pixi.js-legacy": "6.1.2", + "@pixi/core": "^6.5.10", + "@pixi/display": "^6.5.10", + "@pixi/extensions": "^6.5.10", + "@pixi/utils": "^6.5.10", "posthog-js": "^1.57.2", "prop-types": "^15.5.10", "qr-creator": "^1.0.0", diff --git a/newIDE/app/src/EventsSheet/ParameterFields/ObjectAnimationNameField.js b/newIDE/app/src/EventsSheet/ParameterFields/ObjectAnimationNameField.js index 891d2d7386ee..3a8001e8d08f 100644 --- a/newIDE/app/src/EventsSheet/ParameterFields/ObjectAnimationNameField.js +++ b/newIDE/app/src/EventsSheet/ParameterFields/ObjectAnimationNameField.js @@ -89,12 +89,26 @@ export default React.forwardRef( }) .filter(Boolean) .sort(); + } else if (object.getType() === 'SpineObject::SpineObject') { + const spineConfiguration = gd.asSpineConfiguration( + object.getConfiguration() + ); + + return mapFor(0, spineConfiguration.getAnimationsCount(), index => { + const animationName = spineConfiguration + .getAnimation(index) + .getName(); + return animationName.length > 0 ? animationName : null; + }) + .filter(Boolean) + .sort(); } return []; }; const animationNames = getAnimationNames(); + console.log('newIDE ObjectAnimationNameField ', animationNames); const isCurrentValueInAnimationNamesList = !!animationNames.find( animationName => `"${animationName}"` === props.value diff --git a/newIDE/app/src/JsExtensionsLoader/BrowserJsExtensionsLoader.js b/newIDE/app/src/JsExtensionsLoader/BrowserJsExtensionsLoader.js index 4f0056b50a6b..162225a6f0ac 100644 --- a/newIDE/app/src/JsExtensionsLoader/BrowserJsExtensionsLoader.js +++ b/newIDE/app/src/JsExtensionsLoader/BrowserJsExtensionsLoader.js @@ -172,7 +172,7 @@ const jsExtensions = [ objectsRenderingServiceModules: {}, }, { - name: 'Spine', + name: 'SpineObject', // $FlowExpectedError - this path is ignored for Flow. extensionModule: require('GDJS-for-web-app-only/Runtime/Extensions/Spine/JsExtension.js'), objectsRenderingServiceModules: {}, diff --git a/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js b/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js index 3cdfcd9515cb..d16288803fbb 100644 --- a/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js @@ -44,7 +44,7 @@ const DragSourceAndDropTarget = makeDragSourceAndDropTarget( 'model3d-animations-list' ); -const styles = { +export const styles = { rowContainer: { display: 'flex', flexDirection: 'column', @@ -91,7 +91,7 @@ type PropertyFieldProps = {| propertyName: string, |}; -const PropertyField = ({ +export const PropertyField = ({ objectConfiguration, propertyName, }: PropertyFieldProps) => { @@ -136,7 +136,7 @@ const PropertyField = ({ ); }; -const PropertyCheckbox = ({ +export const PropertyCheckbox = ({ objectConfiguration, propertyName, }: PropertyFieldProps) => { @@ -178,7 +178,7 @@ type PropertyResourceSelectorProps = {| onChange: (value: string) => void, |}; -const PropertyResourceSelector = ({ +export const PropertyResourceSelector = ({ objectConfiguration, propertyName, project, @@ -254,6 +254,7 @@ const Model3DEditor = ({ const forceUpdate = useForceUpdate(); const model3DConfiguration = gd.asModel3DConfiguration(objectConfiguration); + console.log('Model3DEditod, ', model3DConfiguration, objectConfiguration) const properties = objectConfiguration.getProperties(); const [nameErrors, setNameErrors] = React.useState<{ [number]: React.Node }>( diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js new file mode 100644 index 000000000000..22084b99a510 --- /dev/null +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -0,0 +1,511 @@ +// @flow + +import * as React from 'react'; +import { Trans } from '@lingui/macro'; +import { t } from '@lingui/macro'; +import { type EditorProps } from './EditorProps.flow'; +import { ColumnStackLayout, ResponsiveLineStackLayout } from '../../UI/Layout'; +import Text from '../../UI/Text'; +import SemiControlledTextField from '../../UI/SemiControlledTextField'; +import useForceUpdate from '../../Utils/UseForceUpdate'; +import Checkbox from '../../UI/Checkbox'; +import { Column, Line, Spacer } from '../../UI/Grid'; +import SelectField from '../../UI/SelectField'; +import SelectOption from '../../UI/SelectOption'; +import IconButton from '../../UI/IconButton'; +import RaisedButton from '../../UI/RaisedButton'; +import FlatButton from '../../UI/FlatButton'; +import { mapFor } from '../../Utils/MapFor'; +import ScrollView, { type ScrollViewInterface } from '../../UI/ScrollView'; +import { EmptyPlaceholder } from '../../UI/EmptyPlaceholder'; +import Add from '../../UI/CustomSvgIcons/Add'; +import Trash from '../../UI/CustomSvgIcons/Trash'; +import { makeDragSourceAndDropTarget } from '../../UI/DragAndDrop/DragSourceAndDropTarget'; +import { DragHandleIcon } from '../../UI/DragHandle'; +import DropIndicator from '../../UI/SortableVirtualizedItemList/DropIndicator'; +import GDevelopThemeContext from '../../UI/Theme/GDevelopThemeContext'; +import PixiResourcesLoader from '../../ObjectsRendering/PixiResourcesLoader'; +import useAlertDialog from '../../UI/Alert/useAlertDialog'; +import { PropertyResourceSelector, PropertyField, styles } from './Model3DEditor'; +import { ISkeletonData } from 'pixi-spine'; + +const { gd }: libGDevelop = global; + +const DragSourceAndDropTarget = makeDragSourceAndDropTarget( + 'spine-animations-list' +); + +const SpineEditor = ({ + objectConfiguration, + project, + layout, + object, + onSizeUpdated, + onObjectUpdated, + resourceManagementProps, +}: EditorProps) => { + const scrollView = React.useRef(null); + + const [ + justAddedAnimationName, + setJustAddedAnimationName, + ] = React.useState(null); + const justAddedAnimationElement = React.useRef(null); + + React.useEffect( + () => { + if ( + scrollView.current && + justAddedAnimationElement.current && + justAddedAnimationName + ) { + scrollView.current.scrollTo(justAddedAnimationElement.current); + setJustAddedAnimationName(null); + justAddedAnimationElement.current = null; + } + }, + [justAddedAnimationName] + ); + const { showAlert } = useAlertDialog(); + + const draggedAnimationIndex = React.useRef(null); + + const gdevelopTheme = React.useContext(GDevelopThemeContext); + const forceUpdate = useForceUpdate(); + + const spineConfiguration = gd.asSpineConfiguration(objectConfiguration); + console.log('SpineEditod, ', spineConfiguration, objectConfiguration) + const properties = objectConfiguration.getProperties(); + + const [nameErrors, setNameErrors] = React.useState<{ [number]: React.Node }>( + {} + ); + + const [skeleton, setSkeleton] = React.useState(null); + const getSkeleton = React.useCallback( + (jsonResourceName: string, imageResourceName: string, atlasResourceName: string) => { + if ([jsonResourceName, imageResourceName, atlasResourceName].some(resName => !resName)) { + return; + } + + PixiResourcesLoader.getSpineData(project, jsonResourceName, imageResourceName, atlasResourceName).then( + newSkeleton => { + setSkeleton(newSkeleton); + } + ); + }, + [project] + ); + getSkeleton( + properties.get('jsonResourceName').getValue(), + properties.get('imageResourceName').getValue(), + properties.get('atlasResourceName').getValue() + ); + + const onChangeJsonResourceName = React.useCallback( + (jsonResourceName: string) => { + getSkeleton( + jsonResourceName, + properties.get('imageResourceName').getValue(), + properties.get('atlasResourceName').getValue() + ); + }, + [getSkeleton] + ); + const onChangeImageResourceName = React.useCallback( + (imageResourceName: string) => { + getSkeleton( + properties.get('jsonResourceName').getValue(), + imageResourceName, + properties.get('atlasResourceName').getValue() + ); + }, + [getSkeleton] + ); + const onChangeAtlasResourceName = React.useCallback( + (atlasResourceName: string) => { + getSkeleton( + properties.get('jsonResourceName').getValue(), + properties.get('imageResourceName').getValue(), + atlasResourceName + ); + }, + [getSkeleton] + ); + + const scanNewAnimations = React.useCallback( + () => { + if (!skeleton) { + return; + } + setNameErrors({}); + + const animationSources = mapFor( + 0, + spineConfiguration.getAnimationsCount(), + animationIndex => + spineConfiguration.getAnimation(animationIndex).getSource() + ); + + let hasAddedAnimation = false; + for (const resourceAnimation of skeleton.animations) { + if (animationSources.includes(resourceAnimation.name)) { + continue; + } + const newAnimationName = spineConfiguration.hasAnimationNamed( + resourceAnimation.name + ) + ? '' + : resourceAnimation.name; + + const newAnimation = new gd.SpineAnimation(); + newAnimation.setName(newAnimationName); + newAnimation.setSource(resourceAnimation.name); + spineConfiguration.addAnimation(newAnimation); + newAnimation.delete(); + hasAddedAnimation = true; + } + if (hasAddedAnimation) { + forceUpdate(); + onSizeUpdated(); + if (onObjectUpdated) onObjectUpdated(); + + // Scroll to the bottom of the list. + // Ideally, we'd wait for the list to be updated to scroll, but + // to simplify the code, we just wait a few ms for a new render + // to be done. + setTimeout(() => { + if (scrollView.current) { + scrollView.current.scrollToBottom(); + } + }, 100); // A few ms is enough for a new render to be done. + } else { + showAlert({ + title: t`No new animation`, + message: t`Every animation from the Spine file is already in the list.`, + }); + } + }, + [ + forceUpdate, + skeleton, + spineConfiguration, + onObjectUpdated, + onSizeUpdated, + showAlert, + ] + ); + + const addAnimation = React.useCallback( + () => { + setNameErrors({}); + + const emptyAnimation = new gd.SpineAnimation(); + spineConfiguration.addAnimation(emptyAnimation); + emptyAnimation.delete(); + forceUpdate(); + onSizeUpdated(); + if (onObjectUpdated) onObjectUpdated(); + + // Scroll to the bottom of the list. + // Ideally, we'd wait for the list to be updated to scroll, but + // to simplify the code, we just wait a few ms for a new render + // to be done. + setTimeout(() => { + if (scrollView.current) { + scrollView.current.scrollToBottom(); + } + }, 100); // A few ms is enough for a new render to be done. + }, + [forceUpdate, onObjectUpdated, onSizeUpdated, spineConfiguration] + ); + + const removeAnimation = React.useCallback( + animationIndex => { + setNameErrors({}); + + spineConfiguration.removeAnimation(animationIndex); + forceUpdate(); + onSizeUpdated(); + if (onObjectUpdated) onObjectUpdated(); + }, + [forceUpdate, onObjectUpdated, onSizeUpdated, spineConfiguration] + ); + + const moveAnimation = React.useCallback( + (targetIndex: number) => { + const draggedIndex = draggedAnimationIndex.current; + if (draggedIndex === null) return; + + setNameErrors({}); + + spineConfiguration.moveAnimation( + draggedIndex, + targetIndex > draggedIndex ? targetIndex - 1 : targetIndex + ); + forceUpdate(); + }, + [spineConfiguration, forceUpdate] + ); + + const changeAnimationName = React.useCallback( + (animationIndex, newName) => { + const currentName = spineConfiguration + .getAnimation(animationIndex) + .getName(); + if (currentName === newName) return; + const animation = spineConfiguration.getAnimation(animationIndex); + + setNameErrors({}); + + if (newName !== '' && spineConfiguration.hasAnimationNamed(newName)) { + // The indexes can be used as a key because errors are cleared when + // animations are moved. + setNameErrors({ + ...nameErrors, + [animationIndex]: ( + The animation name {newName} is already taken + ), + }); + return; + } + + animation.setName(newName); + // TODO EBO Refactor event-based object events when an animation is renamed. + if (layout && object) { + gd.WholeProjectRefactorer.renameObjectAnimation( + project, + layout, + object, + currentName, + newName + ); + } + forceUpdate(); + if (onObjectUpdated) onObjectUpdated(); + }, + [ + spineConfiguration, + layout, + object, + forceUpdate, + onObjectUpdated, + nameErrors, + project, + ] + ); + + const sourceSelectOptions = skeleton + ? skeleton.animations.map(animation => { + return ( + + ); + }) + : []; + + return ( + <> + + + + + + + Appearance + + + + + Play + + + Animations + + {spineConfiguration.getAnimationsCount() === 0 ? ( + + Add your first animation} + description={ + Animations are a sequence of images. + } + actionLabel={Add an animation} + helpPagePath="/objects/sprite" + tutorialId="intermediate-changing-animations" + onAction={addAnimation} + /> + + ) : ( + + {mapFor( + 0, + spineConfiguration.getAnimationsCount(), + animationIndex => { + const animation = spineConfiguration.getAnimation( + animationIndex + ); + + const animationRef = + justAddedAnimationName === animation.getName() + ? justAddedAnimationElement + : null; + + return ( + { + draggedAnimationIndex.current = animationIndex; + return {}; + }} + canDrag={() => true} + canDrop={() => true} + drop={() => { + moveAnimation(animationIndex); + }} + > + {({ + connectDragSource, + connectDropTarget, + isOver, + canDrop, + }) => + connectDropTarget( +

+ {isOver && } +
+ + {connectDragSource( + + + + + + )} + + Animation #{animationIndex} + + + + changeAnimationName(animationIndex, text) + } + fullWidth + /> + + removeAnimation(animationIndex) + } + > + + + + +
+ + + { + animation.setSource(event.target.value); + forceUpdate(); + }} + margin="dense" + fullWidth + floatingLabelText={ + Spine animation name + } + translatableHintText={t`Choose an animation`} + > + {sourceSelectOptions} + + Loop} + checked={animation.shouldLoop()} + onCheck={(e, checked) => { + animation.setShouldLoop(checked); + forceUpdate(); + }} + /> + +
+ ) + } + + ); + } + )} + + )} + + + + + + Scan missing animations} + onClick={scanNewAnimations} + /> + Add an animation} + primary + onClick={addAnimation} + icon={} + /> + + + + ); +}; + +export default SpineEditor; diff --git a/newIDE/app/src/ObjectEditor/ObjectsEditorService.js b/newIDE/app/src/ObjectEditor/ObjectsEditorService.js index 1bbd80e16aab..0e0808ed3a08 100644 --- a/newIDE/app/src/ObjectEditor/ObjectsEditorService.js +++ b/newIDE/app/src/ObjectEditor/ObjectsEditorService.js @@ -10,6 +10,7 @@ import ObjectPropertiesEditor from './Editors/ObjectPropertiesEditor'; import CustomObjectPropertiesEditor from './Editors/CustomObjectPropertiesEditor'; import Cube3DEditor from './Editors/Cube3DEditor'; import Model3DEditor from './Editors/Model3DEditor'; +import SpineEditor from './Editors/SpineEditor'; const gd: libGDevelop = global.gd; @@ -165,6 +166,21 @@ const ObjectsEditorService = { gd.asObjectJsImplementation(objectConfiguration), helpPagePath: '/objects/3d-model', }, + 'SpineObject::SpineObject': { + component: SpineEditor, + createNewObject: ( + objectConfiguration: gdObjectConfiguration + ): gdObjectConfiguration => + gd + .asObjectJsImplementation(objectConfiguration) + .clone() + .release(), + castToObjectType: ( + objectConfiguration: gdObjectConfiguration + ): gdObjectJsImplementation => + gd.asObjectJsImplementation(objectConfiguration), + helpPagePath: '/objects/3d-model', + }, 'TiledSpriteObject::TiledSprite': { component: TiledSpriteEditor, createNewObject: (): gdTiledSpriteObject => new gd.TiledSpriteObject(), diff --git a/newIDE/app/src/ObjectsList/index.js b/newIDE/app/src/ObjectsList/index.js index 0dabec7c5dc9..aebeecdc8869 100644 --- a/newIDE/app/src/ObjectsList/index.js +++ b/newIDE/app/src/ObjectsList/index.js @@ -74,6 +74,7 @@ const objectTypeToDefaultName = { 'TextInput::TextInputObject': 'NewTextInput', 'Scene3D::Model3DObject': 'New3DModel', 'Scene3D::Cube3DObject': 'New3DBox', + 'SpineObject::SpineObject': 'NewSpine', 'Video::VideoObject': 'NewVideo', }; diff --git a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js index 0ebff09bc78d..43372df81eb6 100644 --- a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js +++ b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js @@ -12,7 +12,8 @@ import PixiResourcesLoader from './PixiResourcesLoader'; import ResourcesLoader from '../ResourcesLoader'; import RenderedInstance from './Renderers/RenderedInstance'; import Rendered3DInstance from './Renderers/Rendered3DInstance'; -import * as PIXI from 'pixi.js-legacy'; +import * as PIXI_LEGACY from 'pixi.js-legacy'; +import * as PIXI_SPINE from 'pixi-spine'; import * as THREE from 'three'; import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils'; import optionalRequire from '../Utils/OptionalRequire'; @@ -20,10 +21,12 @@ import { rgbOrHexToHexNumber } from '../Utils/ColorTransformer'; const path = optionalRequire('path'); const electron = optionalRequire('electron'); const gd: libGDevelop = global.gd; +const PIXI = { ...PIXI_LEGACY, ...PIXI_SPINE }; // Some PixiJS plugins like pixi-tilemap are not distributed as UMD modules, // or still require a global PIXI object to be accessible, so we expose PIXI here. // This can be removed if no more extension PixiJS plugin requires this. +// global.PIXI = PIXI; global.PIXI = PIXI; // We also export it as GlobalPIXIModule, which is normally used in GDJS runtime and extensions // to allow TypeScript typings of PIXI to work. diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 96567ac259f8..43f983780350 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -2,23 +2,30 @@ import slugs from 'slugs'; import axios from 'axios'; import * as PIXI from 'pixi.js-legacy'; +import * as PIXI_SPINE from 'pixi-spine'; import * as THREE from 'three'; import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; import ResourcesLoader from '../ResourcesLoader'; import { loadFontFace } from '../Utils/FontFaceLoader'; import { checkIfCredentialsRequired } from '../Utils/CrossOrigin'; +import { ISkeleton } from 'pixi-spine'; const gd: libGDevelop = global.gd; +// PIXI_SPINE.SpineParser.registerLoaderPlugin(); +PIXI.Loader.registerPlugin(PIXI_SPINE.SpineParser); + +type ResourcePromise = { [resourceName: string]: Promise }; + const loadedBitmapFonts = {}; const loadedFontFamilies = {}; const loadedTextures = {}; const invalidTexture = PIXI.Texture.from('res/error48.png'); const loadedThreeTextures = {}; const loadedThreeMaterials = {}; -const loadedOrLoading3DModelPromises: { - [resourceName: string]: Promise, -} = {}; +const loadedOrLoading3DModelPromises: ResourcePromise = {}; +const atlasPromises: ResourcePromise = {}; +const spineDataPromises: ResourcePromise = {}; const createInvalidModel = (): GLTF => { /** @@ -349,6 +356,56 @@ export default class PixiResourcesLoader { return loadingPromise; } + static async getSpineData( + project: gdProject, + spineName: string, + atlasImageName: string, + atlasTextName: string + ): Promise { + const loader = PIXI.Loader.shared; + const resourceManager = project.getResourcesManager(); + const resourcesData = [ + [spineName, 'json'], + [atlasImageName, 'image'], + [atlasTextName, 'atlas'], + ]; + + for (const [resName, resKind] of resourcesData) { + if (!resourceManager.hasResource(resName)) { + return Promise.reject(`Unknown ${resKind} file ${resName}.`); + } + if (resourceManager.getResource(resName).getKind() !== resKind) { + return Promise.reject(`The resource called ${resName} is not of appropriate file type ${resKind}.`); + } + } + + // https://github.com/pixijs/spine/blob/master/examples/preload_atlas_text.md + if (!atlasPromises[atlasTextName]) { + atlasPromises[atlasTextName] = new Promise(resolve => { + loader + .add(atlasTextName, ResourcesLoader.getResourceFullUrl(project, atlasTextName, { isResourceForPixi: true }), { xhrType: 'text' }) + .load((_, atlasData) => resolve(atlasData[atlasTextName].data)) + }); + } + + if (!spineDataPromises[spineName]) { + spineDataPromises[spineName] = new Promise(resolve => { + atlasPromises[atlasTextName].then(atlasRawData => { + const metadata = { + image: this.getPIXITexture(project, atlasImageName), + atlasRawData, + }; + + loader + .add(spineName, ResourcesLoader.getResourceFullUrl(project, spineName, { isResourceForPixi: true }), { metadata }) + .load((_, jsonData) => resolve(jsonData[spineName].spineData)); + }) + }); + } + + return spineDataPromises[spineName]; + } + /** * Return the PIXI video texture represented by the given resource. * If not loaded, it will load it. @@ -531,37 +588,4 @@ export default class PixiResourcesLoader { .then(response => response.data); } - static getResourceAtlasData( - project: gdProject, - resourceName: string - ): Promise { - if (!project.getResourcesManager().hasResource(resourceName)) { - return Promise.reject(`Unknown atlas file ${resourceName}.`); - } - - const resource = project.getResourcesManager().getResource(resourceName); - if (resource.getKind() !== 'atlas') { - return Promise.reject(`The resource called ${resourceName} is not a json file.`); - } - - const url = ResourcesLoader.getResourceFullUrl(project, resourceName, { - isResourceForPixi: true, - }); - - // const gltfLoader = getOrCreateGltfLoader(); - // gltfLoader.withCredentials = checkIfCredentialsRequired(url); - // return new Promise((resolve, reject) => { - // gltfLoader.load( - // url, - // gltf => { - // traverseToSetBasicMaterialFromMeshes(gltf.scene); - // resolve(gltf); - // }, - // undefined, - // error => { - // reject(error); - // } - // ); - // }); - } } diff --git a/newIDE/app/src/ResourcesList/BrowserResourceSources.js b/newIDE/app/src/ResourcesList/BrowserResourceSources.js index ac671b90ee4e..2c47110216b3 100644 --- a/newIDE/app/src/ResourcesList/BrowserResourceSources.js +++ b/newIDE/app/src/ResourcesList/BrowserResourceSources.js @@ -197,7 +197,9 @@ const browserResourceSources: Array = [ /> ), })), - ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => ({ + ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => { + console.log('Choose from asset store Browser'); + return { name: `resource-store-${kind}`, displayName: t`Choose from asset store`, displayTab: 'standalone', @@ -210,7 +212,7 @@ const browserResourceSources: Array = [ key={`resource-store-${kind}`} /> ), - })), + }}), ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => ({ name: `url-chooser-${kind}`, displayName: t`Use a public URL`, diff --git a/newIDE/app/src/ResourcesList/LocalResourceSources.js b/newIDE/app/src/ResourcesList/LocalResourceSources.js index e8bb4550f27c..8ab7f5deaadc 100644 --- a/newIDE/app/src/ResourcesList/LocalResourceSources.js +++ b/newIDE/app/src/ResourcesList/LocalResourceSources.js @@ -229,7 +229,9 @@ const localResourceSources: Array = [ /> ), })), - ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => ({ + ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => { + console.log('Choose from asset store Local'); + return { name: `resource-store-${kind}`, displayName: t`Choose from asset store`, displayTab: 'standalone', @@ -242,7 +244,7 @@ const localResourceSources: Array = [ key={`resource-store-${kind}`} /> ), - })), + }}), ]; export default localResourceSources; diff --git a/newIDE/app/src/ResourcesList/ResourceSelector.js b/newIDE/app/src/ResourcesList/ResourceSelector.js index 55b14eb35303..5c22454d90fd 100644 --- a/newIDE/app/src/ResourcesList/ResourceSelector.js +++ b/newIDE/app/src/ResourcesList/ResourceSelector.js @@ -182,7 +182,10 @@ const ResourceSelector = React.forwardRef( const addFrom = React.useCallback( async (source: ResourceSource) => { try { - if (!source) return; + if (!source) { + console.log('source is undef') + return; + } const resources = await resourceManagementProps.onChooseResource({ initialSourceName: source.name, diff --git a/newIDE/app/src/ResourcesList/ResourceSource.js b/newIDE/app/src/ResourcesList/ResourceSource.js index 93511809648a..b03f3974fb02 100644 --- a/newIDE/app/src/ResourcesList/ResourceSource.js +++ b/newIDE/app/src/ResourcesList/ResourceSource.js @@ -83,7 +83,7 @@ export const allResourceKindsAndMetadata = [ createNewResource: () => new gd.Model3DResource(), }, { - kind: 'Atlas', + kind: 'atlas', displayName: t`Atlas`, fileExtensions: ['atlas'], createNewResource: () => new gd.AtlasResource(), From 93903c6f2abeace34d006bca118318f521d47347 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Mon, 14 Aug 2023 18:28:26 +0300 Subject: [PATCH 03/80] add isAnimationComplete condition and isUpdatable expression, condition, action to spine object --- Extensions/Spine/JsExtension.js | 28 ++++++++++ .../Spine/spineruntimeobject-pixi-renderer.ts | 52 ++++++++++++++----- Extensions/Spine/spineruntimeobject.ts | 14 ++++- 3 files changed, 81 insertions(+), 13 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 336c4a00ae18..50b761991410 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -92,7 +92,35 @@ module.exports = { ) .setFunctionName('setScale') .setGetter('getScale'); + + object + .addCondition( + 'isAnimationComplete', + _('Animation complete'), + _('Check if the animation being played by the Spine object is complete.'), + _('The animation of _PARAM0_ is complete'), + _('Animations and images'), + 'res/conditions/animation24.png', + 'res/conditions/animation.png' + ) + .addParameter('object', _('Spine'), 'SpineObject') + .markAsSimple() + .setFunctionName('isAnimationComplete'); + object + .addExpressionAndConditionAndAction( + 'boolean', + 'Updatable', + _('Updatable'), + _('an animation is updatable'), + _('Updatable'), + 'res/conditions/animation24.png', + 'res/conditions/animation.png' + ) + .addParameter('object', _('Spine'), 'SpineObject') + .useStandardParameters('boolean', gd.ParameterOptions.makeNewOptions()) + .setFunctionName('setIsUpdatable') + .setGetter('isUpdatable'); object .addExpressionAndConditionAndAction( diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index f7b2d5a0f7cb..e18e286dc329 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -2,13 +2,31 @@ namespace gdjs { import PIXI = GlobalPIXIModule.PIXI; import PIXI_SPINE = GlobalPIXIModule.PIXI_SPINE; + type SpineCb = (s: PIXI_SPINE.Spine) => T; + /** * The PIXI.js renderer for the Bitmap Text runtime object. */ export class SpineRuntimeObjectPixiRenderer { _object: gdjs.SpineRuntimeObject; _pixiObject: PIXI.Container; - _spine!: Promise; + _spine?: PIXI_SPINE.Spine; + _spinePromise!: Promise; + private _isUpdatable = true; + private _isAnimationCompelete = true; + + get isAnimationCompelete() { + return this._isAnimationCompelete; + } + + get isUpdatable() { + return this._isUpdatable; + } + + set isUpdatable(isUpdatable: boolean) { + this._isUpdatable = isUpdatable; + this.applySpineAction(spine => spine.autoUpdate = this._isUpdatable); + } /** * @param runtimeObject The object to render @@ -44,7 +62,7 @@ namespace gdjs { } updateTimeScale() { - this._spine.then(spine => spine.state.timeScale = this._object.getTimeScale()); + this.applySpineAction(spine => spine.state.timeScale = this._object.getTimeScale()); } updateScale(): void { @@ -78,21 +96,21 @@ namespace gdjs { } setWidth(width: float): void { - this._spine.then(spine => { + this.applySpineAction(spine => { spine.width = width; this.updateBounds(spine); - }); + }) } setHeight(height: float): void { - this._spine.then(spine => { + this.applySpineAction(spine => { spine.height = height; this.updateBounds(spine); }); } setSize(width: float, height: float): void { - this._spine?.then(spine => { + this.applySpineAction(spine => { spine.width = width; spine.height = height; this.updateBounds(spine); @@ -100,25 +118,35 @@ namespace gdjs { } setAnimation(animation: string, loop: boolean) { - this._spine?.then(s => { + this.applySpineAction(s => { + this._isAnimationCompelete = false; + s.state.addListener({ complete: () => this._isAnimationCompelete = true }); s.state.setAnimation(0, animation, loop); this.updateBounds(s); }); } + private applySpineAction(action: SpineCb) { + if (this._spine) { + action(this._spine); + } else { + this._spinePromise.then(action); + } + } + private constructSpine() { const game = this.instanceContainer.getGame(); const spineJson = game.getJsonManager().getLoadedJson(this._object.jsonResourceName)!; const atlasText = game.getTextManager().get(this._object.atlasResourceName)!; const atlasImage = game.getImageManager().getPIXITexture(this._object.imageResourceName)!; - this._spine = this.getSpineSkeleton(spineJson, atlasText, atlasImage) + this._spinePromise = this.getSpineSkeleton(spineJson, atlasText, atlasImage) .then(skeleton => { - const s = new PIXI_SPINE.Spine(skeleton); - this._pixiObject.addChild(s); - this.updateBounds(s); + this._spine = new PIXI_SPINE.Spine(skeleton); + this._pixiObject.addChild(this._spine); + this.updateBounds(this._spine); - return s; + return this._spine; }); } diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 47d748bc4d7c..721fe4cb6858 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -189,9 +189,21 @@ namespace gdjs { ); } - isCurrentAnimationName(name): boolean { + isAnimationComplete(): boolean { + return this._renderer.isAnimationCompelete; + } + + isCurrentAnimationName(name: string): boolean { return this.getAnimationName() === name; } + + setIsUpdatable(isUpdatable: boolean): void { + this._renderer.isUpdatable = isUpdatable; + } + + isUpdatable(): boolean { + return this._renderer.isUpdatable; + } } gdjs.registerObject( From 086e49fc817f5289cb021ca358039b129148a9eb Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Mon, 14 Aug 2023 18:35:17 +0300 Subject: [PATCH 04/80] fix extension configuration --- Extensions/Spine/JsExtension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 50b761991410..3953d2751d5a 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -114,7 +114,7 @@ module.exports = { _('Updatable'), _('an animation is updatable'), _('Updatable'), - 'res/conditions/animation24.png', + '', 'res/conditions/animation.png' ) .addParameter('object', _('Spine'), 'SpineObject') From 476eea80d7705ef11b2bc75bfa766d3a4c09aa42 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Thu, 17 Aug 2023 10:46:15 +0300 Subject: [PATCH 05/80] make spine creation synchrounous in SpineRuntimeObject --- Extensions/Spine/SpineObjectConfiguration.cpp | 18 ++-- .../Spine/spineruntimeobject-pixi-renderer.ts | 84 +++++-------------- Extensions/Spine/spineruntimeobject.ts | 7 +- GDJS/GDJS/IDE/ExporterHelper.cpp | 2 +- GDJS/Runtime/runtimegame.ts | 3 +- GDJS/Runtime/textmanager.ts | 23 ++++- 6 files changed, 59 insertions(+), 78 deletions(-) diff --git a/Extensions/Spine/SpineObjectConfiguration.cpp b/Extensions/Spine/SpineObjectConfiguration.cpp index cb45bf190c3e..597da2690f25 100644 --- a/Extensions/Spine/SpineObjectConfiguration.cpp +++ b/Extensions/Spine/SpineObjectConfiguration.cpp @@ -96,11 +96,11 @@ SpineObjectConfiguration::GetProperties() const { } bool SpineObjectConfiguration::UpdateInitialInstanceProperty( - gd::InitialInstance &instance, const gd::String &propertyName, - const gd::String &newValue, gd::Project &project, gd::Layout &layout) { + gd::InitialInstance &instance, const gd::String &propertyName, + const gd::String &newValue, gd::Project &project, gd::Layout &layout +) { if (propertyName == "animation") { - instance.SetRawDoubleProperty( - "animation", std::max(0, newValue.empty() ? 0 : newValue.To())); + instance.SetRawDoubleProperty("animation", std::max(0, newValue.empty() ? 0 : newValue.To())); } return true; @@ -110,10 +110,9 @@ std::map SpineObjectConfiguration::GetInitialInstanceProperties(const gd::InitialInstance &instance, gd::Project &project, gd::Layout &layout) { std::map properties; properties["animation"] = - gd::PropertyDescriptor( - gd::String::From(instance.GetRawDoubleProperty("animation"))) - .SetLabel(_("Animation")) - .SetType("number"); + gd::PropertyDescriptor(gd::String::From(instance.GetRawDoubleProperty("animation"))) + .SetLabel(_("Animation")) + .SetType("number"); return properties; } @@ -141,8 +140,7 @@ void SpineObjectConfiguration::DoUnserializeFrom(gd::Project &project, const gd: } } -void SpineObjectConfiguration::DoSerializeTo( - gd::SerializerElement &element) const { +void SpineObjectConfiguration::DoSerializeTo(gd::SerializerElement &element) const { auto &content = element.AddChild("content"); content.SetAttribute("scale", scale); content.SetAttribute("opacity", opacity); diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index e18e286dc329..f242b91f903d 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -2,17 +2,13 @@ namespace gdjs { import PIXI = GlobalPIXIModule.PIXI; import PIXI_SPINE = GlobalPIXIModule.PIXI_SPINE; - type SpineCb = (s: PIXI_SPINE.Spine) => T; - /** * The PIXI.js renderer for the Bitmap Text runtime object. */ export class SpineRuntimeObjectPixiRenderer { _object: gdjs.SpineRuntimeObject; _pixiObject: PIXI.Container; - _spine?: PIXI_SPINE.Spine; - _spinePromise!: Promise; - private _isUpdatable = true; + _spine!: PIXI_SPINE.Spine; private _isAnimationCompelete = true; get isAnimationCompelete() { @@ -20,12 +16,11 @@ namespace gdjs { } get isUpdatable() { - return this._isUpdatable; + return this._spine.autoUpdate; } set isUpdatable(isUpdatable: boolean) { - this._isUpdatable = isUpdatable; - this.applySpineAction(spine => spine.autoUpdate = this._isUpdatable); + this._spine.autoUpdate = isUpdatable } /** @@ -62,7 +57,7 @@ namespace gdjs { } updateTimeScale() { - this.applySpineAction(spine => spine.state.timeScale = this._object.getTimeScale()); + this._spine.state.timeScale = this._object.getTimeScale(); } updateScale(): void { @@ -96,79 +91,46 @@ namespace gdjs { } setWidth(width: float): void { - this.applySpineAction(spine => { - spine.width = width; - this.updateBounds(spine); - }) + this._spine.width = width; + this.updateBounds(this._spine); } setHeight(height: float): void { - this.applySpineAction(spine => { - spine.height = height; - this.updateBounds(spine); - }); + this._spine.height = height; + this.updateBounds(this._spine); } setSize(width: float, height: float): void { - this.applySpineAction(spine => { - spine.width = width; - spine.height = height; - this.updateBounds(spine); - }); + this._spine.width = width; + this._spine.height = height; + this.updateBounds(this._spine); } setAnimation(animation: string, loop: boolean) { - this.applySpineAction(s => { - this._isAnimationCompelete = false; - s.state.addListener({ complete: () => this._isAnimationCompelete = true }); - s.state.setAnimation(0, animation, loop); - this.updateBounds(s); - }); - } - - private applySpineAction(action: SpineCb) { - if (this._spine) { - action(this._spine); - } else { - this._spinePromise.then(action); - } + this._isAnimationCompelete = false; + this._spine.state.addListener({ complete: () => this._isAnimationCompelete = true }); + this._spine.state.setAnimation(0, animation, loop); + this._spine.update(0); + this.updateBounds(this._spine); } private constructSpine() { const game = this.instanceContainer.getGame(); const spineJson = game.getJsonManager().getLoadedJson(this._object.jsonResourceName)!; - const atlasText = game.getTextManager().get(this._object.atlasResourceName)!; - const atlasImage = game.getImageManager().getPIXITexture(this._object.imageResourceName)!; + const atlas = game.getTextManager().getAtlasTexture(this._object.atlasResourceName)!; - this._spinePromise = this.getSpineSkeleton(spineJson, atlasText, atlasImage) - .then(skeleton => { - this._spine = new PIXI_SPINE.Spine(skeleton); - this._pixiObject.addChild(this._spine); - this.updateBounds(this._spine); - - return this._spine; - }); + const resourceMoc = {}; + const spineParser = new PIXI_SPINE.SpineParser(); + spineParser.parseData(resourceMoc as any, spineParser.createJsonParser(), atlas, spineJson); + this._spine = new PIXI_SPINE.Spine((resourceMoc as unknown as { spineData: PIXI_SPINE.ISkeletonData }).spineData); + this._pixiObject.addChild(this._spine); + this.updateBounds(this._spine); } private updateBounds(s: PIXI_SPINE.Spine) { const localBounds = s.getLocalBounds(undefined, true); s.position.set(-localBounds.x * s.scale.x, -localBounds.y * s.scale.y); } - - private getSpineSkeleton(spineJson: Object, atlasText: string, atlasImage: PIXI.Texture) { - return new Promise((resolve) => { - new PIXI_SPINE.TextureAtlas( - atlasText, - (_, textureCb) => textureCb(atlasImage.baseTexture), - (atlas) => { - const resourceMoc = {}; - const spineParser = new PIXI_SPINE.SpineParser(); - spineParser.parseData(resourceMoc as any, spineParser.createJsonParser(), atlas, spineJson); - - resolve((resourceMoc as unknown as { spineData: PIXI_SPINE.ISkeletonData }).spineData); - }); - }); - } } export const SpineRuntimeObjectRenderer = SpineRuntimeObjectPixiRenderer; } diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 721fe4cb6858..997f943cb0d5 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -19,7 +19,7 @@ namespace gdjs { private _scale: number; private _timeScale: number; private _animations: SpineAnimation[]; - private _currentAnimationIndex!: number; + private _currentAnimationIndex = 0; private _renderer: gdjs.SpineRuntimeObjectPixiRenderer; readonly jsonResourceName: string; @@ -74,11 +74,14 @@ namespace gdjs { } extraInitializationFromInitialInstance(initialInstanceData: InstanceData) { + let animationIndex = this._currentAnimationIndex; for (const extraData of initialInstanceData.numberProperties || []) { if (extraData.name === 'animation') { - this.setAnimationIndex(extraData.value); + animationIndex = extraData.value; } } + this.setAnimationIndex(animationIndex); + if (initialInstanceData.customSize) { // prioritize custom size this.setScale(1); diff --git a/GDJS/GDJS/IDE/ExporterHelper.cpp b/GDJS/GDJS/IDE/ExporterHelper.cpp index 33556c257e69..7b08f8f6793c 100644 --- a/GDJS/GDJS/IDE/ExporterHelper.cpp +++ b/GDJS/GDJS/IDE/ExporterHelper.cpp @@ -624,7 +624,6 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers, InsertUnique(includesFiles, "AsyncTasksManager.js"); InsertUnique(includesFiles, "inputmanager.js"); InsertUnique(includesFiles, "jsonmanager.js"); - InsertUnique(includesFiles, "textmanager.js"); InsertUnique(includesFiles, "Model3DManager.js"); InsertUnique(includesFiles, "timemanager.js"); InsertUnique(includesFiles, "polygon.js"); @@ -698,6 +697,7 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers, InsertUnique(includesFiles, "pixi-renderers/runtimescene-pixi-renderer.js"); InsertUnique(includesFiles, "pixi-renderers/layer-pixi-renderer.js"); InsertUnique(includesFiles, "pixi-renderers/pixi-image-manager.js"); + InsertUnique(includesFiles, "textmanager.js"); InsertUnique(includesFiles, "pixi-renderers/pixi-bitmapfont-manager.js"); InsertUnique(includesFiles, "pixi-renderers/spriteruntimeobject-pixi-renderer.js"); diff --git a/GDJS/Runtime/runtimegame.ts b/GDJS/Runtime/runtimegame.ts index 6e7cb86c68fe..e6bb18da1822 100644 --- a/GDJS/Runtime/runtimegame.ts +++ b/GDJS/Runtime/runtimegame.ts @@ -230,7 +230,8 @@ namespace gdjs { ); this._textManager = new gdjs.TextManager( this._data.resources.resources, - this._resourcesLoader + this._resourcesLoader, + this._imageManager ) this._bitmapFontManager = new gdjs.BitmapFontManager( this._data.resources.resources, diff --git a/GDJS/Runtime/textmanager.ts b/GDJS/Runtime/textmanager.ts index 5a254cf5159e..9b97ee87e6be 100644 --- a/GDJS/Runtime/textmanager.ts +++ b/GDJS/Runtime/textmanager.ts @@ -5,6 +5,7 @@ */ namespace gdjs { const logger = new gdjs.Logger('Text Manager'); + import PIXI_SPINE = GlobalPIXIModule.PIXI_SPINE; type TextManagerOnProgressCallback = ( loadedCount: integer, totalCount: integer @@ -33,6 +34,7 @@ namespace gdjs { _resources: ResourceData[]; _loadedTexts: { [key: string]: string } = {}; + _loadedTextureAtlases: { [key: string]: PIXI_SPINE.TextureAtlas } = {}; _callbacks: { [key: string]: Array } = {}; /** @@ -41,7 +43,8 @@ namespace gdjs { */ constructor( resources: ResourceData[], - resourcesLoader: RuntimeGameResourcesLoader + resourcesLoader: RuntimeGameResourcesLoader, + private _imageManager: ImageManager ) { this._resources = resources; this._resourcesLoader = resourcesLoader; @@ -125,7 +128,17 @@ namespace gdjs { this.callCallback(resourceName, `HTTP error: ${xhr.status} (${xhr.statusText })`, null); } else { this._loadedTexts[resourceName] = xhr.response; - this.callCallback(resourceName, null, xhr.response); + + new PIXI_SPINE.TextureAtlas( + xhr.response, + (path, textureCb) => { + const atlasImagePath = resourceName.substring(0, resourceName.lastIndexOf('/') + 1) + path; + textureCb(this._imageManager.getPIXITexture(atlasImagePath).baseTexture) + }, + (atlas) => { + this._loadedTextureAtlases[resourceName] = atlas; + this.callCallback(resourceName, null, xhr.response); + }); } }; xhr.onerror = () => this.callCallback(resourceName, 'Network error', null); @@ -162,8 +175,12 @@ namespace gdjs { * @param resourceName The name of the text resource. * @returns the content of the text resource, if loaded. `null` otherwise. */ - get(resourceName: string): string | null { + getText(resourceName: string): string | null { return this._loadedTexts[resourceName] || null; } + + getAtlasTexture(resourceName: string): PIXI_SPINE.TextureAtlas | null { + return this._loadedTextureAtlases[resourceName] || null; + } } } From 6ecd04e722ccecb1e03747218b69d6ee14f93519 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Thu, 17 Aug 2023 12:36:58 +0300 Subject: [PATCH 06/80] use regex to get atlas image path --- GDJS/Runtime/textmanager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GDJS/Runtime/textmanager.ts b/GDJS/Runtime/textmanager.ts index 9b97ee87e6be..d4d791f39f7c 100644 --- a/GDJS/Runtime/textmanager.ts +++ b/GDJS/Runtime/textmanager.ts @@ -132,7 +132,7 @@ namespace gdjs { new PIXI_SPINE.TextureAtlas( xhr.response, (path, textureCb) => { - const atlasImagePath = resourceName.substring(0, resourceName.lastIndexOf('/') + 1) + path; + const atlasImagePath = resourceName.match(/(^.*[\\\/]|^[^\\\/].*)/i)![0] + path; textureCb(this._imageManager.getPIXITexture(atlasImagePath).baseTexture) }, (atlas) => { From 88cda55573a42e64df96be07a338f52c765a6c7a Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Fri, 18 Aug 2023 15:15:13 +0300 Subject: [PATCH 07/80] fix spine extension issues --- Extensions/Spine/JsExtension.js | 2 +- Extensions/Spine/spineruntimeobject.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 3953d2751d5a..28bc3f041e82 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -138,7 +138,7 @@ module.exports = { .useStandardParameters('number', gd.ParameterOptions.makeNewOptions()) .markAsSimple() .setFunctionName('setAnimationIndex') - .setGetter('getAnimationIndex'); + .setGetter('getCurrentAnimationIndex'); object .addExpressionAndConditionAndAction( diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 997f943cb0d5..d1525ac6efe2 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -177,7 +177,7 @@ namespace gdjs { getAnimationName(): string { return this.isAnimationIndex(this._currentAnimationIndex) ? - '' : this._animations[this._currentAnimationIndex].name; + this._animations[this._currentAnimationIndex].name : ''; } getAnimationIndex(animationName: string) { From 9ed5fbc6cfdebc74f24dbf8393b85ac99363f204 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 22 Aug 2023 13:31:12 +0300 Subject: [PATCH 08/80] clean up code --- Extensions/Spine/JsExtension.js | 9 +-- .../Spine/spineruntimeobject-pixi-renderer.ts | 65 ++++++++----------- Extensions/Spine/spineruntimeobject.ts | 6 +- GDJS/GDJS/IDE/ExporterHelper.cpp | 2 +- .../pixi-atlas-manager.ts} | 51 ++++++++------- GDJS/Runtime/runtimegame.ts | 12 ++-- GDJS/tests/karma.conf.js | 1 - .../ObjectsRendering/PixiResourcesLoader.js | 13 +++- 8 files changed, 77 insertions(+), 82 deletions(-) rename GDJS/Runtime/{textmanager.ts => pixi-renderers/pixi-atlas-manager.ts} (77%) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 28bc3f041e82..e3b9d626c9f9 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -238,12 +238,10 @@ module.exports = { this._pixiContainer.addChild(this._pixiObject); this.loadSpine(); - this.update(); } - // use smth better. can I create texture of default spine stage ? static getThumbnail(project, resourcesLoader, objectConfiguration) { - return 'JsPlatform/Extensions/3d_box.svg'; + return 'CppPlatform/Extensions/spriteicon.png'; } loadSpine() { @@ -253,7 +251,7 @@ module.exports = { this._pixiResourcesLoader .getSpineData(this._project, jsonResourceName, imageResourceName, atlasResourceName) - .then((spineData) => {; + .then((spineData) => { this._spine = new PIXI.Spine(spineData); this._pixiObject.addChild(this._spine); this.update(); @@ -261,10 +259,8 @@ module.exports = { } update() { - // instance settings this._pixiObject.position.set(this._instance.getX(), this._instance.getY()); - // object settings this.setAnimation(this._instance.getRawDoubleProperty('animation')); const width = this.getWidth(); @@ -295,7 +291,6 @@ module.exports = { return; } - // should I do that ? maybe just { return; } ? if (!Number.isInteger(index) || index < 0) { index = 0; } else if (configuration.getAnimationsCount() <= index) { diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index f242b91f903d..63a570343819 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -1,13 +1,8 @@ namespace gdjs { - import PIXI = GlobalPIXIModule.PIXI; import PIXI_SPINE = GlobalPIXIModule.PIXI_SPINE; - /** - * The PIXI.js renderer for the Bitmap Text runtime object. - */ export class SpineRuntimeObjectPixiRenderer { _object: gdjs.SpineRuntimeObject; - _pixiObject: PIXI.Container; _spine!: PIXI_SPINE.Spine; private _isAnimationCompelete = true; @@ -32,28 +27,26 @@ namespace gdjs { private instanceContainer: gdjs.RuntimeInstanceContainer ) { this._object = runtimeObject; - this._pixiObject = new PIXI.Container(); - this.constructSpine(); - - // Set the object on the scene - instanceContainer - .getLayer('') - .getRenderer() - .addRendererObject(this._pixiObject, runtimeObject.getZOrder()); + this.constructSpine(); this.updateTimeScale(); this.updatePosition(); this.updateAngle(); this.updateOpacity(); this.updateScale(); + + instanceContainer + .getLayer('') + .getRenderer() + .addRendererObject(this._spine, runtimeObject.getZOrder()); } getRendererObject() { - return this._pixiObject; + return this._spine; } onDestroy() { - this._pixiObject.destroy(); + this._spine.destroy(); } updateTimeScale() { @@ -61,49 +54,44 @@ namespace gdjs { } updateScale(): void { - this._pixiObject.scale.set(Math.max(this._object.getScale(), 0)); - } - - getScale() { - // is it ok ? see it as a pattern - return Math.max(this._pixiObject.scale.x, this._pixiObject.scale.y); + this._spine.scale.set(Math.max(this._object.getScale(), 0)); + this.updateBounds(); } updatePosition(): void { - this._pixiObject.position.x = this._object.x; - this._pixiObject.position.y = this._object.y; + this.updateBounds(); } updateAngle(): void { - this._pixiObject.rotation = gdjs.toRad(this._object.angle); + this._spine.rotation = gdjs.toRad(this._object.angle); } updateOpacity(): void { - this._pixiObject.alpha = this._object.getOpacity() / 255; + this._spine.alpha = this._object.getOpacity() / 255; } getWidth(): float { - return this._pixiObject.width; + return this._spine.width; } getHeight(): float { - return this._pixiObject.height; + return this._spine.height; } setWidth(width: float): void { this._spine.width = width; - this.updateBounds(this._spine); + this.updateBounds(); } setHeight(height: float): void { this._spine.height = height; - this.updateBounds(this._spine); + this.updateBounds(); } setSize(width: float, height: float): void { this._spine.width = width; this._spine.height = height; - this.updateBounds(this._spine); + this.updateBounds(); } setAnimation(animation: string, loop: boolean) { @@ -111,25 +99,28 @@ namespace gdjs { this._spine.state.addListener({ complete: () => this._isAnimationCompelete = true }); this._spine.state.setAnimation(0, animation, loop); this._spine.update(0); - this.updateBounds(this._spine); + this.updateBounds(); } private constructSpine() { const game = this.instanceContainer.getGame(); const spineJson = game.getJsonManager().getLoadedJson(this._object.jsonResourceName)!; - const atlas = game.getTextManager().getAtlasTexture(this._object.atlasResourceName)!; + const atlas = game.getAtlasManager().getAtlasTexture(this._object.atlasResourceName)!; const resourceMoc = {}; const spineParser = new PIXI_SPINE.SpineParser(); spineParser.parseData(resourceMoc as any, spineParser.createJsonParser(), atlas, spineJson); this._spine = new PIXI_SPINE.Spine((resourceMoc as unknown as { spineData: PIXI_SPINE.ISkeletonData }).spineData); - this._pixiObject.addChild(this._spine); - this.updateBounds(this._spine); } - private updateBounds(s: PIXI_SPINE.Spine) { - const localBounds = s.getLocalBounds(undefined, true); - s.position.set(-localBounds.x * s.scale.x, -localBounds.y * s.scale.y); + private updateBounds() { + this._spine.position.x = this._object.x; + this._spine.position.y = this._object.y; + + const localBounds = this._spine.getLocalBounds(undefined, true); + + this._spine.position.x -= localBounds.x * this._spine.scale.x; + this._spine.position.y -= localBounds.y * this._spine.scale.y; } } export const SpineRuntimeObjectRenderer = SpineRuntimeObjectPixiRenderer; diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index d1525ac6efe2..e801ea0d1747 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -57,13 +57,12 @@ namespace gdjs { oldObjectData: SpineObjectData, newObjectData: SpineObjectData ): boolean { - super.updateFromObjectData + super.updateFromObjectData(oldObjectData, newObjectData); + if (oldObjectData.content.opacity !== newObjectData.content.opacity) { this.setOpacity(newObjectData.content.opacity); } if (oldObjectData.content.scale !== newObjectData.content.scale) { - // should I prioritize custom size here ? - // is there a same cb if instance properties have been changed ? this.setScale(newObjectData.content.scale); } if (oldObjectData.content.timeScale !== newObjectData.content.timeScale) { @@ -83,7 +82,6 @@ namespace gdjs { this.setAnimationIndex(animationIndex); if (initialInstanceData.customSize) { - // prioritize custom size this.setScale(1); this._renderer.setSize(initialInstanceData.width, initialInstanceData.height); this.invalidateHitboxes(); diff --git a/GDJS/GDJS/IDE/ExporterHelper.cpp b/GDJS/GDJS/IDE/ExporterHelper.cpp index 7b08f8f6793c..db7409608b6c 100644 --- a/GDJS/GDJS/IDE/ExporterHelper.cpp +++ b/GDJS/GDJS/IDE/ExporterHelper.cpp @@ -697,7 +697,7 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers, InsertUnique(includesFiles, "pixi-renderers/runtimescene-pixi-renderer.js"); InsertUnique(includesFiles, "pixi-renderers/layer-pixi-renderer.js"); InsertUnique(includesFiles, "pixi-renderers/pixi-image-manager.js"); - InsertUnique(includesFiles, "textmanager.js"); + InsertUnique(includesFiles, "pixi-renderers/pixi-atlas-manager.js"); InsertUnique(includesFiles, "pixi-renderers/pixi-bitmapfont-manager.js"); InsertUnique(includesFiles, "pixi-renderers/spriteruntimeobject-pixi-renderer.js"); diff --git a/GDJS/Runtime/textmanager.ts b/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts similarity index 77% rename from GDJS/Runtime/textmanager.ts rename to GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts index d4d791f39f7c..f8fd4fbfc6df 100644 --- a/GDJS/Runtime/textmanager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts @@ -4,38 +4,39 @@ * This project is released under the MIT License. */ namespace gdjs { - const logger = new gdjs.Logger('Text Manager'); import PIXI_SPINE = GlobalPIXIModule.PIXI_SPINE; - type TextManagerOnProgressCallback = ( + + const logger = new gdjs.Logger('Text Manager'); + type AtlasManagerOnProgressCallback = ( loadedCount: integer, totalCount: integer ) => void; - type TextManagerOnCompleteCallback = (totalCount: integer) => void; + type AtlasManagerOnCompleteCallback = (totalCount: integer) => void; /** The callback called when a text that was requested is loaded (or an error occurred). */ - export type TextManagerRequestCallback = ( + export type AtlasManagerRequestCallback = ( error: Error | null, content: Object | null ) => void; - const textKinds: ReadonlyArray = ['atlas']; - const isTextResource = (resource: ResourceData) => textKinds.includes(resource.kind); + const atlasKinds: ReadonlyArray = ['atlas']; + const isTextResource = (resource: ResourceData) => atlasKinds.includes(resource.kind); /** - * TextManager loads text files (using `XMLHttpRequest`), using the "atlas" resources - * registered in the game resources. + * AtlasManager loads text files (using `XMLHttpRequest`), using the "atlas" resources + * registered in the game resources and process them to Pixi TextureAtlas. * * Contrary to audio/fonts, text files are loaded asynchronously, when requested. * You should properly handle errors, and give the developer/player a way to know * that loading failed. */ - export class TextManager { + export class AtlasManager { _resourcesLoader: RuntimeGameResourcesLoader; _resources: ResourceData[]; - _loadedTexts: { [key: string]: string } = {}; + _loadedAtlases: { [key: string]: string } = {}; _loadedTextureAtlases: { [key: string]: PIXI_SPINE.TextureAtlas } = {}; - _callbacks: { [key: string]: Array } = {}; + _callbacks: { [key: string]: Array } = {}; /** * @param resources The resources data of the game. @@ -69,15 +70,14 @@ namespace gdjs { * @param onComplete The function called when all texts are loaded. */ preload( - onProgress: TextManagerOnProgressCallback, - onComplete: TextManagerOnCompleteCallback + onProgress: AtlasManagerOnProgressCallback, + onComplete: AtlasManagerOnCompleteCallback ): void { - const resources = this._resources; - const textResources = resources.filter((resource) => isTextResource(resource) && !resource.disablePreload); + const textResources = this._resources.filter((resource) => isTextResource(resource) && !resource.disablePreload); if (!textResources.length) { return onComplete(0); } let loaded = 0; - const onLoad: TextManagerRequestCallback = (error) => { + const onLoad: AtlasManagerRequestCallback = (error) => { if (error) { logger.error('Error while preloading a text resource:' + error); } @@ -100,7 +100,7 @@ namespace gdjs { * @param resourceName The resource pointing to the json file to load. * @param callback The callback function called when json is loaded (or an error occurred). */ - load(resourceName: string, callback: TextManagerRequestCallback): void { + load(resourceName: string, callback: AtlasManagerRequestCallback): void { const resource = this._resources.find((resource) => isTextResource(resource) && resource.name === resourceName); if (!resource) { return callback(new Error(`Can't find resource with name: "${resourceName}" (or is not a text resource).`), null); @@ -108,7 +108,7 @@ namespace gdjs { // Don't fetch again an object that is already in memory if (this.isLoaded(resourceName)) { - return callback(null, this._loadedTexts[resourceName]); + return callback(null, this._loadedAtlases[resourceName]); } // Don't fetch again an object that is already being fetched. @@ -127,7 +127,7 @@ namespace gdjs { if (xhr.status !== 200) { this.callCallback(resourceName, `HTTP error: ${xhr.status} (${xhr.statusText })`, null); } else { - this._loadedTexts[resourceName] = xhr.response; + this._loadedAtlases[resourceName] = xhr.response; new PIXI_SPINE.TextureAtlas( xhr.response, @@ -165,20 +165,25 @@ namespace gdjs { * @returns true if the content of the text resource is loaded. false otherwise. */ isLoaded(resourceName: string): boolean { - return typeof this._loadedTexts[resourceName] === 'string'; + return typeof this._loadedAtlases[resourceName] === 'string'; } /** - * Get the object for the given resource that is already loaded (preloaded or loaded with `load`). + * Get the raw atlas text for the given resource that is already loaded (preloaded or loaded with `load`). * If the resource is not loaded, `null` will be returned. - * * @param resourceName The name of the text resource. * @returns the content of the text resource, if loaded. `null` otherwise. */ getText(resourceName: string): string | null { - return this._loadedTexts[resourceName] || null; + return this.isLoaded(resourceName) ? this._loadedAtlases[resourceName] : null; } + /** + * Get the Pixi TextureAtlas for the given resource that is already loaded (preloaded or loaded with `load`). + * If the resource is not loaded, `null` will be returned. + * @param resourceName The name of the text resource. + * @returns the TextureAtlas of the atlas, if loaded. `null` otherwise. + */ getAtlasTexture(resourceName: string): PIXI_SPINE.TextureAtlas | null { return this._loadedTextureAtlases[resourceName] || null; } diff --git a/GDJS/Runtime/runtimegame.ts b/GDJS/Runtime/runtimegame.ts index e6bb18da1822..559542484ba4 100644 --- a/GDJS/Runtime/runtimegame.ts +++ b/GDJS/Runtime/runtimegame.ts @@ -140,7 +140,7 @@ namespace gdjs { _soundManager: SoundManager; _fontManager: FontManager; _jsonManager: JsonManager; - _textManager: TextManager; + _atlasManager: AtlasManager; _model3DManager: Model3DManager; _effectsManager: EffectsManager; _bitmapFontManager: BitmapFontManager; @@ -228,7 +228,7 @@ namespace gdjs { this._data.resources.resources, this._resourcesLoader ); - this._textManager = new gdjs.TextManager( + this._atlasManager = new gdjs.AtlasManager( this._data.resources.resources, this._resourcesLoader, this._imageManager @@ -326,7 +326,7 @@ namespace gdjs { this._soundManager, this._fontManager, this._jsonManager, - this._textManager, + this._atlasManager, this._bitmapFontManager, this._model3DManager, ].forEach((manager) => manager.setResources(resources)); @@ -408,8 +408,8 @@ namespace gdjs { * resources. * @return The text manager for the game */ - getTextManager(): gdjs.TextManager { - return this._textManager; + getAtlasManager(): gdjs.AtlasManager { + return this._atlasManager; } /** @@ -779,7 +779,7 @@ namespace gdjs { } }, function (model3DTotalCount) { - that._textManager.preload( + that._atlasManager.preload( function (count, total) { const percent = Math.floor( ((texturesTotalCount + diff --git a/GDJS/tests/karma.conf.js b/GDJS/tests/karma.conf.js index 730b441e7b75..9e68cc0208c9 100644 --- a/GDJS/tests/karma.conf.js +++ b/GDJS/tests/karma.conf.js @@ -49,7 +49,6 @@ module.exports = function (config) { './newIDE/app/resources/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver.js', './newIDE/app/resources/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js', './newIDE/app/resources/GDJS/Runtime/jsonmanager.js', - './newIDE/app/resources/GDJS/Runtime/textmanager.js', './newIDE/app/resources/GDJS/Runtime/Model3DManager.js', './newIDE/app/resources/GDJS/Runtime/timemanager.js', './newIDE/app/resources/GDJS/Runtime/polygon.js', diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 43f983780350..21b05ffceb01 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -356,6 +356,14 @@ export default class PixiResourcesLoader { return loadingPromise; } + /** + * Return the Pixi spine data to the specified resource names. + * @param project The project + * @param spineName The name of the spine json resource + * @param atlasImageName The name of the atlas image resource + * @param atlasTextName The name of the atlas text resource + * @returns The requested material. + */ static async getSpineData( project: gdProject, spineName: string, @@ -381,11 +389,10 @@ export default class PixiResourcesLoader { // https://github.com/pixijs/spine/blob/master/examples/preload_atlas_text.md if (!atlasPromises[atlasTextName]) { - atlasPromises[atlasTextName] = new Promise(resolve => { + atlasPromises[atlasTextName] = new Promise(resolve => loader .add(atlasTextName, ResourcesLoader.getResourceFullUrl(project, atlasTextName, { isResourceForPixi: true }), { xhrType: 'text' }) - .load((_, atlasData) => resolve(atlasData[atlasTextName].data)) - }); + .load((_, atlasData) => resolve(atlasData[atlasTextName].data))); } if (!spineDataPromises[spineName]) { From 01c2afcdd39090273b05df2b8545e7aaad12af75 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 22 Aug 2023 14:23:17 +0300 Subject: [PATCH 09/80] solve flow test errors --- Extensions/Spine/JsExtension.js | 8 ++++---- newIDE/app/src/ObjectEditor/Editors/SpineEditor.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index e3b9d626c9f9..6ebbc91dc2d2 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -204,7 +204,7 @@ module.exports = { registerInstanceRenderers: function ( objectsRenderingService /*: ObjectsRenderingService */ ) { - const { PIXI, RenderedInstance } = objectsRenderingService; + const { PIXI, RenderedInstance, gd } = objectsRenderingService; class RenderedSpineInstance extends RenderedInstance { _spine; @@ -299,9 +299,9 @@ module.exports = { this._animationIndex = index; const animation = configuration.getAnimation(index); - const name = animation.getName?.(); - const source = animation.getSource?.(); - const shouldLoop = animation.shouldLoop?.(); + const name = animation.getName(); + const source = animation.getSource(); + const shouldLoop = animation.shouldLoop(); // reset scale to track new animation range // if custome size is set it will be reinitialized in update method diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 22084b99a510..54bac5e1d96a 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -29,7 +29,7 @@ import useAlertDialog from '../../UI/Alert/useAlertDialog'; import { PropertyResourceSelector, PropertyField, styles } from './Model3DEditor'; import { ISkeletonData } from 'pixi-spine'; -const { gd }: libGDevelop = global; +const gd: libGDevelop = global.gd; const DragSourceAndDropTarget = makeDragSourceAndDropTarget( 'spine-animations-list' From 95f54749b40cf224a05462d37c8787bf024b30b6 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 22 Aug 2023 14:23:59 +0300 Subject: [PATCH 10/80] apply format --- .../ParameterFields/AtlasResourceField.js | 4 +-- .../src/ObjectEditor/Editors/Model3DEditor.js | 2 +- .../src/ObjectEditor/Editors/SpineEditor.js | 33 ++++++++++++++----- .../ObjectsRendering/PixiResourcesLoader.js | 28 ++++++++++++---- .../ResourcesList/BrowserResourceSources.js | 27 +++++++-------- .../src/ResourcesList/LocalResourceSources.js | 27 +++++++-------- .../app/src/ResourcesList/ResourceSelector.js | 2 +- 7 files changed, 76 insertions(+), 47 deletions(-) diff --git a/newIDE/app/src/EventsSheet/ParameterFields/AtlasResourceField.js b/newIDE/app/src/EventsSheet/ParameterFields/AtlasResourceField.js index f8515e2a6296..a43feee70ac6 100644 --- a/newIDE/app/src/EventsSheet/ParameterFields/AtlasResourceField.js +++ b/newIDE/app/src/EventsSheet/ParameterFields/AtlasResourceField.js @@ -39,9 +39,7 @@ export default React.forwardRef( fullWidth initialResourceName={props.value} onChange={props.onChange} - floatingLabelText={ - Choose the atlas file (.atlas) to use - } + floatingLabelText={Choose the atlas file (.atlas) to use} onRequestClose={props.onRequestClose} onApply={props.onApply} ref={field} diff --git a/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js b/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js index d16288803fbb..24e75f46a15b 100644 --- a/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js @@ -254,7 +254,7 @@ const Model3DEditor = ({ const forceUpdate = useForceUpdate(); const model3DConfiguration = gd.asModel3DConfiguration(objectConfiguration); - console.log('Model3DEditod, ', model3DConfiguration, objectConfiguration) + console.log('Model3DEditod, ', model3DConfiguration, objectConfiguration); const properties = objectConfiguration.getProperties(); const [nameErrors, setNameErrors] = React.useState<{ [number]: React.Node }>( diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 54bac5e1d96a..0b20a2532112 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -26,7 +26,11 @@ import DropIndicator from '../../UI/SortableVirtualizedItemList/DropIndicator'; import GDevelopThemeContext from '../../UI/Theme/GDevelopThemeContext'; import PixiResourcesLoader from '../../ObjectsRendering/PixiResourcesLoader'; import useAlertDialog from '../../UI/Alert/useAlertDialog'; -import { PropertyResourceSelector, PropertyField, styles } from './Model3DEditor'; +import { + PropertyResourceSelector, + PropertyField, + styles, +} from './Model3DEditor'; import { ISkeletonData } from 'pixi-spine'; const gd: libGDevelop = global.gd; @@ -74,7 +78,7 @@ const SpineEditor = ({ const forceUpdate = useForceUpdate(); const spineConfiguration = gd.asSpineConfiguration(objectConfiguration); - console.log('SpineEditod, ', spineConfiguration, objectConfiguration) + console.log('SpineEditod, ', spineConfiguration, objectConfiguration); const properties = objectConfiguration.getProperties(); const [nameErrors, setNameErrors] = React.useState<{ [number]: React.Node }>( @@ -83,16 +87,27 @@ const SpineEditor = ({ const [skeleton, setSkeleton] = React.useState(null); const getSkeleton = React.useCallback( - (jsonResourceName: string, imageResourceName: string, atlasResourceName: string) => { - if ([jsonResourceName, imageResourceName, atlasResourceName].some(resName => !resName)) { + ( + jsonResourceName: string, + imageResourceName: string, + atlasResourceName: string + ) => { + if ( + [jsonResourceName, imageResourceName, atlasResourceName].some( + resName => !resName + ) + ) { return; } - PixiResourcesLoader.getSpineData(project, jsonResourceName, imageResourceName, atlasResourceName).then( - newSkeleton => { - setSkeleton(newSkeleton); - } - ); + PixiResourcesLoader.getSpineData( + project, + jsonResourceName, + imageResourceName, + atlasResourceName + ).then(newSkeleton => { + setSkeleton(newSkeleton); + }); }, [project] ); diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index ca61c23f7447..b6b16bf2e2e0 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -375,16 +375,25 @@ export default class PixiResourcesLoader { return Promise.reject(`Unknown ${resKind} file ${resName}.`); } if (resourceManager.getResource(resName).getKind() !== resKind) { - return Promise.reject(`The resource called ${resName} is not of appropriate file type ${resKind}.`); + return Promise.reject( + `The resource called ${resName} is not of appropriate file type ${resKind}.` + ); } } - + // https://github.com/pixijs/spine/blob/master/examples/preload_atlas_text.md if (!atlasPromises[atlasTextName]) { atlasPromises[atlasTextName] = new Promise(resolve => loader - .add(atlasTextName, ResourcesLoader.getResourceFullUrl(project, atlasTextName, { isResourceForPixi: true }), { xhrType: 'text' }) - .load((_, atlasData) => resolve(atlasData[atlasTextName].data))); + .add( + atlasTextName, + ResourcesLoader.getResourceFullUrl(project, atlasTextName, { + isResourceForPixi: true, + }), + { xhrType: 'text' } + ) + .load((_, atlasData) => resolve(atlasData[atlasTextName].data)) + ); } if (!spineDataPromises[spineName]) { @@ -396,9 +405,15 @@ export default class PixiResourcesLoader { }; loader - .add(spineName, ResourcesLoader.getResourceFullUrl(project, spineName, { isResourceForPixi: true }), { metadata }) + .add( + spineName, + ResourcesLoader.getResourceFullUrl(project, spineName, { + isResourceForPixi: true, + }), + { metadata } + ) .load((_, jsonData) => resolve(jsonData[spineName].spineData)); - }) + }); }); } @@ -586,5 +601,4 @@ export default class PixiResourcesLoader { }) .then(response => response.data); } - } diff --git a/newIDE/app/src/ResourcesList/BrowserResourceSources.js b/newIDE/app/src/ResourcesList/BrowserResourceSources.js index 2c47110216b3..8c67d5aa890d 100644 --- a/newIDE/app/src/ResourcesList/BrowserResourceSources.js +++ b/newIDE/app/src/ResourcesList/BrowserResourceSources.js @@ -200,19 +200,20 @@ const browserResourceSources: Array = [ ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => { console.log('Choose from asset store Browser'); return { - name: `resource-store-${kind}`, - displayName: t`Choose from asset store`, - displayTab: 'standalone', - kind, - renderComponent: (props: ResourceSourceComponentProps) => ( - - ), - }}), + name: `resource-store-${kind}`, + displayName: t`Choose from asset store`, + displayTab: 'standalone', + kind, + renderComponent: (props: ResourceSourceComponentProps) => ( + + ), + }; + }), ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => ({ name: `url-chooser-${kind}`, displayName: t`Use a public URL`, diff --git a/newIDE/app/src/ResourcesList/LocalResourceSources.js b/newIDE/app/src/ResourcesList/LocalResourceSources.js index 8ab7f5deaadc..19074a650aaa 100644 --- a/newIDE/app/src/ResourcesList/LocalResourceSources.js +++ b/newIDE/app/src/ResourcesList/LocalResourceSources.js @@ -232,19 +232,20 @@ const localResourceSources: Array = [ ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => { console.log('Choose from asset store Local'); return { - name: `resource-store-${kind}`, - displayName: t`Choose from asset store`, - displayTab: 'standalone', - kind, - renderComponent: (props: ResourceSourceComponentProps) => ( - - ), - }}), + name: `resource-store-${kind}`, + displayName: t`Choose from asset store`, + displayTab: 'standalone', + kind, + renderComponent: (props: ResourceSourceComponentProps) => ( + + ), + }; + }), ]; export default localResourceSources; diff --git a/newIDE/app/src/ResourcesList/ResourceSelector.js b/newIDE/app/src/ResourcesList/ResourceSelector.js index 5c22454d90fd..d2696d522aaf 100644 --- a/newIDE/app/src/ResourcesList/ResourceSelector.js +++ b/newIDE/app/src/ResourcesList/ResourceSelector.js @@ -183,7 +183,7 @@ const ResourceSelector = React.forwardRef( async (source: ResourceSource) => { try { if (!source) { - console.log('source is undef') + console.log('source is undef'); return; } From e36a0507e3baf00b8889e1e849f4d7cd272d0b12 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Thu, 31 Aug 2023 18:37:49 +0300 Subject: [PATCH 11/80] ignore pixi-spine during check-types --- tsconfig.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tsconfig.json b/tsconfig.json index 15647e42da0e..3ff3a8904900 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "strictNullChecks": true, "strictFunctionTypes": true, "strictPropertyInitialization": true, + "skipLibCheck": true, // Not used (as we don't compile with tsc), but necessary for iterating on Map/Set. "downlevelIteration": true, // Required by PixiJS, for importing 3rd-party dependencies like EventEmitter3. @@ -36,6 +37,7 @@ // Exclude pre-built js code "exclude": [ "GDJS/Runtime/pixi-renderers/pixi.js", + "GDJS/Runtime/pixi-renderers/pixi-spine.umd.js", "GDJS/Runtime/Cordova", "GDJS/Runtime/Electron", "GDJS/Runtime/FacebookInstantGames", From 3477f58f17abefb1a74f4ae1e7b5a4d94684292a Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Thu, 31 Aug 2023 19:02:30 +0300 Subject: [PATCH 12/80] format and style code, fix some test --- Extensions/Spine/GDevelop.code-workspace | 125 ------------------ Extensions/Spine/JsExtension.js | 24 ++-- .../Spine/spineruntimeobject-pixi-renderer.ts | 85 ++++++++---- Extensions/Spine/spineruntimeobject.ts | 62 +++++---- .../pixi-renderers/pixi-atlas-manager.ts | 92 ++++++++++--- GDJS/Runtime/runtimegame.ts | 7 +- .../ObjectsRendering/PixiResourcesLoader.js | 3 +- 7 files changed, 183 insertions(+), 215 deletions(-) delete mode 100644 Extensions/Spine/GDevelop.code-workspace diff --git a/Extensions/Spine/GDevelop.code-workspace b/Extensions/Spine/GDevelop.code-workspace deleted file mode 100644 index c3986797c37a..000000000000 --- a/Extensions/Spine/GDevelop.code-workspace +++ /dev/null @@ -1,125 +0,0 @@ -{ - "folders": [ - { - "path": "../.." - } - ], - "settings": { - "files.associations": { - "*.idl": "java", - "Fastfile": "ruby", - "iosfwd": "cpp", - "functional": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "algorithm": "cpp", - "random": "cpp", - "__config": "cpp", - "cstddef": "cpp", - "exception": "cpp", - "initializer_list": "cpp", - "new": "cpp", - "stdexcept": "cpp", - "typeinfo": "cpp", - "*.tcc": "cpp", - "cctype": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "complex": "cpp", - "cstdarg": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "istream": "cpp", - "limits": "cpp", - "memory": "cpp", - "ostream": "cpp", - "sstream": "cpp", - "streambuf": "cpp", - "hashtable": "cpp", - "tuple": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "__split_buffer": "cpp", - "deque": "cpp", - "iterator": "cpp", - "list": "cpp", - "map": "cpp", - "queue": "cpp", - "regex": "cpp", - "set": "cpp", - "stack": "cpp", - "string": "cpp", - "vector": "cpp", - "iostream": "cpp", - "__functional_03": "cpp", - "__hash_table": "cpp", - "__tree": "cpp", - "bitset": "cpp", - "__bit_reference": "cpp", - "__mutex_base": "cpp", - "fstream": "cpp", - "ios": "cpp", - "__locale": "cpp", - "valarray": "cpp", - "freeglut_spaceball.c": "cpp", - "__tuple": "cpp", - "hash_map": "cpp", - "hash_set": "cpp", - "system_error": "cpp", - "__nullptr": "cpp", - "__functional_base": "cpp", - "__functional_base_03": "cpp", - "chrono": "cpp", - "ratio": "cpp", - "atomic": "cpp", - "locale": "cpp", - "string_view": "cpp", - "__string": "cpp", - "cstring": "cpp", - "iomanip": "cpp", - "cstdint": "cpp", - "forward_list": "cpp", - "mutex": "cpp", - "__hash": "cpp", - "__debug": "cpp", - "__threading_support": "cpp", - "any": "cpp", - "array": "cpp", - "cinttypes": "cpp", - "numeric": "cpp", - "__memory": "cpp", - "__errc": "cpp", - "__node_handle": "cpp", - "bit": "cpp", - "optional": "cpp", - "filesystem": "cpp", - "compare": "cpp", - "concepts": "cpp", - "xfacet": "cpp", - "xhash": "cpp", - "xiosbase": "cpp", - "xlocale": "cpp", - "xlocinfo": "cpp", - "xlocmon": "cpp", - "xlocnum": "cpp", - "xloctime": "cpp", - "xmemory": "cpp", - "xstddef": "cpp", - "xstring": "cpp", - "xtr1common": "cpp", - "xtree": "cpp", - "xutility": "cpp", - "xlocbuf": "cpp", - "xlocmes": "cpp", - "xmemory0": "cpp", - "memory_resource": "cpp", - "__bits": "cpp", - "__verbose_abort": "cpp", - "variant": "cpp" - }, - "javascript.validate.enable": false - } -} \ No newline at end of file diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 6ebbc91dc2d2..c4ebaff39f94 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -31,7 +31,7 @@ module.exports = { 'SpineObject', _('Spine'), _('Displays a Spine animation.'), - 'Aurélien Vivet', + 'Vladyslav Pohorielov', 'Open source (MIT License)' ) .setExtensionHelpPath('/objects/spine') @@ -271,8 +271,8 @@ module.exports = { this._rect.lineStyle(0, 0xFFFFFF); this._rect.drawRect(0, 0, width, height); - if (this._spine) { - const s = this._spine; + const s = this._spine; + if (s) { s.width = width; s.height = height; s.alpha = this.properties.get('opacity').getValue() / 255; @@ -283,9 +283,11 @@ module.exports = { this._pixiObject.calculateBounds(); } + /** + * @param {number} animation index + */ setAnimation(index) { - const s = this._spine; - const {configuration} = this; + const {configuration, _spine:s} = this; if (!s || configuration.hasNoAnimations() || index === this._animationIndex) { return; @@ -304,7 +306,7 @@ module.exports = { const shouldLoop = animation.shouldLoop(); // reset scale to track new animation range - // if custome size is set it will be reinitialized in update method + // if custom size is set it will be reinitialized in update method s.scale.set(1, 1); s.state.setAnimation(0, source, shouldLoop); s.state.tracks[0].trackTime = 0; @@ -314,14 +316,20 @@ module.exports = { this._initialHeight = s.height; } + /** + * @returns {number} default width + */ getDefaultWidth() { - const scale = +this.properties.get('scale').getValue() || 1; + const scale = Number(this.properties.get('scale').getValue()) || 1; return typeof this._initialWidth === 'number' ? this._initialWidth * scale : 256; } + /** + * @returns {number} default height + */ getDefaultHeight() { - const scale = +this.properties.get('scale').getValue() || 1; + const scale = Number(this.properties.get('scale').getValue()) || 1; return typeof this._initialHeight === 'number' ? this._initialHeight * scale : 256; } diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index 63a570343819..1809f3ae50cb 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -1,22 +1,16 @@ namespace gdjs { import PIXI_SPINE = GlobalPIXIModule.PIXI_SPINE; + function assert(value: any, message?: string): asserts value { + if (!value) { + throw new Error(message); + } + } + export class SpineRuntimeObjectPixiRenderer { _object: gdjs.SpineRuntimeObject; _spine!: PIXI_SPINE.Spine; - private _isAnimationCompelete = true; - - get isAnimationCompelete() { - return this._isAnimationCompelete; - } - - get isUpdatable() { - return this._spine.autoUpdate; - } - - set isUpdatable(isUpdatable: boolean) { - this._spine.autoUpdate = isUpdatable - } + private _isAnimationComplete = true; /** * @param runtimeObject The object to render @@ -41,15 +35,15 @@ namespace gdjs { .addRendererObject(this._spine, runtimeObject.getZOrder()); } - getRendererObject() { + getRendererObject(): PIXI_SPINE.Spine { return this._spine; } - onDestroy() { + onDestroy(): void { this._spine.destroy(); } - updateTimeScale() { + updateTimeScale(): void { this._spine.state.timeScale = this._object.getTimeScale(); } @@ -94,29 +88,64 @@ namespace gdjs { this.updateBounds(); } - setAnimation(animation: string, loop: boolean) { - this._isAnimationCompelete = false; - this._spine.state.addListener({ complete: () => this._isAnimationCompelete = true }); + setAnimation(animation: string, loop: boolean): void { + this._isAnimationComplete = false; + this._spine.state.addListener({ + complete: () => (this._isAnimationComplete = true), + }); this._spine.state.setAnimation(0, animation, loop); this._spine.update(0); this.updateBounds(); } - private constructSpine() { + isAnimationCompelete(): boolean { + return this._isAnimationComplete; + } + + isUpdatable(): boolean { + return this._spine.autoUpdate; + } + + setIsUpdatable(isUpdatable: boolean): void { + this._spine.autoUpdate = isUpdatable; + } + + private constructSpine(): void { const game = this.instanceContainer.getGame(); - const spineJson = game.getJsonManager().getLoadedJson(this._object.jsonResourceName)!; - const atlas = game.getAtlasManager().getAtlasTexture(this._object.atlasResourceName)!; + const spineJson = game + .getJsonManager() + .getLoadedJson(this._object.jsonResourceName); + assert( + spineJson, + `Unavailable ${this._object.jsonResourceName} spine json!` + ); + const atlas = game + .getAtlasManager() + .getAtlasTexture(this._object.atlasResourceName); + assert( + atlas, + `Unavailable ${this._object.atlasResourceName} spine atlas!` + ); const resourceMoc = {}; const spineParser = new PIXI_SPINE.SpineParser(); - spineParser.parseData(resourceMoc as any, spineParser.createJsonParser(), atlas, spineJson); - this._spine = new PIXI_SPINE.Spine((resourceMoc as unknown as { spineData: PIXI_SPINE.ISkeletonData }).spineData); - } - - private updateBounds() { + spineParser.parseData( + resourceMoc as any, + spineParser.createJsonParser(), + atlas, + spineJson + ); + this._spine = new PIXI_SPINE.Spine( + ((resourceMoc as unknown) as { + spineData: PIXI_SPINE.ISkeletonData; + }).spineData + ); + } + + private updateBounds(): void { this._spine.position.x = this._object.x; this._spine.position.y = this._object.y; - + const localBounds = this._spine.getLocalBounds(undefined, true); this._spine.position.x -= localBounds.x * this._spine.scale.x; diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index e801ea0d1747..f207b491c6b4 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -1,4 +1,6 @@ namespace gdjs { + import PIXI_SPINE = GlobalPIXIModule.PIXI_SPINE; + type SpineAnimation = { name: string; source: string; loop: boolean }; export type SpineObjectDataType = { @@ -43,13 +45,16 @@ namespace gdjs { this.jsonResourceName = objectData.content.jsonResourceName; this.atlasResourceName = objectData.content.atlasResourceName; this.imageResourceName = objectData.content.imageResourceName; - this._renderer = new gdjs.SpineRuntimeObjectRenderer(this, instanceContainer); + this._renderer = new gdjs.SpineRuntimeObjectRenderer( + this, + instanceContainer + ); // *ALWAYS* call `this.onCreated()` at the very end of your object constructor. this.onCreated(); } - getRendererObject() { + getRendererObject(): PIXI_SPINE.Spine { return this._renderer.getRendererObject(); } @@ -72,7 +77,9 @@ namespace gdjs { return true; } - extraInitializationFromInitialInstance(initialInstanceData: InstanceData) { + extraInitializationFromInitialInstance( + initialInstanceData: InstanceData + ): void { let animationIndex = this._currentAnimationIndex; for (const extraData of initialInstanceData.numberProperties || []) { if (extraData.name === 'animation') { @@ -83,7 +90,10 @@ namespace gdjs { if (initialInstanceData.customSize) { this.setScale(1); - this._renderer.setSize(initialInstanceData.width, initialInstanceData.height); + this._renderer.setSize( + initialInstanceData.width, + initialInstanceData.height + ); this.invalidateHitboxes(); } } @@ -128,10 +138,7 @@ namespace gdjs { } setOpacity(opacity: float): void { - this._opacity = - opacity < 0 ? 0 : - opacity > 255 ? 255 : - opacity; + this._opacity = PixiFiltersTools.clampValue(opacity, 0, 255); this._renderer.updateOpacity(); } @@ -157,15 +164,17 @@ namespace gdjs { this.invalidateHitboxes(); } - setAnimationIndex(animationIndex: number) { - if (!this.isAnimationIndex(animationIndex)) { return; } + setAnimationIndex(animationIndex: number): void { + if (!this.isAnimationIndex(animationIndex)) { + return; + } const animation = this._animations[animationIndex]; this._currentAnimationIndex = animationIndex; this._renderer.setAnimation(animation.source, animation.loop); } - setAnimationName(animationName: string) { + setAnimationName(animationName: string): void { this.setAnimationIndex(this.getAnimationIndex(animationName)); } @@ -174,24 +183,27 @@ namespace gdjs { } getAnimationName(): string { - return this.isAnimationIndex(this._currentAnimationIndex) ? - this._animations[this._currentAnimationIndex].name : ''; + return this.isAnimationIndex(this._currentAnimationIndex) + ? this._animations[this._currentAnimationIndex].name + : ''; } - getAnimationIndex(animationName: string) { - return this._animations.findIndex(animation => animation.name === animationName); + getAnimationIndex(animationName: string): number { + return this._animations.findIndex( + (animation) => animation.name === animationName + ); } - isAnimationIndex(animationIndex: number) { + isAnimationIndex(animationIndex: number): boolean { return ( - Number.isInteger(animationIndex) - && animationIndex >= 0 - && animationIndex < this._animations.length + Number.isInteger(animationIndex) && + animationIndex >= 0 && + animationIndex < this._animations.length ); } isAnimationComplete(): boolean { - return this._renderer.isAnimationCompelete; + return this._renderer.isAnimationCompelete(); } isCurrentAnimationName(name: string): boolean { @@ -199,17 +211,13 @@ namespace gdjs { } setIsUpdatable(isUpdatable: boolean): void { - this._renderer.isUpdatable = isUpdatable; + this._renderer.setIsUpdatable(isUpdatable); } isUpdatable(): boolean { - return this._renderer.isUpdatable; + return this._renderer.isUpdatable(); } } - gdjs.registerObject( - 'SpineObject::SpineObject', - // @ts-ignore - gdjs.SpineRuntimeObject - ); + gdjs.registerObject('SpineObject::SpineObject', gdjs.SpineRuntimeObject); } diff --git a/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts index f8fd4fbfc6df..38e108afd021 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts @@ -6,7 +6,7 @@ namespace gdjs { import PIXI_SPINE = GlobalPIXIModule.PIXI_SPINE; - const logger = new gdjs.Logger('Text Manager'); + const logger = new gdjs.Logger('Atlas Manager'); type AtlasManagerOnProgressCallback = ( loadedCount: integer, totalCount: integer @@ -20,7 +20,8 @@ namespace gdjs { ) => void; const atlasKinds: ReadonlyArray = ['atlas']; - const isTextResource = (resource: ResourceData) => atlasKinds.includes(resource.kind); + const isTextResource = (resource: ResourceData) => + atlasKinds.includes(resource.kind); /** * AtlasManager loads text files (using `XMLHttpRequest`), using the "atlas" resources @@ -33,7 +34,6 @@ namespace gdjs { export class AtlasManager { _resourcesLoader: RuntimeGameResourcesLoader; _resources: ResourceData[]; - _loadedAtlases: { [key: string]: string } = {}; _loadedTextureAtlases: { [key: string]: PIXI_SPINE.TextureAtlas } = {}; _callbacks: { [key: string]: Array } = {}; @@ -73,8 +73,12 @@ namespace gdjs { onProgress: AtlasManagerOnProgressCallback, onComplete: AtlasManagerOnCompleteCallback ): void { - const textResources = this._resources.filter((resource) => isTextResource(resource) && !resource.disablePreload); - if (!textResources.length) { return onComplete(0); } + const textResources = this._resources.filter( + (resource) => isTextResource(resource) && !resource.disablePreload + ); + if (!textResources.length) { + return onComplete(0); + } let loaded = 0; const onLoad: AtlasManagerRequestCallback = (error) => { @@ -101,9 +105,16 @@ namespace gdjs { * @param callback The callback function called when json is loaded (or an error occurred). */ load(resourceName: string, callback: AtlasManagerRequestCallback): void { - const resource = this._resources.find((resource) => isTextResource(resource) && resource.name === resourceName); + const resource = this._resources.find( + (resource) => isTextResource(resource) && resource.name === resourceName + ); if (!resource) { - return callback(new Error(`Can't find resource with name: "${resourceName}" (or is not a text resource).`), null); + return callback( + new Error( + `Can't find resource with name: "${resourceName}" (or is not a text resource).` + ), + null + ); } // Don't fetch again an object that is already in memory @@ -121,38 +132,73 @@ namespace gdjs { this._callbacks[resourceName] = [callback]; const xhr = new XMLHttpRequest(); xhr.responseType = 'text'; - xhr.withCredentials = this._resourcesLoader.checkIfCredentialsRequired(resource.file); + xhr.withCredentials = this._resourcesLoader.checkIfCredentialsRequired( + resource.file + ); xhr.open('GET', this._resourcesLoader.getFullUrl(resource.file)); xhr.onload = () => { if (xhr.status !== 200) { - this.callCallback(resourceName, `HTTP error: ${xhr.status} (${xhr.statusText })`, null); + this.callCallback( + resourceName, + `HTTP error: ${xhr.status} (${xhr.statusText})`, + null + ); } else { this._loadedAtlases[resourceName] = xhr.response; new PIXI_SPINE.TextureAtlas( xhr.response, (path, textureCb) => { - const atlasImagePath = resourceName.match(/(^.*[\\\/]|^[^\\\/].*)/i)![0] + path; - textureCb(this._imageManager.getPIXITexture(atlasImagePath).baseTexture) + const resourceDirectory = /(^.*[\\\/]|^[^\\\/].*)/i; + const atlasImagePath = + resourceName.match(resourceDirectory)![0] + path; + textureCb( + this._imageManager.getPIXITexture(atlasImagePath).baseTexture + ); }, (atlas) => { this._loadedTextureAtlases[resourceName] = atlas; this.callCallback(resourceName, null, xhr.response); - }); + } + ); } }; - xhr.onerror = () => this.callCallback(resourceName, 'Network error', null); - xhr.onabort = () => this.callCallback(resourceName, 'Request aborted', null); + xhr.onerror = () => + this.callCallback(resourceName, 'Network error', null); + xhr.onabort = () => + this.callCallback(resourceName, 'Request aborted', null); xhr.send(); } - protected callCallback(resourceName: string, errorMessage: string, text: null): void - protected callCallback(resourceName: string, errorMessage: null, text: string): void - protected callCallback(resourceName: string, errorMessage: string | null, text: string | null): void { - if (!this._callbacks[resourceName]) { return; } - + protected callCallback( + resourceName: string, + errorMessage: string, + text: null + ): void; + protected callCallback( + resourceName: string, + errorMessage: null, + text: string + ): void; + protected callCallback( + resourceName: string, + errorMessage: string | null, + text: string | null + ): void { + if (!this._callbacks[resourceName]) { + return; + } + for (const callback of this._callbacks[resourceName]) { - const error = typeof errorMessage === 'string' ? new Error(errorMessage) : null; + const error = + typeof errorMessage === 'string' ? new Error(errorMessage) : null; + + if (!text) { + throw new Error( + `Unavailable text for ${resourceName} atlas resource!` + ); + } + callback(error, text); } @@ -165,7 +211,7 @@ namespace gdjs { * @returns true if the content of the text resource is loaded. false otherwise. */ isLoaded(resourceName: string): boolean { - return typeof this._loadedAtlases[resourceName] === 'string'; + return resourceName in this._loadedAtlases; } /** @@ -175,7 +221,9 @@ namespace gdjs { * @returns the content of the text resource, if loaded. `null` otherwise. */ getText(resourceName: string): string | null { - return this.isLoaded(resourceName) ? this._loadedAtlases[resourceName] : null; + return this.isLoaded(resourceName) + ? this._loadedAtlases[resourceName] + : null; } /** diff --git a/GDJS/Runtime/runtimegame.ts b/GDJS/Runtime/runtimegame.ts index 559542484ba4..4baea3c3a312 100644 --- a/GDJS/Runtime/runtimegame.ts +++ b/GDJS/Runtime/runtimegame.ts @@ -232,7 +232,7 @@ namespace gdjs { this._data.resources.resources, this._resourcesLoader, this._imageManager - ) + ); this._bitmapFontManager = new gdjs.BitmapFontManager( this._data.resources.resources, this._resourcesLoader, @@ -811,7 +811,8 @@ namespace gdjs { 100 ); loadingScreen.setPercent(percent); - if (progressCallback) progressCallback(percent); + if (progressCallback) + progressCallback(percent); }) .then(() => loadingScreen.unload()) .then(() => @@ -821,7 +822,7 @@ namespace gdjs { callback(); }); } - ) + ); } ); } diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index b6b16bf2e2e0..af1e16ce8f0a 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -12,7 +12,6 @@ import { checkIfCredentialsRequired } from '../Utils/CrossOrigin'; import { ISkeleton } from 'pixi-spine'; const gd: libGDevelop = global.gd; -// PIXI_SPINE.SpineParser.registerLoaderPlugin(); PIXI.Loader.registerPlugin(PIXI_SPINE.SpineParser); type ResourcePromise = { [resourceName: string]: Promise }; @@ -361,7 +360,7 @@ export default class PixiResourcesLoader { spineName: string, atlasImageName: string, atlasTextName: string - ): Promise { + ): Promise { const loader = PIXI.Loader.shared; const resourceManager = project.getResourcesManager(); const resourcesData = [ From 2313fe935c1af208ecafc183e75f58b9d9c6a97b Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Thu, 31 Aug 2023 19:13:01 +0300 Subject: [PATCH 13/80] remove console logs, solve typos --- GDJS/Runtime/runtimegame.ts | 8 ++++---- newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js | 1 - newIDE/app/src/ObjectEditor/Editors/SpineEditor.js | 2 -- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/GDJS/Runtime/runtimegame.ts b/GDJS/Runtime/runtimegame.ts index 4baea3c3a312..7e7da457038f 100644 --- a/GDJS/Runtime/runtimegame.ts +++ b/GDJS/Runtime/runtimegame.ts @@ -404,9 +404,9 @@ namespace gdjs { } /** - * Get the text manager of the game, used to load text from game + * Get the atlas manager of the game, used to load atlases from game * resources. - * @return The text manager for the game + * @return The atlas manager for the game */ getAtlasManager(): gdjs.AtlasManager { return this._atlasManager; @@ -796,7 +796,7 @@ namespace gdjs { progressCallback(percent); } }, - function (textsTotalCount) { + function (atlasesTotalCount) { that._bitmapFontManager .loadBitmapFontData((count) => { var percent = Math.floor( @@ -805,7 +805,7 @@ namespace gdjs { fontTotalCount + jsonTotalCount + model3DTotalCount + - textsTotalCount + + atlasesTotalCount + count) / allAssetsTotal) * 100 diff --git a/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js b/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js index 24e75f46a15b..c671986c9899 100644 --- a/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js @@ -254,7 +254,6 @@ const Model3DEditor = ({ const forceUpdate = useForceUpdate(); const model3DConfiguration = gd.asModel3DConfiguration(objectConfiguration); - console.log('Model3DEditod, ', model3DConfiguration, objectConfiguration); const properties = objectConfiguration.getProperties(); const [nameErrors, setNameErrors] = React.useState<{ [number]: React.Node }>( diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 0b20a2532112..1f7cd21ed1ff 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -78,7 +78,6 @@ const SpineEditor = ({ const forceUpdate = useForceUpdate(); const spineConfiguration = gd.asSpineConfiguration(objectConfiguration); - console.log('SpineEditod, ', spineConfiguration, objectConfiguration); const properties = objectConfiguration.getProperties(); const [nameErrors, setNameErrors] = React.useState<{ [number]: React.Node }>( @@ -286,7 +285,6 @@ const SpineEditor = ({ } animation.setName(newName); - // TODO EBO Refactor event-based object events when an animation is renamed. if (layout && object) { gd.WholeProjectRefactorer.renameObjectAnimation( project, From 4ac52de3d385f055944ebe6f4828fa0f50823825 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 19 Sep 2023 12:17:53 +0300 Subject: [PATCH 14/80] remove pixi deps --- newIDE/app/package-lock.json | 28 ++++++++++++++++++---------- newIDE/app/package.json | 4 ---- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/newIDE/app/package-lock.json b/newIDE/app/package-lock.json index 050f439a040c..2b57977cbb1c 100644 --- a/newIDE/app/package-lock.json +++ b/newIDE/app/package-lock.json @@ -16,10 +16,6 @@ "@material-ui/core": "4.11.0", "@material-ui/icons": "4.9.1", "@material-ui/lab": "4.0.0-alpha.56", - "@pixi/core": "^6.5.10", - "@pixi/display": "^6.5.10", - "@pixi/extensions": "^6.5.10", - "@pixi/utils": "^6.5.10", "@supercharge/promise-pool": "^1.6.0", "algoliasearch": "3.33.0", "axios": "^0.18.1", @@ -6320,6 +6316,7 @@ "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", + "peer": true, "dependencies": { "@types/offscreencanvas": "^2019.6.4" }, @@ -6341,6 +6338,7 @@ "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "peer": true, "peerDependencies": { "@pixi/constants": "6.5.10", "@pixi/math": "6.5.10", @@ -6351,7 +6349,8 @@ "node_modules/@pixi/extensions": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/extensions/-/extensions-6.5.10.tgz", - "integrity": "sha512-EIUGza+E+sCy3dupuIjvRK/WyVyfSzHb5XsxRaxNrPwvG1iIUIqNqZ3owLYCo4h17fJWrj/yXVufNNtUKQccWQ==" + "integrity": "sha512-EIUGza+E+sCy3dupuIjvRK/WyVyfSzHb5XsxRaxNrPwvG1iIUIqNqZ3owLYCo4h17fJWrj/yXVufNNtUKQccWQ==", + "peer": true }, "node_modules/@pixi/math": { "version": "6.5.10", @@ -6396,6 +6395,7 @@ "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "peer": true, "dependencies": { "@types/earcut": "^2.1.0", "earcut": "^2.2.4", @@ -6410,7 +6410,8 @@ "node_modules/@pixi/utils/node_modules/eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.10", @@ -15781,7 +15782,8 @@ "node_modules/@types/offscreencanvas": { "version": "2019.7.0", "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz", - "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==" + "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==", + "peer": true }, "node_modules/@types/overlayscrollbars": { "version": "1.12.1", @@ -50924,6 +50926,7 @@ "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.5.10.tgz", "integrity": "sha512-Gdzp5ENypyglvsh5Gv3teUZnZnmizo4xOsL+QqmWALdFlJXJwLJMVhKVThV/q/095XR6i4Ou54oshn+m4EkuFw==", + "peer": true, "requires": { "@types/offscreencanvas": "^2019.6.4" } @@ -50932,12 +50935,14 @@ "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.5.10.tgz", "integrity": "sha512-NxFdDDxlbH5fQkzGHraLGoTMucW9pVgXqQm13TSmkA3NWIi/SItHL4qT2SI8nmclT9Vid1VDEBCJFAbdeuQw1Q==", + "peer": true, "requires": {} }, "@pixi/extensions": { "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/extensions/-/extensions-6.5.10.tgz", - "integrity": "sha512-EIUGza+E+sCy3dupuIjvRK/WyVyfSzHb5XsxRaxNrPwvG1iIUIqNqZ3owLYCo4h17fJWrj/yXVufNNtUKQccWQ==" + "integrity": "sha512-EIUGza+E+sCy3dupuIjvRK/WyVyfSzHb5XsxRaxNrPwvG1iIUIqNqZ3owLYCo4h17fJWrj/yXVufNNtUKQccWQ==", + "peer": true }, "@pixi/math": { "version": "6.5.10", @@ -50976,6 +50981,7 @@ "version": "6.5.10", "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.5.10.tgz", "integrity": "sha512-4f4qDMmAz9IoSAe08G2LAxUcEtG9jSdudfsMQT2MG+OpfToirboE6cNoO0KnLCvLzDVE/mfisiQ9uJbVA9Ssdw==", + "peer": true, "requires": { "@types/earcut": "^2.1.0", "earcut": "^2.2.4", @@ -50986,7 +50992,8 @@ "eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "peer": true } } }, @@ -57042,7 +57049,8 @@ "@types/offscreencanvas": { "version": "2019.7.0", "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz", - "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==" + "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==", + "peer": true }, "@types/overlayscrollbars": { "version": "1.12.1", diff --git a/newIDE/app/package.json b/newIDE/app/package.json index ab630f1f67fb..f127282c740d 100644 --- a/newIDE/app/package.json +++ b/newIDE/app/package.json @@ -55,10 +55,6 @@ "pixi-simple-gesture": "github:4ian/pixi-simple-gesture#v0.3.3", "pixi-spine": "^3.0.0", "pixi.js-legacy": "6.1.2", - "@pixi/core": "^6.5.10", - "@pixi/display": "^6.5.10", - "@pixi/extensions": "^6.5.10", - "@pixi/utils": "^6.5.10", "posthog-js": "^1.57.2", "prop-types": "^15.5.10", "qr-creator": "^1.0.0", From a6895fc967da5cbf04ed69eb3673832610248b85 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Fri, 3 Nov 2023 17:14:59 +0200 Subject: [PATCH 15/80] update pixi-spine to 4.x.x --- Extensions/Spine/JsExtension.js | 2 + .../Spine/spineruntimeobject-pixi-renderer.ts | 113 +- Extensions/Spine/spineruntimeobject.ts | 5 +- GDJS/GDJS/IDE/ExporterHelper.cpp | 3 +- .../pixi-renderers/pixi-atlas-manager.ts | 170 +- .../pixi-json-manager.ts} | 94 +- .../pixi-renderers/pixi-spine-manager.ts | 45 + GDJS/Runtime/pixi-renderers/pixi-spine.umd.js | 24233 +--------------- GDJS/Runtime/pixi-renderers/pixi.js | 2 +- GDJS/Runtime/runtimegame.ts | 21 +- GDJS/Runtime/types/global-pixi-spine.d.ts | 7 +- GDJS/Runtime/types/global-pixi.d.ts | 1 + GDJS/package-lock.json | 2 +- GDJS/package.json | 15 +- GDJS/tests/karma.conf.js | 1 - newIDE/app/package-lock.json | 1186 +- newIDE/app/package.json | 15 +- .../src/ObjectEditor/Editors/SpineEditor.js | 62 +- .../ObjectsRenderingService.js | 4 + .../ObjectsRendering/PixiResourcesLoader.js | 62 +- 20 files changed, 751 insertions(+), 25292 deletions(-) rename GDJS/Runtime/{jsonmanager.ts => pixi-renderers/pixi-json-manager.ts} (70%) create mode 100644 GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index c4ebaff39f94..fdd516487ad2 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -252,6 +252,8 @@ module.exports = { this._pixiResourcesLoader .getSpineData(this._project, jsonResourceName, imageResourceName, atlasResourceName) .then((spineData) => { + if (!spineData) return; + this._spine = new PIXI.Spine(spineData); this._pixiObject.addChild(this._spine); this.update(); diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index 1809f3ae50cb..4abba0104558 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -1,16 +1,12 @@ namespace gdjs { - import PIXI_SPINE = GlobalPIXIModule.PIXI_SPINE; - function assert(value: any, message?: string): asserts value { - if (!value) { - throw new Error(message); - } - } + const isSpine = (obj: any): obj is pixi_spine.Spine => obj instanceof pixi_spine.Spine; export class SpineRuntimeObjectPixiRenderer { - _object: gdjs.SpineRuntimeObject; - _spine!: PIXI_SPINE.Spine; + private _object: gdjs.SpineRuntimeObject; + private _rendererObject!: pixi_spine.Spine | PIXI.Container; private _isAnimationComplete = true; + private _spinePropertiesReplacer: Record = { }; /** * @param runtimeObject The object to render @@ -32,23 +28,25 @@ namespace gdjs { instanceContainer .getLayer('') .getRenderer() - .addRendererObject(this._spine, runtimeObject.getZOrder()); + .addRendererObject(this._rendererObject, runtimeObject.getZOrder()); } - getRendererObject(): PIXI_SPINE.Spine { - return this._spine; + getRendererObject(): pixi_spine.Spine | PIXI.Container { + return this._rendererObject; } onDestroy(): void { - this._spine.destroy(); + this._rendererObject.destroy(); } updateTimeScale(): void { - this._spine.state.timeScale = this._object.getTimeScale(); + if (!isSpine(this._rendererObject)) return; + + this._rendererObject.state.timeScale = this._object.getTimeScale(); } updateScale(): void { - this._spine.scale.set(Math.max(this._object.getScale(), 0)); + this._rendererObject.scale.set(Math.max(this._object.getScale(), 0)); this.updateBounds(); } @@ -57,45 +55,49 @@ namespace gdjs { } updateAngle(): void { - this._spine.rotation = gdjs.toRad(this._object.angle); + this._rendererObject.rotation = gdjs.toRad(this._object.angle); } updateOpacity(): void { - this._spine.alpha = this._object.getOpacity() / 255; + this._rendererObject.alpha = this._object.getOpacity() / 255; } getWidth(): float { - return this._spine.width; + return this._rendererObject.width; } getHeight(): float { - return this._spine.height; + return this._rendererObject.height; } setWidth(width: float): void { - this._spine.width = width; + this._rendererObject.width = width; this.updateBounds(); } setHeight(height: float): void { - this._spine.height = height; + this._rendererObject.height = height; this.updateBounds(); } setSize(width: float, height: float): void { - this._spine.width = width; - this._spine.height = height; + this._rendererObject.width = width; + this._rendererObject.height = height; this.updateBounds(); } setAnimation(animation: string, loop: boolean): void { - this._isAnimationComplete = false; - this._spine.state.addListener({ - complete: () => (this._isAnimationComplete = true), - }); - this._spine.state.setAnimation(0, animation, loop); - this._spine.update(0); - this.updateBounds(); + if (isSpine(this._rendererObject)) { + this._isAnimationComplete = false; + this._rendererObject.state.addListener({ + complete: () => (this._isAnimationComplete = true), + }); + this._rendererObject.state.setAnimation(0, animation, loop); + this._rendererObject.update(0); + this.updateBounds(); + } else { + this._isAnimationComplete = true; + } } isAnimationCompelete(): boolean { @@ -103,53 +105,36 @@ namespace gdjs { } isUpdatable(): boolean { - return this._spine.autoUpdate; + if (isSpine(this._rendererObject)) { + return this._rendererObject.autoUpdate; + } + + return !!this._spinePropertiesReplacer.autoUpdate; } setIsUpdatable(isUpdatable: boolean): void { - this._spine.autoUpdate = isUpdatable; + if (isSpine(this._rendererObject)) { + this._rendererObject.autoUpdate = isUpdatable; + } else { + this._spinePropertiesReplacer.autoUpdate = isUpdatable; + } } private constructSpine(): void { const game = this.instanceContainer.getGame(); - const spineJson = game - .getJsonManager() - .getLoadedJson(this._object.jsonResourceName); - assert( - spineJson, - `Unavailable ${this._object.jsonResourceName} spine json!` - ); - const atlas = game - .getAtlasManager() - .getAtlasTexture(this._object.atlasResourceName); - assert( - atlas, - `Unavailable ${this._object.atlasResourceName} spine atlas!` - ); - - const resourceMoc = {}; - const spineParser = new PIXI_SPINE.SpineParser(); - spineParser.parseData( - resourceMoc as any, - spineParser.createJsonParser(), - atlas, - spineJson - ); - this._spine = new PIXI_SPINE.Spine( - ((resourceMoc as unknown) as { - spineData: PIXI_SPINE.ISkeletonData; - }).spineData - ); + const spineData = game.getSpineManager().getSpine(this._object.jsonResourceName); + + this._rendererObject = spineData ? new pixi_spine.Spine(spineData) : new PIXI.Container(); } private updateBounds(): void { - this._spine.position.x = this._object.x; - this._spine.position.y = this._object.y; + this._rendererObject.position.x = this._object.x; + this._rendererObject.position.y = this._object.y; - const localBounds = this._spine.getLocalBounds(undefined, true); + const localBounds = this._rendererObject.getLocalBounds(undefined, true); - this._spine.position.x -= localBounds.x * this._spine.scale.x; - this._spine.position.y -= localBounds.y * this._spine.scale.y; + this._rendererObject.position.x -= localBounds.x * this._rendererObject.scale.x; + this._rendererObject.position.y -= localBounds.y * this._rendererObject.scale.y; } } export const SpineRuntimeObjectRenderer = SpineRuntimeObjectPixiRenderer; diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index f207b491c6b4..74e70cc30317 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -1,6 +1,5 @@ -namespace gdjs { - import PIXI_SPINE = GlobalPIXIModule.PIXI_SPINE; +namespace gdjs { type SpineAnimation = { name: string; source: string; loop: boolean }; export type SpineObjectDataType = { @@ -54,7 +53,7 @@ namespace gdjs { this.onCreated(); } - getRendererObject(): PIXI_SPINE.Spine { + getRendererObject(): pixi_spine.Spine | PIXI.Container { return this._renderer.getRendererObject(); } diff --git a/GDJS/GDJS/IDE/ExporterHelper.cpp b/GDJS/GDJS/IDE/ExporterHelper.cpp index fcabc8dbbecf..68d43fde23a7 100644 --- a/GDJS/GDJS/IDE/ExporterHelper.cpp +++ b/GDJS/GDJS/IDE/ExporterHelper.cpp @@ -623,7 +623,6 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers, InsertUnique(includesFiles, "libs/rbush.js"); InsertUnique(includesFiles, "AsyncTasksManager.js"); InsertUnique(includesFiles, "inputmanager.js"); - InsertUnique(includesFiles, "jsonmanager.js"); InsertUnique(includesFiles, "Model3DManager.js"); InsertUnique(includesFiles, "timemanager.js"); InsertUnique(includesFiles, "polygon.js"); @@ -697,6 +696,8 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers, InsertUnique(includesFiles, "pixi-renderers/runtimescene-pixi-renderer.js"); InsertUnique(includesFiles, "pixi-renderers/layer-pixi-renderer.js"); InsertUnique(includesFiles, "pixi-renderers/pixi-image-manager.js"); + InsertUnique(includesFiles, "pixi-renderers/pixi-spine-manager.js"); + InsertUnique(includesFiles, "pixi-renderers/pixi-json-manager.js"); InsertUnique(includesFiles, "pixi-renderers/pixi-atlas-manager.js"); InsertUnique(includesFiles, "pixi-renderers/pixi-bitmapfont-manager.js"); InsertUnique(includesFiles, diff --git a/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts index 776d5a5b9bf5..1053622d8fdd 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts @@ -9,16 +9,14 @@ namespace gdjs { loadedCount: integer, totalCount: integer ) => void; - type AtlasManagerOnCompleteCallback = (totalCount: integer) => void; - /** The callback called when a text that was requested is loaded (or an error occurred). */ export type AtlasManagerRequestCallback = ( error: Error | null, - content: Object | null + content?: pixi_spine.TextureAtlas ) => void; const atlasKinds: ReadonlyArray = ['atlas']; - const isTextResource = (resource: ResourceData) => + const isAtlasResource = (resource: ResourceData) => atlasKinds.includes(resource.kind); /** @@ -32,8 +30,7 @@ namespace gdjs { export class AtlasManager { _resourcesLoader: RuntimeGameResourcesLoader; _resources: ResourceData[]; - _loadedAtlases: { [key: string]: string } = {}; - _loadedTextureAtlases: { [key: string]: PIXI_SPINE.TextureAtlas } = {}; + _loadedAtlases: { [key: string]: pixi_spine.TextureAtlas } = {}; _callbacks: { [key: string]: Array } = {}; /** @@ -67,138 +64,61 @@ namespace gdjs { * @param onProgress The function called after each texts is loaded. * @param onComplete The function called when all texts are loaded. */ - async preload( + async preloadAll( onProgress: AtlasManagerOnProgressCallback, ): Promise { - const textResources = this._resources.filter( - (resource) => isTextResource(resource) && !resource.disablePreload + const atlasResources = this._resources.filter( + (resource) => isAtlasResource(resource) && !resource.disablePreload ); let loaded = 0; await Promise.all( - textResources.map((resource, i) => new Promise((resolve) => { + atlasResources.map((resource, i) => new Promise((resolve) => { const onLoad: AtlasManagerRequestCallback = (error) => { if (error) { logger.error('Error while preloading a text resource:' + error); } - onProgress(loaded, textResources.length); + onProgress(loaded, atlasResources.length); resolve(); }; - this.load(textResources[i].name, onLoad); + this.load(atlasResources[i], onLoad); })) ); - return Promise.resolve(textResources.length); + return Promise.resolve(atlasResources.length); } - /** - * Request the text file from the given resource name. - * This method is asynchronous. When loaded, the `callback` is called with the error - * (null if none) and the loaded test (a string). - * - * @param resourceName The resource pointing to the json file to load. - * @param callback The callback function called when json is loaded (or an error occurred). - */ - load(resourceName: string, callback: AtlasManagerRequestCallback): void { - const resource = this._resources.find( - (resource) => isTextResource(resource) && resource.name === resourceName - ); - if (!resource) { - return callback( - new Error( - `Can't find resource with name: "${resourceName}" (or is not a text resource).` - ), - null - ); - } - - // Don't fetch again an object that is already in memory - if (this.isLoaded(resourceName)) { - return callback(null, this._loadedAtlases[resourceName]); - } - - // Don't fetch again an object that is already being fetched. - const callbacks = this._callbacks[resourceName]; - if (callbacks) { - callbacks.push(callback); - return; - } - - this._callbacks[resourceName] = [callback]; - const xhr = new XMLHttpRequest(); - xhr.responseType = 'text'; - xhr.withCredentials = this._resourcesLoader.checkIfCredentialsRequired( - resource.file - ); - xhr.open('GET', this._resourcesLoader.getFullUrl(resource.file)); - xhr.onload = () => { - if (xhr.status !== 200) { - this.callCallback( - resourceName, - `HTTP error: ${xhr.status} (${xhr.statusText})`, - null - ); - } else { - this._loadedAtlases[resourceName] = xhr.response; - - new PIXI_SPINE.TextureAtlas( - xhr.response, - (path, textureCb) => { - const resourceDirectory = /(^.*[\\\/]|^[^\\\/].*)/i; - const atlasImagePath = - resourceName.match(resourceDirectory)![0] + path; - textureCb( - this._imageManager.getPIXITexture(atlasImagePath).baseTexture - ); - }, - (atlas) => { - this._loadedTextureAtlases[resourceName] = atlas; - this.callCallback(resourceName, null, xhr.response); - } - ); - } - }; - xhr.onerror = () => - this.callCallback(resourceName, 'Network error', null); - xhr.onabort = () => - this.callCallback(resourceName, 'Request aborted', null); - xhr.send(); - } + load(resource: ResourceData, callback: AtlasManagerRequestCallback): void { + if (!isAtlasResource(resource)) callback(new Error(`${resource.name} is on atlas!`)); - protected callCallback( - resourceName: string, - errorMessage: string, - text: null - ): void; - protected callCallback( - resourceName: string, - errorMessage: null, - text: string - ): void; - protected callCallback( - resourceName: string, - errorMessage: string | null, - text: string | null - ): void { - if (!this._callbacks[resourceName]) { - return; - } - - for (const callback of this._callbacks[resourceName]) { - const error = - typeof errorMessage === 'string' ? new Error(errorMessage) : null; - - if (!text) { - throw new Error( - `Unavailable text for ${resourceName} atlas resource!` - ); - } + const metadata = resource.metadata ? JSON.parse(resource.metadata) : { }; - callback(error, text); - } + if (!metadata.image) callback(new Error(`${resource.name} do not have image metadata!`)); - delete this._callbacks[resourceName]; + const image = this._imageManager.getPIXITexture(metadata.image); + const onLoad = (atlas: pixi_spine.TextureAtlas) => { + this._loadedAtlases[resource.name] = atlas; + callback(null, atlas); + }; + + + PIXI.Assets.setPreferences({ + preferWorkers: false, + crossOrigin: this._resourcesLoader.checkIfCredentialsRequired( + resource.file + ) + ? 'use-credentials' + : 'anonymous', + }); + PIXI.Assets.add(resource.name, resource.file, { image }); + PIXI.Assets.load(resource.name).then((atlas) => { + if (typeof atlas === 'string') { + new pixi_spine.TextureAtlas(atlas, (_, textureCb) => textureCb(image.baseTexture), onLoad); + } else { + onLoad(atlas); + } + }); } /** @@ -210,26 +130,14 @@ namespace gdjs { return resourceName in this._loadedAtlases; } - /** - * Get the raw atlas text for the given resource that is already loaded (preloaded or loaded with `load`). - * If the resource is not loaded, `null` will be returned. - * @param resourceName The name of the text resource. - * @returns the content of the text resource, if loaded. `null` otherwise. - */ - getText(resourceName: string): string | null { - return this.isLoaded(resourceName) - ? this._loadedAtlases[resourceName] - : null; - } - /** * Get the Pixi TextureAtlas for the given resource that is already loaded (preloaded or loaded with `load`). * If the resource is not loaded, `null` will be returned. * @param resourceName The name of the text resource. * @returns the TextureAtlas of the atlas, if loaded. `null` otherwise. */ - getAtlasTexture(resourceName: string): PIXI_SPINE.TextureAtlas | null { - return this._loadedTextureAtlases[resourceName] || null; + getAtlasTexture(resourceName: string): pixi_spine.TextureAtlas | null { + return this._loadedAtlases[resourceName] || null; } } } diff --git a/GDJS/Runtime/jsonmanager.ts b/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts similarity index 70% rename from GDJS/Runtime/jsonmanager.ts rename to GDJS/Runtime/pixi-renderers/pixi-json-manager.ts index 398b94931088..2ba5718f3987 100644 --- a/GDJS/Runtime/jsonmanager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts @@ -4,7 +4,8 @@ * This project is released under the MIT License. */ namespace gdjs { - const logger = new gdjs.Logger('JSON Manager'); + const logger = new gdjs.Logger('Json Manager'); + /** The callback called when a json that was requested is loaded (or an error occurred). */ export type JsonManagerRequestCallback = ( @@ -26,6 +27,8 @@ namespace gdjs { _loadedJsons: { [key: string]: Object } = {}; _callbacks: { [key: string]: Array } = {}; + _spineManager: SpineManager; + _atlasManager: AtlasManager; /** * @param resourceDataArray The resources data of the game. @@ -33,11 +36,15 @@ namespace gdjs { */ constructor( resourceDataArray: ResourceData[], - resourcesLoader: RuntimeGameResourcesLoader + resourcesLoader: RuntimeGameResourcesLoader, + spineManager: SpineManager, + atlasManager: AtlasManager, ) { this._resources = new Map(); this.setResources(resourceDataArray); this._resourcesLoader = resourcesLoader; + this._spineManager = spineManager; + this._atlasManager = atlasManager; } /** @@ -58,40 +65,50 @@ namespace gdjs { } } - /** - * Request all the json resources to be preloaded (unless they are marked as not preloaded). - * - * Note that even if a JSON is already loaded, it will be reloaded (useful for hot-reloading, - * as JSON files can have been modified without the editor knowing). - * - * @param onProgress The function called after each json is loaded. - */ - async preloadJsons( - onProgress: (loadedCount: integer, totalCount: integer) => void + async preloadAll( + onProgress: (loadingCount: integer, totalCount: integer) => void ): Promise { - const preloadedResources = [...this._resources.values()].filter( - (resource) => !resource.disablePreload - ); - - let loadedCount = 0; - await Promise.all( - preloadedResources.map(async (resource) => { + let loadedNumber = 0; + const getPreferences = (file: string) => ({ + preferWorkers: false, + crossOrigin: this._resourcesLoader.checkIfCredentialsRequired(file) + ? 'use-credentials' + : 'anonymous', + } as Partial); + const jsonPromises = Array.from(this._resources.values(), async (resource) => { try { - await this.loadJsonAsync(resource.name); + if (resource.kind === 'json') { + const metadata = resource.metadata ? JSON.parse(resource.metadata) : { }; + const atlasInDependencies = !!metadata.atlas && this._atlasManager.isLoaded(metadata.atlas); + + PIXI.Assets.setPreferences(getPreferences(resource.file)); + PIXI.Assets.add(resource.name, resource.file, atlasInDependencies ? { spineAtlas: this._atlasManager.getAtlasTexture(metadata.atlas) } : undefined) + let loadedJson = await PIXI.Assets.load(resource.name); + + if (loadedJson.spineData) { + this._spineManager.setSpine(resource.name, loadedJson.spineData) + } else { + this._loadedJsons[resource.name] = loadedJson; + } + } else { + await this.loadJsonAsync(resource.name); + } } catch (error) { - logger.error('Error while preloading a json resource:' + error); + console.log('spine loading error', error) } - loadedCount++; - onProgress(loadedCount, this._resources.size); - }) - ); - return loadedCount; + + onProgress(loadedNumber++, this._resources.size); + }); + + await Promise.all(jsonPromises); + + return loadedNumber; } loadJsonAsync(resourceName: string): Promise { const that = this; return new Promise((resolve, reject) => { - that.loadJson(resourceName, (error, content) => { + that.load(resourceName, (error, content) => { if (error) { reject(error.message); } @@ -100,32 +117,15 @@ namespace gdjs { }); } - /** - * Request the json file from the given resource name. - * This method is asynchronous. When loaded, the `callback` is called with the error - * (null if none) and the loaded json (a JS Object). - * - * @param resourceName The resource pointing to the json file to load. - * @param callback The callback function called when json is loaded (or an error occurred). - */ - loadJson(resourceName: string, callback: JsonManagerRequestCallback): void { + load(resourceName: string, callback: JsonManagerRequestCallback): void { const resource = this._resources.get(resourceName); if (!resource) { - callback( - new Error( - 'Can\'t find resource with name: "' + - resourceName + - '" (or is not a json resource).' - ), - null - ); - return; + return callback(new Error(`Can't find resource with name: "${resourceName}" (or is not a json resource).`), null); } // Don't fetch again an object that is already in memory if (this._loadedJsons[resourceName]) { - callback(null, this._loadedJsons[resourceName]); - return; + return callback(null, this._loadedJsons[resourceName]); } // Don't fetch again an object that is already being fetched. { diff --git a/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts new file mode 100644 index 000000000000..38753b672811 --- /dev/null +++ b/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts @@ -0,0 +1,45 @@ +/* + * GDevelop JS Platform + * Copyright 2013-present Florian Rival (Florian.Rival@gmail.com). All rights reserved. + * This project is released under the MIT License. + */ +namespace gdjs { + const logger = new gdjs.Logger('Spine Manager'); + + /** + * JsonManager loads json files (using `XMLHttpRequest`), using the "json" resources + * registered in the game resources. + * + * Contrary to audio/fonts, json files are loaded asynchronously, when requested. + * You should properly handle errors, and give the developer/player a way to know + * that loading failed. + */ + export class SpineManager { + _spineData: { [key: string]: pixi_spine.ISkeletonData } = {}; + + setSpine(resourceName: string, spineData: pixi_spine.ISkeletonData) { + this._spineData[resourceName] = spineData; + } + + /** + * Get the object for the given resource that is already loaded (preloaded or loaded with `loadJson`). + * If the resource is not loaded, `null` will be returned. + * + * @param resourceName The name of the json resource. + * @returns the content of the json resource, if loaded. `null` otherwise. + */ + getSpine(resourceName: string): pixi_spine.ISkeletonData { + return this._spineData[resourceName] || null; + } + + /** + * Check if the given json resource was loaded (preloaded or loaded with `loadJson`). + * @param resourceName The name of the json resource. + * @returns true if the content of the json resource is loaded. false otherwise. + */ + isSpineLoaded(resourceName: string): boolean { + return !!this._spineData[resourceName]; + } + } + } + \ No newline at end of file diff --git a/GDJS/Runtime/pixi-renderers/pixi-spine.umd.js b/GDJS/Runtime/pixi-renderers/pixi-spine.umd.js index 4a4f5380493d..7fcbf95b10af 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-spine.umd.js +++ b/GDJS/Runtime/pixi-renderers/pixi-spine.umd.js @@ -1,24220 +1,13 @@ -/* eslint-disable */ - -/*! - * pixi-spine - v3.1.2 - * Compiled Tue, 01 Aug 2023 11:10:46 UTC - * - * pixi-spine is licensed under SPINE-LICENSE - * http://esotericsoftware.com/spine-runtimes-license - * - * Copyright 2019-2020, Ivan Igorevich Popelyshev , All Rights Reserved - */ -this.PIXI = this.PIXI || {}; -this.PIXI.spine = this.PIXI.spine || {}; -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@pixi/loaders'), require('@pixi/core'), require('@pixi/constants'), require('@pixi/math'), require('@pixi/display'), require('@pixi/sprite'), require('@pixi/mesh-extras'), require('@pixi/graphics'), require('@pixi/utils')) : - typeof define === 'function' && define.amd ? define(['exports', '@pixi/loaders', '@pixi/core', '@pixi/constants', '@pixi/math', '@pixi/display', '@pixi/sprite', '@pixi/mesh-extras', '@pixi/graphics', '@pixi/utils'], factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pixi_spine = {}, global.PIXI, global.PIXI, global.PIXI, global.PIXI, global.PIXI, global.PIXI, global.PIXI, global.PIXI, global.PIXI.utils)); -})(this, (function (exports, loaders, core, constants, math, display, sprite, meshExtras, graphics, utils) { 'use strict'; - - /* eslint-disable */ - - /** - * @public - */ - exports.AttachmentType = void 0; - (function (AttachmentType) { - AttachmentType[AttachmentType["Region"] = 0] = "Region"; - AttachmentType[AttachmentType["BoundingBox"] = 1] = "BoundingBox"; - AttachmentType[AttachmentType["Mesh"] = 2] = "Mesh"; - AttachmentType[AttachmentType["LinkedMesh"] = 3] = "LinkedMesh"; - AttachmentType[AttachmentType["Path"] = 4] = "Path"; - AttachmentType[AttachmentType["Point"] = 5] = "Point"; - AttachmentType[AttachmentType["Clipping"] = 6] = "Clipping"; - })(exports.AttachmentType || (exports.AttachmentType = {})); - - /** - * @public - */ - var BinaryInput = /** @class */ (function () { - function BinaryInput(data, strings, index, buffer) { - if (strings === void 0) { strings = new Array(); } - if (index === void 0) { index = 0; } - if (buffer === void 0) { buffer = new DataView(data.buffer); } - this.strings = strings; - this.index = index; - this.buffer = buffer; - } - BinaryInput.prototype.readByte = function () { - return this.buffer.getInt8(this.index++); - }; - BinaryInput.prototype.readUnsignedByte = function () { - return this.buffer.getUint8(this.index++); - }; - BinaryInput.prototype.readShort = function () { - var value = this.buffer.getInt16(this.index); - this.index += 2; - return value; - }; - BinaryInput.prototype.readInt32 = function () { - var value = this.buffer.getInt32(this.index); - this.index += 4; - return value; - }; - BinaryInput.prototype.readInt = function (optimizePositive) { - var b = this.readByte(); - var result = b & 0x7F; - if ((b & 0x80) != 0) { - b = this.readByte(); - result |= (b & 0x7F) << 7; - if ((b & 0x80) != 0) { - b = this.readByte(); - result |= (b & 0x7F) << 14; - if ((b & 0x80) != 0) { - b = this.readByte(); - result |= (b & 0x7F) << 21; - if ((b & 0x80) != 0) { - b = this.readByte(); - result |= (b & 0x7F) << 28; - } - } - } - } - return optimizePositive ? result : ((result >>> 1) ^ -(result & 1)); - }; - BinaryInput.prototype.readStringRef = function () { - var index = this.readInt(true); - return index == 0 ? null : this.strings[index - 1]; - }; - BinaryInput.prototype.readString = function () { - var byteCount = this.readInt(true); - switch (byteCount) { - case 0: - return null; - case 1: - return ""; - } - byteCount--; - var chars = ""; - for (var i = 0; i < byteCount;) { - var b = this.readUnsignedByte(); - switch (b >> 4) { - case 12: - case 13: - chars += String.fromCharCode(((b & 0x1F) << 6 | this.readByte() & 0x3F)); - i += 2; - break; - case 14: - chars += String.fromCharCode(((b & 0x0F) << 12 | (this.readByte() & 0x3F) << 6 | this.readByte() & 0x3F)); - i += 3; - break; - default: - chars += String.fromCharCode(b); - i++; - } - } - return chars; - }; - BinaryInput.prototype.readFloat = function () { - var value = this.buffer.getFloat32(this.index); - this.index += 4; - return value; - }; - BinaryInput.prototype.readBoolean = function () { - return this.readByte() != 0; - }; - return BinaryInput; - }()); - - // Those enums were moved from Animation.ts of spine 3.8 and 4.0 - /** Controls how a timeline value is mixed with the setup pose value or current pose value when a timeline's `alpha` - * < 1. - * - * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. - * @public - * */ - exports.MixBlend = void 0; - (function (MixBlend) { - /** Transitions from the setup value to the timeline value (the current value is not used). Before the first key, the setup - * value is set. */ - MixBlend[MixBlend["setup"] = 0] = "setup"; - /** Transitions from the current value to the timeline value. Before the first key, transitions from the current value to - * the setup value. Timelines which perform instant transitions, such as DrawOrderTimeline or - * AttachmentTimeline, use the setup value before the first key. - * - * `first` is intended for the first animations applied, not for animations layered on top of those. */ - MixBlend[MixBlend["first"] = 1] = "first"; - /** Transitions from the current value to the timeline value. No change is made before the first key (the current value is - * kept until the first key). - * - * `replace` is intended for animations layered on top of others, not for the first animations applied. */ - MixBlend[MixBlend["replace"] = 2] = "replace"; - /** Transitions from the current value to the current value plus the timeline value. No change is made before the first key - * (the current value is kept until the first key). - * - * `add` is intended for animations layered on top of others, not for the first animations applied. Properties - * keyed by additive animations must be set manually or by another animation before applying the additive animations, else - * the property values will increase continually. */ - MixBlend[MixBlend["add"] = 3] = "add"; - })(exports.MixBlend || (exports.MixBlend = {})); - /** Indicates whether a timeline's `alpha` is mixing out over time toward 0 (the setup or current pose value) or - * mixing in toward 1 (the timeline's value). - * - * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. - * @public - * */ - exports.MixDirection = void 0; - (function (MixDirection) { - MixDirection[MixDirection["mixIn"] = 0] = "mixIn"; - MixDirection[MixDirection["mixOut"] = 1] = "mixOut"; - })(exports.MixDirection || (exports.MixDirection = {})); - - // These enums were moved from PathConstraintData.ts of spine 3.7, 3.8 and 4.0 - /** 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. - * @public - * */ - exports.PositionMode = void 0; - (function (PositionMode) { - PositionMode[PositionMode["Fixed"] = 0] = "Fixed"; - PositionMode[PositionMode["Percent"] = 1] = "Percent"; - })(exports.PositionMode || (exports.PositionMode = {})); - /** Controls how bones are rotated, translated, and scaled to match the path. - * - * [Rotate mode](http://esotericsoftware.com/spine-path-constraints#Rotate-mod) in the Spine User Guide. - * @public - * */ - exports.RotateMode = void 0; - (function (RotateMode) { - RotateMode[RotateMode["Tangent"] = 0] = "Tangent"; - RotateMode[RotateMode["Chain"] = 1] = "Chain"; - RotateMode[RotateMode["ChainScale"] = 2] = "ChainScale"; - })(exports.RotateMode || (exports.RotateMode = {})); - - // This enum was moved from BoneData.ts of spine 3.7, 3.8 and 4.0 - /** Determines how a bone inherits world transforms from parent bones. - * @public - * */ - exports.TransformMode = void 0; - (function (TransformMode) { - TransformMode[TransformMode["Normal"] = 0] = "Normal"; - TransformMode[TransformMode["OnlyTranslation"] = 1] = "OnlyTranslation"; - TransformMode[TransformMode["NoRotationOrReflection"] = 2] = "NoRotationOrReflection"; - TransformMode[TransformMode["NoScale"] = 3] = "NoScale"; - TransformMode[TransformMode["NoScaleOrReflection"] = 4] = "NoScaleOrReflection"; - })(exports.TransformMode || (exports.TransformMode = {})); - - /*! ***************************************************************************** - Copyright (c) Microsoft Corporation. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. - ***************************************************************************** */ - /* global Reflect, Promise */ - - var extendStatics$4 = function(d, b) { - extendStatics$4 = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics$4(d, b); - }; - - function __extends$4(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics$4(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - } - - /** - * @public - */ - function filterFromString(text) { - switch (text.toLowerCase()) { - case "nearest": return exports.TextureFilter.Nearest; - case "linear": return exports.TextureFilter.Linear; - case "mipmap": return exports.TextureFilter.MipMap; - case "mipmapnearestnearest": return exports.TextureFilter.MipMapNearestNearest; - case "mipmaplinearnearest": return exports.TextureFilter.MipMapLinearNearest; - case "mipmapnearestlinear": return exports.TextureFilter.MipMapNearestLinear; - case "mipmaplinearlinear": return exports.TextureFilter.MipMapLinearLinear; - default: throw new Error("Unknown texture filter " + text); - } - } - /** - * @public - */ - function wrapFromString(text) { - switch (text.toLowerCase()) { - case "mirroredtepeat": return exports.TextureWrap.MirroredRepeat; - case "clamptoedge": return exports.TextureWrap.ClampToEdge; - case "repeat": return exports.TextureWrap.Repeat; - default: throw new Error("Unknown texture wrap " + text); - } - } - /** - * @public - */ - exports.TextureFilter = void 0; - (function (TextureFilter) { - TextureFilter[TextureFilter["Nearest"] = 9728] = "Nearest"; - TextureFilter[TextureFilter["Linear"] = 9729] = "Linear"; - TextureFilter[TextureFilter["MipMap"] = 9987] = "MipMap"; - TextureFilter[TextureFilter["MipMapNearestNearest"] = 9984] = "MipMapNearestNearest"; - TextureFilter[TextureFilter["MipMapLinearNearest"] = 9985] = "MipMapLinearNearest"; - TextureFilter[TextureFilter["MipMapNearestLinear"] = 9986] = "MipMapNearestLinear"; - TextureFilter[TextureFilter["MipMapLinearLinear"] = 9987] = "MipMapLinearLinear"; // WebGLRenderingContext.LINEAR_MIPMAP_LINEAR - })(exports.TextureFilter || (exports.TextureFilter = {})); - /** - * @public - */ - exports.TextureWrap = void 0; - (function (TextureWrap) { - TextureWrap[TextureWrap["MirroredRepeat"] = 33648] = "MirroredRepeat"; - TextureWrap[TextureWrap["ClampToEdge"] = 33071] = "ClampToEdge"; - TextureWrap[TextureWrap["Repeat"] = 10497] = "Repeat"; // WebGLRenderingContext.REPEAT - })(exports.TextureWrap || (exports.TextureWrap = {})); - /** - * @public - */ - var TextureRegion = /** @class */ (function () { - function TextureRegion() { - //thats for overrides - this.size = null; - this.names = null; - this.values = null; - this.renderObject = null; - } - Object.defineProperty(TextureRegion.prototype, "width", { - get: function () { - var tex = this.texture; - if (tex.trim) { - return tex.trim.width; - } - return tex.orig.width; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "height", { - get: function () { - var tex = this.texture; - if (tex.trim) { - return tex.trim.height; - } - return tex.orig.height; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "u", { - get: function () { - return this.texture._uvs.x0; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "v", { - get: function () { - return this.texture._uvs.y0; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "u2", { - get: function () { - return this.texture._uvs.x2; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "v2", { - get: function () { - return this.texture._uvs.y2; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "offsetX", { - get: function () { - var tex = this.texture; - return tex.trim ? tex.trim.x : 0; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "offsetY", { - get: function () { - // console.warn("Deprecation Warning: @Hackerham: I guess, if you are using PIXI-SPINE ATLAS region.offsetY, you want a texture, right? Use region.texture from now on."); - return this.spineOffsetY; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "pixiOffsetY", { - get: function () { - var tex = this.texture; - return tex.trim ? tex.trim.y : 0; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "spineOffsetY", { - get: function () { - var tex = this.texture; - return this.originalHeight - this.height - (tex.trim ? tex.trim.y : 0); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "originalWidth", { - get: function () { - return this.texture.orig.width; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "originalHeight", { - get: function () { - return this.texture.orig.height; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "x", { - get: function () { - return this.texture.frame.x; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "y", { - get: function () { - return this.texture.frame.y; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "rotate", { - get: function () { - return this.texture.rotate !== 0; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TextureRegion.prototype, "degrees", { - get: function () { - return (360 - this.texture.rotate * 45) % 360; - }, - enumerable: false, - configurable: true - }); - return TextureRegion; - }()); - - var RegionFields = /** @class */ (function () { - function RegionFields() { - this.x = 0; - this.y = 0; - this.width = 0; - this.height = 0; - this.offsetX = 0; - this.offsetY = 0; - this.originalWidth = 0; - this.originalHeight = 0; - this.rotate = 0; - this.index = 0; - } - return RegionFields; - }()); - /** - * @public - */ - var TextureAtlas = /** @class */ (function () { - function TextureAtlas(atlasText, textureLoader, callback) { - this.pages = new Array(); - this.regions = new Array(); - if (atlasText) { - this.addSpineAtlas(atlasText, textureLoader, callback); - } - } - TextureAtlas.prototype.addTexture = function (name, texture) { - var pages = this.pages; - var page = null; - for (var i = 0; i < pages.length; i++) { - if (pages[i].baseTexture === texture.baseTexture) { - page = pages[i]; - break; - } - } - if (page === null) { - page = new TextureAtlasPage(); - page.name = 'texturePage'; - var baseTexture = texture.baseTexture; - page.width = baseTexture.realWidth; - page.height = baseTexture.realHeight; - page.baseTexture = baseTexture; - //those fields are not relevant in Pixi - page.minFilter = page.magFilter = exports.TextureFilter.Nearest; - page.uWrap = exports.TextureWrap.ClampToEdge; - page.vWrap = exports.TextureWrap.ClampToEdge; - pages.push(page); - } - var region = new TextureAtlasRegion(); - region.name = name; - region.page = page; - region.texture = texture; - region.index = -1; - this.regions.push(region); - return region; - }; - TextureAtlas.prototype.addTextureHash = function (textures, stripExtension) { - for (var key in textures) { - if (textures.hasOwnProperty(key)) { - this.addTexture(stripExtension && key.indexOf('.') !== -1 ? key.substr(0, key.lastIndexOf('.')) : key, textures[key]); - } - } - }; - TextureAtlas.prototype.addSpineAtlas = function (atlasText, textureLoader, callback) { - return this.load(atlasText, textureLoader, callback); - }; - TextureAtlas.prototype.load = function (atlasText, textureLoader, callback) { - var _this = this; - if (textureLoader == null) - throw new Error("textureLoader cannot be null."); - var reader = new TextureAtlasReader(atlasText); - var entry = new Array(4); - var page = null; - var pageFields = {}; - var region = null; - pageFields["size"] = function () { - page.width = parseInt(entry[1]); - page.height = parseInt(entry[2]); - }; - pageFields["format"] = function () { - // page.format = Format[tuple[0]]; we don't need format in WebGL - }; - pageFields["filter"] = function () { - page.minFilter = filterFromString(entry[1]); - page.magFilter = filterFromString(entry[2]); - }; - pageFields["repeat"] = function () { - if (entry[1].indexOf('x') != -1) - page.uWrap = exports.TextureWrap.Repeat; - if (entry[1].indexOf('y') != -1) - page.vWrap = exports.TextureWrap.Repeat; - }; - pageFields["pma"] = function () { - page.pma = entry[1] == "true"; - }; - var regionFields = {}; - regionFields["xy"] = function () { - region.x = parseInt(entry[1]); - region.y = parseInt(entry[2]); - }; - regionFields["size"] = function () { - region.width = parseInt(entry[1]); - region.height = parseInt(entry[2]); - }; - regionFields["bounds"] = function () { - region.x = parseInt(entry[1]); - region.y = parseInt(entry[2]); - region.width = parseInt(entry[3]); - region.height = parseInt(entry[4]); - }; - regionFields["offset"] = function () { - region.offsetX = parseInt(entry[1]); - region.offsetY = parseInt(entry[2]); - }; - regionFields["orig"] = function () { - region.originalWidth = parseInt(entry[1]); - region.originalHeight = parseInt(entry[2]); - }; - regionFields["offsets"] = function () { - region.offsetX = parseInt(entry[1]); - region.offsetY = parseInt(entry[2]); - region.originalWidth = parseInt(entry[3]); - region.originalHeight = parseInt(entry[4]); - }; - regionFields["rotate"] = function () { - var rotateValue = entry[1]; - var rotate = 0; - if (rotateValue.toLocaleLowerCase() == "true") { - rotate = 6; - } - else if (rotateValue.toLocaleLowerCase() == "false") { - rotate = 0; - } - else { - rotate = ((720 - parseFloat(rotateValue)) % 360) / 45; - } - region.rotate = rotate; - }; - regionFields["index"] = function () { - region.index = parseInt(entry[1]); - }; - var line = reader.readLine(); - // Ignore empty lines before first entry. - while (line != null && line.trim().length == 0) - line = reader.readLine(); - // Header entries. - while (true) { - if (line == null || line.trim().length == 0) - break; - if (reader.readEntry(entry, line) == 0) - break; // Silently ignore all header fields. - line = reader.readLine(); - } - var iterateParser = function () { - while (true) { - if (line == null) { - return callback && callback(_this); - } - if (line.trim().length == 0) { - page = null; - line = reader.readLine(); - } - else if (page === null) { - page = new TextureAtlasPage(); - page.name = line.trim(); - while (true) { - if (reader.readEntry(entry, line = reader.readLine()) == 0) - break; - var field = pageFields[entry[0]]; - if (field) - field(); - } - _this.pages.push(page); - textureLoader(page.name, function (texture) { - if (texture === null) { - _this.pages.splice(_this.pages.indexOf(page), 1); - return callback && callback(null); - } - page.baseTexture = texture; - //TODO: set scaleMode and mipmapMode from spine - if (page.pma) { - texture.alphaMode = constants.ALPHA_MODES.PMA; - } - if (!texture.valid) { - texture.setSize(page.width, page.height); - } - page.setFilters(); - if (!page.width || !page.height) { - page.width = texture.realWidth; - page.height = texture.realHeight; - if (!page.width || !page.height) { - console.log("ERROR spine atlas page " + page.name + ": meshes wont work if you dont specify size in atlas (http://www.html5gamedevs.com/topic/18888-pixi-spines-and-meshes/?p=107121)"); - } - } - iterateParser(); - }); - break; - } - else { - region = new RegionFields(); - var atlasRegion = new TextureAtlasRegion(); - atlasRegion.name = line; - atlasRegion.page = page; - var names = null; - var values = null; - while (true) { - var count = reader.readEntry(entry, line = reader.readLine()); - if (count == 0) - break; - var field = regionFields[entry[0]]; - if (field) - field(); - else { - if (names == null) { - names = []; - values = []; - } - names.push(entry[0]); - var entryValues = []; - for (var i = 0; i < count; i++) - entryValues.push(parseInt(entry[i + 1])); - values.push(entryValues); - } - } - if (region.originalWidth == 0 && region.originalHeight == 0) { - region.originalWidth = region.width; - region.originalHeight = region.height; - } - var resolution = page.baseTexture.resolution; - region.x /= resolution; - region.y /= resolution; - region.width /= resolution; - region.height /= resolution; - region.originalWidth /= resolution; - region.originalHeight /= resolution; - region.offsetX /= resolution; - region.offsetY /= resolution; - var swapWH = region.rotate % 4 !== 0; - var frame = new math.Rectangle(region.x, region.y, swapWH ? region.height : region.width, swapWH ? region.width : region.height); - var orig = new math.Rectangle(0, 0, region.originalWidth, region.originalHeight); - var trim = new math.Rectangle(region.offsetX, region.originalHeight - region.height - region.offsetY, region.width, region.height); - atlasRegion.texture = new core.Texture(atlasRegion.page.baseTexture, frame, orig, trim, region.rotate); - atlasRegion.index = region.index; - atlasRegion.texture.updateUvs(); - _this.regions.push(atlasRegion); - } - } - }; - iterateParser(); - }; - TextureAtlas.prototype.findRegion = function (name) { - for (var i = 0; i < this.regions.length; i++) { - if (this.regions[i].name == name) { - return this.regions[i]; - } - } - return null; - }; - TextureAtlas.prototype.dispose = function () { - for (var i = 0; i < this.pages.length; i++) { - this.pages[i].baseTexture.dispose(); - } - }; - return TextureAtlas; - }()); - /** - * @public - */ - var TextureAtlasReader = /** @class */ (function () { - function TextureAtlasReader(text) { - this.index = 0; - this.lines = text.split(/\r\n|\r|\n/); - } - TextureAtlasReader.prototype.readLine = function () { - if (this.index >= this.lines.length) - return null; - return this.lines[this.index++]; - }; - TextureAtlasReader.prototype.readEntry = function (entry, line) { - if (line == null) - return 0; - line = line.trim(); - if (line.length == 0) - return 0; - var colon = line.indexOf(':'); - if (colon == -1) - return 0; - entry[0] = line.substr(0, colon).trim(); - for (var i = 1, lastMatch = colon + 1;; i++) { - var comma = line.indexOf(',', lastMatch); - if (comma == -1) { - entry[i] = line.substr(lastMatch).trim(); - return i; - } - entry[i] = line.substr(lastMatch, comma - lastMatch).trim(); - lastMatch = comma + 1; - if (i == 4) - return 4; - } - }; - return TextureAtlasReader; - }()); - /** - * @public - */ - var TextureAtlasPage = /** @class */ (function () { - function TextureAtlasPage() { - this.minFilter = exports.TextureFilter.Nearest; - this.magFilter = exports.TextureFilter.Nearest; - this.uWrap = exports.TextureWrap.ClampToEdge; - this.vWrap = exports.TextureWrap.ClampToEdge; - } - TextureAtlasPage.prototype.setFilters = function () { - var tex = this.baseTexture; - var filter = this.minFilter; - if (filter == exports.TextureFilter.Linear) { - tex.scaleMode = constants.SCALE_MODES.LINEAR; - } - else if (this.minFilter == exports.TextureFilter.Nearest) { - tex.scaleMode = constants.SCALE_MODES.NEAREST; - } - else { - tex.mipmap = constants.MIPMAP_MODES.POW2; - if (filter == exports.TextureFilter.MipMapNearestNearest) { - tex.scaleMode = constants.SCALE_MODES.NEAREST; - } - else { - tex.scaleMode = constants.SCALE_MODES.LINEAR; - } - } - }; - return TextureAtlasPage; - }()); - /** - * @public - */ - var TextureAtlasRegion = /** @class */ (function (_super) { - __extends$4(TextureAtlasRegion, _super); - function TextureAtlasRegion() { - return _super !== null && _super.apply(this, arguments) || this; - } - return TextureAtlasRegion; - }(TextureRegion)); - - var fround_polyfill = (function (array) { - return function (x) { - return array[0] = x, array[0]; - }; - })(new Float32Array(1)); - var fround = Math.fround || fround_polyfill; - /** - * @public - */ - var IntSet = /** @class */ (function () { - function IntSet() { - this.array = new Array(); - } - IntSet.prototype.add = function (value) { - var contains = this.contains(value); - this.array[value | 0] = value | 0; - return !contains; - }; - IntSet.prototype.contains = function (value) { - return this.array[value | 0] != undefined; - }; - IntSet.prototype.remove = function (value) { - this.array[value | 0] = undefined; - }; - IntSet.prototype.clear = function () { - this.array.length = 0; - }; - return IntSet; - }()); - /** - * @public - */ - var StringSet = /** @class */ (function () { - function StringSet() { - this.entries = {}; - this.size = 0; - } - StringSet.prototype.add = function (value) { - var contains = this.entries[value]; - this.entries[value] = true; - if (!contains) { - this.size++; - return true; - } - return false; - }; - StringSet.prototype.addAll = function (values) { - var oldSize = this.size; - for (var i = 0, n = values.length; i < n; i++) - this.add(values[i]); - return oldSize != this.size; - }; - StringSet.prototype.contains = function (value) { - return this.entries[value]; - }; - StringSet.prototype.clear = function () { - this.entries = {}; - this.size = 0; - }; - return StringSet; - }()); - /** - * @public - */ - var Color = /** @class */ (function () { - function Color(r, g, b, a) { - if (r === void 0) { r = 0; } - if (g === void 0) { g = 0; } - if (b === void 0) { b = 0; } - if (a === void 0) { a = 0; } - this.r = r; - this.g = g; - this.b = b; - this.a = a; - } - Color.prototype.set = function (r, g, b, a) { - this.r = r; - this.g = g; - this.b = b; - this.a = a; - return this.clamp(); - }; - Color.prototype.setFromColor = function (c) { - this.r = c.r; - this.g = c.g; - this.b = c.b; - this.a = c.a; - return this; - }; - Color.prototype.setFromString = function (hex) { - hex = hex.charAt(0) == '#' ? hex.substr(1) : hex; - this.r = parseInt(hex.substr(0, 2), 16) / 255; - this.g = parseInt(hex.substr(2, 2), 16) / 255; - this.b = parseInt(hex.substr(4, 2), 16) / 255; - this.a = hex.length != 8 ? 1 : parseInt(hex.substr(6, 2), 16) / 255; - return this; - }; - Color.prototype.add = function (r, g, b, a) { - this.r += r; - this.g += g; - this.b += b; - this.a += a; - return this.clamp(); - }; - Color.prototype.clamp = function () { - if (this.r < 0) - this.r = 0; - else if (this.r > 1) - this.r = 1; - if (this.g < 0) - this.g = 0; - else if (this.g > 1) - this.g = 1; - if (this.b < 0) - this.b = 0; - else if (this.b > 1) - this.b = 1; - if (this.a < 0) - this.a = 0; - else if (this.a > 1) - this.a = 1; - return this; - }; - Color.rgba8888ToColor = function (color, value) { - color.r = ((value & 0xff000000) >>> 24) / 255; - color.g = ((value & 0x00ff0000) >>> 16) / 255; - color.b = ((value & 0x0000ff00) >>> 8) / 255; - color.a = ((value & 0x000000ff)) / 255; - }; - Color.rgb888ToColor = function (color, value) { - color.r = ((value & 0x00ff0000) >>> 16) / 255; - color.g = ((value & 0x0000ff00) >>> 8) / 255; - color.b = ((value & 0x000000ff)) / 255; - }; - Color.fromString = function (hex) { - return new Color().setFromString(hex); - }; - Color.WHITE = new Color(1, 1, 1, 1); - Color.RED = new Color(1, 0, 0, 1); - Color.GREEN = new Color(0, 1, 0, 1); - Color.BLUE = new Color(0, 0, 1, 1); - Color.MAGENTA = new Color(1, 0, 1, 1); - return Color; - }()); - /** - * @public - */ - var MathUtils = /** @class */ (function () { - function MathUtils() { - } - MathUtils.clamp = function (value, min, max) { - if (value < min) - return min; - if (value > max) - return max; - return value; - }; - MathUtils.cosDeg = function (degrees) { - return Math.cos(degrees * MathUtils.degRad); - }; - MathUtils.sinDeg = function (degrees) { - return Math.sin(degrees * MathUtils.degRad); - }; - MathUtils.signum = function (value) { - return value > 0 ? 1 : value < 0 ? -1 : 0; - }; - MathUtils.toInt = function (x) { - return x > 0 ? Math.floor(x) : Math.ceil(x); - }; - MathUtils.cbrt = function (x) { - var y = Math.pow(Math.abs(x), 1 / 3); - return x < 0 ? -y : y; - }; - MathUtils.randomTriangular = function (min, max) { - return MathUtils.randomTriangularWith(min, max, (min + max) * 0.5); - }; - MathUtils.randomTriangularWith = function (min, max, mode) { - var u = Math.random(); - var d = max - min; - if (u <= (mode - min) / d) - return min + Math.sqrt(u * d * (mode - min)); - return max - Math.sqrt((1 - u) * d * (max - mode)); - }; - MathUtils.isPowerOfTwo = function (value) { - return value && (value & (value - 1)) === 0; - }; - MathUtils.PI = 3.1415927; - MathUtils.PI2 = MathUtils.PI * 2; - MathUtils.radiansToDegrees = 180 / MathUtils.PI; - MathUtils.radDeg = MathUtils.radiansToDegrees; - MathUtils.degreesToRadians = MathUtils.PI / 180; - MathUtils.degRad = MathUtils.degreesToRadians; - return MathUtils; - }()); - /** - * @public - */ - var Interpolation = /** @class */ (function () { - function Interpolation() { - } - Interpolation.prototype.apply = function (start, end, a) { - return start + (end - start) * this.applyInternal(a); - }; - return Interpolation; - }()); - /** - * @public - */ - var Pow = /** @class */ (function (_super) { - __extends$4(Pow, _super); - function Pow(power) { - var _this = _super.call(this) || this; - _this.power = 2; - _this.power = power; - return _this; - } - Pow.prototype.applyInternal = function (a) { - if (a <= 0.5) - return Math.pow(a * 2, this.power) / 2; - return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1; - }; - return Pow; - }(Interpolation)); - /** - * @public - */ - var PowOut = /** @class */ (function (_super) { - __extends$4(PowOut, _super); - function PowOut(power) { - return _super.call(this, power) || this; - } - PowOut.prototype.applyInternal = function (a) { - return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1; - }; - return PowOut; - }(Pow)); - /** - * @public - */ - var Utils = /** @class */ (function () { - function Utils() { - } - Utils.arrayCopy = function (source, sourceStart, dest, destStart, numElements) { - for (var i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) { - dest[j] = source[i]; - } - }; - Utils.arrayFill = function (array, fromIndex, toIndex, value) { - for (var i = fromIndex; i < toIndex; i++) - array[i] = value; - }; - Utils.setArraySize = function (array, size, value) { - if (value === void 0) { value = 0; } - var oldSize = array.length; - if (oldSize == size) - return array; - array.length = size; - if (oldSize < size) { - for (var i = oldSize; i < size; i++) - array[i] = value; - } - return array; - }; - Utils.ensureArrayCapacity = function (array, size, value) { - if (value === void 0) { value = 0; } - if (array.length >= size) - return array; - return Utils.setArraySize(array, size, value); - }; - Utils.newArray = function (size, defaultValue) { - var array = new Array(size); - for (var i = 0; i < size; i++) - array[i] = defaultValue; - return array; - }; - Utils.newFloatArray = function (size) { - if (Utils.SUPPORTS_TYPED_ARRAYS) - return new Float32Array(size); - else { - var array = new Array(size); - for (var i = 0; i < array.length; i++) - array[i] = 0; - return array; - } - }; - Utils.newShortArray = function (size) { - if (Utils.SUPPORTS_TYPED_ARRAYS) - return new Int16Array(size); - else { - var array = new Array(size); - for (var i = 0; i < array.length; i++) - array[i] = 0; - return array; - } - }; - Utils.toFloatArray = function (array) { - return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array; - }; - Utils.toSinglePrecision = function (value) { - return Utils.SUPPORTS_TYPED_ARRAYS ? fround(value) : value; - }; - // This function is used to fix WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 - Utils.webkit602BugfixHelper = function (alpha, blend) { - }; - Utils.contains = function (array, element, identity) { - for (var i = 0; i < array.length; i++) - if (array[i] == element) - return true; - return false; - }; - Utils.enumValue = function (type, name) { - return type[name[0].toUpperCase() + name.slice(1)]; - }; - Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined"; - return Utils; - }()); - /** - * @public - */ - var DebugUtils = /** @class */ (function () { - function DebugUtils() { - } - DebugUtils.logBones = function (skeleton) { - for (var i = 0; i < skeleton.bones.length; i++) { - var bone = skeleton.bones[i]; - var mat = bone.matrix; - console.log(bone.data.name + ", " + mat.a + ", " + mat.b + ", " + mat.c + ", " + mat.d + ", " + mat.tx + ", " + mat.ty); - } - }; - return DebugUtils; - }()); - /** - * @public - */ - var Pool = /** @class */ (function () { - function Pool(instantiator) { - this.items = new Array(); - this.instantiator = instantiator; - } - Pool.prototype.obtain = function () { - return this.items.length > 0 ? this.items.pop() : this.instantiator(); - }; - Pool.prototype.free = function (item) { - if (item.reset) - item.reset(); - this.items.push(item); - }; - Pool.prototype.freeAll = function (items) { - for (var i = 0; i < items.length; i++) - this.free(items[i]); - }; - Pool.prototype.clear = function () { - this.items.length = 0; - }; - return Pool; - }()); - /** - * @public - */ - var Vector2 = /** @class */ (function () { - function Vector2(x, y) { - if (x === void 0) { x = 0; } - if (y === void 0) { y = 0; } - this.x = x; - this.y = y; - } - Vector2.prototype.set = function (x, y) { - this.x = x; - this.y = y; - return this; - }; - Vector2.prototype.length = function () { - var x = this.x; - var y = this.y; - return Math.sqrt(x * x + y * y); - }; - Vector2.prototype.normalize = function () { - var len = this.length(); - if (len != 0) { - this.x /= len; - this.y /= len; - } - return this; - }; - return Vector2; - }()); - /** - * @public - */ - var TimeKeeper = /** @class */ (function () { - function TimeKeeper() { - this.maxDelta = 0.064; - this.framesPerSecond = 0; - this.delta = 0; - this.totalTime = 0; - this.lastTime = Date.now() / 1000; - this.frameCount = 0; - this.frameTime = 0; - } - TimeKeeper.prototype.update = function () { - var now = Date.now() / 1000; - this.delta = now - this.lastTime; - this.frameTime += this.delta; - this.totalTime += this.delta; - if (this.delta > this.maxDelta) - this.delta = this.maxDelta; - this.lastTime = now; - this.frameCount++; - if (this.frameTime > 1) { - this.framesPerSecond = this.frameCount / this.frameTime; - this.frameTime = 0; - this.frameCount = 0; - } - }; - return TimeKeeper; - }()); - /** - * @public - */ - var WindowedMean = /** @class */ (function () { - function WindowedMean(windowSize) { - if (windowSize === void 0) { windowSize = 32; } - this.addedValues = 0; - this.lastValue = 0; - this.mean = 0; - this.dirty = true; - this.values = new Array(windowSize); - } - WindowedMean.prototype.hasEnoughData = function () { - return this.addedValues >= this.values.length; - }; - WindowedMean.prototype.addValue = function (value) { - if (this.addedValues < this.values.length) - this.addedValues++; - this.values[this.lastValue++] = value; - if (this.lastValue > this.values.length - 1) - this.lastValue = 0; - this.dirty = true; - }; - WindowedMean.prototype.getMean = function () { - if (this.hasEnoughData()) { - if (this.dirty) { - var mean = 0; - for (var i = 0; i < this.values.length; i++) - mean += this.values[i]; - this.mean = mean / this.values.length; - this.dirty = false; - } - return this.mean; - } - return 0; - }; - return WindowedMean; - }()); - - /** Collects each visible BoundingBoxAttachment and computes the world vertices for its polygon. The polygon vertices are - * provided along with convenience methods for doing hit detection. - * @public - * */ - var SkeletonBoundsBase = /** @class */ (function () { - function SkeletonBoundsBase() { - /** The left edge of the axis aligned bounding box. */ - this.minX = 0; - /** The bottom edge of the axis aligned bounding box. */ - this.minY = 0; - /** The right edge of the axis aligned bounding box. */ - this.maxX = 0; - /** The top edge of the axis aligned bounding box. */ - this.maxY = 0; - /** The visible bounding boxes. */ - this.boundingBoxes = new Array(); - /** The world vertices for the bounding box polygons. */ - this.polygons = new Array(); - this.polygonPool = new Pool(function () { - return Utils.newFloatArray(16); - }); - } - /** Clears any previous polygons, finds all visible bounding box attachments, and computes the world vertices for each bounding - * box's polygon. - * @param updateAabb If true, the axis aligned bounding box containing all the polygons is computed. If false, the - * SkeletonBounds AABB methods will always return true. */ - SkeletonBoundsBase.prototype.update = function (skeleton, updateAabb) { - if (!skeleton) - throw new Error("skeleton cannot be null."); - var boundingBoxes = this.boundingBoxes; - var polygons = this.polygons; - var polygonPool = this.polygonPool; - var slots = skeleton.slots; - var slotCount = slots.length; - boundingBoxes.length = 0; - polygonPool.freeAll(polygons); - polygons.length = 0; - for (var i = 0; i < slotCount; i++) { - var slot = slots[i]; - if (!slot.bone.active) - continue; - var attachment = slot.getAttachment(); - if (attachment != null && attachment.type === exports.AttachmentType.BoundingBox) { - var boundingBox = attachment; - boundingBoxes.push(boundingBox); - var polygon = polygonPool.obtain(); - if (polygon.length != boundingBox.worldVerticesLength) { - polygon = Utils.newFloatArray(boundingBox.worldVerticesLength); - } - polygons.push(polygon); - boundingBox.computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2); - } - } - if (updateAabb) { - this.aabbCompute(); - } - else { - this.minX = Number.POSITIVE_INFINITY; - this.minY = Number.POSITIVE_INFINITY; - this.maxX = Number.NEGATIVE_INFINITY; - this.maxY = Number.NEGATIVE_INFINITY; - } - }; - SkeletonBoundsBase.prototype.aabbCompute = function () { - var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; - var polygons = this.polygons; - for (var i = 0, n = polygons.length; i < n; i++) { - var polygon = polygons[i]; - var vertices = polygon; - for (var ii = 0, nn = polygon.length; ii < nn; ii += 2) { - var x = vertices[ii]; - var y = vertices[ii + 1]; - minX = Math.min(minX, x); - minY = Math.min(minY, y); - maxX = Math.max(maxX, x); - maxY = Math.max(maxY, y); - } - } - this.minX = minX; - this.minY = minY; - this.maxX = maxX; - this.maxY = maxY; - }; - /** Returns true if the axis aligned bounding box contains the point. */ - SkeletonBoundsBase.prototype.aabbContainsPoint = function (x, y) { - return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY; - }; - /** Returns true if the axis aligned bounding box intersects the line segment. */ - SkeletonBoundsBase.prototype.aabbIntersectsSegment = function (x1, y1, x2, y2) { - var minX = this.minX; - var minY = this.minY; - var maxX = this.maxX; - var maxY = this.maxY; - if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY)) - return false; - var m = (y2 - y1) / (x2 - x1); - var y = m * (minX - x1) + y1; - if (y > minY && y < maxY) - return true; - y = m * (maxX - x1) + y1; - if (y > minY && y < maxY) - return true; - var x = (minY - y1) / m + x1; - if (x > minX && x < maxX) - return true; - x = (maxY - y1) / m + x1; - if (x > minX && x < maxX) - return true; - return false; - }; - /** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */ - SkeletonBoundsBase.prototype.aabbIntersectsSkeleton = function (bounds) { - return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY; - }; - /** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more - * efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. - * Cannot be done here because BoundingBoxAttachment is not a thing yet*/ - SkeletonBoundsBase.prototype.containsPoint = function (x, y) { - var polygons = this.polygons; - for (var i = 0, n = polygons.length; i < n; i++) - if (this.containsPointPolygon(polygons[i], x, y)) - return this.boundingBoxes[i]; - return null; - }; - /** Returns true if the polygon contains the point. */ - SkeletonBoundsBase.prototype.containsPointPolygon = function (polygon, x, y) { - var vertices = polygon; - var nn = polygon.length; - var prevIndex = nn - 2; - var inside = false; - for (var ii = 0; ii < nn; ii += 2) { - var vertexY = vertices[ii + 1]; - var prevY = vertices[prevIndex + 1]; - if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) { - var vertexX = vertices[ii]; - if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x) - inside = !inside; - } - prevIndex = ii; - } - return inside; - }; - /** Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it - * is usually more efficient to only call this method if {@link #aabbIntersectsSegment()} returns - * true. */ - SkeletonBoundsBase.prototype.intersectsSegment = function (x1, y1, x2, y2) { - var polygons = this.polygons; - for (var i = 0, n = polygons.length; i < n; i++) - if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2)) - return this.boundingBoxes[i]; - return null; - }; - /** Returns true if the polygon contains any part of the line segment. */ - SkeletonBoundsBase.prototype.intersectsSegmentPolygon = function (polygon, x1, y1, x2, y2) { - var vertices = polygon; - var nn = polygon.length; - var width12 = x1 - x2, height12 = y1 - y2; - var det1 = x1 * y2 - y1 * x2; - var x3 = vertices[nn - 2], y3 = vertices[nn - 1]; - for (var ii = 0; ii < nn; ii += 2) { - var x4 = vertices[ii], y4 = vertices[ii + 1]; - var det2 = x3 * y4 - y3 * x4; - var width34 = x3 - x4, height34 = y3 - y4; - var det3 = width12 * height34 - height12 * width34; - var x = (det1 * width34 - width12 * det2) / det3; - if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) { - var y = (det1 * height34 - height12 * det2) / det3; - if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) - return true; - } - x3 = x4; - y3 = y4; - } - return false; - }; - /** Returns the polygon for the specified bounding box, or null. */ - SkeletonBoundsBase.prototype.getPolygon = function (boundingBox) { - if (!boundingBox) - throw new Error("boundingBox cannot be null."); - var index = this.boundingBoxes.indexOf(boundingBox); - return index == -1 ? null : this.polygons[index]; - }; - /** The width of the axis aligned bounding box. */ - SkeletonBoundsBase.prototype.getWidth = function () { - return this.maxX - this.minX; - }; - /** The height of the axis aligned bounding box. */ - SkeletonBoundsBase.prototype.getHeight = function () { - return this.maxY - this.minY; - }; - return SkeletonBoundsBase; - }()); - - /** - * @public - */ - var settings = { - yDown: true, - /** - * pixi-spine gives option to not fail at certain parsing errors - * spine-ts fails here - */ - FAIL_ON_NON_EXISTING_SKIN: false, - /** - * past Spine.globalAutoUpdate - */ - GLOBAL_AUTO_UPDATE: true, - /** - * past Spine.globalDelayLimit - */ - GLOBAL_DELAY_LIMIT: 0, - }; - - var tempRgb = [0, 0, 0]; - /** - * @public - */ - var SpineSprite = /** @class */ (function (_super) { - __extends$4(SpineSprite, _super); - function SpineSprite() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.region = null; - _this.attachment = null; - return _this; - } - return SpineSprite; - }(sprite.Sprite)); - /** - * @public - */ - var SpineMesh = /** @class */ (function (_super) { - __extends$4(SpineMesh, _super); - function SpineMesh(texture, vertices, uvs, indices, drawMode) { - var _this = _super.call(this, texture, vertices, uvs, indices, drawMode) || this; - _this.region = null; - _this.attachment = null; - return _this; - } - return SpineMesh; - }(meshExtras.SimpleMesh)); - /** - * A class that enables the you to import and run your spine animations in pixi. - * The Spine animation data needs to be loaded using either the Loader or a SpineLoader before it can be used by this class - * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source - * - * ```js - * let spineAnimation = new spine(spineData); - * ``` - * - * @public - * @class - * @extends Container - * @memberof spine - * @param spineData {object} The spine data loaded from a spine atlas. - */ - var SpineBase = /** @class */ (function (_super) { - __extends$4(SpineBase, _super); - function SpineBase(spineData) { - var _this = _super.call(this) || this; - if (!spineData) { - throw new Error('The spineData param is required.'); - } - if ((typeof spineData) === "string") { - throw new Error('spineData param cant be string. Please use spine.Spine.fromAtlas("YOUR_RESOURCE_NAME") from now on.'); - } - /** - * The spineData object - * - * @member {object} - */ - _this.spineData = spineData; - /** - * A spine Skeleton object - * - * @member {object} - */ - _this.createSkeleton(spineData); - /** - * An array of containers - * - * @member {Container[]} - */ - _this.slotContainers = []; - _this.tempClipContainers = []; - for (var i = 0, n = _this.skeleton.slots.length; i < n; i++) { - var slot = _this.skeleton.slots[i]; - var attachment = slot.getAttachment(); - var slotContainer = _this.newContainer(); - _this.slotContainers.push(slotContainer); - _this.addChild(slotContainer); - _this.tempClipContainers.push(null); - if (!attachment) { - continue; - } - if (attachment.type === exports.AttachmentType.Region) { - var spriteName = attachment.name; - var sprite = _this.createSprite(slot, attachment, spriteName); - slot.currentSprite = sprite; - slot.currentSpriteName = spriteName; - slotContainer.addChild(sprite); - } - else if (attachment.type === exports.AttachmentType.Mesh) { - var mesh = _this.createMesh(slot, attachment); - slot.currentMesh = mesh; - slot.currentMeshId = attachment.id; - slot.currentMeshName = attachment.name; - slotContainer.addChild(mesh); - } - else if (attachment.type === exports.AttachmentType.Clipping) { - _this.createGraphics(slot, attachment); - slotContainer.addChild(slot.clippingContainer); - slotContainer.addChild(slot.currentGraphics); - } - } - /** - * The tint applied to all spine slots. This is a [r,g,b] value. A value of [1,1,1] will remove any tint effect. - * - * @member {number} - * @memberof spine.Spine# - */ - _this.tintRgb = new Float32Array([1, 1, 1]); - _this.autoUpdate = true; - _this.visible = true; - return _this; - } - Object.defineProperty(SpineBase.prototype, "debug", { - get: function () { - return this._debug; - }, - set: function (value) { - var _a; - if (value == this._debug) { // soft equality allows null == undefined - return; - } - (_a = this._debug) === null || _a === void 0 ? void 0 : _a.unregisterSpine(this); - value === null || value === void 0 ? void 0 : value.registerSpine(this); - this._debug = value; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(SpineBase.prototype, "autoUpdate", { - /** - * If this flag is set to true, the spine animation will be automatically updated every - * time the object id drawn. The down side of this approach is that the delta time is - * automatically calculated and you could miss out on cool effects like slow motion, - * pause, skip ahead and the sorts. Most of these effects can be achieved even with - * autoUpdate enabled but are harder to achieve. - * - * @member {boolean} - * @memberof spine.Spine# - * @default true - */ - get: function () { - return this._autoUpdate; - }, - set: function (value) { - if (value !== this._autoUpdate) { - this._autoUpdate = value; - this.updateTransform = value ? SpineBase.prototype.autoUpdateTransform : display.Container.prototype.updateTransform; - } - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(SpineBase.prototype, "tint", { - /** - * The tint applied to the spine object. This is a hex value. A value of 0xFFFFFF will remove any tint effect. - * - * @member {number} - * @memberof spine.Spine# - * @default 0xFFFFFF - */ - get: function () { - return utils.rgb2hex(this.tintRgb); - }, - set: function (value) { - this.tintRgb = utils.hex2rgb(value, this.tintRgb); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(SpineBase.prototype, "delayLimit", { - /** - * Limit value for the update dt with Spine.globalDelayLimit - * that can be overridden with localDelayLimit - * @return {number} - Maximum processed dt value for the update - */ - get: function () { - var limit = typeof this.localDelayLimit !== "undefined" ? - this.localDelayLimit : settings.GLOBAL_DELAY_LIMIT; - // If limit is 0, this means there is no limit for the delay - return limit || Number.MAX_VALUE; - }, - enumerable: false, - configurable: true - }); - /** - * Update the spine skeleton and its animations by delta time (dt) - * - * @param dt {number} Delta time. Time by which the animation should be updated - */ - SpineBase.prototype.update = function (dt) { - var _a; - // Limit delta value to avoid animation jumps - var delayLimit = this.delayLimit; - if (dt > delayLimit) - dt = delayLimit; - this.state.update(dt); - this.state.apply(this.skeleton); - //check we haven't been destroyed via a spine event callback in state update - if (!this.skeleton) - return; - this.skeleton.updateWorldTransform(); - var slots = this.skeleton.slots; - // in case pixi has double tint - var globalClr = this.color; - var light = null, dark = null; - if (globalClr) { - light = globalClr.light; - dark = globalClr.dark; - } - else { - light = this.tintRgb; - } - // let thack = false; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - var attachment = slot.getAttachment(); - var slotContainer = this.slotContainers[i]; - if (!attachment) { - slotContainer.visible = false; - continue; - } - var spriteColor = null; - if (attachment.sequence) { - attachment.sequence.apply(slot, attachment); - } - var region = attachment.region; - var attColor = attachment.color; - switch (attachment != null && attachment.type) { - case exports.AttachmentType.Region: - var transform = slotContainer.transform; - transform.setFromMatrix(slot.bone.matrix); - region = attachment.region; - if (slot.currentMesh) { - slot.currentMesh.visible = false; - slot.currentMesh = null; - slot.currentMeshId = undefined; - slot.currentMeshName = undefined; - } - if (!region) { - if (slot.currentSprite) { - slot.currentSprite.renderable = false; - } - break; - } - if (!slot.currentSpriteName || slot.currentSpriteName !== attachment.name) { - var spriteName = attachment.name; - if (slot.currentSprite) { - slot.currentSprite.visible = false; - } - slot.sprites = slot.sprites || {}; - if (slot.sprites[spriteName] !== undefined) { - slot.sprites[spriteName].visible = true; - } - else { - var sprite = this.createSprite(slot, attachment, spriteName); - slotContainer.addChild(sprite); - } - slot.currentSprite = slot.sprites[spriteName]; - slot.currentSpriteName = spriteName; - // force sprite update when attachment name is same. - // issues https://github.com/pixijs/pixi-spine/issues/318 - } - slot.currentSprite.renderable = true; - if (!slot.hackRegion) { - this.setSpriteRegion(attachment, slot.currentSprite, region); - } - if (slot.currentSprite.color) { - //YAY! double - tint! - spriteColor = slot.currentSprite.color; - } - else { - tempRgb[0] = light[0] * slot.color.r * attColor.r; - tempRgb[1] = light[1] * slot.color.g * attColor.g; - tempRgb[2] = light[2] * slot.color.b * attColor.b; - slot.currentSprite.tint = utils.rgb2hex(tempRgb); - } - slot.currentSprite.blendMode = slot.blendMode; - break; - case exports.AttachmentType.Mesh: - if (slot.currentSprite) { - //TODO: refactor this thing, switch it on and off for container - slot.currentSprite.visible = false; - slot.currentSprite = null; - slot.currentSpriteName = undefined; - //TODO: refactor this shit - var transform_1 = new math.Transform(); - transform_1._parentID = -1; - transform_1._worldID = slotContainer.transform._worldID; - slotContainer.transform = transform_1; - } - if (!region) { - if (slot.currentMesh) { - slot.currentMesh.renderable = false; - } - break; - } - var id = attachment.id; - if (slot.currentMeshId === undefined || slot.currentMeshId !== id) { - var meshId = id; - if (slot.currentMesh) { - slot.currentMesh.visible = false; - } - slot.meshes = slot.meshes || {}; - if (slot.meshes[meshId] !== undefined) { - slot.meshes[meshId].visible = true; - } - else { - var mesh = this.createMesh(slot, attachment); - slotContainer.addChild(mesh); - } - slot.currentMesh = slot.meshes[meshId]; - slot.currentMeshName = attachment.name; - slot.currentMeshId = meshId; - } - slot.currentMesh.renderable = true; - attachment.computeWorldVerticesOld(slot, slot.currentMesh.vertices); - if (slot.currentMesh.color) { - // pixi-heaven - spriteColor = slot.currentMesh.color; - } - else { - tempRgb[0] = light[0] * slot.color.r * attColor.r; - tempRgb[1] = light[1] * slot.color.g * attColor.g; - tempRgb[2] = light[2] * slot.color.b * attColor.b; - slot.currentMesh.tint = utils.rgb2hex(tempRgb); - } - slot.currentMesh.blendMode = slot.blendMode; - if (!slot.hackRegion) { - this.setMeshRegion(attachment, slot.currentMesh, region); - } - break; - case exports.AttachmentType.Clipping: - if (!slot.currentGraphics) { - this.createGraphics(slot, attachment); - slotContainer.addChild(slot.clippingContainer); - slotContainer.addChild(slot.currentGraphics); - } - this.updateGraphics(slot, attachment); - slotContainer.alpha = 1.0; - slotContainer.visible = true; - continue; - default: - slotContainer.visible = false; - continue; - } - slotContainer.visible = true; - // pixi has double tint - if (spriteColor) { - var r0 = slot.color.r * attColor.r; - var g0 = slot.color.g * attColor.g; - var b0 = slot.color.b * attColor.b; - //YAY! double-tint! - spriteColor.setLight(light[0] * r0 + dark[0] * (1.0 - r0), light[1] * g0 + dark[1] * (1.0 - g0), light[2] * b0 + dark[2] * (1.0 - b0)); - if (slot.darkColor) { - r0 = slot.darkColor.r; - g0 = slot.darkColor.g; - b0 = slot.darkColor.b; - } - else { - r0 = 0.0; - g0 = 0.0; - b0 = 0.0; - } - spriteColor.setDark(light[0] * r0 + dark[0] * (1 - r0), light[1] * g0 + dark[1] * (1 - g0), light[2] * b0 + dark[2] * (1 - b0)); - } - slotContainer.alpha = slot.color.a; - } - //== this is clipping implementation === - //TODO: remove parent hacks when pixi masks allow it - var drawOrder = this.skeleton.drawOrder; - var clippingAttachment = null; - var clippingContainer = null; - for (var i = 0, n = drawOrder.length; i < n; i++) { - var slot = slots[drawOrder[i].data.index]; - var slotContainer = this.slotContainers[drawOrder[i].data.index]; - if (!clippingContainer) { - //Adding null check as it is possible for slotContainer.parent to be null in the event of a spine being disposed off in its loop callback - if (slotContainer.parent !== null && slotContainer.parent !== this) { - slotContainer.parent.removeChild(slotContainer); - //silend add hack - slotContainer.parent = this; - } - } - if (slot.currentGraphics && slot.getAttachment()) { - clippingContainer = slot.clippingContainer; - clippingAttachment = slot.getAttachment(); - clippingContainer.children.length = 0; - this.children[i] = slotContainer; - if (clippingAttachment.endSlot === slot.data) { - clippingAttachment.endSlot = null; - } - } - else { - if (clippingContainer) { - var c = this.tempClipContainers[i]; - if (!c) { - c = this.tempClipContainers[i] = this.newContainer(); - c.visible = false; - } - this.children[i] = c; - //silent remove hack - slotContainer.parent = null; - clippingContainer.addChild(slotContainer); - if (clippingAttachment.endSlot == slot.data) { - clippingContainer.renderable = true; - clippingContainer = null; - clippingAttachment = null; - } - } - else { - this.children[i] = slotContainer; - } - } - } - // if you can debug, then debug! - (_a = this._debug) === null || _a === void 0 ? void 0 : _a.renderDebug(this); - }; - SpineBase.prototype.setSpriteRegion = function (attachment, sprite, region) { - // prevent setters calling when attachment and region is same - if (sprite.attachment === attachment && sprite.region === region) { - return; - } - sprite.region = region; - sprite.attachment = attachment; - sprite.texture = region.texture; - sprite.rotation = attachment.rotation * MathUtils.degRad; - sprite.position.x = attachment.x; - sprite.position.y = attachment.y; - sprite.alpha = attachment.color.a; - if (!region.size) { - sprite.scale.x = attachment.scaleX * attachment.width / region.originalWidth; - sprite.scale.y = -attachment.scaleY * attachment.height / region.originalHeight; - } - else { - //hacked! - sprite.scale.x = region.size.width / region.originalWidth; - sprite.scale.y = -region.size.height / region.originalHeight; - } - }; - SpineBase.prototype.setMeshRegion = function (attachment, mesh, region) { - if (mesh.attachment === attachment && mesh.region === region) { - return; - } - mesh.region = region; - mesh.attachment = attachment; - mesh.texture = region.texture; - region.texture.updateUvs(); - mesh.uvBuffer.update(attachment.regionUVs); - }; - /** - * When autoupdate is set to yes this function is used as pixi's updateTransform function - * - * @private - */ - SpineBase.prototype.autoUpdateTransform = function () { - if (settings.GLOBAL_AUTO_UPDATE) { - this.lastTime = this.lastTime || Date.now(); - var timeDelta = (Date.now() - this.lastTime) * 0.001; - this.lastTime = Date.now(); - this.update(timeDelta); - } - else { - this.lastTime = 0; - } - display.Container.prototype.updateTransform.call(this); - }; - /** - * Create a new sprite to be used with core.RegionAttachment - * - * @param slot {spine.Slot} The slot to which the attachment is parented - * @param attachment {spine.RegionAttachment} The attachment that the sprite will represent - * @private - */ - SpineBase.prototype.createSprite = function (slot, attachment, defName) { - var region = attachment.region; - if (slot.hackAttachment === attachment) { - region = slot.hackRegion; - } - var texture = region ? region.texture : null; - var sprite = this.newSprite(texture); - sprite.anchor.set(0.5); - if (region) { - this.setSpriteRegion(attachment, sprite, attachment.region); - } - slot.sprites = slot.sprites || {}; - slot.sprites[defName] = sprite; - return sprite; - }; - /** - * Creates a Strip from the spine data - * @param slot {spine.Slot} The slot to which the attachment is parented - * @param attachment {spine.RegionAttachment} The attachment that the sprite will represent - * @private - */ - SpineBase.prototype.createMesh = function (slot, attachment) { - var region = attachment.region; - if (slot.hackAttachment === attachment) { - region = slot.hackRegion; - slot.hackAttachment = null; - slot.hackRegion = null; - } - var strip = this.newMesh(region ? region.texture : null, new Float32Array(attachment.regionUVs.length), attachment.regionUVs, new Uint16Array(attachment.triangles), constants.DRAW_MODES.TRIANGLES); - if (typeof strip._canvasPadding !== "undefined") { - strip._canvasPadding = 1.5; - } - strip.alpha = attachment.color.a; - strip.region = attachment.region; - if (region) { - this.setMeshRegion(attachment, strip, region); - } - slot.meshes = slot.meshes || {}; - slot.meshes[attachment.id] = strip; - return strip; - }; - //@ts-ignore - SpineBase.prototype.createGraphics = function (slot, clip) { - var graphics = this.newGraphics(); - var poly = new math.Polygon([]); - graphics.clear(); - graphics.beginFill(0xffffff, 1); - graphics.drawPolygon(poly); - graphics.renderable = false; - slot.currentGraphics = graphics; - slot.clippingContainer = this.newContainer(); - slot.clippingContainer.mask = slot.currentGraphics; - return graphics; - }; - SpineBase.prototype.updateGraphics = function (slot, clip) { - var geom = slot.currentGraphics.geometry; - var vertices = geom.graphicsData[0].shape.points; - var n = clip.worldVerticesLength; - vertices.length = n; - clip.computeWorldVertices(slot, 0, n, vertices, 0, 2); - geom.invalidate(); - }; - /** - * Changes texture in attachment in specific slot. - * - * PIXI runtime feature, it was made to satisfy our users. - * - * @param slotIndex {number} - * @param [texture = null] {PIXI.Texture} If null, take default (original) texture - * @param [size = null] {PIXI.Point} sometimes we need new size for region attachment, you can pass 'texture.orig' there - * @returns {boolean} Success flag - */ - SpineBase.prototype.hackTextureBySlotIndex = function (slotIndex, texture, size) { - if (texture === void 0) { texture = null; } - if (size === void 0) { size = null; } - var slot = this.skeleton.slots[slotIndex]; - if (!slot) { - return false; - } - var attachment = slot.getAttachment(); - var region = attachment.region; - if (texture) { - region = new TextureRegion(); - region.texture = texture; - region.size = size; - slot.hackRegion = region; - slot.hackAttachment = attachment; - } - else { - slot.hackRegion = null; - slot.hackAttachment = null; - } - if (slot.currentSprite) { - this.setSpriteRegion(attachment, slot.currentSprite, region); - } - else if (slot.currentMesh) { - this.setMeshRegion(attachment, slot.currentMesh, region); - } - return true; - }; - /** - * Changes texture in attachment in specific slot. - * - * PIXI runtime feature, it was made to satisfy our users. - * - * @param slotName {string} - * @param [texture = null] {PIXI.Texture} If null, take default (original) texture - * @param [size = null] {PIXI.Point} sometimes we need new size for region attachment, you can pass 'texture.orig' there - * @returns {boolean} Success flag - */ - SpineBase.prototype.hackTextureBySlotName = function (slotName, texture, size) { - if (texture === void 0) { texture = null; } - if (size === void 0) { size = null; } - var index = this.skeleton.findSlotIndex(slotName); - if (index == -1) { - return false; - } - return this.hackTextureBySlotIndex(index, texture, size); - }; - /** - * Changes texture of an attachment - * - * PIXI runtime feature, it was made to satisfy our users. - * - * @param slotName {string} - * @param attachmentName {string} - * @param [texture = null] {PIXI.Texture} If null, take default (original) texture - * @param [size = null] {PIXI.Point} sometimes we need new size for region attachment, you can pass 'texture.orig' there - * @returns {boolean} Success flag - */ - SpineBase.prototype.hackTextureAttachment = function (slotName, attachmentName, texture, size) { - if (size === void 0) { size = null; } - // changes the texture of an attachment at the skeleton level - var slotIndex = this.skeleton.findSlotIndex(slotName); - var attachment = this.skeleton.getAttachmentByName(slotName, attachmentName); - attachment.region.texture = texture; - var slot = this.skeleton.slots[slotIndex]; - if (!slot) { - return false; - } - // gets the currently active attachment in this slot - var currentAttachment = slot.getAttachment(); - if (attachmentName === currentAttachment.name) { - // if the attachment we are changing is currently active, change the the live texture - var region = attachment.region; - if (texture) { - region = new TextureRegion(); - region.texture = texture; - region.size = size; - slot.hackRegion = region; - slot.hackAttachment = currentAttachment; - } - else { - slot.hackRegion = null; - slot.hackAttachment = null; - } - if (slot.currentSprite && slot.currentSprite.region != region) { - this.setSpriteRegion(currentAttachment, slot.currentSprite, region); - slot.currentSprite.region = region; - } - else if (slot.currentMesh && slot.currentMesh.region != region) { - this.setMeshRegion(currentAttachment, slot.currentMesh, region); - } - return true; - } - return false; - }; - //those methods can be overriden to spawn different classes - SpineBase.prototype.newContainer = function () { - return new display.Container(); - }; - SpineBase.prototype.newSprite = function (tex) { - return new SpineSprite(tex); - }; - SpineBase.prototype.newGraphics = function () { - return new graphics.Graphics(); - }; - SpineBase.prototype.newMesh = function (texture, vertices, uvs, indices, drawMode) { - return new SpineMesh(texture, vertices, uvs, indices, drawMode); - }; - SpineBase.prototype.transformHack = function () { - return 1; - }; - /** - * Hack for pixi-display and pixi-lights. Every attachment name ending with a suffix will be added to different layer - * @param nameSuffix - * @param group - * @param outGroup - */ - SpineBase.prototype.hackAttachmentGroups = function (nameSuffix, group, outGroup) { - if (!nameSuffix) { - return undefined; - } - var list_d = [], list_n = []; - for (var i = 0, len = this.skeleton.slots.length; i < len; i++) { - var slot = this.skeleton.slots[i]; - var name_1 = slot.currentSpriteName || slot.currentMeshName || ""; - var target = slot.currentSprite || slot.currentMesh; - if (name_1.endsWith(nameSuffix)) { - target.parentGroup = group; - list_n.push(target); - } - else if (outGroup && target) { - target.parentGroup = outGroup; - list_d.push(target); - } - } - return [list_d, list_n]; - }; - SpineBase.prototype.destroy = function (options) { - this.debug = null; // setter will do the cleanup - for (var i = 0, n = this.skeleton.slots.length; i < n; i++) { - var slot = this.skeleton.slots[i]; - for (var name_2 in slot.meshes) { - slot.meshes[name_2].destroy(options); - } - slot.meshes = null; - for (var name_3 in slot.sprites) { - slot.sprites[name_3].destroy(options); - } - slot.sprites = null; - } - for (var i = 0, n = this.slotContainers.length; i < n; i++) { - this.slotContainers[i].destroy(options); - } - this.spineData = null; - this.skeleton = null; - this.slotContainers = null; - this.stateData = null; - this.state = null; - this.tempClipContainers = null; - _super.prototype.destroy.call(this, options); - }; - SpineBase.clippingPolygon = []; - return SpineBase; - }(display.Container)); - /** - * The visibility of the spine object. If false the object will not be drawn, - * the updateTransform function will not be called, and the spine will not be automatically updated. - * - * @member {boolean} - * @memberof spine.Spine# - * @default true - */ - Object.defineProperty(SpineBase.prototype, 'visible', { - get: function () { - return this._visible; - }, - set: function (value) { - if (value !== this._visible) { - this._visible = value; - if (value) { - this.lastTime = 0; - } - } - } - }); - - /** - * This is a debug renderer that uses PixiJS Graphics under the hood. - * @public - */ - var SpineDebugRenderer = /** @class */ (function () { - function SpineDebugRenderer() { - this.registeredSpines = new Map(); - this.drawDebug = true; - this.drawMeshHull = true; - this.drawMeshTriangles = true; - this.drawBones = true; - this.drawPaths = true; - this.drawBoundingBoxes = true; - this.drawClipping = true; - this.drawRegionAttachments = true; - this.lineWidth = 1; - this.regionAttachmentsColor = 0x0078ff; - this.meshHullColor = 0x0078ff; - this.meshTrianglesColor = 0xffcc00; - this.clippingPolygonColor = 0xff00ff; - this.boundingBoxesRectColor = 0x00ff00; - this.boundingBoxesPolygonColor = 0x00ff00; - this.boundingBoxesCircleColor = 0x00ff00; - this.pathsCurveColor = 0xff0000; - this.pathsLineColor = 0xff00ff; - this.skeletonXYColor = 0xff0000; - this.bonesColor = 0x00eecc; - } - /** - * The debug is attached by force to each spine object. So we need to create it inside the spine when we get the first update - */ - SpineDebugRenderer.prototype.registerSpine = function (spine) { - if (this.registeredSpines.has(spine)) { - console.warn("SpineDebugRenderer.registerSpine() - this spine is already registered!", spine); - } - var debugDisplayObjects = { - parentDebugContainer: new display.Container(), - bones: new display.Container(), - skeletonXY: new graphics.Graphics(), - regionAttachmentsShape: new graphics.Graphics(), - meshTrianglesLine: new graphics.Graphics(), - meshHullLine: new graphics.Graphics(), - clippingPolygon: new graphics.Graphics(), - boundingBoxesRect: new graphics.Graphics(), - boundingBoxesCircle: new graphics.Graphics(), - boundingBoxesPolygon: new graphics.Graphics(), - pathsCurve: new graphics.Graphics(), - pathsLine: new graphics.Graphics(), - }; - debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.bones); - debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.skeletonXY); - debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.regionAttachmentsShape); - debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.meshTrianglesLine); - debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.meshHullLine); - debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.clippingPolygon); - debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.boundingBoxesRect); - debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.boundingBoxesCircle); - debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.boundingBoxesPolygon); - debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.pathsCurve); - debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.pathsLine); - spine.addChild(debugDisplayObjects.parentDebugContainer); - this.registeredSpines.set(spine, debugDisplayObjects); - }; - SpineDebugRenderer.prototype.renderDebug = function (spine) { - if (!this.registeredSpines.has(spine)) { - // This should never happen. Spines are registered when you assign spine.debug - this.registerSpine(spine); - } - var debugDisplayObjects = this.registeredSpines.get(spine); - debugDisplayObjects.skeletonXY.clear(); - debugDisplayObjects.regionAttachmentsShape.clear(); - debugDisplayObjects.meshTrianglesLine.clear(); - debugDisplayObjects.meshHullLine.clear(); - debugDisplayObjects.clippingPolygon.clear(); - debugDisplayObjects.boundingBoxesRect.clear(); - debugDisplayObjects.boundingBoxesCircle.clear(); - debugDisplayObjects.boundingBoxesPolygon.clear(); - debugDisplayObjects.pathsCurve.clear(); - debugDisplayObjects.pathsLine.clear(); - for (var len = debugDisplayObjects.bones.children.length; len > 0; len--) { - debugDisplayObjects.bones.children[len - 1].destroy({ children: true, texture: true, baseTexture: true }); - } - var scale = spine.scale.x || spine.scale.y || 1; - var lineWidth = this.lineWidth / scale; - if (this.drawBones) { - this.drawBonesFunc(spine, debugDisplayObjects, lineWidth, scale); - } - if (this.drawPaths) { - this.drawPathsFunc(spine, debugDisplayObjects, lineWidth); - } - if (this.drawBoundingBoxes) { - this.drawBoundingBoxesFunc(spine, debugDisplayObjects, lineWidth); - } - if (this.drawClipping) { - this.drawClippingFunc(spine, debugDisplayObjects, lineWidth); - } - if (this.drawMeshHull || this.drawMeshTriangles) { - this.drawMeshHullAndMeshTriangles(spine, debugDisplayObjects, lineWidth); - } - if (this.drawRegionAttachments) { - this.drawRegionAttachmentsFunc(spine, debugDisplayObjects, lineWidth); - } - }; - SpineDebugRenderer.prototype.drawBonesFunc = function (spine, debugDisplayObjects, lineWidth, scale) { - var skeleton = spine.skeleton; - var skeletonX = skeleton.x; - var skeletonY = skeleton.y; - var bones = skeleton.bones; - debugDisplayObjects.skeletonXY.lineStyle(lineWidth, this.skeletonXYColor, 1); - for (var i = 0, len = bones.length; i < len; i++) { - var bone = bones[i], boneLen = bone.data.length, starX = skeletonX + bone.matrix.tx, starY = skeletonY + bone.matrix.ty, endX = skeletonX + boneLen * bone.matrix.a + bone.matrix.tx, endY = skeletonY + boneLen * bone.matrix.b + bone.matrix.ty; - if (bone.data.name === "root" || bone.data.parent === null) { - continue; - } - // Triangle calculation formula - // area: A=sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))/4 - // alpha: alpha=acos((pow(b, 2)+pow(c, 2)-pow(a, 2))/(2*b*c)) - // beta: beta=acos((pow(a, 2)+pow(c, 2)-pow(b, 2))/(2*a*c)) - // gamma: gamma=acos((pow(a, 2)+pow(b, 2)-pow(c, 2))/(2*a*b)) - var w = Math.abs(starX - endX), h = Math.abs(starY - endY), - // a = w, // side length a - a2 = Math.pow(w, 2), // square root of side length a - b = h, // side length b - b2 = Math.pow(h, 2), // square root of side length b - c = Math.sqrt(a2 + b2), // side length c - c2 = Math.pow(c, 2), // square root of side length c - rad = Math.PI / 180, - // A = Math.acos([a2 + c2 - b2] / [2 * a * c]) || 0, // Angle A - // C = Math.acos([a2 + b2 - c2] / [2 * a * b]) || 0, // C angle - B = Math.acos((c2 + b2 - a2) / (2 * b * c)) || 0; // angle of corner B - if (c === 0) { - continue; - } - var gp = new graphics.Graphics(); - debugDisplayObjects.bones.addChild(gp); - // draw bone - var refRation = c / 50 / scale; - gp.beginFill(this.bonesColor, 1); - gp.drawPolygon(0, 0, 0 - refRation, c - refRation * 3, 0, c - refRation, 0 + refRation, c - refRation * 3); - gp.endFill(); - gp.x = starX; - gp.y = starY; - gp.pivot.y = c; - // Calculate bone rotation angle - var rotation = 0; - if (starX < endX && starY < endY) { - // bottom right - rotation = -B + 180 * rad; - } - else if (starX > endX && starY < endY) { - // bottom left - rotation = 180 * rad + B; - } - else if (starX > endX && starY > endY) { - // top left - rotation = -B; - } - else if (starX < endX && starY > endY) { - // bottom left - rotation = B; - } - else if (starY === endY && starX < endX) { - // To the right - rotation = 90 * rad; - } - else if (starY === endY && starX > endX) { - // go left - rotation = -90 * rad; - } - else if (starX === endX && starY < endY) { - // down - rotation = 180 * rad; - } - else if (starX === endX && starY > endY) { - // up - rotation = 0; - } - gp.rotation = rotation; - // Draw the starting rotation point of the bone - gp.lineStyle(lineWidth + refRation / 2.4, this.bonesColor, 1); - gp.beginFill(0x000000, 0.6); - gp.drawCircle(0, c, refRation * 1.2); - gp.endFill(); - } - // Draw the skeleton starting point "X" form - var startDotSize = lineWidth * 3; - debugDisplayObjects.skeletonXY.moveTo(skeletonX - startDotSize, skeletonY - startDotSize); - debugDisplayObjects.skeletonXY.lineTo(skeletonX + startDotSize, skeletonY + startDotSize); - debugDisplayObjects.skeletonXY.moveTo(skeletonX + startDotSize, skeletonY - startDotSize); - debugDisplayObjects.skeletonXY.lineTo(skeletonX - startDotSize, skeletonY + startDotSize); - }; - SpineDebugRenderer.prototype.drawRegionAttachmentsFunc = function (spine, debugDisplayObjects, lineWidth) { - var skeleton = spine.skeleton; - var slots = skeleton.slots; - debugDisplayObjects.regionAttachmentsShape.lineStyle(lineWidth, this.regionAttachmentsColor, 1); - for (var i = 0, len = slots.length; i < len; i++) { - var slot = slots[i], attachment = slot.getAttachment(); - if (attachment == null || attachment.type !== exports.AttachmentType.Region) { - continue; - } - var regionAttachment = attachment; - var vertices = new Float32Array(8); - regionAttachment === null || regionAttachment === void 0 ? void 0 : regionAttachment.updateOffset(); // We don't need this on all versions - regionAttachment.computeWorldVertices(slot, vertices, 0, 2); - debugDisplayObjects.regionAttachmentsShape.drawPolygon(Array.from(vertices.slice(0, 8))); - } - }; - SpineDebugRenderer.prototype.drawMeshHullAndMeshTriangles = function (spine, debugDisplayObjects, lineWidth) { - var skeleton = spine.skeleton; - var slots = skeleton.slots; - debugDisplayObjects.meshHullLine.lineStyle(lineWidth, this.meshHullColor, 1); - debugDisplayObjects.meshTrianglesLine.lineStyle(lineWidth, this.meshTrianglesColor, 1); - for (var i = 0, len = slots.length; i < len; i++) { - var slot = slots[i]; - if (!slot.bone.active) { - continue; - } - var attachment = slot.getAttachment(); - if (attachment == null || attachment.type !== exports.AttachmentType.Mesh) { - continue; - } - var meshAttachment = attachment; - var vertices = new Float32Array(meshAttachment.worldVerticesLength), triangles = meshAttachment.triangles; - var hullLength = meshAttachment.hullLength; - meshAttachment.computeWorldVertices(slot, 0, meshAttachment.worldVerticesLength, vertices, 0, 2); - // draw the skinned mesh (triangle) - if (this.drawMeshTriangles) { - for (var i_1 = 0, len_1 = triangles.length; i_1 < len_1; i_1 += 3) { - var v1 = triangles[i_1] * 2, v2 = triangles[i_1 + 1] * 2, v3 = triangles[i_1 + 2] * 2; - debugDisplayObjects.meshTrianglesLine.moveTo(vertices[v1], vertices[v1 + 1]); - debugDisplayObjects.meshTrianglesLine.lineTo(vertices[v2], vertices[v2 + 1]); - debugDisplayObjects.meshTrianglesLine.lineTo(vertices[v3], vertices[v3 + 1]); - } - } - // draw skin border - if (this.drawMeshHull && hullLength > 0) { - hullLength = (hullLength >> 1) * 2; - var lastX = vertices[hullLength - 2], lastY = vertices[hullLength - 1]; - for (var i_2 = 0, len_2 = hullLength; i_2 < len_2; i_2 += 2) { - var x = vertices[i_2], y = vertices[i_2 + 1]; - debugDisplayObjects.meshHullLine.moveTo(x, y); - debugDisplayObjects.meshHullLine.lineTo(lastX, lastY); - lastX = x; - lastY = y; - } - } - } - }; - SpineDebugRenderer.prototype.drawClippingFunc = function (spine, debugDisplayObjects, lineWidth) { - var skeleton = spine.skeleton; - var slots = skeleton.slots; - debugDisplayObjects.clippingPolygon.lineStyle(lineWidth, this.clippingPolygonColor, 1); - for (var i = 0, len = slots.length; i < len; i++) { - var slot = slots[i]; - if (!slot.bone.active) { - continue; - } - var attachment = slot.getAttachment(); - if (attachment == null || attachment.type !== exports.AttachmentType.Clipping) { - continue; - } - var clippingAttachment = attachment; - var nn = clippingAttachment.worldVerticesLength, world = new Float32Array(nn); - clippingAttachment.computeWorldVertices(slot, 0, nn, world, 0, 2); - debugDisplayObjects.clippingPolygon.drawPolygon(Array.from(world)); - } - }; - SpineDebugRenderer.prototype.drawBoundingBoxesFunc = function (spine, debugDisplayObjects, lineWidth) { - var _this = this; - // draw the total outline of the bounding box - debugDisplayObjects.boundingBoxesRect.lineStyle(lineWidth, this.boundingBoxesRectColor, 5); - var bounds = new SkeletonBoundsBase(); - bounds.update(spine.skeleton, true); - debugDisplayObjects.boundingBoxesRect.drawRect(bounds.minX, bounds.minY, bounds.getWidth(), bounds.getHeight()); - var polygons = bounds.polygons, drawPolygon = function (polygonVertices, _offset, count) { - debugDisplayObjects.boundingBoxesPolygon.lineStyle(lineWidth, _this.boundingBoxesPolygonColor, 1); - debugDisplayObjects.boundingBoxesPolygon.beginFill(_this.boundingBoxesPolygonColor, 0.1); - if (count < 3) { - throw new Error("Polygon must contain at least 3 vertices"); - } - var paths = [], dotSize = lineWidth * 2; - for (var i = 0, len = polygonVertices.length; i < len; i += 2) { - var x1 = polygonVertices[i], y1 = polygonVertices[i + 1]; - // draw the bounding box node - debugDisplayObjects.boundingBoxesCircle.lineStyle(0); - debugDisplayObjects.boundingBoxesCircle.beginFill(_this.boundingBoxesCircleColor); - debugDisplayObjects.boundingBoxesCircle.drawCircle(x1, y1, dotSize); - debugDisplayObjects.boundingBoxesCircle.endFill(); - paths.push(x1, y1); - } - // draw the bounding box area - debugDisplayObjects.boundingBoxesPolygon.drawPolygon(paths); - debugDisplayObjects.boundingBoxesPolygon.endFill(); - }; - for (var i = 0, len = polygons.length; i < len; i++) { - var polygon = polygons[i]; - drawPolygon(polygon, 0, polygon.length); - } - }; - SpineDebugRenderer.prototype.drawPathsFunc = function (spine, debugDisplayObjects, lineWidth) { - var skeleton = spine.skeleton; - var slots = skeleton.slots; - debugDisplayObjects.pathsCurve.lineStyle(lineWidth, this.pathsCurveColor, 1); - debugDisplayObjects.pathsLine.lineStyle(lineWidth, this.pathsLineColor, 1); - for (var i = 0, len = slots.length; i < len; i++) { - var slot = slots[i]; - if (!slot.bone.active) { - continue; - } - var attachment = slot.getAttachment(); - if (attachment == null || attachment.type !== exports.AttachmentType.Path) { - continue; - } - var pathAttachment = attachment; - var nn = pathAttachment.worldVerticesLength; - var world = new Float32Array(nn); - pathAttachment.computeWorldVertices(slot, 0, nn, world, 0, 2); - var x1 = world[2], y1 = world[3], x2 = 0, y2 = 0; - if (pathAttachment.closed) { - var cx1 = world[0], cy1 = world[1], cx2 = world[nn - 2], cy2 = world[nn - 1]; - x2 = world[nn - 4]; - y2 = world[nn - 3]; - // curve - debugDisplayObjects.pathsCurve.moveTo(x1, y1); - debugDisplayObjects.pathsCurve.bezierCurveTo(cx1, cy1, cx2, cy2, x2, y2); - // handle - debugDisplayObjects.pathsLine.moveTo(x1, y1); - debugDisplayObjects.pathsLine.lineTo(cx1, cy1); - debugDisplayObjects.pathsLine.moveTo(x2, y2); - debugDisplayObjects.pathsLine.lineTo(cx2, cy2); - } - nn -= 4; - for (var ii = 4; ii < nn; ii += 6) { - var cx1 = world[ii], cy1 = world[ii + 1], cx2 = world[ii + 2], cy2 = world[ii + 3]; - x2 = world[ii + 4]; - y2 = world[ii + 5]; - // curve - debugDisplayObjects.pathsCurve.moveTo(x1, y1); - debugDisplayObjects.pathsCurve.bezierCurveTo(cx1, cy1, cx2, cy2, x2, y2); - // handle - debugDisplayObjects.pathsLine.moveTo(x1, y1); - debugDisplayObjects.pathsLine.lineTo(cx1, cy1); - debugDisplayObjects.pathsLine.moveTo(x2, y2); - debugDisplayObjects.pathsLine.lineTo(cx2, cy2); - x1 = x2; - y1 = y2; - } - } - }; - SpineDebugRenderer.prototype.unregisterSpine = function (spine) { - if (!this.registeredSpines.has(spine)) { - console.warn("SpineDebugRenderer.unregisterSpine() - spine is not registered, can't unregister!", spine); - } - var debugDisplayObjects = this.registeredSpines.get(spine); - debugDisplayObjects.parentDebugContainer.destroy({ baseTexture: true, children: true, texture: true }); - this.registeredSpines.delete(spine); - }; - return SpineDebugRenderer; - }()); - - /* eslint-disable */ - - function isJson(resource) { - return resource.type === loaders.LoaderResource.TYPE.JSON; - } - function isBuffer(resource) { - return resource.xhrType === loaders.LoaderResource.XHR_RESPONSE_TYPE.BUFFER; - } - loaders.LoaderResource.setExtensionXhrType('skel', loaders.LoaderResource.XHR_RESPONSE_TYPE.BUFFER); - /** - * @public - */ - var AbstractSpineParser = /** @class */ (function () { - function AbstractSpineParser() { - } - AbstractSpineParser.prototype.genMiddleware = function () { - var self = this; - return { - use: function (resource, next) { - // skip if no data, its not json, or it isn't atlas data - if (!resource.data) { - return next(); - } - var isJsonSpineModel = isJson(resource) && resource.data.bones; - var isBinarySpineModel = isBuffer(resource) && (resource.extension === 'skel' || resource.metadata - && resource.metadata.spineMetadata); - if (!isJsonSpineModel && !isBinarySpineModel) { - return next(); - } - var parser = null; - var dataToParse = resource.data; - if (isJsonSpineModel) { - parser = self.createJsonParser(); - } - else { - parser = self.createBinaryParser(); - if (resource.data instanceof ArrayBuffer) { - dataToParse = new Uint8Array(resource.data); - } - } - var metadata = (resource.metadata || {}); - var metadataSkeletonScale = metadata ? metadata.spineSkeletonScale : null; - if (metadataSkeletonScale) { - parser.scale = metadataSkeletonScale; - } - var metadataAtlas = metadata.spineAtlas; - if (metadataAtlas === false) { - return next(); - } - if (metadataAtlas && metadataAtlas.pages) { - self.parseData(resource, parser, metadataAtlas, dataToParse); - return next(); - } - var metadataAtlasSuffix = metadata.spineAtlasSuffix || '.atlas'; - /** - * use a bit of hackery to load the atlas file, here we assume that the .json, .atlas and .png files - * that correspond to the spine file are in the same base URL and that the .json and .atlas files - * have the same name - */ - var atlasPath = resource.url; - var queryStringPos = atlasPath.indexOf('?'); - if (queryStringPos > 0) { - //remove querystring - atlasPath = atlasPath.substr(0, queryStringPos); - } - atlasPath = atlasPath.substr(0, atlasPath.lastIndexOf('.')) + metadataAtlasSuffix; - // use atlas path as a params. (no need to use same atlas file name with json file name) - if (metadata.spineAtlasFile) { - atlasPath = metadata.spineAtlasFile; - } - //remove the baseUrl - atlasPath = atlasPath.replace(this.baseUrl, ''); - var atlasOptions = { - crossOrigin: resource.crossOrigin, - xhrType: loaders.LoaderResource.XHR_RESPONSE_TYPE.TEXT, - metadata: metadata.spineMetadata || null, - parentResource: resource - }; - var imageOptions = { - crossOrigin: resource.crossOrigin, - metadata: metadata.imageMetadata || null, - parentResource: resource - }; - var baseUrl = resource.url.substr(0, resource.url.lastIndexOf('/') + 1); - //remove the baseUrl - baseUrl = baseUrl.replace(this.baseUrl, ''); - var namePrefix = metadata.imageNamePrefix || (resource.name + '_atlas_page_'); - var adapter = metadata.images ? staticImageLoader(metadata.images) - : metadata.image ? staticImageLoader({ 'default': metadata.image }) - : metadata.imageLoader ? metadata.imageLoader(this, namePrefix, baseUrl, imageOptions) - : imageLoaderAdapter(this, namePrefix, baseUrl, imageOptions); - function createSkeletonWithRawAtlas(rawData) { - new TextureAtlas(rawData, adapter, function (spineAtlas) { - if (spineAtlas) { - self.parseData(resource, parser, spineAtlas, dataToParse); - } - next(); - }); - } - if (metadata.atlasRawData) { - createSkeletonWithRawAtlas(metadata.atlasRawData); - } - else { - this.add(resource.name + '_atlas', atlasPath, atlasOptions, function (atlasResource) { - if (!atlasResource.error) { - createSkeletonWithRawAtlas(atlasResource.data); - } - else { - next(); - } - }); - } - } - }; - }; - return AbstractSpineParser; - }()); - /** - * @public - */ - function imageLoaderAdapter(loader, namePrefix, baseUrl, imageOptions) { - if (baseUrl && baseUrl.lastIndexOf('/') !== (baseUrl.length - 1)) { - baseUrl += '/'; - } - return function (line, callback) { - var name = namePrefix + line; - var url = baseUrl + line; - var cachedResource = loader.resources[name]; - if (cachedResource) { - var done = function () { - callback(cachedResource.texture.baseTexture); - }; - if (cachedResource.texture) { - done(); - } - else { - cachedResource.onAfterMiddleware.add(done); - } - } - else { - loader.add(name, url, imageOptions, function (resource) { - if (!resource.error) { - if (line.indexOf('-pma.') >= 0) { - resource.texture.baseTexture.alphaMode = constants.ALPHA_MODES.PMA; - } - callback(resource.texture.baseTexture); - } - else { - callback(null); - } - }); - } - }; - } - /** - * @public - */ - function syncImageLoaderAdapter(baseUrl, crossOrigin) { - if (baseUrl && baseUrl.lastIndexOf('/') !== (baseUrl.length - 1)) { - baseUrl += '/'; - } - return function (line, callback) { - callback(core.BaseTexture.from(line, crossOrigin)); - }; - } - /** - * @public - */ - function staticImageLoader(pages) { - return function (line, callback) { - var page = pages[line] || pages['default']; - if (page && page.baseTexture) - callback(page.baseTexture); - else - callback(page); - }; - } - - /* eslint-disable */ - - /*! ***************************************************************************** - Copyright (c) Microsoft Corporation. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. - ***************************************************************************** */ - /* global Reflect, Promise */ - - var extendStatics$3 = function(d, b) { - extendStatics$3 = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics$3(d, b); - }; - - function __extends$3(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics$3(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - } - - /** - * @public - */ - var Attachment$2 = /** @class */ (function () { - function Attachment(name) { - if (name == null) - throw new Error("name cannot be null."); - this.name = name; - } - return Attachment; - }()); - /** - * @public - */ - var VertexAttachment$2 = /** @class */ (function (_super) { - __extends$3(VertexAttachment, _super); - function VertexAttachment(name) { - var _this = _super.call(this, name) || this; - _this.id = (VertexAttachment.nextID++ & 65535) << 11; - _this.worldVerticesLength = 0; - _this.deformAttachment = _this; - return _this; - } - VertexAttachment.prototype.computeWorldVerticesOld = function (slot, worldVertices) { - this.computeWorldVertices(slot, 0, this.worldVerticesLength, worldVertices, 0, 2); - }; - /** Transforms local vertices to world coordinates. - * @param start The index of the first local vertex value to transform. Each vertex has 2 values, x and y. - * @param count The number of world vertex values to output. Must be <= {@link #getWorldVerticesLength()} - start. - * @param worldVertices The output world vertices. Must have a length >= offset + count. - * @param offset The worldVertices index to begin writing values. */ - VertexAttachment.prototype.computeWorldVertices = function (slot, start, count, worldVertices, offset, stride) { - count = offset + (count >> 1) * stride; - var skeleton = slot.bone.skeleton; - var deformArray = slot.deform; - var vertices = this.vertices; - var bones = this.bones; - if (bones == null) { - if (deformArray.length > 0) - vertices = deformArray; - var mat = slot.bone.matrix; - var x = mat.tx; - var y = mat.ty; - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - for (var v_1 = start, w = offset; w < count; v_1 += 2, w += stride) { - var vx = vertices[v_1], vy = vertices[v_1 + 1]; - worldVertices[w] = vx * a + vy * b + x; - worldVertices[w + 1] = vx * c + vy * d + y; - } - return; - } - var v = 0, skip = 0; - for (var i = 0; i < start; i += 2) { - var n = bones[v]; - v += n + 1; - skip += n; - } - var skeletonBones = skeleton.bones; - if (deformArray.length == 0) { - for (var w = offset, b = skip * 3; w < count; w += stride) { - var wx = 0, wy = 0; - var n = bones[v++]; - n += v; - for (; v < n; v++, b += 3) { - var mat = skeletonBones[bones[v]].matrix; - var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; - wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; - wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; - } - worldVertices[w] = wx; - worldVertices[w + 1] = wy; - } - } - else { - var deform = deformArray; - for (var w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { - var wx = 0, wy = 0; - var n = bones[v++]; - n += v; - for (; v < n; v++, b += 3, f += 2) { - var mat = skeletonBones[bones[v]].matrix; - var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; - wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; - wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; - } - worldVertices[w] = wx; - worldVertices[w + 1] = wy; - } - } - }; - VertexAttachment.prototype.copyTo = function (attachment) { - if (this.bones != null) { - attachment.bones = new Array(this.bones.length); - Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length); - } - else - attachment.bones = null; - if (this.vertices != null) { - attachment.vertices = Utils.newFloatArray(this.vertices.length); - Utils.arrayCopy(this.vertices, 0, attachment.vertices, 0, this.vertices.length); - } - else - attachment.vertices = null; - attachment.worldVerticesLength = this.worldVerticesLength; - attachment.deformAttachment = this.deformAttachment; - }; - VertexAttachment.nextID = 0; - return VertexAttachment; - }(Attachment$2)); - - /** - * @public - */ - var BoundingBoxAttachment$2 = /** @class */ (function (_super) { - __extends$3(BoundingBoxAttachment, _super); - function BoundingBoxAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.BoundingBox; - _this.color = new Color(1, 1, 1, 1); - return _this; - } - BoundingBoxAttachment.prototype.copy = function () { - var copy = new BoundingBoxAttachment(this.name); - this.copyTo(copy); - copy.color.setFromColor(this.color); - return copy; - }; - return BoundingBoxAttachment; - }(VertexAttachment$2)); - - /** - * @public - */ - var ClippingAttachment$2 = /** @class */ (function (_super) { - __extends$3(ClippingAttachment, _super); - function ClippingAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Clipping; - // Nonessential. - _this.color = new Color(0.2275, 0.2275, 0.8078, 1); // ce3a3aff - return _this; - } - ClippingAttachment.prototype.copy = function () { - var copy = new ClippingAttachment(this.name); - this.copyTo(copy); - copy.endSlot = this.endSlot; - copy.color.setFromColor(this.color); - return copy; - }; - return ClippingAttachment; - }(VertexAttachment$2)); - - /** - * @public - */ - var MeshAttachment$2 = /** @class */ (function (_super) { - __extends$3(MeshAttachment, _super); - function MeshAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Mesh; - _this.color = new Color(1, 1, 1, 1); - _this.tempColor = new Color(0, 0, 0, 0); - return _this; - } - MeshAttachment.prototype.getParentMesh = function () { - return this.parentMesh; - }; - /** @param parentMesh May be null. */ - MeshAttachment.prototype.setParentMesh = function (parentMesh) { - this.parentMesh = parentMesh; - if (parentMesh != null) { - this.bones = parentMesh.bones; - this.vertices = parentMesh.vertices; - this.worldVerticesLength = parentMesh.worldVerticesLength; - this.regionUVs = parentMesh.regionUVs; - this.triangles = parentMesh.triangles; - this.hullLength = parentMesh.hullLength; - this.worldVerticesLength = parentMesh.worldVerticesLength; - } - }; - MeshAttachment.prototype.copy = function () { - if (this.parentMesh != null) - return this.newLinkedMesh(); - var copy = new MeshAttachment(this.name); - copy.region = this.region; - copy.path = this.path; - copy.color.setFromColor(this.color); - this.copyTo(copy); - copy.regionUVs = new Float32Array(this.regionUVs.length); - Utils.arrayCopy(this.regionUVs, 0, copy.regionUVs, 0, this.regionUVs.length); - copy.triangles = new Array(this.triangles.length); - Utils.arrayCopy(this.triangles, 0, copy.triangles, 0, this.triangles.length); - copy.hullLength = this.hullLength; - // Nonessential. - if (this.edges != null) { - copy.edges = new Array(this.edges.length); - Utils.arrayCopy(this.edges, 0, copy.edges, 0, this.edges.length); - } - copy.width = this.width; - copy.height = this.height; - return copy; - }; - MeshAttachment.prototype.newLinkedMesh = function () { - var copy = new MeshAttachment(this.name); - copy.region = this.region; - copy.path = this.path; - copy.color.setFromColor(this.color); - copy.deformAttachment = this.deformAttachment; - copy.setParentMesh(this.parentMesh != null ? this.parentMesh : this); - // copy.updateUVs(); - return copy; - }; - return MeshAttachment; - }(VertexAttachment$2)); - - /** - * @public - */ - var PathAttachment$2 = /** @class */ (function (_super) { - __extends$3(PathAttachment, _super); - function PathAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Path; - _this.closed = false; - _this.constantSpeed = false; - _this.color = new Color(1, 1, 1, 1); - return _this; - } - PathAttachment.prototype.copy = function () { - var copy = new PathAttachment(this.name); - this.copyTo(copy); - copy.lengths = new Array(this.lengths.length); - Utils.arrayCopy(this.lengths, 0, copy.lengths, 0, this.lengths.length); - copy.closed = closed; - copy.constantSpeed = this.constantSpeed; - copy.color.setFromColor(this.color); - return copy; - }; - return PathAttachment; - }(VertexAttachment$2)); - - /** - * @public - */ - var PointAttachment$2 = /** @class */ (function (_super) { - __extends$3(PointAttachment, _super); - function PointAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Point; - _this.color = new Color(0.38, 0.94, 0, 1); - return _this; - } - PointAttachment.prototype.computeWorldPosition = function (bone, point) { - var mat = bone.matrix; - point.x = this.x * mat.a + this.y * mat.c + bone.worldX; - point.y = this.x * mat.b + this.y * mat.d + bone.worldY; - return point; - }; - PointAttachment.prototype.computeWorldRotation = function (bone) { - var mat = bone.matrix; - var cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation); - var x = cos * mat.a + sin * mat.c; - var y = cos * mat.b + sin * mat.d; - return Math.atan2(y, x) * MathUtils.radDeg; - }; - PointAttachment.prototype.copy = function () { - var copy = new PointAttachment(this.name); - copy.x = this.x; - copy.y = this.y; - copy.rotation = this.rotation; - copy.color.setFromColor(this.color); - return copy; - }; - return PointAttachment; - }(VertexAttachment$2)); - - /** - * @public - */ - var Slot$2 = /** @class */ (function () { - function Slot(data, bone) { - this.deform = new Array(); - if (data == null) - throw new Error("data cannot be null."); - if (bone == null) - throw new Error("bone cannot be null."); - this.data = data; - this.bone = bone; - this.color = new Color(); - this.darkColor = data.darkColor == null ? null : new Color(); - this.setToSetupPose(); - this.blendMode = this.data.blendMode; - } - /** @return May be null. */ - Slot.prototype.getAttachment = function () { - return this.attachment; - }; - /** Sets the attachment and if it changed, resets {@link #getAttachmentTime()} and clears {@link #getAttachmentVertices()}. - * @param attachment May be null. */ - Slot.prototype.setAttachment = function (attachment) { - if (this.attachment == attachment) - return; - this.attachment = attachment; - this.attachmentTime = this.bone.skeleton.time; - this.deform.length = 0; - }; - Slot.prototype.setAttachmentTime = function (time) { - this.attachmentTime = this.bone.skeleton.time - time; - }; - /** Returns the time since the attachment was set. */ - Slot.prototype.getAttachmentTime = function () { - return this.bone.skeleton.time - this.attachmentTime; - }; - Slot.prototype.setToSetupPose = function () { - this.color.setFromColor(this.data.color); - if (this.darkColor != null) - this.darkColor.setFromColor(this.data.darkColor); - if (this.data.attachmentName == null) - this.attachment = null; - else { - this.attachment = null; - this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName)); - } - }; - return Slot; - }()); - - /** - * @public - */ - var RegionAttachment$2 = /** @class */ (function (_super) { - __extends$3(RegionAttachment, _super); - function RegionAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Region; - _this.x = 0; - _this.y = 0; - _this.scaleX = 1; - _this.scaleY = 1; - _this.rotation = 0; - _this.width = 0; - _this.height = 0; - _this.color = new Color(1, 1, 1, 1); - _this.offset = Utils.newFloatArray(8); - _this.uvs = Utils.newFloatArray(8); - _this.tempColor = new Color(1, 1, 1, 1); - return _this; - } - RegionAttachment.prototype.updateOffset = function () { - var regionScaleX = this.width / this.region.originalWidth * this.scaleX; - var regionScaleY = this.height / this.region.originalHeight * this.scaleY; - var localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; - var localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; - var localX2 = localX + this.region.width * regionScaleX; - var localY2 = localY + this.region.height * regionScaleY; - var radians = this.rotation * Math.PI / 180; - var cos = Math.cos(radians); - var sin = Math.sin(radians); - var localXCos = localX * cos + this.x; - var localXSin = localX * sin; - var localYCos = localY * cos + this.y; - var localYSin = localY * sin; - var localX2Cos = localX2 * cos + this.x; - var localX2Sin = localX2 * sin; - var localY2Cos = localY2 * cos + this.y; - var localY2Sin = localY2 * sin; - var offset = this.offset; - offset[RegionAttachment.OX1] = localXCos - localYSin; - offset[RegionAttachment.OY1] = localYCos + localXSin; - offset[RegionAttachment.OX2] = localXCos - localY2Sin; - offset[RegionAttachment.OY2] = localY2Cos + localXSin; - offset[RegionAttachment.OX3] = localX2Cos - localY2Sin; - offset[RegionAttachment.OY3] = localY2Cos + localX2Sin; - offset[RegionAttachment.OX4] = localX2Cos - localYSin; - offset[RegionAttachment.OY4] = localYCos + localX2Sin; - }; - RegionAttachment.prototype.setRegion = function (region) { - this.region = region; - var uvs = this.uvs; - if (region.rotate) { - uvs[2] = region.u; - uvs[3] = region.v2; - uvs[4] = region.u; - uvs[5] = region.v; - uvs[6] = region.u2; - uvs[7] = region.v; - uvs[0] = region.u2; - uvs[1] = region.v2; - } - else { - uvs[0] = region.u; - uvs[1] = region.v2; - uvs[2] = region.u; - uvs[3] = region.v; - uvs[4] = region.u2; - uvs[5] = region.v; - uvs[6] = region.u2; - uvs[7] = region.v2; - } - }; - RegionAttachment.prototype.computeWorldVertices = function (bone, worldVertices, offset, stride) { - var vertexOffset = this.offset; - var mat = bone instanceof Slot$2 ? bone.bone.matrix : bone.matrix; - var x = mat.tx, y = mat.ty; - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var offsetX = 0, offsetY = 0; - offsetX = vertexOffset[RegionAttachment.OX1]; - offsetY = vertexOffset[RegionAttachment.OY1]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // br - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - offset += stride; - offsetX = vertexOffset[RegionAttachment.OX2]; - offsetY = vertexOffset[RegionAttachment.OY2]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // bl - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - offset += stride; - offsetX = vertexOffset[RegionAttachment.OX3]; - offsetY = vertexOffset[RegionAttachment.OY3]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // ul - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - offset += stride; - offsetX = vertexOffset[RegionAttachment.OX4]; - offsetY = vertexOffset[RegionAttachment.OY4]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // ur - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - }; - RegionAttachment.prototype.copy = function () { - var copy = new RegionAttachment(this.name); - copy.region = this.region; - copy.rendererObject = this.rendererObject; - copy.path = this.path; - copy.x = this.x; - copy.y = this.y; - copy.scaleX = this.scaleX; - copy.scaleY = this.scaleY; - copy.rotation = this.rotation; - copy.width = this.width; - copy.height = this.height; - Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, 8); - Utils.arrayCopy(this.offset, 0, copy.offset, 0, 8); - copy.color.setFromColor(this.color); - return copy; - }; - RegionAttachment.OX1 = 0; - RegionAttachment.OY1 = 1; - RegionAttachment.OX2 = 2; - RegionAttachment.OY2 = 3; - RegionAttachment.OX3 = 4; - RegionAttachment.OY3 = 5; - RegionAttachment.OX4 = 6; - RegionAttachment.OY4 = 7; - RegionAttachment.X1 = 0; - RegionAttachment.Y1 = 1; - RegionAttachment.C1R = 2; - RegionAttachment.C1G = 3; - RegionAttachment.C1B = 4; - RegionAttachment.C1A = 5; - RegionAttachment.U1 = 6; - RegionAttachment.V1 = 7; - RegionAttachment.X2 = 8; - RegionAttachment.Y2 = 9; - RegionAttachment.C2R = 10; - RegionAttachment.C2G = 11; - RegionAttachment.C2B = 12; - RegionAttachment.C2A = 13; - RegionAttachment.U2 = 14; - RegionAttachment.V2 = 15; - RegionAttachment.X3 = 16; - RegionAttachment.Y3 = 17; - RegionAttachment.C3R = 18; - RegionAttachment.C3G = 19; - RegionAttachment.C3B = 20; - RegionAttachment.C3A = 21; - RegionAttachment.U3 = 22; - RegionAttachment.V3 = 23; - RegionAttachment.X4 = 24; - RegionAttachment.Y4 = 25; - RegionAttachment.C4R = 26; - RegionAttachment.C4G = 27; - RegionAttachment.C4B = 28; - RegionAttachment.C4A = 29; - RegionAttachment.U4 = 30; - RegionAttachment.V4 = 31; - return RegionAttachment; - }(Attachment$2)); - - /** - * @public - */ - var JitterEffect$1 = /** @class */ (function () { - function JitterEffect(jitterX, jitterY) { - this.jitterX = 0; - this.jitterY = 0; - this.jitterX = jitterX; - this.jitterY = jitterY; - } - JitterEffect.prototype.begin = function (skeleton) { - }; - JitterEffect.prototype.transform = function (position, uv, light, dark) { - position.x += MathUtils.randomTriangular(-this.jitterX, this.jitterY); - position.y += MathUtils.randomTriangular(-this.jitterX, this.jitterY); - }; - JitterEffect.prototype.end = function () { - }; - return JitterEffect; - }()); - - /** - * @public - */ - var SwirlEffect$1 = /** @class */ (function () { - function SwirlEffect(radius) { - this.centerX = 0; - this.centerY = 0; - this.radius = 0; - this.angle = 0; - this.worldX = 0; - this.worldY = 0; - this.radius = radius; - } - SwirlEffect.prototype.begin = function (skeleton) { - this.worldX = skeleton.x + this.centerX; - this.worldY = skeleton.y + this.centerY; - }; - SwirlEffect.prototype.transform = function (position, uv, light, dark) { - var radAngle = this.angle * MathUtils.degreesToRadians; - var x = position.x - this.worldX; - var y = position.y - this.worldY; - var dist = Math.sqrt(x * x + y * y); - if (dist < this.radius) { - var theta = SwirlEffect.interpolation.apply(0, radAngle, (this.radius - dist) / this.radius); - var cos = Math.cos(theta); - var sin = Math.sin(theta); - position.x = cos * x - sin * y + this.worldX; - position.y = sin * x + cos * y + this.worldY; - } - }; - SwirlEffect.prototype.end = function () { - }; - SwirlEffect.interpolation = new PowOut(2); - return SwirlEffect; - }()); - - /** A simple container for a list of timelines and a name. */ - /** - * @public - */ - var Animation$2 = /** @class */ (function () { - function Animation(name, timelines, duration) { - if (name == null) - throw new Error("name cannot be null."); - if (timelines == null) - throw new Error("timelines cannot be null."); - this.name = name; - this.timelines = timelines; - this.timelineIds = []; - for (var i = 0; i < timelines.length; i++) - this.timelineIds[timelines[i].getPropertyId()] = true; - this.duration = duration; - } - Animation.prototype.hasTimeline = function (id) { - return this.timelineIds[id] == true; - }; - /** Applies all the animation's timelines to the specified skeleton. - * - * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. - * @param loop If true, the animation repeats after {@link #getDuration()}. - * @param events May be null to ignore fired events. */ - Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, blend, direction) { - if (skeleton == null) - throw new Error("skeleton cannot be null."); - if (loop && this.duration != 0) { - time %= this.duration; - if (lastTime > 0) - lastTime %= this.duration; - } - var timelines = this.timelines; - for (var i = 0, n = timelines.length; i < n; i++) - timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction); - }; - /** @param target After the first and before the last value. - * @returns index of first value greater than the target. */ - Animation.binarySearch = function (values, target, step) { - if (step === void 0) { step = 1; } - var low = 0; - var high = values.length / step - 2; - if (high == 0) - return step; - var current = high >>> 1; - while (true) { - if (values[(current + 1) * step] <= target) - low = current + 1; - else - high = current; - if (low == high) - return (low + 1) * step; - current = (low + high) >>> 1; - } - }; - Animation.linearSearch = function (values, target, step) { - for (var i = 0, last = values.length - step; i <= last; i += step) - if (values[i] > target) - return i; - return -1; - }; - return Animation; - }()); - /** - * @public - */ - var TimelineType$1; - (function (TimelineType) { - TimelineType[TimelineType["rotate"] = 0] = "rotate"; - TimelineType[TimelineType["translate"] = 1] = "translate"; - TimelineType[TimelineType["scale"] = 2] = "scale"; - TimelineType[TimelineType["shear"] = 3] = "shear"; - TimelineType[TimelineType["attachment"] = 4] = "attachment"; - TimelineType[TimelineType["color"] = 5] = "color"; - TimelineType[TimelineType["deform"] = 6] = "deform"; - TimelineType[TimelineType["event"] = 7] = "event"; - TimelineType[TimelineType["drawOrder"] = 8] = "drawOrder"; - TimelineType[TimelineType["ikConstraint"] = 9] = "ikConstraint"; - TimelineType[TimelineType["transformConstraint"] = 10] = "transformConstraint"; - TimelineType[TimelineType["pathConstraintPosition"] = 11] = "pathConstraintPosition"; - TimelineType[TimelineType["pathConstraintSpacing"] = 12] = "pathConstraintSpacing"; - TimelineType[TimelineType["pathConstraintMix"] = 13] = "pathConstraintMix"; - TimelineType[TimelineType["twoColor"] = 14] = "twoColor"; - })(TimelineType$1 || (TimelineType$1 = {})); - /** The base class for timelines that use interpolation between key frame values. */ - /** - * @public - */ - var CurveTimeline$2 = /** @class */ (function () { - function CurveTimeline(frameCount) { - if (frameCount <= 0) - throw new Error("frameCount must be > 0: " + frameCount); - this.curves = Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE); - } - /** The number of key frames for this timeline. */ - CurveTimeline.prototype.getFrameCount = function () { - return this.curves.length / CurveTimeline.BEZIER_SIZE + 1; - }; - /** Sets the specified key frame to linear interpolation. */ - CurveTimeline.prototype.setLinear = function (frameIndex) { - this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.LINEAR; - }; - /** Sets the specified key frame to stepped interpolation. */ - CurveTimeline.prototype.setStepped = function (frameIndex) { - this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.STEPPED; - }; - /** Returns the interpolation type for the specified key frame. - * @returns Linear is 0, stepped is 1, Bezier is 2. */ - CurveTimeline.prototype.getCurveType = function (frameIndex) { - var index = frameIndex * CurveTimeline.BEZIER_SIZE; - if (index == this.curves.length) - return CurveTimeline.LINEAR; - var type = this.curves[index]; - if (type == CurveTimeline.LINEAR) - return CurveTimeline.LINEAR; - if (type == CurveTimeline.STEPPED) - return CurveTimeline.STEPPED; - return CurveTimeline.BEZIER; - }; - /** Sets the specified key frame to Bezier interpolation. `cx1` and `cx2` are from 0 to 1, - * representing the percent of time between the two key frames. `cy1` and `cy2` are the percent of the - * difference between the key frame's values. */ - CurveTimeline.prototype.setCurve = function (frameIndex, cx1, cy1, cx2, cy2) { - var tmpx = (-cx1 * 2 + cx2) * 0.03, tmpy = (-cy1 * 2 + cy2) * 0.03; - var dddfx = ((cx1 - cx2) * 3 + 1) * 0.006, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006; - var ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy; - var dfx = cx1 * 0.3 + tmpx + dddfx * 0.16666667, dfy = cy1 * 0.3 + tmpy + dddfy * 0.16666667; - var i = frameIndex * CurveTimeline.BEZIER_SIZE; - var curves = this.curves; - curves[i++] = CurveTimeline.BEZIER; - var x = dfx, y = dfy; - for (var n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { - curves[i] = x; - curves[i + 1] = y; - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - x += dfx; - y += dfy; - } - }; - /** Returns the interpolated percentage for the specified key frame and linear percentage. */ - CurveTimeline.prototype.getCurvePercent = function (frameIndex, percent) { - percent = MathUtils.clamp(percent, 0, 1); - var curves = this.curves; - var i = frameIndex * CurveTimeline.BEZIER_SIZE; - var type = curves[i]; - if (type == CurveTimeline.LINEAR) - return percent; - if (type == CurveTimeline.STEPPED) - return 0; - i++; - var x = 0; - for (var start = i, n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { - x = curves[i]; - if (x >= percent) { - var prevX = void 0, prevY = void 0; - if (i == start) { - prevX = 0; - prevY = 0; - } - else { - prevX = curves[i - 2]; - prevY = curves[i - 1]; - } - return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX); - } - } - var y = curves[i - 1]; - return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1. - }; - CurveTimeline.LINEAR = 0; - CurveTimeline.STEPPED = 1; - CurveTimeline.BEZIER = 2; - CurveTimeline.BEZIER_SIZE = 10 * 2 - 1; - return CurveTimeline; - }()); - /** Changes a bone's local {@link Bone#rotation}. */ - /** - * @public - */ - var RotateTimeline$2 = /** @class */ (function (_super) { - __extends$3(RotateTimeline, _super); - function RotateTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount << 1); - return _this; - } - RotateTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.rotate << 24) + this.boneIndex; - }; - /** Sets the time and angle of the specified keyframe. */ - RotateTimeline.prototype.setFrame = function (frameIndex, time, degrees) { - frameIndex <<= 1; - this.frames[frameIndex] = time; - this.frames[frameIndex + RotateTimeline.ROTATION] = degrees; - }; - RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var frames = this.frames; - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.rotation = bone.data.rotation; - return; - case exports.MixBlend.first: - var r_1 = bone.data.rotation - bone.rotation; - bone.rotation += (r_1 - (16384 - ((16384.499999999996 - r_1 / 360) | 0)) * 360) * alpha; - } - return; - } - if (time >= frames[frames.length - RotateTimeline.ENTRIES]) { // Time is after last frame. - var r_2 = frames[frames.length + RotateTimeline.PREV_ROTATION]; - switch (blend) { - case exports.MixBlend.setup: - bone.rotation = bone.data.rotation + r_2 * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - r_2 += bone.data.rotation - bone.rotation; - r_2 -= (16384 - ((16384.499999999996 - r_2 / 360) | 0)) * 360; // Wrap within -180 and 180. - case exports.MixBlend.add: - bone.rotation += r_2 * alpha; - } - return; - } - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, RotateTimeline.ENTRIES); - var prevRotation = frames[frame + RotateTimeline.PREV_ROTATION]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime)); - var r = frames[frame + RotateTimeline.ROTATION] - prevRotation; - r = prevRotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * percent; - switch (blend) { - case exports.MixBlend.setup: - bone.rotation = bone.data.rotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - r += bone.data.rotation - bone.rotation; - case exports.MixBlend.add: - bone.rotation += (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; - } - }; - RotateTimeline.ENTRIES = 2; - RotateTimeline.PREV_TIME = -2; - RotateTimeline.PREV_ROTATION = -1; - RotateTimeline.ROTATION = 1; - return RotateTimeline; - }(CurveTimeline$2)); - /** Changes a bone's local {@link Bone#x} and {@link Bone#y}. */ - /** - * @public - */ - var TranslateTimeline$2 = /** @class */ (function (_super) { - __extends$3(TranslateTimeline, _super); - function TranslateTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES); - return _this; - } - TranslateTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.translate << 24) + this.boneIndex; - }; - /** Sets the time in seconds, x, and y values for the specified key frame. */ - TranslateTimeline.prototype.setFrame = function (frameIndex, time, x, y) { - frameIndex *= TranslateTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + TranslateTimeline.X] = x; - this.frames[frameIndex + TranslateTimeline.Y] = y; - }; - TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var frames = this.frames; - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.x = bone.data.x; - bone.y = bone.data.y; - return; - case exports.MixBlend.first: - bone.x += (bone.data.x - bone.x) * alpha; - bone.y += (bone.data.y - bone.y) * alpha; - } - return; - } - var x = 0, y = 0; - if (time >= frames[frames.length - TranslateTimeline.ENTRIES]) { // Time is after last frame. - x = frames[frames.length + TranslateTimeline.PREV_X]; - y = frames[frames.length + TranslateTimeline.PREV_Y]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, TranslateTimeline.ENTRIES); - x = frames[frame + TranslateTimeline.PREV_X]; - y = frames[frame + TranslateTimeline.PREV_Y]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / TranslateTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TranslateTimeline.PREV_TIME] - frameTime)); - x += (frames[frame + TranslateTimeline.X] - x) * percent; - y += (frames[frame + TranslateTimeline.Y] - y) * percent; - } - switch (blend) { - case exports.MixBlend.setup: - bone.x = bone.data.x + x * alpha; - bone.y = bone.data.y + y * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bone.x += (bone.data.x + x - bone.x) * alpha; - bone.y += (bone.data.y + y - bone.y) * alpha; - break; - case exports.MixBlend.add: - bone.x += x * alpha; - bone.y += y * alpha; - } - }; - TranslateTimeline.ENTRIES = 3; - TranslateTimeline.PREV_TIME = -3; - TranslateTimeline.PREV_X = -2; - TranslateTimeline.PREV_Y = -1; - TranslateTimeline.X = 1; - TranslateTimeline.Y = 2; - return TranslateTimeline; - }(CurveTimeline$2)); - /** Changes a bone's local {@link Bone#scaleX)} and {@link Bone#scaleY}. */ - /** - * @public - */ - var ScaleTimeline$2 = /** @class */ (function (_super) { - __extends$3(ScaleTimeline, _super); - function ScaleTimeline(frameCount) { - return _super.call(this, frameCount) || this; - } - ScaleTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.scale << 24) + this.boneIndex; - }; - ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var frames = this.frames; - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.scaleX = bone.data.scaleX; - bone.scaleY = bone.data.scaleY; - return; - case exports.MixBlend.first: - bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; - bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; - } - return; - } - var x = 0, y = 0; - if (time >= frames[frames.length - ScaleTimeline.ENTRIES]) { // Time is after last frame. - x = frames[frames.length + ScaleTimeline.PREV_X] * bone.data.scaleX; - y = frames[frames.length + ScaleTimeline.PREV_Y] * bone.data.scaleY; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, ScaleTimeline.ENTRIES); - x = frames[frame + ScaleTimeline.PREV_X]; - y = frames[frame + ScaleTimeline.PREV_Y]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / ScaleTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ScaleTimeline.PREV_TIME] - frameTime)); - x = (x + (frames[frame + ScaleTimeline.X] - x) * percent) * bone.data.scaleX; - y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY; - } - if (alpha == 1) { - if (blend == exports.MixBlend.add) { - bone.scaleX += x - bone.data.scaleX; - bone.scaleY += y - bone.data.scaleY; - } - else { - bone.scaleX = x; - bone.scaleY = y; - } - } - else { - var bx = 0, by = 0; - if (direction == exports.MixDirection.mixOut) { - switch (blend) { - case exports.MixBlend.setup: - bx = bone.data.scaleX; - by = bone.data.scaleY; - bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; - bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bx = bone.scaleX; - by = bone.scaleY; - bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; - bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; - break; - case exports.MixBlend.add: - bx = bone.scaleX; - by = bone.scaleY; - bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bone.data.scaleX) * alpha; - bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - bone.data.scaleY) * alpha; - } - } - else { - switch (blend) { - case exports.MixBlend.setup: - bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x); - by = Math.abs(bone.data.scaleY) * MathUtils.signum(y); - bone.scaleX = bx + (x - bx) * alpha; - bone.scaleY = by + (y - by) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bx = Math.abs(bone.scaleX) * MathUtils.signum(x); - by = Math.abs(bone.scaleY) * MathUtils.signum(y); - bone.scaleX = bx + (x - bx) * alpha; - bone.scaleY = by + (y - by) * alpha; - break; - case exports.MixBlend.add: - bx = MathUtils.signum(x); - by = MathUtils.signum(y); - bone.scaleX = Math.abs(bone.scaleX) * bx + (x - Math.abs(bone.data.scaleX) * bx) * alpha; - bone.scaleY = Math.abs(bone.scaleY) * by + (y - Math.abs(bone.data.scaleY) * by) * alpha; - } - } - } - }; - return ScaleTimeline; - }(TranslateTimeline$2)); - /** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. */ - /** - * @public - */ - var ShearTimeline$2 = /** @class */ (function (_super) { - __extends$3(ShearTimeline, _super); - function ShearTimeline(frameCount) { - return _super.call(this, frameCount) || this; - } - ShearTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.shear << 24) + this.boneIndex; - }; - ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var frames = this.frames; - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.shearX = bone.data.shearX; - bone.shearY = bone.data.shearY; - return; - case exports.MixBlend.first: - bone.shearX += (bone.data.shearX - bone.shearX) * alpha; - bone.shearY += (bone.data.shearY - bone.shearY) * alpha; - } - return; - } - var x = 0, y = 0; - if (time >= frames[frames.length - ShearTimeline.ENTRIES]) { // Time is after last frame. - x = frames[frames.length + ShearTimeline.PREV_X]; - y = frames[frames.length + ShearTimeline.PREV_Y]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, ShearTimeline.ENTRIES); - x = frames[frame + ShearTimeline.PREV_X]; - y = frames[frame + ShearTimeline.PREV_Y]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / ShearTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ShearTimeline.PREV_TIME] - frameTime)); - x = x + (frames[frame + ShearTimeline.X] - x) * percent; - y = y + (frames[frame + ShearTimeline.Y] - y) * percent; - } - switch (blend) { - case exports.MixBlend.setup: - bone.shearX = bone.data.shearX + x * alpha; - bone.shearY = bone.data.shearY + y * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; - bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; - break; - case exports.MixBlend.add: - bone.shearX += x * alpha; - bone.shearY += y * alpha; - } - }; - return ShearTimeline; - }(TranslateTimeline$2)); - /** Changes a slot's {@link Slot#color}. */ - /** - * @public - */ - var ColorTimeline$1 = /** @class */ (function (_super) { - __extends$3(ColorTimeline, _super); - function ColorTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES); - return _this; - } - ColorTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.color << 24) + this.slotIndex; - }; - /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ - ColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a) { - frameIndex *= ColorTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + ColorTimeline.R] = r; - this.frames[frameIndex + ColorTimeline.G] = g; - this.frames[frameIndex + ColorTimeline.B] = b; - this.frames[frameIndex + ColorTimeline.A] = a; - }; - ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - slot.color.setFromColor(slot.data.color); - return; - case exports.MixBlend.first: - var color = slot.color, setup = slot.data.color; - color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha); - } - return; - } - var r = 0, g = 0, b = 0, a = 0; - if (time >= frames[frames.length - ColorTimeline.ENTRIES]) { // Time is after last frame. - var i = frames.length; - r = frames[i + ColorTimeline.PREV_R]; - g = frames[i + ColorTimeline.PREV_G]; - b = frames[i + ColorTimeline.PREV_B]; - a = frames[i + ColorTimeline.PREV_A]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, ColorTimeline.ENTRIES); - r = frames[frame + ColorTimeline.PREV_R]; - g = frames[frame + ColorTimeline.PREV_G]; - b = frames[frame + ColorTimeline.PREV_B]; - a = frames[frame + ColorTimeline.PREV_A]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / ColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ColorTimeline.PREV_TIME] - frameTime)); - r += (frames[frame + ColorTimeline.R] - r) * percent; - g += (frames[frame + ColorTimeline.G] - g) * percent; - b += (frames[frame + ColorTimeline.B] - b) * percent; - a += (frames[frame + ColorTimeline.A] - a) * percent; - } - if (alpha == 1) - slot.color.set(r, g, b, a); - else { - var color = slot.color; - if (blend == exports.MixBlend.setup) - color.setFromColor(slot.data.color); - color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha); - } - }; - ColorTimeline.ENTRIES = 5; - ColorTimeline.PREV_TIME = -5; - ColorTimeline.PREV_R = -4; - ColorTimeline.PREV_G = -3; - ColorTimeline.PREV_B = -2; - ColorTimeline.PREV_A = -1; - ColorTimeline.R = 1; - ColorTimeline.G = 2; - ColorTimeline.B = 3; - ColorTimeline.A = 4; - return ColorTimeline; - }(CurveTimeline$2)); - /** Changes a slot's {@link Slot#color} and {@link Slot#darkColor} for two color tinting. */ - /** - * @public - */ - var TwoColorTimeline$1 = /** @class */ (function (_super) { - __extends$3(TwoColorTimeline, _super); - function TwoColorTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES); - return _this; - } - TwoColorTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.twoColor << 24) + this.slotIndex; - }; - /** Sets the time in seconds, light, and dark colors for the specified key frame. */ - TwoColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a, r2, g2, b2) { - frameIndex *= TwoColorTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + TwoColorTimeline.R] = r; - this.frames[frameIndex + TwoColorTimeline.G] = g; - this.frames[frameIndex + TwoColorTimeline.B] = b; - this.frames[frameIndex + TwoColorTimeline.A] = a; - this.frames[frameIndex + TwoColorTimeline.R2] = r2; - this.frames[frameIndex + TwoColorTimeline.G2] = g2; - this.frames[frameIndex + TwoColorTimeline.B2] = b2; - }; - TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - slot.color.setFromColor(slot.data.color); - slot.darkColor.setFromColor(slot.data.darkColor); - return; - case exports.MixBlend.first: - var light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor; - light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha); - dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0); - } - return; - } - var r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; - if (time >= frames[frames.length - TwoColorTimeline.ENTRIES]) { // Time is after last frame. - var i = frames.length; - r = frames[i + TwoColorTimeline.PREV_R]; - g = frames[i + TwoColorTimeline.PREV_G]; - b = frames[i + TwoColorTimeline.PREV_B]; - a = frames[i + TwoColorTimeline.PREV_A]; - r2 = frames[i + TwoColorTimeline.PREV_R2]; - g2 = frames[i + TwoColorTimeline.PREV_G2]; - b2 = frames[i + TwoColorTimeline.PREV_B2]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, TwoColorTimeline.ENTRIES); - r = frames[frame + TwoColorTimeline.PREV_R]; - g = frames[frame + TwoColorTimeline.PREV_G]; - b = frames[frame + TwoColorTimeline.PREV_B]; - a = frames[frame + TwoColorTimeline.PREV_A]; - r2 = frames[frame + TwoColorTimeline.PREV_R2]; - g2 = frames[frame + TwoColorTimeline.PREV_G2]; - b2 = frames[frame + TwoColorTimeline.PREV_B2]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / TwoColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TwoColorTimeline.PREV_TIME] - frameTime)); - r += (frames[frame + TwoColorTimeline.R] - r) * percent; - g += (frames[frame + TwoColorTimeline.G] - g) * percent; - b += (frames[frame + TwoColorTimeline.B] - b) * percent; - a += (frames[frame + TwoColorTimeline.A] - a) * percent; - r2 += (frames[frame + TwoColorTimeline.R2] - r2) * percent; - g2 += (frames[frame + TwoColorTimeline.G2] - g2) * percent; - b2 += (frames[frame + TwoColorTimeline.B2] - b2) * percent; - } - if (alpha == 1) { - slot.color.set(r, g, b, a); - slot.darkColor.set(r2, g2, b2, 1); - } - else { - var light = slot.color, dark = slot.darkColor; - if (blend == exports.MixBlend.setup) { - light.setFromColor(slot.data.color); - dark.setFromColor(slot.data.darkColor); - } - light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha); - dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0); - } - }; - TwoColorTimeline.ENTRIES = 8; - TwoColorTimeline.PREV_TIME = -8; - TwoColorTimeline.PREV_R = -7; - TwoColorTimeline.PREV_G = -6; - TwoColorTimeline.PREV_B = -5; - TwoColorTimeline.PREV_A = -4; - TwoColorTimeline.PREV_R2 = -3; - TwoColorTimeline.PREV_G2 = -2; - TwoColorTimeline.PREV_B2 = -1; - TwoColorTimeline.R = 1; - TwoColorTimeline.G = 2; - TwoColorTimeline.B = 3; - TwoColorTimeline.A = 4; - TwoColorTimeline.R2 = 5; - TwoColorTimeline.G2 = 6; - TwoColorTimeline.B2 = 7; - return TwoColorTimeline; - }(CurveTimeline$2)); - /** Changes a slot's {@link Slot#attachment}. */ - /** - * @public - */ - var AttachmentTimeline$2 = /** @class */ (function () { - function AttachmentTimeline(frameCount) { - this.frames = Utils.newFloatArray(frameCount); - this.attachmentNames = new Array(frameCount); - } - AttachmentTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.attachment << 24) + this.slotIndex; - }; - /** The number of key frames for this timeline. */ - AttachmentTimeline.prototype.getFrameCount = function () { - return this.frames.length; - }; - /** Sets the time in seconds and the attachment name for the specified key frame. */ - AttachmentTimeline.prototype.setFrame = function (frameIndex, time, attachmentName) { - this.frames[frameIndex] = time; - this.attachmentNames[frameIndex] = attachmentName; - }; - AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - if (direction == exports.MixDirection.mixOut) { - if (blend == exports.MixBlend.setup) - this.setAttachment(skeleton, slot, slot.data.attachmentName); - return; - } - var frames = this.frames; - if (time < frames[0]) { - if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) - this.setAttachment(skeleton, slot, slot.data.attachmentName); - return; - } - var frameIndex = 0; - if (time >= frames[frames.length - 1]) // Time is after last frame. - frameIndex = frames.length - 1; - else - frameIndex = Animation$2.binarySearch(frames, time, 1) - 1; - var attachmentName = this.attachmentNames[frameIndex]; - skeleton.slots[this.slotIndex] - .setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); - }; - AttachmentTimeline.prototype.setAttachment = function (skeleton, slot, attachmentName) { - slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); - }; - return AttachmentTimeline; - }()); - var zeros$1 = null; - /** Changes a slot's {@link Slot#deform} to deform a {@link VertexAttachment}. */ - /** - * @public - */ - var DeformTimeline$2 = /** @class */ (function (_super) { - __extends$3(DeformTimeline, _super); - function DeformTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount); - _this.frameVertices = new Array(frameCount); - if (zeros$1 == null) - zeros$1 = Utils.newFloatArray(64); - return _this; - } - DeformTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.deform << 27) + +this.attachment.id + this.slotIndex; - }; - /** Sets the time in seconds and the vertices for the specified key frame. - * @param vertices Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */ - DeformTimeline.prototype.setFrame = function (frameIndex, time, vertices) { - this.frames[frameIndex] = time; - this.frameVertices[frameIndex] = vertices; - }; - DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - var slotAttachment = slot.getAttachment(); - if (!(slotAttachment instanceof VertexAttachment$2) || !(slotAttachment.deformAttachment == this.attachment)) - return; - var deformArray = slot.deform; - if (deformArray.length == 0) - blend = exports.MixBlend.setup; - var frameVertices = this.frameVertices; - var vertexCount = frameVertices[0].length; - var frames = this.frames; - if (time < frames[0]) { - var vertexAttachment = slotAttachment; - switch (blend) { - case exports.MixBlend.setup: - deformArray.length = 0; - return; - case exports.MixBlend.first: - if (alpha == 1) { - deformArray.length = 0; - break; - } - var deform_1 = Utils.setArraySize(deformArray, vertexCount); - if (vertexAttachment.bones == null) { - // Unweighted vertex positions. - var setupVertices = vertexAttachment.vertices; - for (var i = 0; i < vertexCount; i++) - deform_1[i] += (setupVertices[i] - deform_1[i]) * alpha; - } - else { - // Weighted deform offsets. - alpha = 1 - alpha; - for (var i = 0; i < vertexCount; i++) - deform_1[i] *= alpha; - } - } - return; - } - var deform = Utils.setArraySize(deformArray, vertexCount); - if (time >= frames[frames.length - 1]) { // Time is after last frame. - var lastVertices = frameVertices[frames.length - 1]; - if (alpha == 1) { - if (blend == exports.MixBlend.add) { - var vertexAttachment = slotAttachment; - if (vertexAttachment.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i_1 = 0; i_1 < vertexCount; i_1++) { - deform[i_1] += lastVertices[i_1] - setupVertices[i_1]; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i_2 = 0; i_2 < vertexCount; i_2++) - deform[i_2] += lastVertices[i_2]; - } - } - else { - Utils.arrayCopy(lastVertices, 0, deform, 0, vertexCount); - } - } - else { - switch (blend) { - case exports.MixBlend.setup: { - var vertexAttachment_1 = slotAttachment; - if (vertexAttachment_1.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment_1.vertices; - for (var i_3 = 0; i_3 < vertexCount; i_3++) { - var setup = setupVertices[i_3]; - deform[i_3] = setup + (lastVertices[i_3] - setup) * alpha; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i_4 = 0; i_4 < vertexCount; i_4++) - deform[i_4] = lastVertices[i_4] * alpha; - } - break; - } - case exports.MixBlend.first: - case exports.MixBlend.replace: - for (var i_5 = 0; i_5 < vertexCount; i_5++) - deform[i_5] += (lastVertices[i_5] - deform[i_5]) * alpha; - break; - case exports.MixBlend.add: - var vertexAttachment = slotAttachment; - if (vertexAttachment.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i_6 = 0; i_6 < vertexCount; i_6++) { - deform[i_6] += (lastVertices[i_6] - setupVertices[i_6]) * alpha; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i_7 = 0; i_7 < vertexCount; i_7++) - deform[i_7] += lastVertices[i_7] * alpha; - } - } - } - return; - } - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time); - var prevVertices = frameVertices[frame - 1]; - var nextVertices = frameVertices[frame]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime)); - if (alpha == 1) { - if (blend == exports.MixBlend.add) { - var vertexAttachment = slotAttachment; - if (vertexAttachment.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i_8 = 0; i_8 < vertexCount; i_8++) { - var prev = prevVertices[i_8]; - deform[i_8] += prev + (nextVertices[i_8] - prev) * percent - setupVertices[i_8]; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i_9 = 0; i_9 < vertexCount; i_9++) { - var prev = prevVertices[i_9]; - deform[i_9] += prev + (nextVertices[i_9] - prev) * percent; - } - } - } - else { - for (var i_10 = 0; i_10 < vertexCount; i_10++) { - var prev = prevVertices[i_10]; - deform[i_10] = prev + (nextVertices[i_10] - prev) * percent; - } - } - } - else { - switch (blend) { - case exports.MixBlend.setup: { - var vertexAttachment_2 = slotAttachment; - if (vertexAttachment_2.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment_2.vertices; - for (var i_11 = 0; i_11 < vertexCount; i_11++) { - var prev = prevVertices[i_11], setup = setupVertices[i_11]; - deform[i_11] = setup + (prev + (nextVertices[i_11] - prev) * percent - setup) * alpha; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i_12 = 0; i_12 < vertexCount; i_12++) { - var prev = prevVertices[i_12]; - deform[i_12] = (prev + (nextVertices[i_12] - prev) * percent) * alpha; - } - } - break; - } - case exports.MixBlend.first: - case exports.MixBlend.replace: - for (var i_13 = 0; i_13 < vertexCount; i_13++) { - var prev = prevVertices[i_13]; - deform[i_13] += (prev + (nextVertices[i_13] - prev) * percent - deform[i_13]) * alpha; - } - break; - case exports.MixBlend.add: - var vertexAttachment = slotAttachment; - if (vertexAttachment.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i_14 = 0; i_14 < vertexCount; i_14++) { - var prev = prevVertices[i_14]; - deform[i_14] += (prev + (nextVertices[i_14] - prev) * percent - setupVertices[i_14]) * alpha; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i_15 = 0; i_15 < vertexCount; i_15++) { - var prev = prevVertices[i_15]; - deform[i_15] += (prev + (nextVertices[i_15] - prev) * percent) * alpha; - } - } - } - } - }; - return DeformTimeline; - }(CurveTimeline$2)); - /** Fires an {@link Event} when specific animation times are reached. */ - /** - * @public - */ - var EventTimeline$2 = /** @class */ (function () { - function EventTimeline(frameCount) { - this.frames = Utils.newFloatArray(frameCount); - this.events = new Array(frameCount); - } - EventTimeline.prototype.getPropertyId = function () { - return TimelineType$1.event << 24; - }; - /** The number of key frames for this timeline. */ - EventTimeline.prototype.getFrameCount = function () { - return this.frames.length; - }; - /** Sets the time in seconds and the event for the specified key frame. */ - EventTimeline.prototype.setFrame = function (frameIndex, event) { - this.frames[frameIndex] = event.time; - this.events[frameIndex] = event; - }; - /** Fires events for frames > `lastTime` and <= `time`. */ - EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - if (firedEvents == null) - return; - var frames = this.frames; - var frameCount = this.frames.length; - if (lastTime > time) { // Fire events after last time for looped animations. - this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction); - lastTime = -1; - } - else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame. - return; - if (time < frames[0]) - return; // Time is before first frame. - var frame = 0; - if (lastTime < frames[0]) - frame = 0; - else { - frame = Animation$2.binarySearch(frames, lastTime); - var frameTime = frames[frame]; - while (frame > 0) { // Fire multiple events with the same frame. - if (frames[frame - 1] != frameTime) - break; - frame--; - } - } - for (; frame < frameCount && time >= frames[frame]; frame++) - firedEvents.push(this.events[frame]); - }; - return EventTimeline; - }()); - /** Changes a skeleton's {@link Skeleton#drawOrder}. */ - /** - * @public - */ - var DrawOrderTimeline$2 = /** @class */ (function () { - function DrawOrderTimeline(frameCount) { - this.frames = Utils.newFloatArray(frameCount); - this.drawOrders = new Array(frameCount); - } - DrawOrderTimeline.prototype.getPropertyId = function () { - return TimelineType$1.drawOrder << 24; - }; - /** The number of key frames for this timeline. */ - DrawOrderTimeline.prototype.getFrameCount = function () { - return this.frames.length; - }; - /** Sets the time in seconds and the draw order for the specified key frame. - * @param drawOrder For each slot in {@link Skeleton#slots}, the index of the new draw order. May be null to use setup pose - * draw order. */ - DrawOrderTimeline.prototype.setFrame = function (frameIndex, time, drawOrder) { - this.frames[frameIndex] = time; - this.drawOrders[frameIndex] = drawOrder; - }; - DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var drawOrder = skeleton.drawOrder; - var slots = skeleton.slots; - if (direction == exports.MixDirection.mixOut && blend == exports.MixBlend.setup) { - Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); - return; - } - var frames = this.frames; - if (time < frames[0]) { - if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) - Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); - return; - } - var frame = 0; - if (time >= frames[frames.length - 1]) // Time is after last frame. - frame = frames.length - 1; - else - frame = Animation$2.binarySearch(frames, time) - 1; - var drawOrderToSetupIndex = this.drawOrders[frame]; - if (drawOrderToSetupIndex == null) - Utils.arrayCopy(slots, 0, drawOrder, 0, slots.length); - else { - for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++) - drawOrder[i] = slots[drawOrderToSetupIndex[i]]; - } - }; - return DrawOrderTimeline; - }()); - /** Changes an IK constraint's {@link IkConstraint#mix}, {@link IkConstraint#softness}, - * {@link IkConstraint#bendDirection}, {@link IkConstraint#stretch}, and {@link IkConstraint#compress}. */ - /** - * @public - */ - var IkConstraintTimeline$2 = /** @class */ (function (_super) { - __extends$3(IkConstraintTimeline, _super); - function IkConstraintTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES); - return _this; - } - IkConstraintTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.ikConstraint << 24) + this.ikConstraintIndex; - }; - /** Sets the time in seconds, mix, softness, bend direction, compress, and stretch for the specified key frame. */ - IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, softness, bendDirection, compress, stretch) { - frameIndex *= IkConstraintTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; - this.frames[frameIndex + IkConstraintTimeline.SOFTNESS] = softness; - this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; - this.frames[frameIndex + IkConstraintTimeline.COMPRESS] = compress ? 1 : 0; - this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0; - }; - IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var frames = this.frames; - var constraint = skeleton.ikConstraints[this.ikConstraintIndex]; - if (!constraint.active) - return; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.mix = constraint.data.mix; - constraint.softness = constraint.data.softness; - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - return; - case exports.MixBlend.first: - constraint.mix += (constraint.data.mix - constraint.mix) * alpha; - constraint.softness += (constraint.data.softness - constraint.softness) * alpha; - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - } - return; - } - if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { // Time is after last frame. - if (blend == exports.MixBlend.setup) { - constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; - constraint.softness = constraint.data.softness - + (frames[frames.length + IkConstraintTimeline.PREV_SOFTNESS] - constraint.data.softness) * alpha; - if (direction == exports.MixDirection.mixOut) { - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - } - else { - constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; - constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; - constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; - } - } - else { - constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; - constraint.softness += (frames[frames.length + IkConstraintTimeline.PREV_SOFTNESS] - constraint.softness) * alpha; - if (direction == exports.MixDirection.mixIn) { - constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; - constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; - constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; - } - } - return; - } - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, IkConstraintTimeline.ENTRIES); - var mix = frames[frame + IkConstraintTimeline.PREV_MIX]; - var softness = frames[frame + IkConstraintTimeline.PREV_SOFTNESS]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); - if (blend == exports.MixBlend.setup) { - constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; - constraint.softness = constraint.data.softness - + (softness + (frames[frame + IkConstraintTimeline.SOFTNESS] - softness) * percent - constraint.data.softness) * alpha; - if (direction == exports.MixDirection.mixOut) { - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - } - else { - constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; - constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; - constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; - } - } - else { - constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; - constraint.softness += (softness + (frames[frame + IkConstraintTimeline.SOFTNESS] - softness) * percent - constraint.softness) * alpha; - if (direction == exports.MixDirection.mixIn) { - constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; - constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; - constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; - } - } - }; - IkConstraintTimeline.ENTRIES = 6; - IkConstraintTimeline.PREV_TIME = -6; - IkConstraintTimeline.PREV_MIX = -5; - IkConstraintTimeline.PREV_SOFTNESS = -4; - IkConstraintTimeline.PREV_BEND_DIRECTION = -3; - IkConstraintTimeline.PREV_COMPRESS = -2; - IkConstraintTimeline.PREV_STRETCH = -1; - IkConstraintTimeline.MIX = 1; - IkConstraintTimeline.SOFTNESS = 2; - IkConstraintTimeline.BEND_DIRECTION = 3; - IkConstraintTimeline.COMPRESS = 4; - IkConstraintTimeline.STRETCH = 5; - return IkConstraintTimeline; - }(CurveTimeline$2)); - /** Changes a transform constraint's {@link TransformConstraint#rotateMix}, {@link TransformConstraint#translateMix}, - * {@link TransformConstraint#scaleMix}, and {@link TransformConstraint#shearMix}. */ - /** - * @public - */ - var TransformConstraintTimeline$2 = /** @class */ (function (_super) { - __extends$3(TransformConstraintTimeline, _super); - function TransformConstraintTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES); - return _this; - } - TransformConstraintTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.transformConstraint << 24) + this.transformConstraintIndex; - }; - /** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. */ - TransformConstraintTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix, scaleMix, shearMix) { - frameIndex *= TransformConstraintTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + TransformConstraintTimeline.ROTATE] = rotateMix; - this.frames[frameIndex + TransformConstraintTimeline.TRANSLATE] = translateMix; - this.frames[frameIndex + TransformConstraintTimeline.SCALE] = scaleMix; - this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix; - }; - TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var frames = this.frames; - var constraint = skeleton.transformConstraints[this.transformConstraintIndex]; - if (!constraint.active) - return; - if (time < frames[0]) { - var data = constraint.data; - switch (blend) { - case exports.MixBlend.setup: - constraint.rotateMix = data.rotateMix; - constraint.translateMix = data.translateMix; - constraint.scaleMix = data.scaleMix; - constraint.shearMix = data.shearMix; - return; - case exports.MixBlend.first: - constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha; - constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha; - constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha; - constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha; - } - return; - } - var rotate = 0, translate = 0, scale = 0, shear = 0; - if (time >= frames[frames.length - TransformConstraintTimeline.ENTRIES]) { // Time is after last frame. - var i = frames.length; - rotate = frames[i + TransformConstraintTimeline.PREV_ROTATE]; - translate = frames[i + TransformConstraintTimeline.PREV_TRANSLATE]; - scale = frames[i + TransformConstraintTimeline.PREV_SCALE]; - shear = frames[i + TransformConstraintTimeline.PREV_SHEAR]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, TransformConstraintTimeline.ENTRIES); - rotate = frames[frame + TransformConstraintTimeline.PREV_ROTATE]; - translate = frames[frame + TransformConstraintTimeline.PREV_TRANSLATE]; - scale = frames[frame + TransformConstraintTimeline.PREV_SCALE]; - shear = frames[frame + TransformConstraintTimeline.PREV_SHEAR]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / TransformConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TransformConstraintTimeline.PREV_TIME] - frameTime)); - rotate += (frames[frame + TransformConstraintTimeline.ROTATE] - rotate) * percent; - translate += (frames[frame + TransformConstraintTimeline.TRANSLATE] - translate) * percent; - scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent; - shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent; - } - if (blend == exports.MixBlend.setup) { - var data = constraint.data; - constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha; - constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha; - constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha; - constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha; - } - else { - constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; - constraint.translateMix += (translate - constraint.translateMix) * alpha; - constraint.scaleMix += (scale - constraint.scaleMix) * alpha; - constraint.shearMix += (shear - constraint.shearMix) * alpha; - } - }; - TransformConstraintTimeline.ENTRIES = 5; - TransformConstraintTimeline.PREV_TIME = -5; - TransformConstraintTimeline.PREV_ROTATE = -4; - TransformConstraintTimeline.PREV_TRANSLATE = -3; - TransformConstraintTimeline.PREV_SCALE = -2; - TransformConstraintTimeline.PREV_SHEAR = -1; - TransformConstraintTimeline.ROTATE = 1; - TransformConstraintTimeline.TRANSLATE = 2; - TransformConstraintTimeline.SCALE = 3; - TransformConstraintTimeline.SHEAR = 4; - return TransformConstraintTimeline; - }(CurveTimeline$2)); - /** Changes a path constraint's {@link PathConstraint#position}. */ - /** - * @public - */ - var PathConstraintPositionTimeline$2 = /** @class */ (function (_super) { - __extends$3(PathConstraintPositionTimeline, _super); - function PathConstraintPositionTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES); - return _this; - } - PathConstraintPositionTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.pathConstraintPosition << 24) + this.pathConstraintIndex; - }; - /** Sets the time in seconds and path constraint position for the specified key frame. */ - PathConstraintPositionTimeline.prototype.setFrame = function (frameIndex, time, value) { - frameIndex *= PathConstraintPositionTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value; - }; - PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var frames = this.frames; - var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; - if (!constraint.active) - return; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.position = constraint.data.position; - return; - case exports.MixBlend.first: - constraint.position += (constraint.data.position - constraint.position) * alpha; - } - return; - } - var position = 0; - if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES]) // Time is after last frame. - position = frames[frames.length + PathConstraintPositionTimeline.PREV_VALUE]; - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, PathConstraintPositionTimeline.ENTRIES); - position = frames[frame + PathConstraintPositionTimeline.PREV_VALUE]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime)); - position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent; - } - if (blend == exports.MixBlend.setup) - constraint.position = constraint.data.position + (position - constraint.data.position) * alpha; - else - constraint.position += (position - constraint.position) * alpha; - }; - PathConstraintPositionTimeline.ENTRIES = 2; - PathConstraintPositionTimeline.PREV_TIME = -2; - PathConstraintPositionTimeline.PREV_VALUE = -1; - PathConstraintPositionTimeline.VALUE = 1; - return PathConstraintPositionTimeline; - }(CurveTimeline$2)); - /** Changes a path constraint's {@link PathConstraint#spacing}. */ - /** - * @public - */ - var PathConstraintSpacingTimeline$2 = /** @class */ (function (_super) { - __extends$3(PathConstraintSpacingTimeline, _super); - function PathConstraintSpacingTimeline(frameCount) { - return _super.call(this, frameCount) || this; - } - PathConstraintSpacingTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.pathConstraintSpacing << 24) + this.pathConstraintIndex; - }; - PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var frames = this.frames; - var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; - if (!constraint.active) - return; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.spacing = constraint.data.spacing; - return; - case exports.MixBlend.first: - constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha; - } - return; - } - var spacing = 0; - if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES]) // Time is after last frame. - spacing = frames[frames.length + PathConstraintSpacingTimeline.PREV_VALUE]; - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, PathConstraintSpacingTimeline.ENTRIES); - spacing = frames[frame + PathConstraintSpacingTimeline.PREV_VALUE]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime)); - spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent; - } - if (blend == exports.MixBlend.setup) - constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha; - else - constraint.spacing += (spacing - constraint.spacing) * alpha; - }; - return PathConstraintSpacingTimeline; - }(PathConstraintPositionTimeline$2)); - /** Changes a transform constraint's {@link PathConstraint#rotateMix} and - * {@link TransformConstraint#translateMix}. */ - /** - * @public - */ - var PathConstraintMixTimeline$2 = /** @class */ (function (_super) { - __extends$3(PathConstraintMixTimeline, _super); - function PathConstraintMixTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES); - return _this; - } - PathConstraintMixTimeline.prototype.getPropertyId = function () { - return (TimelineType$1.pathConstraintMix << 24) + this.pathConstraintIndex; - }; - /** The time in seconds, rotate mix, and translate mix for the specified key frame. */ - PathConstraintMixTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix) { - frameIndex *= PathConstraintMixTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + PathConstraintMixTimeline.ROTATE] = rotateMix; - this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix; - }; - PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var frames = this.frames; - var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; - if (!constraint.active) - return; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.rotateMix = constraint.data.rotateMix; - constraint.translateMix = constraint.data.translateMix; - return; - case exports.MixBlend.first: - constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha; - constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha; - } - return; - } - var rotate = 0, translate = 0; - if (time >= frames[frames.length - PathConstraintMixTimeline.ENTRIES]) { // Time is after last frame. - rotate = frames[frames.length + PathConstraintMixTimeline.PREV_ROTATE]; - translate = frames[frames.length + PathConstraintMixTimeline.PREV_TRANSLATE]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, PathConstraintMixTimeline.ENTRIES); - rotate = frames[frame + PathConstraintMixTimeline.PREV_ROTATE]; - translate = frames[frame + PathConstraintMixTimeline.PREV_TRANSLATE]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / PathConstraintMixTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintMixTimeline.PREV_TIME] - frameTime)); - rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent; - translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent; - } - if (blend == exports.MixBlend.setup) { - constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha; - constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha; - } - else { - constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; - constraint.translateMix += (translate - constraint.translateMix) * alpha; - } - }; - PathConstraintMixTimeline.ENTRIES = 3; - PathConstraintMixTimeline.PREV_TIME = -3; - PathConstraintMixTimeline.PREV_ROTATE = -2; - PathConstraintMixTimeline.PREV_TRANSLATE = -1; - PathConstraintMixTimeline.ROTATE = 1; - PathConstraintMixTimeline.TRANSLATE = 2; - return PathConstraintMixTimeline; - }(CurveTimeline$2)); - - /** Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies - * multiple animations on top of each other (layering). - * - * See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. */ - /** - * @public - */ - var AnimationState$2 = /** @class */ (function () { - function AnimationState(data) { - /** The list of tracks that currently have animations, which may contain null entries. */ - this.tracks = new Array(); - /** Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower - * or faster. Defaults to 1. - * - * See TrackEntry {@link TrackEntry#timeScale} for affecting a single animation. */ - this.timeScale = 1; - this.unkeyedState = 0; - this.events = new Array(); - this.listeners = new Array(); - this.queue = new EventQueue$2(this); - this.propertyIDs = new IntSet(); - this.animationsChanged = false; - this.trackEntryPool = new Pool(function () { return new TrackEntry$2(); }); - this.data = data; - } - /** Increments each track entry {@link TrackEntry#trackTime()}, setting queued animations as current if needed. */ - AnimationState.prototype.update = function (delta) { - delta *= this.timeScale; - var tracks = this.tracks; - for (var i = 0, n = tracks.length; i < n; i++) { - var current = tracks[i]; - if (current == null) - continue; - current.animationLast = current.nextAnimationLast; - current.trackLast = current.nextTrackLast; - var currentDelta = delta * current.timeScale; - if (current.delay > 0) { - current.delay -= currentDelta; - if (current.delay > 0) - continue; - currentDelta = -current.delay; - current.delay = 0; - } - var next = current.next; - if (next != null) { - // When the next entry's delay is passed, change to the next entry, preserving leftover time. - var nextTime = current.trackLast - next.delay; - if (nextTime >= 0) { - next.delay = 0; - next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale; - current.trackTime += currentDelta; - this.setCurrent(i, next, true); - while (next.mixingFrom != null) { - next.mixTime += delta; - next = next.mixingFrom; - } - continue; - } - } - else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) { - tracks[i] = null; - this.queue.end(current); - this.disposeNext(current); - continue; - } - if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) { - // End mixing from entries once all have completed. - var from = current.mixingFrom; - current.mixingFrom = null; - if (from != null) - from.mixingTo = null; - while (from != null) { - this.queue.end(from); - from = from.mixingFrom; - } - } - current.trackTime += currentDelta; - } - this.queue.drain(); - }; - /** Returns true when all mixing from entries are complete. */ - AnimationState.prototype.updateMixingFrom = function (to, delta) { - var from = to.mixingFrom; - if (from == null) - return true; - var finished = this.updateMixingFrom(from, delta); - from.animationLast = from.nextAnimationLast; - from.trackLast = from.nextTrackLast; - // Require mixTime > 0 to ensure the mixing from entry was applied at least once. - if (to.mixTime > 0 && to.mixTime >= to.mixDuration) { - // Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame). - if (from.totalAlpha == 0 || to.mixDuration == 0) { - to.mixingFrom = from.mixingFrom; - if (from.mixingFrom != null) - from.mixingFrom.mixingTo = to; - to.interruptAlpha = from.interruptAlpha; - this.queue.end(from); - } - return finished; - } - from.trackTime += delta * from.timeScale; - to.mixTime += delta; - return false; - }; - /** Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the - * animation state can be applied to multiple skeletons to pose them identically. - * @returns True if any animations were applied. */ - AnimationState.prototype.apply = function (skeleton) { - if (skeleton == null) - throw new Error("skeleton cannot be null."); - if (this.animationsChanged) - this._animationsChanged(); - var events = this.events; - var tracks = this.tracks; - var applied = false; - for (var i_1 = 0, n_1 = tracks.length; i_1 < n_1; i_1++) { - var current = tracks[i_1]; - if (current == null || current.delay > 0) - continue; - applied = true; - var blend = i_1 == 0 ? exports.MixBlend.first : current.mixBlend; - // Apply mixing from entries first. - var mix = current.alpha; - if (current.mixingFrom != null) - mix *= this.applyMixingFrom(current, skeleton, blend); - else if (current.trackTime >= current.trackEnd && current.next == null) - mix = 0; - // Apply current entry. - var animationLast = current.animationLast, animationTime = current.getAnimationTime(); - var timelineCount = current.animation.timelines.length; - var timelines = current.animation.timelines; - if ((i_1 == 0 && mix == 1) || blend == exports.MixBlend.add) { - for (var ii = 0; ii < timelineCount; ii++) { - // Fixes issue #302 on IOS9 where mix, blend sometimes became undefined and caused assets - // to sometimes stop rendering when using color correction, as their RGBA values become NaN. - // (https://github.com/pixijs/pixi-spine/issues/302) - Utils.webkit602BugfixHelper(mix, blend); - var timeline = timelines[ii]; - if (timeline instanceof AttachmentTimeline$2) - this.applyAttachmentTimeline(timeline, skeleton, animationTime, blend, true); - else - timeline.apply(skeleton, animationLast, animationTime, events, mix, blend, exports.MixDirection.mixIn); - } - } - else { - var timelineMode = current.timelineMode; - var firstFrame = current.timelinesRotation.length == 0; - if (firstFrame) - Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null); - var timelinesRotation = current.timelinesRotation; - for (var ii = 0; ii < timelineCount; ii++) { - var timeline_1 = timelines[ii]; - var timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : exports.MixBlend.setup; - if (timeline_1 instanceof RotateTimeline$2) { - this.applyRotateTimeline(timeline_1, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame); - } - else if (timeline_1 instanceof AttachmentTimeline$2) { - this.applyAttachmentTimeline(timeline_1, skeleton, animationTime, blend, true); - } - else { - // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 - Utils.webkit602BugfixHelper(mix, blend); - timeline_1.apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, exports.MixDirection.mixIn); - } - } - } - this.queueEvents(current, animationTime); - events.length = 0; - current.nextAnimationLast = animationTime; - current.nextTrackLast = current.trackTime; - } - // Set slots attachments to the setup pose, if needed. This occurs if an animation that is mixing out sets attachments so - // subsequent timelines see any deform, but the subsequent timelines don't set an attachment (eg they are also mixing out or - // the time is before the first key). - var setupState = this.unkeyedState + AnimationState.SETUP; - var slots = skeleton.slots; - for (var i = 0, n = skeleton.slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.attachmentState == setupState) { - var attachmentName = slot.data.attachmentName; - slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName)); - } - } - this.unkeyedState += 2; // Increasing after each use avoids the need to reset attachmentState for every slot. - this.queue.drain(); - return applied; - }; - AnimationState.prototype.applyMixingFrom = function (to, skeleton, blend) { - var from = to.mixingFrom; - if (from.mixingFrom != null) - this.applyMixingFrom(from, skeleton, blend); - var mix = 0; - if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. - mix = 1; - if (blend == exports.MixBlend.first) - blend = exports.MixBlend.setup; - } - else { - mix = to.mixTime / to.mixDuration; - if (mix > 1) - mix = 1; - if (blend != exports.MixBlend.first) - blend = from.mixBlend; - } - var events = mix < from.eventThreshold ? this.events : null; - var attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold; - var animationLast = from.animationLast, animationTime = from.getAnimationTime(); - var timelineCount = from.animation.timelines.length; - var timelines = from.animation.timelines; - var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); - if (blend == exports.MixBlend.add) { - for (var i = 0; i < timelineCount; i++) - timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, exports.MixDirection.mixOut); - } - else { - var timelineMode = from.timelineMode; - var timelineHoldMix = from.timelineHoldMix; - var firstFrame = from.timelinesRotation.length == 0; - if (firstFrame) - Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null); - var timelinesRotation = from.timelinesRotation; - from.totalAlpha = 0; - for (var i = 0; i < timelineCount; i++) { - var timeline = timelines[i]; - var direction = exports.MixDirection.mixOut; - var timelineBlend = void 0; - var alpha = 0; - switch (timelineMode[i]) { - case AnimationState.SUBSEQUENT: - if (!drawOrder && timeline instanceof DrawOrderTimeline$2) - continue; - timelineBlend = blend; - alpha = alphaMix; - break; - case AnimationState.FIRST: - timelineBlend = exports.MixBlend.setup; - alpha = alphaMix; - break; - case AnimationState.HOLD_SUBSEQUENT: - timelineBlend = blend; - alpha = alphaHold; - break; - case AnimationState.HOLD_FIRST: - timelineBlend = exports.MixBlend.setup; - alpha = alphaHold; - break; - default: - timelineBlend = exports.MixBlend.setup; - var holdMix = timelineHoldMix[i]; - alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration); - break; - } - from.totalAlpha += alpha; - if (timeline instanceof RotateTimeline$2) - this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame); - else if (timeline instanceof AttachmentTimeline$2) - this.applyAttachmentTimeline(timeline, skeleton, animationTime, timelineBlend, attachments); - else { - // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 - Utils.webkit602BugfixHelper(alpha, blend); - if (drawOrder && timeline instanceof DrawOrderTimeline$2 && timelineBlend == exports.MixBlend.setup) - direction = exports.MixDirection.mixIn; - timeline.apply(skeleton, animationLast, animationTime, events, alpha, timelineBlend, direction); - } - } - } - if (to.mixDuration > 0) - this.queueEvents(from, animationTime); - this.events.length = 0; - from.nextAnimationLast = animationTime; - from.nextTrackLast = from.trackTime; - return mix; - }; - AnimationState.prototype.applyAttachmentTimeline = function (timeline, skeleton, time, blend, attachments) { - var slot = skeleton.slots[timeline.slotIndex]; - if (!slot.bone.active) - return; - var frames = timeline.frames; - if (time < frames[0]) { // Time is before first frame. - if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) - this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments); - } - else { - var frameIndex; - if (time >= frames[frames.length - 1]) // Time is after last frame. - frameIndex = frames.length - 1; - else - frameIndex = Animation$2.binarySearch(frames, time) - 1; - this.setAttachment(skeleton, slot, timeline.attachmentNames[frameIndex], attachments); - } - // If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later. - if (slot.attachmentState <= this.unkeyedState) - slot.attachmentState = this.unkeyedState + AnimationState.SETUP; - }; - AnimationState.prototype.setAttachment = function (skeleton, slot, attachmentName, attachments) { - slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName)); - if (attachments) - slot.attachmentState = this.unkeyedState + AnimationState.CURRENT; - }; - AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) { - if (firstFrame) - timelinesRotation[i] = 0; - if (alpha == 1) { - timeline.apply(skeleton, 0, time, null, 1, blend, exports.MixDirection.mixIn); - return; - } - var rotateTimeline = timeline; - var frames = rotateTimeline.frames; - var bone = skeleton.bones[rotateTimeline.boneIndex]; - if (!bone.active) - return; - var r1 = 0, r2 = 0; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.rotation = bone.data.rotation; - default: - return; - case exports.MixBlend.first: - r1 = bone.rotation; - r2 = bone.data.rotation; - } - } - else { - r1 = blend == exports.MixBlend.setup ? bone.data.rotation : bone.rotation; - if (time >= frames[frames.length - RotateTimeline$2.ENTRIES]) // Time is after last frame. - r2 = bone.data.rotation + frames[frames.length + RotateTimeline$2.PREV_ROTATION]; - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$2.binarySearch(frames, time, RotateTimeline$2.ENTRIES); - var prevRotation = frames[frame + RotateTimeline$2.PREV_ROTATION]; - var frameTime = frames[frame]; - var percent = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline$2.PREV_TIME] - frameTime)); - r2 = frames[frame + RotateTimeline$2.ROTATION] - prevRotation; - r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; - r2 = prevRotation + r2 * percent + bone.data.rotation; - r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; - } - } - // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. - var total = 0, diff = r2 - r1; - diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360; - if (diff == 0) { - total = timelinesRotation[i]; - } - else { - var lastTotal = 0, lastDiff = 0; - if (firstFrame) { - lastTotal = 0; - lastDiff = diff; - } - else { - lastTotal = timelinesRotation[i]; // Angle and direction of mix, including loops. - lastDiff = timelinesRotation[i + 1]; // Difference between bones. - } - var current = diff > 0, dir = lastTotal >= 0; - // Detect cross at 0 (not 180). - if (MathUtils.signum(lastDiff) != MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) { - // A cross after a 360 rotation is a loop. - if (Math.abs(lastTotal) > 180) - lastTotal += 360 * MathUtils.signum(lastTotal); - dir = current; - } - total = diff + lastTotal - lastTotal % 360; // Store loops as part of lastTotal. - if (dir != current) - total += 360 * MathUtils.signum(lastTotal); - timelinesRotation[i] = total; - } - timelinesRotation[i + 1] = diff; - r1 += total * alpha; - bone.rotation = r1 - (16384 - ((16384.499999999996 - r1 / 360) | 0)) * 360; - }; - AnimationState.prototype.queueEvents = function (entry, animationTime) { - var animationStart = entry.animationStart, animationEnd = entry.animationEnd; - var duration = animationEnd - animationStart; - var trackLastWrapped = entry.trackLast % duration; - // Queue events before complete. - var events = this.events; - var i = 0, n = events.length; - for (; i < n; i++) { - var event_1 = events[i]; - if (event_1.time < trackLastWrapped) - break; - if (event_1.time > animationEnd) - continue; // Discard events outside animation start/end. - this.queue.event(entry, event_1); - } - // Queue complete if completed a loop iteration or the animation. - var complete = false; - if (entry.loop) - complete = duration == 0 || trackLastWrapped > entry.trackTime % duration; - else - complete = animationTime >= animationEnd && entry.animationLast < animationEnd; - if (complete) - this.queue.complete(entry); - // Queue events after complete. - for (; i < n; i++) { - var event_2 = events[i]; - if (event_2.time < animationStart) - continue; // Discard events outside animation start/end. - this.queue.event(entry, events[i]); - } - }; - /** Removes all animations from all tracks, leaving skeletons in their current pose. - * - * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, - * rather than leaving them in their current pose. */ - AnimationState.prototype.clearTracks = function () { - var oldDrainDisabled = this.queue.drainDisabled; - this.queue.drainDisabled = true; - for (var i = 0, n = this.tracks.length; i < n; i++) - this.clearTrack(i); - this.tracks.length = 0; - this.queue.drainDisabled = oldDrainDisabled; - this.queue.drain(); - }; - /** Removes all animations from the track, leaving skeletons in their current pose. - * - * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, - * rather than leaving them in their current pose. */ - AnimationState.prototype.clearTrack = function (trackIndex) { - if (trackIndex >= this.tracks.length) - return; - var current = this.tracks[trackIndex]; - if (current == null) - return; - this.queue.end(current); - this.disposeNext(current); - var entry = current; - while (true) { - var from = entry.mixingFrom; - if (from == null) - break; - this.queue.end(from); - entry.mixingFrom = null; - entry.mixingTo = null; - entry = from; - } - this.tracks[current.trackIndex] = null; - this.queue.drain(); - }; - AnimationState.prototype.setCurrent = function (index, current, interrupt) { - var from = this.expandToIndex(index); - this.tracks[index] = current; - if (from != null) { - if (interrupt) - this.queue.interrupt(from); - current.mixingFrom = from; - from.mixingTo = current; - current.mixTime = 0; - // Store the interrupted mix percentage. - if (from.mixingFrom != null && from.mixDuration > 0) - current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration); - from.timelinesRotation.length = 0; // Reset rotation for mixing out, in case entry was mixed in. - } - this.queue.start(current); - }; - /** Sets an animation by name. - * - * {@link #setAnimationWith(}. */ - AnimationState.prototype.setAnimation = function (trackIndex, animationName, loop) { - var animation = this.data.skeletonData.findAnimation(animationName); - if (animation == null) - throw new Error("Animation not found: " + animationName); - return this.setAnimationWith(trackIndex, animation, loop); - }; - /** Sets the current animation for a track, discarding any queued animations. If the formerly current track entry was never - * applied to a skeleton, it is replaced (not mixed from). - * @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its - * duration. In either case {@link TrackEntry#trackEnd} determines when the track is cleared. - * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept - * after the {@link AnimationStateListener#dispose()} event occurs. */ - AnimationState.prototype.setAnimationWith = function (trackIndex, animation, loop) { - if (animation == null) - throw new Error("animation cannot be null."); - var interrupt = true; - var current = this.expandToIndex(trackIndex); - if (current != null) { - if (current.nextTrackLast == -1) { - // Don't mix from an entry that was never applied. - this.tracks[trackIndex] = current.mixingFrom; - this.queue.interrupt(current); - this.queue.end(current); - this.disposeNext(current); - current = current.mixingFrom; - interrupt = false; - } - else - this.disposeNext(current); - } - var entry = this.trackEntry(trackIndex, animation, loop, current); - this.setCurrent(trackIndex, entry, interrupt); - this.queue.drain(); - return entry; - }; - /** Queues an animation by name. - * - * See {@link #addAnimationWith()}. */ - AnimationState.prototype.addAnimation = function (trackIndex, animationName, loop, delay) { - var animation = this.data.skeletonData.findAnimation(animationName); - if (animation == null) - throw new Error("Animation not found: " + animationName); - return this.addAnimationWith(trackIndex, animation, loop, delay); - }; - /** Adds an animation to be played after the current or last queued animation for a track. If the track is empty, it is - * equivalent to calling {@link #setAnimationWith()}. - * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry - * minus any mix duration (from the {@link AnimationStateData}) plus the specified `delay` (ie the mix - * ends at (`delay` = 0) or before (`delay` < 0) the previous track entry duration). If the - * previous entry is looping, its next loop completion is used instead of its duration. - * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept - * after the {@link AnimationStateListener#dispose()} event occurs. */ - AnimationState.prototype.addAnimationWith = function (trackIndex, animation, loop, delay) { - if (animation == null) - throw new Error("animation cannot be null."); - var last = this.expandToIndex(trackIndex); - if (last != null) { - while (last.next != null) - last = last.next; - } - var entry = this.trackEntry(trackIndex, animation, loop, last); - if (last == null) { - this.setCurrent(trackIndex, entry, true); - this.queue.drain(); - } - else { - last.next = entry; - if (delay <= 0) { - var duration = last.animationEnd - last.animationStart; - if (duration != 0) { - if (last.loop) - delay += duration * (1 + ((last.trackTime / duration) | 0)); - else - delay += Math.max(duration, last.trackTime); - delay -= this.data.getMix(last.animation, animation); - } - else - delay = last.trackTime; - } - } - entry.delay = delay; - return entry; - }; - /** Sets an empty animation for a track, discarding any queued animations, and sets the track entry's - * {@link TrackEntry#mixduration}. An empty animation has no timelines and serves as a placeholder for mixing in or out. - * - * Mixing out is done by setting an empty animation with a mix duration using either {@link #setEmptyAnimation()}, - * {@link #setEmptyAnimations()}, or {@link #addEmptyAnimation()}. Mixing to an empty animation causes - * the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation - * transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of - * 0 still mixes out over one frame. - * - * Mixing in is done by first setting an empty animation, then adding an animation using - * {@link #addAnimation()} and on the returned track entry, set the - * {@link TrackEntry#setMixDuration()}. Mixing from an empty animation causes the new animation to be applied more and - * more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the - * setup pose value if no lower tracks key the property to the value keyed in the new animation. */ - AnimationState.prototype.setEmptyAnimation = function (trackIndex, mixDuration) { - var entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation, false); - entry.mixDuration = mixDuration; - entry.trackEnd = mixDuration; - return entry; - }; - /** Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's - * {@link TrackEntry#mixDuration}. If the track is empty, it is equivalent to calling - * {@link #setEmptyAnimation()}. - * - * See {@link #setEmptyAnimation()}. - * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry - * minus any mix duration plus the specified `delay` (ie the mix ends at (`delay` = 0) or - * before (`delay` < 0) the previous track entry duration). If the previous entry is looping, its next - * loop completion is used instead of its duration. - * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept - * after the {@link AnimationStateListener#dispose()} event occurs. */ - AnimationState.prototype.addEmptyAnimation = function (trackIndex, mixDuration, delay) { - if (delay <= 0) - delay -= mixDuration; - var entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation, false, delay); - entry.mixDuration = mixDuration; - entry.trackEnd = mixDuration; - return entry; - }; - /** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix - * duration. */ - AnimationState.prototype.setEmptyAnimations = function (mixDuration) { - var oldDrainDisabled = this.queue.drainDisabled; - this.queue.drainDisabled = true; - for (var i = 0, n = this.tracks.length; i < n; i++) { - var current = this.tracks[i]; - if (current != null) - this.setEmptyAnimation(current.trackIndex, mixDuration); - } - this.queue.drainDisabled = oldDrainDisabled; - this.queue.drain(); - }; - AnimationState.prototype.expandToIndex = function (index) { - if (index < this.tracks.length) - return this.tracks[index]; - Utils.ensureArrayCapacity(this.tracks, index + 1, null); - this.tracks.length = index + 1; - return null; - }; - /** @param last May be null. */ - AnimationState.prototype.trackEntry = function (trackIndex, animation, loop, last) { - var entry = this.trackEntryPool.obtain(); - entry.trackIndex = trackIndex; - entry.animation = animation; - entry.loop = loop; - entry.holdPrevious = false; - entry.eventThreshold = 0; - entry.attachmentThreshold = 0; - entry.drawOrderThreshold = 0; - entry.animationStart = 0; - entry.animationEnd = animation.duration; - entry.animationLast = -1; - entry.nextAnimationLast = -1; - entry.delay = 0; - entry.trackTime = 0; - entry.trackLast = -1; - entry.nextTrackLast = -1; - entry.trackEnd = Number.MAX_VALUE; - entry.timeScale = 1; - entry.alpha = 1; - entry.interruptAlpha = 1; - entry.mixTime = 0; - entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation); - entry.mixBlend = exports.MixBlend.replace; - return entry; - }; - AnimationState.prototype.disposeNext = function (entry) { - var next = entry.next; - while (next != null) { - this.queue.dispose(next); - next = next.next; - } - entry.next = null; - }; - AnimationState.prototype._animationsChanged = function () { - this.animationsChanged = false; - this.propertyIDs.clear(); - for (var i = 0, n = this.tracks.length; i < n; i++) { - var entry = this.tracks[i]; - if (entry == null) - continue; - while (entry.mixingFrom != null) - entry = entry.mixingFrom; - do { - if (entry.mixingFrom == null || entry.mixBlend != exports.MixBlend.add) - this.computeHold(entry); - entry = entry.mixingTo; - } while (entry != null); - } - }; - AnimationState.prototype.computeHold = function (entry) { - var to = entry.mixingTo; - var timelines = entry.animation.timelines; - var timelinesCount = entry.animation.timelines.length; - var timelineMode = Utils.setArraySize(entry.timelineMode, timelinesCount); - entry.timelineHoldMix.length = 0; - var timelineDipMix = Utils.setArraySize(entry.timelineHoldMix, timelinesCount); - var propertyIDs = this.propertyIDs; - if (to != null && to.holdPrevious) { - for (var i = 0; i < timelinesCount; i++) { - timelineMode[i] = propertyIDs.add(timelines[i].getPropertyId()) ? AnimationState.HOLD_FIRST : AnimationState.HOLD_SUBSEQUENT; - } - return; - } - outer: for (var i = 0; i < timelinesCount; i++) { - var timeline = timelines[i]; - var id = timeline.getPropertyId(); - if (!propertyIDs.add(id)) - timelineMode[i] = AnimationState.SUBSEQUENT; - else if (to == null || timeline instanceof AttachmentTimeline$2 || timeline instanceof DrawOrderTimeline$2 - || timeline instanceof EventTimeline$2 || !to.animation.hasTimeline(id)) { - timelineMode[i] = AnimationState.FIRST; - } - else { - for (var next = to.mixingTo; next != null; next = next.mixingTo) { - if (next.animation.hasTimeline(id)) - continue; - if (entry.mixDuration > 0) { - timelineMode[i] = AnimationState.HOLD_MIX; - timelineDipMix[i] = next; - continue outer; - } - break; - } - timelineMode[i] = AnimationState.HOLD_FIRST; - } - } - }; - /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */ - AnimationState.prototype.getCurrent = function (trackIndex) { - if (trackIndex >= this.tracks.length) - return null; - return this.tracks[trackIndex]; - }; - /** Adds a listener to receive events for all track entries. */ - AnimationState.prototype.addListener = function (listener) { - if (listener == null) - throw new Error("listener cannot be null."); - this.listeners.push(listener); - }; - /** Removes the listener added with {@link #addListener()}. */ - AnimationState.prototype.removeListener = function (listener) { - var index = this.listeners.indexOf(listener); - if (index >= 0) - this.listeners.splice(index, 1); - }; - /** Removes all listeners added with {@link #addListener()}. */ - AnimationState.prototype.clearListeners = function () { - this.listeners.length = 0; - }; - /** Discards all listener notifications that have not yet been delivered. This can be useful to call from an - * {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery - * are not wanted because new animations are being set. */ - AnimationState.prototype.clearListenerNotifications = function () { - this.queue.clear(); - }; - AnimationState.prototype.setAnimationByName = function (trackIndex, animationName, loop) { - if (!AnimationState.deprecatedWarning1) { - AnimationState.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on."); - } - this.setAnimation(trackIndex, animationName, loop); - }; - AnimationState.prototype.addAnimationByName = function (trackIndex, animationName, loop, delay) { - if (!AnimationState.deprecatedWarning2) { - AnimationState.deprecatedWarning2 = true; - console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on."); - } - this.addAnimation(trackIndex, animationName, loop, delay); - }; - AnimationState.prototype.hasAnimation = function (animationName) { - var animation = this.data.skeletonData.findAnimation(animationName); - return animation !== null; - }; - AnimationState.prototype.hasAnimationByName = function (animationName) { - if (!AnimationState.deprecatedWarning3) { - AnimationState.deprecatedWarning3 = true; - console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on."); - } - return this.hasAnimation(animationName); - }; - AnimationState.emptyAnimation = new Animation$2("", [], 0); - /** 1. A previously applied timeline has set this property. - * - * Result: Mix from the current pose to the timeline pose. */ - AnimationState.SUBSEQUENT = 0; - /** 1. This is the first timeline to set this property. - * 2. The next track entry applied after this one does not have a timeline to set this property. - * - * Result: Mix from the setup pose to the timeline pose. */ - AnimationState.FIRST = 1; - /** 1) A previously applied timeline has set this property.
- * 2) The next track entry to be applied does have a timeline to set this property.
- * 3) The next track entry after that one does not have a timeline to set this property.
- * Result: Mix from the current pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading - * animations that key the same property. A subsequent timeline will set this property using a mix. */ - AnimationState.HOLD_SUBSEQUENT = 2; - /** 1) This is the first timeline to set this property.
- * 2) The next track entry to be applied does have a timeline to set this property.
- * 3) The next track entry after that one does not have a timeline to set this property.
- * Result: Mix from the setup pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading animations - * that key the same property. A subsequent timeline will set this property using a mix. */ - AnimationState.HOLD_FIRST = 3; - /** 1. This is the first timeline to set this property. - * 2. The next track entry to be applied does have a timeline to set this property. - * 3. The next track entry after that one does have a timeline to set this property. - * 4. timelineHoldMix stores the first subsequent track entry that does not have a timeline to set this property. - * - * Result: The same as HOLD except the mix percentage from the timelineHoldMix track entry is used. This handles when more than - * 2 track entries in a row have a timeline that sets the same property. - * - * Eg, A -> B -> C -> D where A, B, and C have a timeline setting same property, but D does not. When A is applied, to avoid - * "dipping" A is not mixed out, however D (the first entry that doesn't set the property) mixing in is used to mix out A - * (which affects B and C). Without using D to mix out, A would be applied fully until mixing completes, then snap into - * place. */ - AnimationState.HOLD_MIX = 4; - AnimationState.SETUP = 1; - AnimationState.CURRENT = 2; - AnimationState.deprecatedWarning1 = false; - AnimationState.deprecatedWarning2 = false; - AnimationState.deprecatedWarning3 = false; - return AnimationState; - }()); - /** Stores settings and other state for the playback of an animation on an {@link AnimationState} track. - * - * References to a track entry must not be kept after the {@link AnimationStateListener#dispose()} event occurs. */ - /** - * @public - */ - var TrackEntry$2 = /** @class */ (function () { - function TrackEntry() { - /** Controls how properties keyed in the animation are mixed with lower tracks. Defaults to {@link MixBlend#replace}, which - * replaces the values from the lower tracks with the animation values. {@link MixBlend#add} adds the animation values to - * the values from the lower tracks. - * - * The `mixBlend` can be set for a new track entry only before {@link AnimationState#apply()} is first - * called. */ - this.mixBlend = exports.MixBlend.replace; - this.timelineMode = new Array(); - this.timelineHoldMix = new Array(); - this.timelinesRotation = new Array(); - } - TrackEntry.prototype.reset = function () { - this.next = null; - this.mixingFrom = null; - this.mixingTo = null; - this.animation = null; - this.listener = null; - this.timelineMode.length = 0; - this.timelineHoldMix.length = 0; - this.timelinesRotation.length = 0; - }; - /** Uses {@link #trackTime} to compute the `animationTime`, which is between {@link #animationStart} - * and {@link #animationEnd}. When the `trackTime` is 0, the `animationTime` is equal to the - * `animationStart` time. */ - TrackEntry.prototype.getAnimationTime = function () { - if (this.loop) { - var duration = this.animationEnd - this.animationStart; - if (duration == 0) - return this.animationStart; - return (this.trackTime % duration) + this.animationStart; - } - return Math.min(this.trackTime + this.animationStart, this.animationEnd); - }; - TrackEntry.prototype.setAnimationLast = function (animationLast) { - this.animationLast = animationLast; - this.nextAnimationLast = animationLast; - }; - /** Returns true if at least one loop has been completed. - * - * See {@link AnimationStateListener#complete()}. */ - TrackEntry.prototype.isComplete = function () { - return this.trackTime >= this.animationEnd - this.animationStart; - }; - /** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the - * long way around when using {@link #alpha} and starting animations on other tracks. - * - * Mixing with {@link MixBlend#replace} involves finding a rotation between two others, which has two possible solutions: - * the short way or the long way around. The two rotations likely change over time, so which direction is the short or long - * way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the - * long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. */ - TrackEntry.prototype.resetRotationDirections = function () { - this.timelinesRotation.length = 0; - }; - Object.defineProperty(TrackEntry.prototype, "time", { - get: function () { - if (!TrackEntry.deprecatedWarning1) { - TrackEntry.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); - } - return this.trackTime; - }, - set: function (value) { - if (!TrackEntry.deprecatedWarning1) { - TrackEntry.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); - } - this.trackTime = value; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TrackEntry.prototype, "endTime", { - get: function () { - if (!TrackEntry.deprecatedWarning2) { - TrackEntry.deprecatedWarning2 = true; - console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); - } - return this.trackTime; - }, - set: function (value) { - if (!TrackEntry.deprecatedWarning2) { - TrackEntry.deprecatedWarning2 = true; - console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); - } - this.trackTime = value; - }, - enumerable: false, - configurable: true - }); - TrackEntry.prototype.loopsCount = function () { - return Math.floor(this.trackTime / this.trackEnd); - }; - TrackEntry.deprecatedWarning1 = false; - TrackEntry.deprecatedWarning2 = false; - return TrackEntry; - }()); - /** - * @public - */ - var EventQueue$2 = /** @class */ (function () { - function EventQueue(animState) { - this.objects = []; - this.drainDisabled = false; - this.animState = animState; - } - EventQueue.prototype.start = function (entry) { - this.objects.push(EventType$2.start); - this.objects.push(entry); - this.animState.animationsChanged = true; - }; - EventQueue.prototype.interrupt = function (entry) { - this.objects.push(EventType$2.interrupt); - this.objects.push(entry); - }; - EventQueue.prototype.end = function (entry) { - this.objects.push(EventType$2.end); - this.objects.push(entry); - this.animState.animationsChanged = true; - }; - EventQueue.prototype.dispose = function (entry) { - this.objects.push(EventType$2.dispose); - this.objects.push(entry); - }; - EventQueue.prototype.complete = function (entry) { - this.objects.push(EventType$2.complete); - this.objects.push(entry); - }; - EventQueue.prototype.event = function (entry, event) { - this.objects.push(EventType$2.event); - this.objects.push(entry); - this.objects.push(event); - }; - EventQueue.prototype.deprecateStuff = function () { - if (!EventQueue.deprecatedWarning1) { - EventQueue.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: onComplete, onStart, onEnd, onEvent art deprecated, please use listeners from now on. 'state.addListener({ complete: function(track, event) { } })'"); - } - return true; - }; - EventQueue.prototype.drain = function () { - if (this.drainDisabled) - return; - this.drainDisabled = true; - var objects = this.objects; - var listeners = this.animState.listeners; - for (var i = 0; i < objects.length; i += 2) { - var type = objects[i]; - var entry = objects[i + 1]; - switch (type) { - case EventType$2.start: - if (entry.listener != null && entry.listener.start) - entry.listener.start(entry); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].start) - listeners[ii].start(entry); - //deprecation - entry.onStart && this.deprecateStuff() && entry.onStart(entry.trackIndex); - this.animState.onStart && this.deprecateStuff() && this.deprecateStuff && this.animState.onStart(entry.trackIndex); - break; - case EventType$2.interrupt: - if (entry.listener != null && entry.listener.interrupt) - entry.listener.interrupt(entry); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].interrupt) - listeners[ii].interrupt(entry); - break; - case EventType$2.end: - if (entry.listener != null && entry.listener.end) - entry.listener.end(entry); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].end) - listeners[ii].end(entry); - //deprecation - entry.onEnd && this.deprecateStuff() && entry.onEnd(entry.trackIndex); - this.animState.onEnd && this.deprecateStuff() && this.animState.onEnd(entry.trackIndex); - // Fall through. - case EventType$2.dispose: - if (entry.listener != null && entry.listener.dispose) - entry.listener.dispose(entry); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].dispose) - listeners[ii].dispose(entry); - this.animState.trackEntryPool.free(entry); - break; - case EventType$2.complete: - if (entry.listener != null && entry.listener.complete) - entry.listener.complete(entry); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].complete) - listeners[ii].complete(entry); - //deprecation - var count = MathUtils.toInt(entry.loopsCount()); - entry.onComplete && this.deprecateStuff() && entry.onComplete(entry.trackIndex, count); - this.animState.onComplete && this.deprecateStuff() && this.animState.onComplete(entry.trackIndex, count); - break; - case EventType$2.event: - var event_3 = objects[i++ + 2]; - if (entry.listener != null && entry.listener.event) - entry.listener.event(entry, event_3); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].event) - listeners[ii].event(entry, event_3); - //deprecation - entry.onEvent && this.deprecateStuff() && entry.onEvent(entry.trackIndex, event_3); - this.animState.onEvent && this.deprecateStuff() && this.animState.onEvent(entry.trackIndex, event_3); - break; - } - } - this.clear(); - this.drainDisabled = false; - }; - EventQueue.prototype.clear = function () { - this.objects.length = 0; - }; - EventQueue.deprecatedWarning1 = false; - return EventQueue; - }()); - /** - * @public - */ - var EventType$2; - (function (EventType) { - EventType[EventType["start"] = 0] = "start"; - EventType[EventType["interrupt"] = 1] = "interrupt"; - EventType[EventType["end"] = 2] = "end"; - EventType[EventType["dispose"] = 3] = "dispose"; - EventType[EventType["complete"] = 4] = "complete"; - EventType[EventType["event"] = 5] = "event"; - })(EventType$2 || (EventType$2 = {})); - /** - * @public - */ - var AnimationStateAdapter$1 = /** @class */ (function () { - function AnimationStateAdapter() { - } - AnimationStateAdapter.prototype.start = function (entry) { - }; - AnimationStateAdapter.prototype.interrupt = function (entry) { - }; - AnimationStateAdapter.prototype.end = function (entry) { - }; - AnimationStateAdapter.prototype.dispose = function (entry) { - }; - AnimationStateAdapter.prototype.complete = function (entry) { - }; - AnimationStateAdapter.prototype.event = function (entry, event) { - }; - return AnimationStateAdapter; - }()); - - /** - * @public - */ - var AnimationStateData$2 = /** @class */ (function () { - function AnimationStateData(skeletonData) { - this.animationToMixTime = {}; - this.defaultMix = 0; - if (skeletonData == null) - throw new Error("skeletonData cannot be null."); - this.skeletonData = skeletonData; - } - AnimationStateData.prototype.setMix = function (fromName, toName, duration) { - var from = this.skeletonData.findAnimation(fromName); - if (from == null) - throw new Error("Animation not found: " + fromName); - var to = this.skeletonData.findAnimation(toName); - if (to == null) - throw new Error("Animation not found: " + toName); - this.setMixWith(from, to, duration); - }; - AnimationStateData.prototype.setMixByName = function (fromName, toName, duration) { - if (!AnimationStateData.deprecatedWarning1) { - AnimationStateData.deprecatedWarning1 = true; - console.warn("Deprecation Warning: AnimationStateData.setMixByName is deprecated, please use setMix from now on."); - } - this.setMix(fromName, toName, duration); - }; - AnimationStateData.prototype.setMixWith = function (from, to, duration) { - if (from == null) - throw new Error("from cannot be null."); - if (to == null) - throw new Error("to cannot be null."); - var key = from.name + "." + to.name; - this.animationToMixTime[key] = duration; - }; - AnimationStateData.prototype.getMix = function (from, to) { - var key = from.name + "." + to.name; - var value = this.animationToMixTime[key]; - return value === undefined ? this.defaultMix : value; - }; - AnimationStateData.deprecatedWarning1 = false; - return AnimationStateData; - }()); - - /** - * @public - */ - var AtlasAttachmentLoader$2 = /** @class */ (function () { - function AtlasAttachmentLoader(atlas) { - this.atlas = atlas; - } - /** @return May be null to not load an attachment. */ - AtlasAttachmentLoader.prototype.newRegionAttachment = function (skin, name, path) { - var region = this.atlas.findRegion(path); - if (region == null) - throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); - var attachment = new RegionAttachment$2(name); - attachment.region = region; - return attachment; - }; - /** @return May be null to not load an attachment. */ - AtlasAttachmentLoader.prototype.newMeshAttachment = function (skin, name, path) { - var region = this.atlas.findRegion(path); - if (region == null) - throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); - var attachment = new MeshAttachment$2(name); - attachment.region = region; - return attachment; - }; - /** @return May be null to not load an attachment. */ - AtlasAttachmentLoader.prototype.newBoundingBoxAttachment = function (skin, name) { - return new BoundingBoxAttachment$2(name); - }; - /** @return May be null to not load an attachment */ - AtlasAttachmentLoader.prototype.newPathAttachment = function (skin, name) { - return new PathAttachment$2(name); - }; - AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) { - return new PointAttachment$2(name); - }; - AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) { - return new ClippingAttachment$2(name); - }; - return AtlasAttachmentLoader; - }()); - - /** - * @public - */ - var Bone$2 = /** @class */ (function () { - /** @param parent May be null. */ - function Bone(data, skeleton, parent) { - //be careful! Spine b,c is c,b in pixi matrix - this.matrix = new math.Matrix(); - this.children = new Array(); - this.x = 0; - this.y = 0; - this.rotation = 0; - this.scaleX = 0; - this.scaleY = 0; - this.shearX = 0; - this.shearY = 0; - this.ax = 0; - this.ay = 0; - this.arotation = 0; - this.ascaleX = 0; - this.ascaleY = 0; - this.ashearX = 0; - this.ashearY = 0; - this.appliedValid = false; - this.sorted = false; - this.active = false; - if (data == null) - throw new Error("data cannot be null."); - if (skeleton == null) - throw new Error("skeleton cannot be null."); - this.data = data; - this.skeleton = skeleton; - this.parent = parent; - this.setToSetupPose(); - } - Object.defineProperty(Bone.prototype, "worldX", { - get: function () { - return this.matrix.tx; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Bone.prototype, "worldY", { - get: function () { - return this.matrix.ty; - }, - enumerable: false, - configurable: true - }); - Bone.prototype.isActive = function () { - return this.active; - }; - /** Same as {@link #updateWorldTransform()}. This method exists for Bone to implement {@link Updatable}. */ - Bone.prototype.update = function () { - this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); - }; - /** Computes the world transform using the parent bone and this bone's local transform. */ - Bone.prototype.updateWorldTransform = function () { - this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); - }; - /** Computes the world transform using the parent bone and the specified local transform. */ - Bone.prototype.updateWorldTransformWith = function (x, y, rotation, scaleX, scaleY, shearX, shearY) { - this.ax = x; - this.ay = y; - this.arotation = rotation; - this.ascaleX = scaleX; - this.ascaleY = scaleY; - this.ashearX = shearX; - this.ashearY = shearY; - this.appliedValid = true; - var parent = this.parent; - var m = this.matrix; - var sx = this.skeleton.scaleX; - var sy = settings.yDown ? -this.skeleton.scaleY : this.skeleton.scaleY; - if (parent == null) { // Root bone. - var skeleton = this.skeleton; - var rotationY = rotation + 90 + shearY; - m.a = MathUtils.cosDeg(rotation + shearX) * scaleX * sx; - m.c = MathUtils.cosDeg(rotationY) * scaleY * sx; - m.b = MathUtils.sinDeg(rotation + shearX) * scaleX * sy; - m.d = MathUtils.sinDeg(rotationY) * scaleY * sy; - m.tx = x * sx + skeleton.x; - m.ty = y * sy + skeleton.y; - return; - } - var pa = parent.matrix.a, pb = parent.matrix.c, pc = parent.matrix.b, pd = parent.matrix.d; - m.tx = pa * x + pb * y + parent.matrix.tx; - m.ty = pc * x + pd * y + parent.matrix.ty; - switch (this.data.transformMode) { - case exports.TransformMode.Normal: { - var rotationY = rotation + 90 + shearY; - var la = MathUtils.cosDeg(rotation + shearX) * scaleX; - var lb = MathUtils.cosDeg(rotationY) * scaleY; - var lc = MathUtils.sinDeg(rotation + shearX) * scaleX; - var ld = MathUtils.sinDeg(rotationY) * scaleY; - m.a = pa * la + pb * lc; - m.c = pa * lb + pb * ld; - m.b = pc * la + pd * lc; - m.d = pc * lb + pd * ld; - return; - } - case exports.TransformMode.OnlyTranslation: { - var rotationY = rotation + 90 + shearY; - m.a = MathUtils.cosDeg(rotation + shearX) * scaleX; - m.c = MathUtils.cosDeg(rotationY) * scaleY; - m.b = MathUtils.sinDeg(rotation + shearX) * scaleX; - m.d = MathUtils.sinDeg(rotationY) * scaleY; - break; - } - case exports.TransformMode.NoRotationOrReflection: { - var s = pa * pa + pc * pc; - var prx = 0; - if (s > 0.0001) { - s = Math.abs(pa * pd - pb * pc) / s; - pa /= this.skeleton.scaleX; - pc /= this.skeleton.scaleY; - pb = pc * s; - pd = pa * s; - prx = Math.atan2(pc, pa) * MathUtils.radDeg; - } - else { - pa = 0; - pc = 0; - prx = 90 - Math.atan2(pd, pb) * MathUtils.radDeg; - } - var rx = rotation + shearX - prx; - var ry = rotation + shearY - prx + 90; - var la = MathUtils.cosDeg(rx) * scaleX; - var lb = MathUtils.cosDeg(ry) * scaleY; - var lc = MathUtils.sinDeg(rx) * scaleX; - var ld = MathUtils.sinDeg(ry) * scaleY; - m.a = pa * la - pb * lc; - m.c = pa * lb - pb * ld; - m.b = pc * la + pd * lc; - m.d = pc * lb + pd * ld; - break; - } - case exports.TransformMode.NoScale: - case exports.TransformMode.NoScaleOrReflection: { - var cos = MathUtils.cosDeg(rotation); - var sin = MathUtils.sinDeg(rotation); - var za = (pa * cos + pb * sin) / sx; - var zc = (pc * cos + pd * sin) / sy; - var s = Math.sqrt(za * za + zc * zc); - if (s > 0.00001) - s = 1 / s; - za *= s; - zc *= s; - s = Math.sqrt(za * za + zc * zc); - if (this.data.transformMode == exports.TransformMode.NoScale - && (pa * pd - pb * pc < 0) != (settings.yDown ? - (this.skeleton.scaleX < 0 != this.skeleton.scaleY > 0) : - (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0))) - s = -s; - var r = Math.PI / 2 + Math.atan2(zc, za); - var zb = Math.cos(r) * s; - var zd = Math.sin(r) * s; - var la = MathUtils.cosDeg(shearX) * scaleX; - var lb = MathUtils.cosDeg(90 + shearY) * scaleY; - var lc = MathUtils.sinDeg(shearX) * scaleX; - var ld = MathUtils.sinDeg(90 + shearY) * scaleY; - m.a = za * la + zb * lc; - m.c = za * lb + zb * ld; - m.b = zc * la + zd * lc; - m.d = zc * lb + zd * ld; - break; - } - } - m.a *= sx; - m.c *= sx; - m.b *= sy; - m.d *= sy; - }; - Bone.prototype.setToSetupPose = function () { - var data = this.data; - this.x = data.x; - this.y = data.y; - this.rotation = data.rotation; - this.scaleX = data.scaleX; - this.scaleY = data.scaleY; - this.shearX = data.shearX; - this.shearY = data.shearY; - }; - Bone.prototype.getWorldRotationX = function () { - return Math.atan2(this.matrix.b, this.matrix.a) * MathUtils.radDeg; - }; - Bone.prototype.getWorldRotationY = function () { - return Math.atan2(this.matrix.d, this.matrix.c) * MathUtils.radDeg; - }; - Bone.prototype.getWorldScaleX = function () { - var m = this.matrix; - return Math.sqrt(m.a * m.a + m.c * m.c); - }; - Bone.prototype.getWorldScaleY = function () { - var m = this.matrix; - return Math.sqrt(m.b * m.b + m.d * m.d); - }; - /** Computes the individual applied transform values from the world transform. This can be useful to perform processing using - * the applied transform after the world transform has been modified directly (eg, by a constraint). - *

- * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. */ - Bone.prototype.updateAppliedTransform = function () { - this.appliedValid = true; - var parent = this.parent; - var m = this.matrix; - if (parent == null) { - this.ax = m.tx; - this.ay = m.ty; - this.arotation = Math.atan2(m.b, m.a) * MathUtils.radDeg; - this.ascaleX = Math.sqrt(m.a * m.a + m.b * m.b); - this.ascaleY = Math.sqrt(m.c * m.c + m.d * m.d); - this.ashearX = 0; - this.ashearY = Math.atan2(m.a * m.c + m.b * m.d, m.a * m.d - m.b * m.c) * MathUtils.radDeg; - return; - } - var pm = parent.matrix; - var pid = 1 / (pm.a * pm.d - pm.b * pm.c); - var dx = m.tx - pm.tx, dy = m.ty - pm.ty; - this.ax = (dx * pm.d * pid - dy * pm.c * pid); - this.ay = (dy * pm.a * pid - dx * pm.b * pid); - var ia = pid * pm.d; - var id = pid * pm.a; - var ib = pid * pm.c; - var ic = pid * pm.b; - var ra = ia * m.a - ib * m.b; - var rb = ia * m.c - ib * m.d; - var rc = id * m.b - ic * m.a; - var rd = id * m.d - ic * m.c; - this.ashearX = 0; - this.ascaleX = Math.sqrt(ra * ra + rc * rc); - if (this.ascaleX > 0.0001) { - var det = ra * rd - rb * rc; - this.ascaleY = det / this.ascaleX; - this.ashearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg; - this.arotation = Math.atan2(rc, ra) * MathUtils.radDeg; - } - else { - this.ascaleX = 0; - this.ascaleY = Math.sqrt(rb * rb + rd * rd); - this.ashearY = 0; - this.arotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg; - } - }; - Bone.prototype.worldToLocal = function (world) { - var m = this.matrix; - var a = m.a, b = m.c, c = m.b, d = m.d; - var invDet = 1 / (a * d - b * c); - var x = world.x - m.tx, y = world.y - m.ty; - world.x = (x * d * invDet - y * b * invDet); - world.y = (y * a * invDet - x * c * invDet); - return world; - }; - Bone.prototype.localToWorld = function (local) { - var m = this.matrix; - var x = local.x, y = local.y; - local.x = x * m.a + y * m.c + m.tx; - local.y = x * m.b + y * m.d + m.ty; - return local; - }; - Bone.prototype.worldToLocalRotation = function (worldRotation) { - var sin = MathUtils.sinDeg(worldRotation), cos = MathUtils.cosDeg(worldRotation); - var mat = this.matrix; - return Math.atan2(mat.a * sin - mat.b * cos, mat.d * cos - mat.c * sin) * MathUtils.radDeg; - }; - Bone.prototype.localToWorldRotation = function (localRotation) { - var sin = MathUtils.sinDeg(localRotation), cos = MathUtils.cosDeg(localRotation); - var mat = this.matrix; - return Math.atan2(cos * mat.b + sin * mat.d, cos * mat.a + sin * mat.c) * MathUtils.radDeg; - }; - Bone.prototype.rotateWorld = function (degrees) { - var mat = this.matrix; - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var cos = MathUtils.cosDeg(degrees), sin = MathUtils.sinDeg(degrees); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - this.appliedValid = false; - }; - return Bone; - }()); - - /** - * @public - */ - var BoneData$2 = /** @class */ (function () { - function BoneData(index, name, parent) { - this.x = 0; - this.y = 0; - this.rotation = 0; - this.scaleX = 1; - this.scaleY = 1; - this.shearX = 0; - this.shearY = 0; - this.transformMode = exports.TransformMode.Normal; - this.skinRequired = false; - this.color = new Color(); - if (index < 0) - throw new Error("index must be >= 0."); - if (name == null) - throw new Error("name cannot be null."); - this.index = index; - this.name = name; - this.parent = parent; - } - return BoneData; - }()); - - /** - * @public - */ - var ConstraintData$1 = /** @class */ (function () { - function ConstraintData(name, order, skinRequired) { - this.name = name; - this.order = order; - this.skinRequired = skinRequired; - } - return ConstraintData; - }()); - - /** - * @public - */ - var Event$2 = /** @class */ (function () { - function Event(time, data) { - if (data == null) - throw new Error("data cannot be null."); - this.time = time; - this.data = data; - } - return Event; - }()); - - /** - * @public - */ - var EventData$2 = /** @class */ (function () { - function EventData(name) { - this.name = name; - } - return EventData; - }()); - - /** - * @public - */ - var IkConstraint$2 = /** @class */ (function () { - function IkConstraint(data, skeleton) { - this.bendDirection = 0; - this.compress = false; - this.stretch = false; - this.mix = 1; - this.softness = 0; - this.active = false; - if (data == null) - throw new Error("data cannot be null."); - if (skeleton == null) - throw new Error("skeleton cannot be null."); - this.data = data; - this.mix = data.mix; - this.softness = data.softness; - this.bendDirection = data.bendDirection; - this.compress = data.compress; - this.stretch = data.stretch; - this.bones = new Array(); - for (var i = 0; i < data.bones.length; i++) - this.bones.push(skeleton.findBone(data.bones[i].name)); - this.target = skeleton.findBone(data.target.name); - } - IkConstraint.prototype.isActive = function () { - return this.active; - }; - IkConstraint.prototype.apply = function () { - this.update(); - }; - IkConstraint.prototype.update = function () { - var target = this.target; - var bones = this.bones; - switch (bones.length) { - case 1: - this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix); - break; - case 2: - this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.softness, this.mix); - break; - } - }; - /** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world - * coordinate system. */ - IkConstraint.prototype.apply1 = function (bone, targetX, targetY, compress, stretch, uniform, alpha) { - if (!bone.appliedValid) - bone.updateAppliedTransform(); - var p = bone.parent.matrix; - var pa = p.a, pb = p.c, pc = p.b, pd = p.d; - var rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0; - switch (bone.data.transformMode) { - case exports.TransformMode.OnlyTranslation: - tx = targetX - bone.worldX; - ty = targetY - bone.worldY; - break; - case exports.TransformMode.NoRotationOrReflection: - var s = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc); - var sa = pa / bone.skeleton.scaleX; - var sc = pc / bone.skeleton.scaleY; - pb = -sc * s * bone.skeleton.scaleX; - pd = sa * s * bone.skeleton.scaleY; - rotationIK += Math.atan2(sc, sa) * MathUtils.radDeg; - // Fall through - default: - var x = targetX - p.tx, y = targetY - p.ty; - var d = pa * pd - pb * pc; - tx = (x * pd - y * pb) / d - bone.ax; - ty = (y * pa - x * pc) / d - bone.ay; - } - rotationIK += Math.atan2(ty, tx) * MathUtils.radDeg; - if (bone.ascaleX < 0) - rotationIK += 180; - if (rotationIK > 180) - rotationIK -= 360; - else if (rotationIK < -180) - rotationIK += 360; - var sx = bone.ascaleX, sy = bone.ascaleY; - if (compress || stretch) { - switch (bone.data.transformMode) { - case exports.TransformMode.NoScale: - case exports.TransformMode.NoScaleOrReflection: - tx = targetX - bone.worldX; - ty = targetY - bone.worldY; - } - var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty); - if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001) { - var s = (dd / b - 1) * alpha + 1; - sx *= s; - if (uniform) - sy *= s; - } - } - bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY); - }; - /** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The - * target is specified in the world coordinate system. - * @param child A direct descendant of the parent bone. */ - IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, softness, alpha) { - if (alpha == 0) { - child.updateWorldTransform(); - return; - } - if (!parent.appliedValid) - parent.updateAppliedTransform(); - if (!child.appliedValid) - child.updateAppliedTransform(); - var px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX; - var pmat = parent.matrix; - var os1 = 0, os2 = 0, s2 = 0; - if (psx < 0) { - psx = -psx; - os1 = 180; - s2 = -1; - } - else { - os1 = 0; - s2 = 1; - } - if (psy < 0) { - psy = -psy; - s2 = -s2; - } - if (csx < 0) { - csx = -csx; - os2 = 180; - } - else - os2 = 0; - var cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = pmat.a, b = pmat.c, c = pmat.b, d = pmat.d; - var u = Math.abs(psx - psy) <= 0.0001; - if (!u) { - cy = 0; - cwx = a * cx + pmat.tx; - cwy = c * cx + pmat.ty; - } - else { - cy = child.ay; - cwx = a * cx + b * cy + pmat.tx; - cwy = c * cx + d * cy + pmat.ty; - } - var pp = parent.parent.matrix; - a = pp.a; - b = pp.c; - c = pp.b; - d = pp.d; - var id = 1 / (a * d - b * c), x = cwx - pp.tx, y = cwy - pp.ty; - var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; - var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2; - if (l1 < 0.0001) { - this.apply1(parent, targetX, targetY, false, stretch, false, alpha); - child.updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); - return; - } - x = targetX - pp.tx; - y = targetY - pp.ty; - var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; - var dd = tx * tx + ty * ty; - if (softness != 0) { - softness *= psx * (csx + 1) / 2; - var td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness; - if (sd > 0) { - var p = Math.min(1, sd / (softness * 2)) - 1; - p = (sd - softness * (1 - p * p)) / td; - tx -= p * tx; - ty -= p * ty; - dd = tx * tx + ty * ty; - } - } - outer: if (u) { - l2 *= psx; - var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2); - if (cos < -1) - cos = -1; - else if (cos > 1) { - cos = 1; - if (stretch) - sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1; - } - a2 = Math.acos(cos) * bendDir; - a = l1 + l2 * cos; - b = l2 * Math.sin(a2); - a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b); - } - else { - a = psx * l2; - b = psy * l2; - var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx); - c = bb * l1 * l1 + aa * dd - aa * bb; - var c1 = -2 * bb * l1, c2 = bb - aa; - d = c1 * c1 - 4 * c2 * c; - if (d >= 0) { - var q = Math.sqrt(d); - if (c1 < 0) - q = -q; - q = -(c1 + q) / 2; - var r0 = q / c2, r1 = c / q; - var r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; - if (r * r <= dd) { - y = Math.sqrt(dd - r * r) * bendDir; - a1 = ta - Math.atan2(y, r); - a2 = Math.atan2(y / psy, (r - l1) / psx); - break outer; - } - } - var minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; - var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; - c = -a * l1 / (aa - bb); - if (c >= -1 && c <= 1) { - c = Math.acos(c); - x = a * Math.cos(c) + l1; - y = b * Math.sin(c); - d = x * x + y * y; - if (d < minDist) { - minAngle = c; - minDist = d; - minX = x; - minY = y; - } - if (d > maxDist) { - maxAngle = c; - maxDist = d; - maxX = x; - maxY = y; - } - } - if (dd <= (minDist + maxDist) / 2) { - a1 = ta - Math.atan2(minY * bendDir, minX); - a2 = minAngle * bendDir; - } - else { - a1 = ta - Math.atan2(maxY * bendDir, maxX); - a2 = maxAngle * bendDir; - } - } - var os = Math.atan2(cy, cx) * s2; - var rotation = parent.arotation; - a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation; - if (a1 > 180) - a1 -= 360; - else if (a1 < -180) - a1 += 360; - parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0); - rotation = child.arotation; - a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; - if (a2 > 180) - a2 -= 360; - else if (a2 < -180) - a2 += 360; - child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); - }; - return IkConstraint; - }()); - - /** - * @public - */ - var IkConstraintData$2 = /** @class */ (function (_super) { - __extends$3(IkConstraintData, _super); - function IkConstraintData(name) { - var _this = _super.call(this, name, 0, false) || this; - _this.bones = new Array(); - _this.bendDirection = 1; - _this.compress = false; - _this.stretch = false; - _this.uniform = false; - _this.mix = 1; - _this.softness = 0; - return _this; - } - return IkConstraintData; - }(ConstraintData$1)); - - /** - * @public - */ - var PathConstraintData$2 = /** @class */ (function (_super) { - __extends$3(PathConstraintData, _super); - function PathConstraintData(name) { - var _this = _super.call(this, name, 0, false) || this; - _this.bones = new Array(); - return _this; - } - return PathConstraintData; - }(ConstraintData$1)); - /** - * @public - */ - var SpacingMode$2; - (function (SpacingMode) { - SpacingMode[SpacingMode["Length"] = 0] = "Length"; - SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed"; - SpacingMode[SpacingMode["Percent"] = 2] = "Percent"; - })(SpacingMode$2 || (SpacingMode$2 = {})); - - /** - * @public - */ - var PathConstraint$2 = /** @class */ (function () { - function PathConstraint(data, skeleton) { - this.position = 0; - this.spacing = 0; - this.rotateMix = 0; - this.translateMix = 0; - this.spaces = new Array(); - this.positions = new Array(); - this.world = new Array(); - this.curves = new Array(); - this.lengths = new Array(); - this.segments = new Array(); - this.active = false; - if (data == null) - throw new Error("data cannot be null."); - if (skeleton == null) - throw new Error("skeleton cannot be null."); - this.data = data; - this.bones = new Array(); - for (var i = 0, n = data.bones.length; i < n; i++) - this.bones.push(skeleton.findBone(data.bones[i].name)); - this.target = skeleton.findSlot(data.target.name); - this.position = data.position; - this.spacing = data.spacing; - this.rotateMix = data.rotateMix; - this.translateMix = data.translateMix; - } - PathConstraint.prototype.isActive = function () { - return this.active; - }; - PathConstraint.prototype.apply = function () { - this.update(); - }; - PathConstraint.prototype.update = function () { - var attachment = this.target.getAttachment(); - if (!(attachment instanceof PathAttachment$2)) - return; - var rotateMix = this.rotateMix, translateMix = this.translateMix; - var translate = translateMix > 0, rotate = rotateMix > 0; - if (!translate && !rotate) - return; - var data = this.data; - var spacingMode = data.spacingMode; - var lengthSpacing = spacingMode == SpacingMode$2.Length; - var rotateMode = data.rotateMode; - var tangents = rotateMode == exports.RotateMode.Tangent, scale = rotateMode == exports.RotateMode.ChainScale; - var boneCount = this.bones.length, spacesCount = tangents ? boneCount : boneCount + 1; - var bones = this.bones; - var spaces = Utils.setArraySize(this.spaces, spacesCount), lengths = null; - var spacing = this.spacing; - if (scale || lengthSpacing) { - if (scale) - lengths = Utils.setArraySize(this.lengths, boneCount); - for (var i = 0, n = spacesCount - 1; i < n;) { - var bone = bones[i]; - var setupLength = bone.data.length; - if (setupLength < PathConstraint.epsilon) { - if (scale) - lengths[i] = 0; - spaces[++i] = 0; - } - else { - var x = setupLength * bone.matrix.a, y = setupLength * bone.matrix.b; - var length_1 = Math.sqrt(x * x + y * y); - if (scale) - lengths[i] = length_1; - spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length_1 / setupLength; - } - } - } - else { - for (var i = 1; i < spacesCount; i++) - spaces[i] = spacing; - } - var positions = this.computeWorldPositions(attachment, spacesCount, tangents, data.positionMode == exports.PositionMode.Percent, spacingMode == SpacingMode$2.Percent); - var boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; - var tip = false; - if (offsetRotation == 0) - tip = rotateMode == exports.RotateMode.Chain; - else { - tip = false; - var p = this.target.bone.matrix; - offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.degRad : -MathUtils.degRad; - } - for (var i = 0, p = 3; i < boneCount; i++, p += 3) { - var bone = bones[i]; - var mat = bone.matrix; - mat.tx += (boneX - mat.tx) * translateMix; - mat.ty += (boneY - mat.ty) * translateMix; - var x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; - if (scale) { - var length_2 = lengths[i]; - if (length_2 != 0) { - var s = (Math.sqrt(dx * dx + dy * dy) / length_2 - 1) * rotateMix + 1; - mat.a *= s; - mat.b *= s; - } - } - boneX = x; - boneY = y; - if (rotate) { - var a = mat.a, b = mat.c, c = mat.b, d = mat.d, r = 0, cos = 0, sin = 0; - if (tangents) - r = positions[p - 1]; - else if (spaces[i + 1] == 0) - r = positions[p + 2]; - else - r = Math.atan2(dy, dx); - r -= Math.atan2(c, a); - if (tip) { - cos = Math.cos(r); - sin = Math.sin(r); - var length_3 = bone.data.length; - boneX += (length_3 * (cos * a - sin * c) - dx) * rotateMix; - boneY += (length_3 * (sin * a + cos * c) - dy) * rotateMix; - } - else { - r += offsetRotation; - } - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) // - r += MathUtils.PI2; - r *= rotateMix; - cos = Math.cos(r); - sin = Math.sin(r); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - } - bone.appliedValid = false; - } - }; - PathConstraint.prototype.computeWorldPositions = function (path, spacesCount, tangents, percentPosition, percentSpacing) { - var target = this.target; - var position = this.position; - var spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = null; - var closed = path.closed; - var verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE; - if (!path.constantSpeed) { - var lengths = path.lengths; - curveCount -= closed ? 1 : 2; - var pathLength_1 = lengths[curveCount]; - if (percentPosition) - position *= pathLength_1; - if (percentSpacing) { - for (var i = 0; i < spacesCount; i++) - spaces[i] *= pathLength_1; - } - world = Utils.setArraySize(this.world, 8); - for (var i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { - var space = spaces[i]; - position += space; - var p = position; - if (closed) { - p %= pathLength_1; - if (p < 0) - p += pathLength_1; - curve = 0; - } - else if (p < 0) { - if (prevCurve != PathConstraint.BEFORE) { - prevCurve = PathConstraint.BEFORE; - path.computeWorldVertices(target, 2, 4, world, 0, 2); - } - this.addBeforePosition(p, world, 0, out, o); - continue; - } - else if (p > pathLength_1) { - if (prevCurve != PathConstraint.AFTER) { - prevCurve = PathConstraint.AFTER; - path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); - } - this.addAfterPosition(p - pathLength_1, world, 0, out, o); - continue; - } - // Determine curve containing position. - for (;; curve++) { - var length_4 = lengths[curve]; - if (p > length_4) - continue; - if (curve == 0) - p /= length_4; - else { - var prev = lengths[curve - 1]; - p = (p - prev) / (length_4 - prev); - } - break; - } - if (curve != prevCurve) { - prevCurve = curve; - if (closed && curve == curveCount) { - path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); - path.computeWorldVertices(target, 0, 4, world, 4, 2); - } - else - path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); - } - this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0)); - } - return out; - } - // World vertices. - if (closed) { - verticesLength += 2; - world = Utils.setArraySize(this.world, verticesLength); - path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); - path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); - world[verticesLength - 2] = world[0]; - world[verticesLength - 1] = world[1]; - } - else { - curveCount--; - verticesLength -= 4; - world = Utils.setArraySize(this.world, verticesLength); - path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); - } - // Curve lengths. - var curves = Utils.setArraySize(this.curves, curveCount); - var pathLength = 0; - var x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; - var tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0; - for (var i = 0, w = 2; i < curveCount; i++, w += 6) { - cx1 = world[w]; - cy1 = world[w + 1]; - cx2 = world[w + 2]; - cy2 = world[w + 3]; - x2 = world[w + 4]; - y2 = world[w + 5]; - tmpx = (x1 - cx1 * 2 + cx2) * 0.1875; - tmpy = (y1 - cy1 * 2 + cy2) * 0.1875; - dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375; - dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375; - ddfx = tmpx * 2 + dddfx; - ddfy = tmpy * 2 + dddfy; - dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667; - dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - dfx += ddfx; - dfy += ddfy; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - dfx += ddfx + dddfx; - dfy += ddfy + dddfy; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - curves[i] = pathLength; - x1 = x2; - y1 = y2; - } - if (percentPosition) - position *= pathLength; - if (percentSpacing) { - for (var i = 0; i < spacesCount; i++) - spaces[i] *= pathLength; - } - var segments = this.segments; - var curveLength = 0; - for (var i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { - var space = spaces[i]; - position += space; - var p = position; - if (closed) { - p %= pathLength; - if (p < 0) - p += pathLength; - curve = 0; - } - else if (p < 0) { - this.addBeforePosition(p, world, 0, out, o); - continue; - } - else if (p > pathLength) { - this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o); - continue; - } - // Determine curve containing position. - for (;; curve++) { - var length_5 = curves[curve]; - if (p > length_5) - continue; - if (curve == 0) - p /= length_5; - else { - var prev = curves[curve - 1]; - p = (p - prev) / (length_5 - prev); - } - break; - } - // Curve segment lengths. - if (curve != prevCurve) { - prevCurve = curve; - var ii = curve * 6; - x1 = world[ii]; - y1 = world[ii + 1]; - cx1 = world[ii + 2]; - cy1 = world[ii + 3]; - cx2 = world[ii + 4]; - cy2 = world[ii + 5]; - x2 = world[ii + 6]; - y2 = world[ii + 7]; - tmpx = (x1 - cx1 * 2 + cx2) * 0.03; - tmpy = (y1 - cy1 * 2 + cy2) * 0.03; - dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006; - dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006; - ddfx = tmpx * 2 + dddfx; - ddfy = tmpy * 2 + dddfy; - dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667; - dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667; - curveLength = Math.sqrt(dfx * dfx + dfy * dfy); - segments[0] = curveLength; - for (ii = 1; ii < 8; ii++) { - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - curveLength += Math.sqrt(dfx * dfx + dfy * dfy); - segments[ii] = curveLength; - } - dfx += ddfx; - dfy += ddfy; - curveLength += Math.sqrt(dfx * dfx + dfy * dfy); - segments[8] = curveLength; - dfx += ddfx + dddfx; - dfy += ddfy + dddfy; - curveLength += Math.sqrt(dfx * dfx + dfy * dfy); - segments[9] = curveLength; - segment = 0; - } - // Weight by segment length. - p *= curveLength; - for (;; segment++) { - var length_6 = segments[segment]; - if (p > length_6) - continue; - if (segment == 0) - p /= length_6; - else { - var prev = segments[segment - 1]; - p = segment + (p - prev) / (length_6 - prev); - } - break; - } - this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0)); - } - return out; - }; - PathConstraint.prototype.addBeforePosition = function (p, temp, i, out, o) { - var x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); - out[o] = x1 + p * Math.cos(r); - out[o + 1] = y1 + p * Math.sin(r); - out[o + 2] = r; - }; - PathConstraint.prototype.addAfterPosition = function (p, temp, i, out, o) { - var x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); - out[o] = x1 + p * Math.cos(r); - out[o + 1] = y1 + p * Math.sin(r); - out[o + 2] = r; - }; - PathConstraint.prototype.addCurvePosition = function (p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) { - if (p == 0 || isNaN(p)) - p = 0.0001; - var tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; - var ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; - var x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; - out[o] = x; - out[o + 1] = y; - if (tangents) - out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); - }; - PathConstraint.NONE = -1; - PathConstraint.BEFORE = -2; - PathConstraint.AFTER = -3; - PathConstraint.epsilon = 0.00001; - return PathConstraint; - }()); - - /** - * @public - */ - var TransformConstraint$2 = /** @class */ (function () { - function TransformConstraint(data, skeleton) { - this.rotateMix = 0; - this.translateMix = 0; - this.scaleMix = 0; - this.shearMix = 0; - this.temp = new Vector2(); - this.active = false; - if (data == null) - throw new Error("data cannot be null."); - if (skeleton == null) - throw new Error("skeleton cannot be null."); - this.data = data; - this.rotateMix = data.rotateMix; - this.translateMix = data.translateMix; - this.scaleMix = data.scaleMix; - this.shearMix = data.shearMix; - this.bones = new Array(); - for (var i = 0; i < data.bones.length; i++) - this.bones.push(skeleton.findBone(data.bones[i].name)); - this.target = skeleton.findBone(data.target.name); - } - TransformConstraint.prototype.isActive = function () { - return this.active; - }; - TransformConstraint.prototype.apply = function () { - this.update(); - }; - TransformConstraint.prototype.update = function () { - if (this.data.local) { - if (this.data.relative) - this.applyRelativeLocal(); - else - this.applyAbsoluteLocal(); - } - else { - if (this.data.relative) - this.applyRelativeWorld(); - else - this.applyAbsoluteWorld(); - } - }; - TransformConstraint.prototype.applyAbsoluteWorld = function () { - var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; - var target = this.target; - var targetMat = target.matrix; - var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; - var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; - var offsetRotation = this.data.offsetRotation * degRadReflect; - var offsetShearY = this.data.offsetShearY * degRadReflect; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - var modified = false; - var mat = bone.matrix; - if (rotateMix != 0) { - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation; - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) - r += MathUtils.PI2; - r *= rotateMix; - var cos = Math.cos(r), sin = Math.sin(r); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - modified = true; - } - if (translateMix != 0) { - var temp = this.temp; - target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); - mat.tx += (temp.x - mat.tx) * translateMix; - mat.ty += (temp.y - mat.ty) * translateMix; - modified = true; - } - if (scaleMix > 0) { - var s = Math.sqrt(mat.a * mat.a + mat.b * mat.b); - var ts = Math.sqrt(ta * ta + tc * tc); - if (s > 0.00001) - s = (s + (ts - s + this.data.offsetScaleX) * scaleMix) / s; - mat.a *= s; - mat.b *= s; - s = Math.sqrt(mat.c * mat.c + mat.d * mat.d); - ts = Math.sqrt(tb * tb + td * td); - if (s > 0.00001) - s = (s + (ts - s + this.data.offsetScaleY) * scaleMix) / s; - mat.c *= s; - mat.d *= s; - modified = true; - } - if (shearMix > 0) { - var b = mat.c, d = mat.d; - var by = Math.atan2(d, b); - var r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(mat.b, mat.a)); - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) - r += MathUtils.PI2; - r = by + (r + offsetShearY) * shearMix; - var s = Math.sqrt(b * b + d * d); - mat.c = Math.cos(r) * s; - mat.d = Math.sin(r) * s; - modified = true; - } - if (modified) - bone.appliedValid = false; - } - }; - TransformConstraint.prototype.applyRelativeWorld = function () { - var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; - var target = this.target; - var targetMat = target.matrix; - var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; - var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; - var offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - var modified = false; - var mat = bone.matrix; - if (rotateMix != 0) { - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var r = Math.atan2(tc, ta) + offsetRotation; - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) - r += MathUtils.PI2; - r *= rotateMix; - var cos = Math.cos(r), sin = Math.sin(r); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - modified = true; - } - if (translateMix != 0) { - var temp = this.temp; - target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); - mat.tx += temp.x * translateMix; - mat.ty += temp.y * translateMix; - modified = true; - } - if (scaleMix > 0) { - var s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * scaleMix + 1; - mat.a *= s; - mat.b *= s; - s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1; - mat.c *= s; - mat.d *= s; - modified = true; - } - if (shearMix > 0) { - var r = Math.atan2(td, tb) - Math.atan2(tc, ta); - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) - r += MathUtils.PI2; - var b = mat.c, d = mat.d; - r = Math.atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * shearMix; - var s = Math.sqrt(b * b + d * d); - mat.c = Math.cos(r) * s; - mat.d = Math.sin(r) * s; - modified = true; - } - if (modified) - bone.appliedValid = false; - } - }; - TransformConstraint.prototype.applyAbsoluteLocal = function () { - var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; - var target = this.target; - if (!target.appliedValid) - target.updateAppliedTransform(); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (!bone.appliedValid) - bone.updateAppliedTransform(); - var rotation = bone.arotation; - if (rotateMix != 0) { - var r = target.arotation - rotation + this.data.offsetRotation; - r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; - rotation += r * rotateMix; - } - var x = bone.ax, y = bone.ay; - if (translateMix != 0) { - x += (target.ax - x + this.data.offsetX) * translateMix; - y += (target.ay - y + this.data.offsetY) * translateMix; - } - var scaleX = bone.ascaleX, scaleY = bone.ascaleY; - if (scaleMix > 0) { - if (scaleX > 0.00001) - scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * scaleMix) / scaleX; - if (scaleY > 0.00001) - scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * scaleMix) / scaleY; - } - var shearY = bone.ashearY; - if (shearMix > 0) { - var r = target.ashearY - shearY + this.data.offsetShearY; - r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; - bone.shearY += r * shearMix; - } - bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); - } - }; - TransformConstraint.prototype.applyRelativeLocal = function () { - var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; - var target = this.target; - if (!target.appliedValid) - target.updateAppliedTransform(); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (!bone.appliedValid) - bone.updateAppliedTransform(); - var rotation = bone.arotation; - if (rotateMix != 0) - rotation += (target.arotation + this.data.offsetRotation) * rotateMix; - var x = bone.ax, y = bone.ay; - if (translateMix != 0) { - x += (target.ax + this.data.offsetX) * translateMix; - y += (target.ay + this.data.offsetY) * translateMix; - } - var scaleX = bone.ascaleX, scaleY = bone.ascaleY; - if (scaleMix > 0) { - if (scaleX > 0.00001) - scaleX *= ((target.ascaleX - 1 + this.data.offsetScaleX) * scaleMix) + 1; - if (scaleY > 0.00001) - scaleY *= ((target.ascaleY - 1 + this.data.offsetScaleY) * scaleMix) + 1; - } - var shearY = bone.ashearY; - if (shearMix > 0) - shearY += (target.ashearY + this.data.offsetShearY) * shearMix; - bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); - } - }; - return TransformConstraint; - }()); - - /** - * @public - */ - var Skeleton$2 = /** @class */ (function () { - function Skeleton(data) { - this._updateCache = new Array(); - this.updateCacheReset = new Array(); - this.time = 0; - this.scaleX = 1; - this.scaleY = 1; - this.x = 0; - this.y = 0; - if (data == null) - throw new Error("data cannot be null."); - this.data = data; - this.bones = new Array(); - for (var i = 0; i < data.bones.length; i++) { - var boneData = data.bones[i]; - var bone = void 0; - if (boneData.parent == null) - bone = new Bone$2(boneData, this, null); - else { - var parent_1 = this.bones[boneData.parent.index]; - bone = new Bone$2(boneData, this, parent_1); - parent_1.children.push(bone); - } - this.bones.push(bone); - } - this.slots = new Array(); - this.drawOrder = new Array(); - for (var i = 0; i < data.slots.length; i++) { - var slotData = data.slots[i]; - var bone = this.bones[slotData.boneData.index]; - var slot = new Slot$2(slotData, bone); - this.slots.push(slot); - this.drawOrder.push(slot); - } - this.ikConstraints = new Array(); - for (var i = 0; i < data.ikConstraints.length; i++) { - var ikConstraintData = data.ikConstraints[i]; - this.ikConstraints.push(new IkConstraint$2(ikConstraintData, this)); - } - this.transformConstraints = new Array(); - for (var i = 0; i < data.transformConstraints.length; i++) { - var transformConstraintData = data.transformConstraints[i]; - this.transformConstraints.push(new TransformConstraint$2(transformConstraintData, this)); - } - this.pathConstraints = new Array(); - for (var i = 0; i < data.pathConstraints.length; i++) { - var pathConstraintData = data.pathConstraints[i]; - this.pathConstraints.push(new PathConstraint$2(pathConstraintData, this)); - } - this.color = new Color(1, 1, 1, 1); - this.updateCache(); - } - Skeleton.prototype.updateCache = function () { - var updateCache = this._updateCache; - updateCache.length = 0; - this.updateCacheReset.length = 0; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - bone.sorted = bone.data.skinRequired; - bone.active = !bone.sorted; - } - if (this.skin != null) { - var skinBones = this.skin.bones; - for (var i = 0, n = this.skin.bones.length; i < n; i++) { - var bone = this.bones[skinBones[i].index]; - do { - bone.sorted = false; - bone.active = true; - bone = bone.parent; - } while (bone != null); - } - } - // IK first, lowest hierarchy depth first. - var ikConstraints = this.ikConstraints; - var transformConstraints = this.transformConstraints; - var pathConstraints = this.pathConstraints; - var ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length; - var constraintCount = ikCount + transformCount + pathCount; - outer: for (var i = 0; i < constraintCount; i++) { - for (var ii = 0; ii < ikCount; ii++) { - var constraint = ikConstraints[ii]; - if (constraint.data.order == i) { - this.sortIkConstraint(constraint); - continue outer; - } - } - for (var ii = 0; ii < transformCount; ii++) { - var constraint = transformConstraints[ii]; - if (constraint.data.order == i) { - this.sortTransformConstraint(constraint); - continue outer; - } - } - for (var ii = 0; ii < pathCount; ii++) { - var constraint = pathConstraints[ii]; - if (constraint.data.order == i) { - this.sortPathConstraint(constraint); - continue outer; - } - } - } - for (var i = 0, n = bones.length; i < n; i++) - this.sortBone(bones[i]); - }; - Skeleton.prototype.sortIkConstraint = function (constraint) { - constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true))); - if (!constraint.active) - return; - var target = constraint.target; - this.sortBone(target); - var constrained = constraint.bones; - var parent = constrained[0]; - this.sortBone(parent); - if (constrained.length > 1) { - var child = constrained[constrained.length - 1]; - if (!(this._updateCache.indexOf(child) > -1)) - this.updateCacheReset.push(child); - } - this._updateCache.push(constraint); - this.sortReset(parent.children); - constrained[constrained.length - 1].sorted = true; - }; - Skeleton.prototype.sortPathConstraint = function (constraint) { - constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true))); - if (!constraint.active) - return; - var slot = constraint.target; - var slotIndex = slot.data.index; - var slotBone = slot.bone; - if (this.skin != null) - this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone); - if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin) - this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone); - for (var i = 0, n = this.data.skins.length; i < n; i++) - this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone); - var attachment = slot.getAttachment(); - if (attachment instanceof PathAttachment$2) - this.sortPathConstraintAttachmentWith(attachment, slotBone); - var constrained = constraint.bones; - var boneCount = constrained.length; - for (var i = 0; i < boneCount; i++) - this.sortBone(constrained[i]); - this._updateCache.push(constraint); - for (var i = 0; i < boneCount; i++) - this.sortReset(constrained[i].children); - for (var i = 0; i < boneCount; i++) - constrained[i].sorted = true; - }; - Skeleton.prototype.sortTransformConstraint = function (constraint) { - constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true))); - if (!constraint.active) - return; - this.sortBone(constraint.target); - var constrained = constraint.bones; - var boneCount = constrained.length; - if (constraint.data.local) { - for (var i = 0; i < boneCount; i++) { - var child = constrained[i]; - this.sortBone(child.parent); - if (!(this._updateCache.indexOf(child) > -1)) - this.updateCacheReset.push(child); - } - } - else { - for (var i = 0; i < boneCount; i++) { - this.sortBone(constrained[i]); - } - } - this._updateCache.push(constraint); - for (var ii = 0; ii < boneCount; ii++) - this.sortReset(constrained[ii].children); - for (var ii = 0; ii < boneCount; ii++) - constrained[ii].sorted = true; - }; - Skeleton.prototype.sortPathConstraintAttachment = function (skin, slotIndex, slotBone) { - var attachments = skin.attachments[slotIndex]; - if (!attachments) - return; - for (var key in attachments) { - this.sortPathConstraintAttachmentWith(attachments[key], slotBone); - } - }; - Skeleton.prototype.sortPathConstraintAttachmentWith = function (attachment, slotBone) { - if (!(attachment instanceof PathAttachment$2)) - return; - var pathBones = attachment.bones; - if (pathBones == null) - this.sortBone(slotBone); - else { - var bones = this.bones; - var i = 0; - while (i < pathBones.length) { - var boneCount = pathBones[i++]; - for (var n = i + boneCount; i < n; i++) { - var boneIndex = pathBones[i]; - this.sortBone(bones[boneIndex]); - } - } - } - }; - Skeleton.prototype.sortBone = function (bone) { - if (bone.sorted) - return; - var parent = bone.parent; - if (parent != null) - this.sortBone(parent); - bone.sorted = true; - this._updateCache.push(bone); - }; - Skeleton.prototype.sortReset = function (bones) { - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (!bone.active) - continue; - if (bone.sorted) - this.sortReset(bone.children); - bone.sorted = false; - } - }; - /** Updates the world transform for each bone and applies constraints. */ - Skeleton.prototype.updateWorldTransform = function () { - var updateCacheReset = this.updateCacheReset; - for (var i = 0, n = updateCacheReset.length; i < n; i++) { - var bone = updateCacheReset[i]; - bone.ax = bone.x; - bone.ay = bone.y; - bone.arotation = bone.rotation; - bone.ascaleX = bone.scaleX; - bone.ascaleY = bone.scaleY; - bone.ashearX = bone.shearX; - bone.ashearY = bone.shearY; - bone.appliedValid = true; - } - var updateCache = this._updateCache; - for (var i = 0, n = updateCache.length; i < n; i++) - updateCache[i].update(); - }; - /** Sets the bones, constraints, and slots to their setup pose values. */ - Skeleton.prototype.setToSetupPose = function () { - this.setBonesToSetupPose(); - this.setSlotsToSetupPose(); - }; - /** Sets the bones and constraints to their setup pose values. */ - Skeleton.prototype.setBonesToSetupPose = function () { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - bones[i].setToSetupPose(); - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) { - var constraint = ikConstraints[i]; - constraint.mix = constraint.data.mix; - constraint.softness = constraint.data.softness; - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - } - var transformConstraints = this.transformConstraints; - for (var i = 0, n = transformConstraints.length; i < n; i++) { - var constraint = transformConstraints[i]; - var data = constraint.data; - constraint.rotateMix = data.rotateMix; - constraint.translateMix = data.translateMix; - constraint.scaleMix = data.scaleMix; - constraint.shearMix = data.shearMix; - } - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) { - var constraint = pathConstraints[i]; - var data = constraint.data; - constraint.position = data.position; - constraint.spacing = data.spacing; - constraint.rotateMix = data.rotateMix; - constraint.translateMix = data.translateMix; - } - }; - Skeleton.prototype.setSlotsToSetupPose = function () { - var slots = this.slots; - Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length); - for (var i = 0, n = slots.length; i < n; i++) - slots[i].setToSetupPose(); - }; - /** @return May return null. */ - Skeleton.prototype.getRootBone = function () { - if (this.bones.length == 0) - return null; - return this.bones[0]; - }; - /** @return May be null. */ - Skeleton.prototype.findBone = function (boneName) { - if (boneName == null) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (bone.data.name == boneName) - return bone; - } - return null; - }; - /** @return -1 if the bone was not found. */ - Skeleton.prototype.findBoneIndex = function (boneName) { - if (boneName == null) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].data.name == boneName) - return i; - return -1; - }; - /** @return May be null. */ - Skeleton.prototype.findSlot = function (slotName) { - if (slotName == null) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.data.name == slotName) - return slot; - } - return null; - }; - /** @return -1 if the bone was not found. */ - Skeleton.prototype.findSlotIndex = function (slotName) { - if (slotName == null) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].data.name == slotName) - return i; - return -1; - }; - /** Sets a skin by name. - * @see #setSkin(Skin) */ - Skeleton.prototype.setSkinByName = function (skinName) { - var skin = this.data.findSkin(skinName); - if (skin == null) - throw new Error("Skin not found: " + skinName); - this.setSkin(skin); - }; - /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}. - * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no - * old skin, each slot's setup mode attachment is attached from the new skin. - * @param newSkin May be null. */ - Skeleton.prototype.setSkin = function (newSkin) { - if (newSkin == this.skin) - return; - if (newSkin != null) { - if (this.skin != null) - newSkin.attachAll(this, this.skin); - else { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - var name_1 = slot.data.attachmentName; - if (name_1 != null) { - var attachment = newSkin.getAttachment(i, name_1); - if (attachment != null) - slot.setAttachment(attachment); - } - } - } - } - this.skin = newSkin; - this.updateCache(); - }; - /** @return May be null. */ - Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) { - return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName); - }; - /** @return May be null. */ - Skeleton.prototype.getAttachment = function (slotIndex, attachmentName) { - if (attachmentName == null) - throw new Error("attachmentName cannot be null."); - if (this.skin != null) { - var attachment = this.skin.getAttachment(slotIndex, attachmentName); - if (attachment != null) - return attachment; - } - if (this.data.defaultSkin != null) - return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); - return null; - }; - /** @param attachmentName May be null. */ - Skeleton.prototype.setAttachment = function (slotName, attachmentName) { - if (slotName == null) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.data.name == slotName) { - var attachment = null; - if (attachmentName != null) { - attachment = this.getAttachment(i, attachmentName); - if (attachment == null) - throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName); - } - slot.setAttachment(attachment); - return; - } - } - throw new Error("Slot not found: " + slotName); - }; - /** @return May be null. */ - Skeleton.prototype.findIkConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) { - var ikConstraint = ikConstraints[i]; - if (ikConstraint.data.name == constraintName) - return ikConstraint; - } - return null; - }; - /** @return May be null. */ - Skeleton.prototype.findTransformConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var transformConstraints = this.transformConstraints; - for (var i = 0, n = transformConstraints.length; i < n; i++) { - var constraint = transformConstraints[i]; - if (constraint.data.name == constraintName) - return constraint; - } - return null; - }; - /** @return May be null. */ - Skeleton.prototype.findPathConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) { - var constraint = pathConstraints[i]; - if (constraint.data.name == constraintName) - return constraint; - } - return null; - }; - /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. - * @param offset The distance from the skeleton origin to the bottom left corner of the AABB. - * @param size The width and height of the AABB. - * @param temp Working memory */ - Skeleton.prototype.getBounds = function (offset, size, temp) { - if (temp === void 0) { temp = new Array(2); } - if (offset == null) - throw new Error("offset cannot be null."); - if (size == null) - throw new Error("size cannot be null."); - var drawOrder = this.drawOrder; - var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; - for (var i = 0, n = drawOrder.length; i < n; i++) { - var slot = drawOrder[i]; - if (!slot.bone.active) - continue; - var verticesLength = 0; - var vertices = null; - var attachment = slot.getAttachment(); - if (attachment instanceof RegionAttachment$2) { - verticesLength = 8; - vertices = Utils.setArraySize(temp, verticesLength, 0); - attachment.computeWorldVertices(slot.bone, vertices, 0, 2); - } - else if (attachment instanceof MeshAttachment$2) { - var mesh = attachment; - verticesLength = mesh.worldVerticesLength; - vertices = Utils.setArraySize(temp, verticesLength, 0); - mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2); - } - if (vertices != null) { - for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) { - var x = vertices[ii], y = vertices[ii + 1]; - minX = Math.min(minX, x); - minY = Math.min(minY, y); - maxX = Math.max(maxX, x); - maxY = Math.max(maxY, y); - } - } - } - offset.set(minX, minY); - size.set(maxX - minX, maxY - minY); - }; - Skeleton.prototype.update = function (delta) { - this.time += delta; - }; - Object.defineProperty(Skeleton.prototype, "flipX", { - get: function () { - return this.scaleX == -1; - }, - set: function (value) { - if (!Skeleton.deprecatedWarning1) { - Skeleton.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); - } - this.scaleX = value ? 1.0 : -1.0; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Skeleton.prototype, "flipY", { - get: function () { - return this.scaleY == -1; - }, - set: function (value) { - if (!Skeleton.deprecatedWarning1) { - Skeleton.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); - } - this.scaleY = value ? 1.0 : -1.0; - }, - enumerable: false, - configurable: true - }); - Skeleton.deprecatedWarning1 = false; - return Skeleton; - }()); - - /** - * @public - */ - var SkeletonData$2 = /** @class */ (function () { - function SkeletonData() { - this.bones = new Array(); // Ordered parents first. - this.slots = new Array(); // Setup pose draw order. - this.skins = new Array(); - this.events = new Array(); - this.animations = new Array(); - this.ikConstraints = new Array(); - this.transformConstraints = new Array(); - this.pathConstraints = new Array(); - // Nonessential - this.fps = 0; - } - SkeletonData.prototype.findBone = function (boneName) { - if (boneName == null) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (bone.name == boneName) - return bone; - } - return null; - }; - SkeletonData.prototype.findBoneIndex = function (boneName) { - if (boneName == null) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].name == boneName) - return i; - return -1; - }; - SkeletonData.prototype.findSlot = function (slotName) { - if (slotName == null) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.name == slotName) - return slot; - } - return null; - }; - SkeletonData.prototype.findSlotIndex = function (slotName) { - if (slotName == null) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].name == slotName) - return i; - return -1; - }; - SkeletonData.prototype.findSkin = function (skinName) { - if (skinName == null) - throw new Error("skinName cannot be null."); - var skins = this.skins; - for (var i = 0, n = skins.length; i < n; i++) { - var skin = skins[i]; - if (skin.name == skinName) - return skin; - } - return null; - }; - SkeletonData.prototype.findEvent = function (eventDataName) { - if (eventDataName == null) - throw new Error("eventDataName cannot be null."); - var events = this.events; - for (var i = 0, n = events.length; i < n; i++) { - var event_1 = events[i]; - if (event_1.name == eventDataName) - return event_1; - } - return null; - }; - SkeletonData.prototype.findAnimation = function (animationName) { - if (animationName == null) - throw new Error("animationName cannot be null."); - var animations = this.animations; - for (var i = 0, n = animations.length; i < n; i++) { - var animation = animations[i]; - if (animation.name == animationName) - return animation; - } - return null; - }; - SkeletonData.prototype.findIkConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) { - var constraint = ikConstraints[i]; - if (constraint.name == constraintName) - return constraint; - } - return null; - }; - SkeletonData.prototype.findTransformConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var transformConstraints = this.transformConstraints; - for (var i = 0, n = transformConstraints.length; i < n; i++) { - var constraint = transformConstraints[i]; - if (constraint.name == constraintName) - return constraint; - } - return null; - }; - SkeletonData.prototype.findPathConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) { - var constraint = pathConstraints[i]; - if (constraint.name == constraintName) - return constraint; - } - return null; - }; - SkeletonData.prototype.findPathConstraintIndex = function (pathConstraintName) { - if (pathConstraintName == null) - throw new Error("pathConstraintName cannot be null."); - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) - if (pathConstraints[i].name == pathConstraintName) - return i; - return -1; - }; - return SkeletonData; - }()); - - /** - * @public - */ - var SlotData$2 = /** @class */ (function () { - function SlotData(index, name, boneData) { - this.color = new Color(1, 1, 1, 1); - if (index < 0) - throw new Error("index must be >= 0."); - if (name == null) - throw new Error("name cannot be null."); - if (boneData == null) - throw new Error("boneData cannot be null."); - this.index = index; - this.name = name; - this.boneData = boneData; - } - return SlotData; - }()); - - /** - * @public - */ - var TransformConstraintData$2 = /** @class */ (function (_super) { - __extends$3(TransformConstraintData, _super); - function TransformConstraintData(name) { - var _this = _super.call(this, name, 0, false) || this; - _this.bones = new Array(); - _this.rotateMix = 0; - _this.translateMix = 0; - _this.scaleMix = 0; - _this.shearMix = 0; - _this.offsetRotation = 0; - _this.offsetX = 0; - _this.offsetY = 0; - _this.offsetScaleX = 0; - _this.offsetScaleY = 0; - _this.offsetShearY = 0; - _this.relative = false; - _this.local = false; - return _this; - } - return TransformConstraintData; - }(ConstraintData$1)); - - /** - * @public - */ - var SkinEntry$1 = /** @class */ (function () { - function SkinEntry(slotIndex, name, attachment) { - this.slotIndex = slotIndex; - this.name = name; - this.attachment = attachment; - } - return SkinEntry; - }()); - /** - * @public - */ - var Skin$2 = /** @class */ (function () { - function Skin(name) { - this.attachments = new Array(); - this.bones = Array(); - this.constraints = new Array(); - if (name == null) - throw new Error("name cannot be null."); - this.name = name; - } - Skin.prototype.setAttachment = function (slotIndex, name, attachment) { - if (attachment == null) - throw new Error("attachment cannot be null."); - var attachments = this.attachments; - if (slotIndex >= attachments.length) - attachments.length = slotIndex + 1; - if (!attachments[slotIndex]) - attachments[slotIndex] = {}; - attachments[slotIndex][name] = attachment; - }; - Skin.prototype.addSkin = function (skin) { - for (var i = 0; i < skin.bones.length; i++) { - var bone = skin.bones[i]; - var contained = false; - for (var j = 0; j < this.bones.length; j++) { - if (this.bones[j] == bone) { - contained = true; - break; - } - } - if (!contained) - this.bones.push(bone); - } - for (var i = 0; i < skin.constraints.length; i++) { - var constraint = skin.constraints[i]; - var contained = false; - for (var j = 0; j < this.constraints.length; j++) { - if (this.constraints[j] == constraint) { - contained = true; - break; - } - } - if (!contained) - this.constraints.push(constraint); - } - var attachments = skin.getAttachments(); - for (var i = 0; i < attachments.length; i++) { - var attachment = attachments[i]; - this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); - } - }; - Skin.prototype.copySkin = function (skin) { - for (var i = 0; i < skin.bones.length; i++) { - var bone = skin.bones[i]; - var contained = false; - for (var j = 0; j < this.bones.length; j++) { - if (this.bones[j] == bone) { - contained = true; - break; - } - } - if (!contained) - this.bones.push(bone); - } - for (var i = 0; i < skin.constraints.length; i++) { - var constraint = skin.constraints[i]; - var contained = false; - for (var j = 0; j < this.constraints.length; j++) { - if (this.constraints[j] == constraint) { - contained = true; - break; - } - } - if (!contained) - this.constraints.push(constraint); - } - var attachments = skin.getAttachments(); - for (var i = 0; i < attachments.length; i++) { - var attachment = attachments[i]; - if (attachment.attachment == null) - continue; - if (attachment.attachment instanceof MeshAttachment$2) { - attachment.attachment = attachment.attachment.newLinkedMesh(); - this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); - } - else { - attachment.attachment = attachment.attachment.copy(); - this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); - } - } - }; - /** @return May be null. */ - Skin.prototype.getAttachment = function (slotIndex, name) { - var dictionary = this.attachments[slotIndex]; - return dictionary ? dictionary[name] : null; - }; - Skin.prototype.removeAttachment = function (slotIndex, name) { - var dictionary = this.attachments[slotIndex]; - if (dictionary) - dictionary[name] = null; - }; - Skin.prototype.getAttachments = function () { - var entries = new Array(); - for (var i = 0; i < this.attachments.length; i++) { - var slotAttachments = this.attachments[i]; - if (slotAttachments) { - for (var name_1 in slotAttachments) { - var attachment = slotAttachments[name_1]; - if (attachment) - entries.push(new SkinEntry$1(i, name_1, attachment)); - } - } - } - return entries; - }; - Skin.prototype.getAttachmentsForSlot = function (slotIndex, attachments) { - var slotAttachments = this.attachments[slotIndex]; - if (slotAttachments) { - for (var name_2 in slotAttachments) { - var attachment = slotAttachments[name_2]; - if (attachment) - attachments.push(new SkinEntry$1(slotIndex, name_2, attachment)); - } - } - }; - Skin.prototype.clear = function () { - this.attachments.length = 0; - this.bones.length = 0; - this.constraints.length = 0; - }; - /** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */ - Skin.prototype.attachAll = function (skeleton, oldSkin) { - var slotIndex = 0; - for (var i = 0; i < skeleton.slots.length; i++) { - var slot = skeleton.slots[i]; - var slotAttachment = slot.getAttachment(); - if (slotAttachment && slotIndex < oldSkin.attachments.length) { - var dictionary = oldSkin.attachments[slotIndex]; - for (var key in dictionary) { - var skinAttachment = dictionary[key]; - if (slotAttachment == skinAttachment) { - var attachment = this.getAttachment(slotIndex, key); - if (attachment != null) - slot.setAttachment(attachment); - break; - } - } - } - slotIndex++; - } - }; - return Skin; - }()); - - /** - * @public - */ - var SkeletonBinary$1 = /** @class */ (function () { - function SkeletonBinary(attachmentLoader) { - this.scale = 1; - this.linkedMeshes = new Array(); - this.attachmentLoader = attachmentLoader; - } - SkeletonBinary.prototype.readSkeletonData = function (binary) { - var scale = this.scale; - var skeletonData = new SkeletonData$2(); - skeletonData.name = ""; // BOZO - var input = new BinaryInput(binary); - skeletonData.hash = input.readString(); - skeletonData.version = input.readString(); - if (skeletonData.version === '3.8.75') { - var error = "Unsupported skeleton data, 3.8.75 is deprecated, please export with a newer version of Spine."; - console.error(error); - } - skeletonData.x = input.readFloat(); - skeletonData.y = input.readFloat(); - skeletonData.width = input.readFloat(); - skeletonData.height = input.readFloat(); - var nonessential = input.readBoolean(); - if (nonessential) { - skeletonData.fps = input.readFloat(); - skeletonData.imagesPath = input.readString(); - skeletonData.audioPath = input.readString(); - } - var n = 0; - // Strings. - n = input.readInt(true); - for (var i = 0; i < n; i++) - input.strings.push(input.readString()); - // Bones. - n = input.readInt(true); - for (var i = 0; i < n; i++) { - var name_1 = input.readString(); - var parent_1 = i == 0 ? null : skeletonData.bones[input.readInt(true)]; - var data = new BoneData$2(i, name_1, parent_1); - data.rotation = input.readFloat(); - data.x = input.readFloat() * scale; - data.y = input.readFloat() * scale; - data.scaleX = input.readFloat(); - data.scaleY = input.readFloat(); - data.shearX = input.readFloat(); - data.shearY = input.readFloat(); - data.length = input.readFloat() * scale; - data.transformMode = SkeletonBinary.TransformModeValues[input.readInt(true)]; - data.skinRequired = input.readBoolean(); - if (nonessential) - Color.rgba8888ToColor(data.color, input.readInt32()); - skeletonData.bones.push(data); - } - // Slots. - n = input.readInt(true); - for (var i = 0; i < n; i++) { - var slotName = input.readString(); - var boneData = skeletonData.bones[input.readInt(true)]; - var data = new SlotData$2(i, slotName, boneData); - Color.rgba8888ToColor(data.color, input.readInt32()); - var darkColor = input.readInt32(); - if (darkColor != -1) - Color.rgb888ToColor(data.darkColor = new Color(), darkColor); - data.attachmentName = input.readStringRef(); - data.blendMode = SkeletonBinary.BlendModeValues[input.readInt(true)]; - skeletonData.slots.push(data); - } - // IK constraints. - n = input.readInt(true); - for (var i = 0, nn = void 0; i < n; i++) { - var data = new IkConstraintData$2(input.readString()); - data.order = input.readInt(true); - data.skinRequired = input.readBoolean(); - nn = input.readInt(true); - for (var ii = 0; ii < nn; ii++) - data.bones.push(skeletonData.bones[input.readInt(true)]); - data.target = skeletonData.bones[input.readInt(true)]; - data.mix = input.readFloat(); - data.softness = input.readFloat() * scale; - data.bendDirection = input.readByte(); - data.compress = input.readBoolean(); - data.stretch = input.readBoolean(); - data.uniform = input.readBoolean(); - skeletonData.ikConstraints.push(data); - } - // Transform constraints. - n = input.readInt(true); - for (var i = 0, nn = void 0; i < n; i++) { - var data = new TransformConstraintData$2(input.readString()); - data.order = input.readInt(true); - data.skinRequired = input.readBoolean(); - nn = input.readInt(true); - for (var ii = 0; ii < nn; ii++) - data.bones.push(skeletonData.bones[input.readInt(true)]); - data.target = skeletonData.bones[input.readInt(true)]; - data.local = input.readBoolean(); - data.relative = input.readBoolean(); - data.offsetRotation = input.readFloat(); - data.offsetX = input.readFloat() * scale; - data.offsetY = input.readFloat() * scale; - data.offsetScaleX = input.readFloat(); - data.offsetScaleY = input.readFloat(); - data.offsetShearY = input.readFloat(); - data.rotateMix = input.readFloat(); - data.translateMix = input.readFloat(); - data.scaleMix = input.readFloat(); - data.shearMix = input.readFloat(); - skeletonData.transformConstraints.push(data); - } - // Path constraints. - n = input.readInt(true); - for (var i = 0, nn = void 0; i < n; i++) { - var data = new PathConstraintData$2(input.readString()); - data.order = input.readInt(true); - data.skinRequired = input.readBoolean(); - nn = input.readInt(true); - for (var ii = 0; ii < nn; ii++) - data.bones.push(skeletonData.bones[input.readInt(true)]); - data.target = skeletonData.slots[input.readInt(true)]; - data.positionMode = SkeletonBinary.PositionModeValues[input.readInt(true)]; - data.spacingMode = SkeletonBinary.SpacingModeValues[input.readInt(true)]; - data.rotateMode = SkeletonBinary.RotateModeValues[input.readInt(true)]; - data.offsetRotation = input.readFloat(); - data.position = input.readFloat(); - if (data.positionMode == exports.PositionMode.Fixed) - data.position *= scale; - data.spacing = input.readFloat(); - if (data.spacingMode == SpacingMode$2.Length || data.spacingMode == SpacingMode$2.Fixed) - data.spacing *= scale; - data.rotateMix = input.readFloat(); - data.translateMix = input.readFloat(); - skeletonData.pathConstraints.push(data); - } - // Default skin. - var defaultSkin = this.readSkin(input, skeletonData, true, nonessential); - if (defaultSkin != null) { - skeletonData.defaultSkin = defaultSkin; - skeletonData.skins.push(defaultSkin); - } - // Skins. - { - var i = skeletonData.skins.length; - Utils.setArraySize(skeletonData.skins, n = i + input.readInt(true)); - for (; i < n; i++) - skeletonData.skins[i] = this.readSkin(input, skeletonData, false, nonessential); - } - // Linked meshes. - n = this.linkedMeshes.length; - for (var i = 0; i < n; i++) { - var linkedMesh = this.linkedMeshes[i]; - var skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); - if (skin == null) - throw new Error("Skin not found: " + linkedMesh.skin); - var parent_2 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); - if (parent_2 == null) - throw new Error("Parent mesh not found: " + linkedMesh.parent); - linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent_2 : linkedMesh.mesh; - linkedMesh.mesh.setParentMesh(parent_2); - // linkedMesh.mesh.updateUVs(); - } - this.linkedMeshes.length = 0; - // Events. - n = input.readInt(true); - for (var i = 0; i < n; i++) { - var data = new EventData$2(input.readStringRef()); - data.intValue = input.readInt(false); - data.floatValue = input.readFloat(); - data.stringValue = input.readString(); - data.audioPath = input.readString(); - if (data.audioPath != null) { - data.volume = input.readFloat(); - data.balance = input.readFloat(); - } - skeletonData.events.push(data); - } - // Animations. - n = input.readInt(true); - for (var i = 0; i < n; i++) - skeletonData.animations.push(this.readAnimation(input, input.readString(), skeletonData)); - return skeletonData; - }; - SkeletonBinary.prototype.readSkin = function (input, skeletonData, defaultSkin, nonessential) { - var skin = null; - var slotCount = 0; - if (defaultSkin) { - slotCount = input.readInt(true); - if (slotCount == 0) - return null; - skin = new Skin$2("default"); - } - else { - skin = new Skin$2(input.readStringRef()); - skin.bones.length = input.readInt(true); - for (var i = 0, n = skin.bones.length; i < n; i++) - skin.bones[i] = skeletonData.bones[input.readInt(true)]; - for (var i = 0, n = input.readInt(true); i < n; i++) - skin.constraints.push(skeletonData.ikConstraints[input.readInt(true)]); - for (var i = 0, n = input.readInt(true); i < n; i++) - skin.constraints.push(skeletonData.transformConstraints[input.readInt(true)]); - for (var i = 0, n = input.readInt(true); i < n; i++) - skin.constraints.push(skeletonData.pathConstraints[input.readInt(true)]); - slotCount = input.readInt(true); - } - for (var i = 0; i < slotCount; i++) { - var slotIndex = input.readInt(true); - for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { - var name_2 = input.readStringRef(); - var attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name_2, nonessential); - if (attachment != null) - skin.setAttachment(slotIndex, name_2, attachment); - } - } - return skin; - }; - SkeletonBinary.prototype.readAttachment = function (input, skeletonData, skin, slotIndex, attachmentName, nonessential) { - var scale = this.scale; - var name = input.readStringRef(); - if (name == null) - name = attachmentName; - var typeIndex = input.readByte(); - var type = SkeletonBinary.AttachmentTypeValues[typeIndex]; - switch (type) { - case exports.AttachmentType.Region: { - var path = input.readStringRef(); - var rotation = input.readFloat(); - var x = input.readFloat(); - var y = input.readFloat(); - var scaleX = input.readFloat(); - var scaleY = input.readFloat(); - var width = input.readFloat(); - var height = input.readFloat(); - var color = input.readInt32(); - if (path == null) - path = name; - var region = this.attachmentLoader.newRegionAttachment(skin, name, path); - if (region == null) - return null; - region.path = path; - region.x = x * scale; - region.y = y * scale; - region.scaleX = scaleX; - region.scaleY = scaleY; - region.rotation = rotation; - region.width = width * scale; - region.height = height * scale; - Color.rgba8888ToColor(region.color, color); - // region.updateOffset(); - return region; - } - case exports.AttachmentType.BoundingBox: { - var vertexCount = input.readInt(true); - var vertices = this.readVertices(input, vertexCount); - var color = nonessential ? input.readInt32() : 0; - var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); - if (box == null) - return null; - box.worldVerticesLength = vertexCount << 1; - box.vertices = vertices.vertices; - box.bones = vertices.bones; - if (nonessential) - Color.rgba8888ToColor(box.color, color); - return box; - } - case exports.AttachmentType.Mesh: { - var path = input.readStringRef(); - var color = input.readInt32(); - var vertexCount = input.readInt(true); - var uvs = this.readFloatArray(input, vertexCount << 1, 1); - var triangles = this.readShortArray(input); - var vertices = this.readVertices(input, vertexCount); - var hullLength = input.readInt(true); - var edges = null; - var width = 0, height = 0; - if (nonessential) { - edges = this.readShortArray(input); - width = input.readFloat(); - height = input.readFloat(); - } - if (path == null) - path = name; - var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); - if (mesh == null) - return null; - mesh.path = path; - Color.rgba8888ToColor(mesh.color, color); - mesh.bones = vertices.bones; - mesh.vertices = vertices.vertices; - mesh.worldVerticesLength = vertexCount << 1; - mesh.triangles = triangles; - mesh.regionUVs = new Float32Array(uvs); - // mesh.updateUVs(); - mesh.hullLength = hullLength << 1; - if (nonessential) { - mesh.edges = edges; - mesh.width = width * scale; - mesh.height = height * scale; - } - return mesh; - } - case exports.AttachmentType.LinkedMesh: { - var path = input.readStringRef(); - var color = input.readInt32(); - var skinName = input.readStringRef(); - var parent_3 = input.readStringRef(); - var inheritDeform = input.readBoolean(); - var width = 0, height = 0; - if (nonessential) { - width = input.readFloat(); - height = input.readFloat(); - } - if (path == null) - path = name; - var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); - if (mesh == null) - return null; - mesh.path = path; - Color.rgba8888ToColor(mesh.color, color); - if (nonessential) { - mesh.width = width * scale; - mesh.height = height * scale; - } - this.linkedMeshes.push(new LinkedMesh$1$1(mesh, skinName, slotIndex, parent_3, inheritDeform)); - return mesh; - } - case exports.AttachmentType.Path: { - var closed_1 = input.readBoolean(); - var constantSpeed = input.readBoolean(); - var vertexCount = input.readInt(true); - var vertices = this.readVertices(input, vertexCount); - var lengths = Utils.newArray(vertexCount / 3, 0); - for (var i = 0, n = lengths.length; i < n; i++) - lengths[i] = input.readFloat() * scale; - var color = nonessential ? input.readInt32() : 0; - var path = this.attachmentLoader.newPathAttachment(skin, name); - if (path == null) - return null; - path.closed = closed_1; - path.constantSpeed = constantSpeed; - path.worldVerticesLength = vertexCount << 1; - path.vertices = vertices.vertices; - path.bones = vertices.bones; - path.lengths = lengths; - if (nonessential) - Color.rgba8888ToColor(path.color, color); - return path; - } - case exports.AttachmentType.Point: { - var rotation = input.readFloat(); - var x = input.readFloat(); - var y = input.readFloat(); - var color = nonessential ? input.readInt32() : 0; - var point = this.attachmentLoader.newPointAttachment(skin, name); - if (point == null) - return null; - point.x = x * scale; - point.y = y * scale; - point.rotation = rotation; - if (nonessential) - Color.rgba8888ToColor(point.color, color); - return point; - } - case exports.AttachmentType.Clipping: { - var endSlotIndex = input.readInt(true); - var vertexCount = input.readInt(true); - var vertices = this.readVertices(input, vertexCount); - var color = nonessential ? input.readInt32() : 0; - var clip = this.attachmentLoader.newClippingAttachment(skin, name); - if (clip == null) - return null; - clip.endSlot = skeletonData.slots[endSlotIndex]; - clip.worldVerticesLength = vertexCount << 1; - clip.vertices = vertices.vertices; - clip.bones = vertices.bones; - if (nonessential) - Color.rgba8888ToColor(clip.color, color); - return clip; - } - } - return null; - }; - SkeletonBinary.prototype.readVertices = function (input, vertexCount) { - var verticesLength = vertexCount << 1; - var vertices = new Vertices$1(); - var scale = this.scale; - if (!input.readBoolean()) { - vertices.vertices = this.readFloatArray(input, verticesLength, scale); - return vertices; - } - var weights = new Array(); - var bonesArray = new Array(); - for (var i = 0; i < vertexCount; i++) { - var boneCount = input.readInt(true); - bonesArray.push(boneCount); - for (var ii = 0; ii < boneCount; ii++) { - bonesArray.push(input.readInt(true)); - weights.push(input.readFloat() * scale); - weights.push(input.readFloat() * scale); - weights.push(input.readFloat()); - } - } - vertices.vertices = Utils.toFloatArray(weights); - vertices.bones = bonesArray; - return vertices; - }; - SkeletonBinary.prototype.readFloatArray = function (input, n, scale) { - var array = new Array(n); - if (scale == 1) { - for (var i = 0; i < n; i++) - array[i] = input.readFloat(); - } - else { - for (var i = 0; i < n; i++) - array[i] = input.readFloat() * scale; - } - return array; - }; - SkeletonBinary.prototype.readShortArray = function (input) { - var n = input.readInt(true); - var array = new Array(n); - for (var i = 0; i < n; i++) - array[i] = input.readShort(); - return array; - }; - SkeletonBinary.prototype.readAnimation = function (input, name, skeletonData) { - var timelines = new Array(); - var scale = this.scale; - var duration = 0; - var tempColor1 = new Color(); - var tempColor2 = new Color(); - // Slot timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var slotIndex = input.readInt(true); - for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { - var timelineType = input.readByte(); - var frameCount = input.readInt(true); - switch (timelineType) { - case SkeletonBinary.SLOT_ATTACHMENT: { - var timeline = new AttachmentTimeline$2(frameCount); - timeline.slotIndex = slotIndex; - for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) - timeline.setFrame(frameIndex, input.readFloat(), input.readStringRef()); - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[frameCount - 1]); - break; - } - case SkeletonBinary.SLOT_COLOR: { - var timeline = new ColorTimeline$1(frameCount); - timeline.slotIndex = slotIndex; - for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { - var time = input.readFloat(); - Color.rgba8888ToColor(tempColor1, input.readInt32()); - timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a); - if (frameIndex < frameCount - 1) - this.readCurve(input, frameIndex, timeline); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(frameCount - 1) * ColorTimeline$1.ENTRIES]); - break; - } - case SkeletonBinary.SLOT_TWO_COLOR: { - var timeline = new TwoColorTimeline$1(frameCount); - timeline.slotIndex = slotIndex; - for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { - var time = input.readFloat(); - Color.rgba8888ToColor(tempColor1, input.readInt32()); - Color.rgb888ToColor(tempColor2, input.readInt32()); - timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a, tempColor2.r, tempColor2.g, tempColor2.b); - if (frameIndex < frameCount - 1) - this.readCurve(input, frameIndex, timeline); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(frameCount - 1) * TwoColorTimeline$1.ENTRIES]); - break; - } - } - } - } - // Bone timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var boneIndex = input.readInt(true); - for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { - var timelineType = input.readByte(); - var frameCount = input.readInt(true); - switch (timelineType) { - case SkeletonBinary.BONE_ROTATE: { - var timeline = new RotateTimeline$2(frameCount); - timeline.boneIndex = boneIndex; - for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { - timeline.setFrame(frameIndex, input.readFloat(), input.readFloat()); - if (frameIndex < frameCount - 1) - this.readCurve(input, frameIndex, timeline); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(frameCount - 1) * RotateTimeline$2.ENTRIES]); - break; - } - case SkeletonBinary.BONE_TRANSLATE: - case SkeletonBinary.BONE_SCALE: - case SkeletonBinary.BONE_SHEAR: { - var timeline = void 0; - var timelineScale = 1; - if (timelineType == SkeletonBinary.BONE_SCALE) - timeline = new ScaleTimeline$2(frameCount); - else if (timelineType == SkeletonBinary.BONE_SHEAR) - timeline = new ShearTimeline$2(frameCount); - else { - timeline = new TranslateTimeline$2(frameCount); - timelineScale = scale; - } - timeline.boneIndex = boneIndex; - for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { - timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale, input.readFloat() * timelineScale); - if (frameIndex < frameCount - 1) - this.readCurve(input, frameIndex, timeline); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(frameCount - 1) * TranslateTimeline$2.ENTRIES]); - break; - } - } - } - } - // IK constraint timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var index = input.readInt(true); - var frameCount = input.readInt(true); - var timeline = new IkConstraintTimeline$2(frameCount); - timeline.ikConstraintIndex = index; - for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { - timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat() * scale, input.readByte(), input.readBoolean(), input.readBoolean()); - if (frameIndex < frameCount - 1) - this.readCurve(input, frameIndex, timeline); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(frameCount - 1) * IkConstraintTimeline$2.ENTRIES]); - } - // Transform constraint timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var index = input.readInt(true); - var frameCount = input.readInt(true); - var timeline = new TransformConstraintTimeline$2(frameCount); - timeline.transformConstraintIndex = index; - for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { - timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat()); - if (frameIndex < frameCount - 1) - this.readCurve(input, frameIndex, timeline); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline$2.ENTRIES]); - } - // Path constraint timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var index = input.readInt(true); - var data = skeletonData.pathConstraints[index]; - for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { - var timelineType = input.readByte(); - var frameCount = input.readInt(true); - switch (timelineType) { - case SkeletonBinary.PATH_POSITION: - case SkeletonBinary.PATH_SPACING: { - var timeline = void 0; - var timelineScale = 1; - if (timelineType == SkeletonBinary.PATH_SPACING) { - timeline = new PathConstraintSpacingTimeline$2(frameCount); - if (data.spacingMode == SpacingMode$2.Length || data.spacingMode == SpacingMode$2.Fixed) - timelineScale = scale; - } - else { - timeline = new PathConstraintPositionTimeline$2(frameCount); - if (data.positionMode == exports.PositionMode.Fixed) - timelineScale = scale; - } - timeline.pathConstraintIndex = index; - for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { - timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale); - if (frameIndex < frameCount - 1) - this.readCurve(input, frameIndex, timeline); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline$2.ENTRIES]); - break; - } - case SkeletonBinary.PATH_MIX: { - var timeline = new PathConstraintMixTimeline$2(frameCount); - timeline.pathConstraintIndex = index; - for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { - timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat()); - if (frameIndex < frameCount - 1) - this.readCurve(input, frameIndex, timeline); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline$2.ENTRIES]); - break; - } - } - } - } - // Deform timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var skin = skeletonData.skins[input.readInt(true)]; - for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { - var slotIndex = input.readInt(true); - for (var iii = 0, nnn = input.readInt(true); iii < nnn; iii++) { - var attachment = skin.getAttachment(slotIndex, input.readStringRef()); - var weighted = attachment.bones != null; - var vertices = attachment.vertices; - var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; - var frameCount = input.readInt(true); - var timeline = new DeformTimeline$2(frameCount); - timeline.slotIndex = slotIndex; - timeline.attachment = attachment; - for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { - var time = input.readFloat(); - var deform = void 0; - var end = input.readInt(true); - if (end == 0) - deform = weighted ? Utils.newFloatArray(deformLength) : vertices; - else { - deform = Utils.newFloatArray(deformLength); - var start = input.readInt(true); - end += start; - if (scale == 1) { - for (var v = start; v < end; v++) - deform[v] = input.readFloat(); - } - else { - for (var v = start; v < end; v++) - deform[v] = input.readFloat() * scale; - } - if (!weighted) { - for (var v = 0, vn = deform.length; v < vn; v++) - deform[v] += vertices[v]; - } - } - timeline.setFrame(frameIndex, time, deform); - if (frameIndex < frameCount - 1) - this.readCurve(input, frameIndex, timeline); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[frameCount - 1]); - } - } - } - // Draw order timeline. - var drawOrderCount = input.readInt(true); - if (drawOrderCount > 0) { - var timeline = new DrawOrderTimeline$2(drawOrderCount); - var slotCount = skeletonData.slots.length; - for (var i = 0; i < drawOrderCount; i++) { - var time = input.readFloat(); - var offsetCount = input.readInt(true); - var drawOrder = Utils.newArray(slotCount, 0); - for (var ii = slotCount - 1; ii >= 0; ii--) - drawOrder[ii] = -1; - var unchanged = Utils.newArray(slotCount - offsetCount, 0); - var originalIndex = 0, unchangedIndex = 0; - for (var ii = 0; ii < offsetCount; ii++) { - var slotIndex = input.readInt(true); - // Collect unchanged items. - while (originalIndex != slotIndex) - unchanged[unchangedIndex++] = originalIndex++; - // Set changed items. - drawOrder[originalIndex + input.readInt(true)] = originalIndex++; - } - // Collect remaining unchanged items. - while (originalIndex < slotCount) - unchanged[unchangedIndex++] = originalIndex++; - // Fill in unchanged items. - for (var ii = slotCount - 1; ii >= 0; ii--) - if (drawOrder[ii] == -1) - drawOrder[ii] = unchanged[--unchangedIndex]; - timeline.setFrame(i, time, drawOrder); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[drawOrderCount - 1]); - } - // Event timeline. - var eventCount = input.readInt(true); - if (eventCount > 0) { - var timeline = new EventTimeline$2(eventCount); - for (var i = 0; i < eventCount; i++) { - var time = input.readFloat(); - var eventData = skeletonData.events[input.readInt(true)]; - var event_1 = new Event$2(time, eventData); - event_1.intValue = input.readInt(false); - event_1.floatValue = input.readFloat(); - event_1.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue; - if (event_1.data.audioPath != null) { - event_1.volume = input.readFloat(); - event_1.balance = input.readFloat(); - } - timeline.setFrame(i, event_1); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[eventCount - 1]); - } - return new Animation$2(name, timelines, duration); - }; - SkeletonBinary.prototype.readCurve = function (input, frameIndex, timeline) { - switch (input.readByte()) { - case SkeletonBinary.CURVE_STEPPED: - timeline.setStepped(frameIndex); - break; - case SkeletonBinary.CURVE_BEZIER: - this.setCurve(timeline, frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat()); - break; - } - }; - SkeletonBinary.prototype.setCurve = function (timeline, frameIndex, cx1, cy1, cx2, cy2) { - timeline.setCurve(frameIndex, cx1, cy1, cx2, cy2); - }; - SkeletonBinary.AttachmentTypeValues = [0 /*AttachmentType.Region*/, 1 /*AttachmentType.BoundingBox*/, 2 /*AttachmentType.Mesh*/, 3 /*AttachmentType.LinkedMesh*/, 4 /*AttachmentType.Path*/, 5 /*AttachmentType.Point*/, 6 /*AttachmentType.Clipping*/]; - SkeletonBinary.TransformModeValues = [exports.TransformMode.Normal, exports.TransformMode.OnlyTranslation, exports.TransformMode.NoRotationOrReflection, exports.TransformMode.NoScale, exports.TransformMode.NoScaleOrReflection]; - SkeletonBinary.PositionModeValues = [exports.PositionMode.Fixed, exports.PositionMode.Percent]; - SkeletonBinary.SpacingModeValues = [SpacingMode$2.Length, SpacingMode$2.Fixed, SpacingMode$2.Percent]; - SkeletonBinary.RotateModeValues = [exports.RotateMode.Tangent, exports.RotateMode.Chain, exports.RotateMode.ChainScale]; - SkeletonBinary.BlendModeValues = [constants.BLEND_MODES.NORMAL, constants.BLEND_MODES.ADD, constants.BLEND_MODES.MULTIPLY, constants.BLEND_MODES.SCREEN]; - SkeletonBinary.BONE_ROTATE = 0; - SkeletonBinary.BONE_TRANSLATE = 1; - SkeletonBinary.BONE_SCALE = 2; - SkeletonBinary.BONE_SHEAR = 3; - SkeletonBinary.SLOT_ATTACHMENT = 0; - SkeletonBinary.SLOT_COLOR = 1; - SkeletonBinary.SLOT_TWO_COLOR = 2; - SkeletonBinary.PATH_POSITION = 0; - SkeletonBinary.PATH_SPACING = 1; - SkeletonBinary.PATH_MIX = 2; - SkeletonBinary.CURVE_LINEAR = 0; - SkeletonBinary.CURVE_STEPPED = 1; - SkeletonBinary.CURVE_BEZIER = 2; - return SkeletonBinary; - }()); - var LinkedMesh$1$1 = /** @class */ (function () { - function LinkedMesh(mesh, skin, slotIndex, parent, inheritDeform) { - this.mesh = mesh; - this.skin = skin; - this.slotIndex = slotIndex; - this.parent = parent; - this.inheritDeform = inheritDeform; - } - return LinkedMesh; - }()); - var Vertices$1 = /** @class */ (function () { - function Vertices(bones, vertices) { - if (bones === void 0) { bones = null; } - if (vertices === void 0) { vertices = null; } - this.bones = bones; - this.vertices = vertices; - } - return Vertices; - }()); - - /** Collects each visible {@link BoundingBoxAttachment} and computes the world vertices for its polygon. The polygon vertices are - * provided along with convenience methods for doing hit detection. - * @public - * */ - var SkeletonBounds$2 = /** @class */ (function (_super) { - __extends$3(SkeletonBounds, _super); - function SkeletonBounds() { - return _super !== null && _super.apply(this, arguments) || this; - } - return SkeletonBounds; - }(SkeletonBoundsBase)); - - /** - * @public - */ - var SkeletonJson$2 = /** @class */ (function () { - function SkeletonJson(attachmentLoader) { - this.scale = 1; - this.linkedMeshes = new Array(); - this.attachmentLoader = attachmentLoader; - } - SkeletonJson.prototype.readSkeletonData = function (json) { - var scale = this.scale; - var skeletonData = new SkeletonData$2(); - var root = typeof (json) === "string" ? JSON.parse(json) : json; - // Skeleton - var skeletonMap = root.skeleton; - if (skeletonMap != null) { - skeletonData.hash = skeletonMap.hash; - skeletonData.version = skeletonMap.spine; - if (skeletonData.version.substr(0, 3) !== '3.8') { - var error = "Spine 3.8 loader cant load version " + skeletonMap.spine + ". Please configure your pixi-spine bundle"; - console.error(error); - } - if (skeletonData.version === '3.8.75') { - var error = "Unsupported skeleton data, 3.8.75 is deprecated, please export with a newer version of Spine."; - console.error(error); - } - skeletonData.x = skeletonMap.x; - skeletonData.y = skeletonMap.y; - skeletonData.width = skeletonMap.width; - skeletonData.height = skeletonMap.height; - skeletonData.fps = skeletonMap.fps; - skeletonData.imagesPath = skeletonMap.images; - } - // Bones - if (root.bones) { - for (var i = 0; i < root.bones.length; i++) { - var boneMap = root.bones[i]; - var parent_1 = null; - var parentName = this.getValue(boneMap, "parent", null); - if (parentName != null) { - parent_1 = skeletonData.findBone(parentName); - if (parent_1 == null) - throw new Error("Parent bone not found: " + parentName); - } - var data = new BoneData$2(skeletonData.bones.length, boneMap.name, parent_1); - data.length = this.getValue(boneMap, "length", 0) * scale; - data.x = this.getValue(boneMap, "x", 0) * scale; - data.y = this.getValue(boneMap, "y", 0) * scale; - data.rotation = this.getValue(boneMap, "rotation", 0); - data.scaleX = this.getValue(boneMap, "scaleX", 1); - data.scaleY = this.getValue(boneMap, "scaleY", 1); - data.shearX = this.getValue(boneMap, "shearX", 0); - data.shearY = this.getValue(boneMap, "shearY", 0); - data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal")); - data.skinRequired = this.getValue(boneMap, "skin", false); - skeletonData.bones.push(data); - } - } - // Slots. - if (root.slots) { - for (var i = 0; i < root.slots.length; i++) { - var slotMap = root.slots[i]; - var slotName = slotMap.name; - var boneName = slotMap.bone; - var boneData = skeletonData.findBone(boneName); - if (boneData == null) - throw new Error("Slot bone not found: " + boneName); - var data = new SlotData$2(skeletonData.slots.length, slotName, boneData); - var color = this.getValue(slotMap, "color", null); - if (color != null) - data.color.setFromString(color); - var dark = this.getValue(slotMap, "dark", null); - if (dark != null) { - data.darkColor = new Color(1, 1, 1, 1); - data.darkColor.setFromString(dark); - } - data.attachmentName = this.getValue(slotMap, "attachment", null); - data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal")); - skeletonData.slots.push(data); - } - } - // IK constraints - if (root.ik) { - for (var i = 0; i < root.ik.length; i++) { - var constraintMap = root.ik[i]; - var data = new IkConstraintData$2(constraintMap.name); - data.order = this.getValue(constraintMap, "order", 0); - data.skinRequired = this.getValue(constraintMap, "skin", false); - for (var j = 0; j < constraintMap.bones.length; j++) { - var boneName = constraintMap.bones[j]; - var bone = skeletonData.findBone(boneName); - if (bone == null) - throw new Error("IK bone not found: " + boneName); - data.bones.push(bone); - } - var targetName = constraintMap.target; - data.target = skeletonData.findBone(targetName); - if (data.target == null) - throw new Error("IK target bone not found: " + targetName); - data.mix = this.getValue(constraintMap, "mix", 1); - data.softness = this.getValue(constraintMap, "softness", 0) * scale; - data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; - data.compress = this.getValue(constraintMap, "compress", false); - data.stretch = this.getValue(constraintMap, "stretch", false); - data.uniform = this.getValue(constraintMap, "uniform", false); - skeletonData.ikConstraints.push(data); - } - } - // Transform constraints. - if (root.transform) { - for (var i = 0; i < root.transform.length; i++) { - var constraintMap = root.transform[i]; - var data = new TransformConstraintData$2(constraintMap.name); - data.order = this.getValue(constraintMap, "order", 0); - data.skinRequired = this.getValue(constraintMap, "skin", false); - for (var j = 0; j < constraintMap.bones.length; j++) { - var boneName = constraintMap.bones[j]; - var bone = skeletonData.findBone(boneName); - if (bone == null) - throw new Error("Transform constraint bone not found: " + boneName); - data.bones.push(bone); - } - var targetName = constraintMap.target; - data.target = skeletonData.findBone(targetName); - if (data.target == null) - throw new Error("Transform constraint target bone not found: " + targetName); - data.local = this.getValue(constraintMap, "local", false); - data.relative = this.getValue(constraintMap, "relative", false); - data.offsetRotation = this.getValue(constraintMap, "rotation", 0); - data.offsetX = this.getValue(constraintMap, "x", 0) * scale; - data.offsetY = this.getValue(constraintMap, "y", 0) * scale; - data.offsetScaleX = this.getValue(constraintMap, "scaleX", 0); - data.offsetScaleY = this.getValue(constraintMap, "scaleY", 0); - data.offsetShearY = this.getValue(constraintMap, "shearY", 0); - data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); - data.translateMix = this.getValue(constraintMap, "translateMix", 1); - data.scaleMix = this.getValue(constraintMap, "scaleMix", 1); - data.shearMix = this.getValue(constraintMap, "shearMix", 1); - skeletonData.transformConstraints.push(data); - } - } - // Path constraints. - if (root.path) { - for (var i = 0; i < root.path.length; i++) { - var constraintMap = root.path[i]; - var data = new PathConstraintData$2(constraintMap.name); - data.order = this.getValue(constraintMap, "order", 0); - data.skinRequired = this.getValue(constraintMap, "skin", false); - for (var j = 0; j < constraintMap.bones.length; j++) { - var boneName = constraintMap.bones[j]; - var bone = skeletonData.findBone(boneName); - if (bone == null) - throw new Error("Transform constraint bone not found: " + boneName); - data.bones.push(bone); - } - var targetName = constraintMap.target; - data.target = skeletonData.findSlot(targetName); - if (data.target == null) - throw new Error("Path target slot not found: " + targetName); - data.positionMode = SkeletonJson.positionModeFromString(this.getValue(constraintMap, "positionMode", "percent")); - data.spacingMode = SkeletonJson.spacingModeFromString(this.getValue(constraintMap, "spacingMode", "length")); - data.rotateMode = SkeletonJson.rotateModeFromString(this.getValue(constraintMap, "rotateMode", "tangent")); - data.offsetRotation = this.getValue(constraintMap, "rotation", 0); - data.position = this.getValue(constraintMap, "position", 0); - if (data.positionMode == exports.PositionMode.Fixed) - data.position *= scale; - data.spacing = this.getValue(constraintMap, "spacing", 0); - if (data.spacingMode == SpacingMode$2.Length || data.spacingMode == SpacingMode$2.Fixed) - data.spacing *= scale; - data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); - data.translateMix = this.getValue(constraintMap, "translateMix", 1); - skeletonData.pathConstraints.push(data); - } - } - // Skins. - if (root.skins) { - for (var i = 0; i < root.skins.length; i++) { - var skinMap = root.skins[i]; - var skin = new Skin$2(skinMap.name); - if (skinMap.bones) { - for (var ii = 0; ii < skinMap.bones.length; ii++) { - var bone = skeletonData.findBone(skinMap.bones[ii]); - if (bone == null) - throw new Error("Skin bone not found: " + skinMap.bones[i]); - skin.bones.push(bone); - } - } - if (skinMap.ik) { - for (var ii = 0; ii < skinMap.ik.length; ii++) { - var constraint = skeletonData.findIkConstraint(skinMap.ik[ii]); - if (constraint == null) - throw new Error("Skin IK constraint not found: " + skinMap.ik[i]); - skin.constraints.push(constraint); - } - } - if (skinMap.transform) { - for (var ii = 0; ii < skinMap.transform.length; ii++) { - var constraint = skeletonData.findTransformConstraint(skinMap.transform[ii]); - if (constraint == null) - throw new Error("Skin transform constraint not found: " + skinMap.transform[i]); - skin.constraints.push(constraint); - } - } - if (skinMap.path) { - for (var ii = 0; ii < skinMap.path.length; ii++) { - var constraint = skeletonData.findPathConstraint(skinMap.path[ii]); - if (constraint == null) - throw new Error("Skin path constraint not found: " + skinMap.path[i]); - skin.constraints.push(constraint); - } - } - for (var slotName in skinMap.attachments) { - var slot = skeletonData.findSlot(slotName); - if (slot == null) - throw new Error("Slot not found: " + slotName); - var slotMap = skinMap.attachments[slotName]; - for (var entryName in slotMap) { - var attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData); - if (attachment != null) - skin.setAttachment(slot.index, entryName, attachment); - } - } - skeletonData.skins.push(skin); - if (skin.name == "default") - skeletonData.defaultSkin = skin; - } - } - // Linked meshes. - for (var i = 0, n = this.linkedMeshes.length; i < n; i++) { - var linkedMesh = this.linkedMeshes[i]; - var skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); - if (skin == null) - throw new Error("Skin not found: " + linkedMesh.skin); - var parent_2 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); - if (parent_2 == null) - throw new Error("Parent mesh not found: " + linkedMesh.parent); - linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent_2 : linkedMesh.mesh; - linkedMesh.mesh.setParentMesh(parent_2); - // linkedMesh.mesh.updateUVs(); - } - this.linkedMeshes.length = 0; - // Events. - if (root.events) { - for (var eventName in root.events) { - var eventMap = root.events[eventName]; - var data = new EventData$2(eventName); - data.intValue = this.getValue(eventMap, "int", 0); - data.floatValue = this.getValue(eventMap, "float", 0); - data.stringValue = this.getValue(eventMap, "string", ""); - data.audioPath = this.getValue(eventMap, "audio", null); - if (data.audioPath != null) { - data.volume = this.getValue(eventMap, "volume", 1); - data.balance = this.getValue(eventMap, "balance", 0); - } - skeletonData.events.push(data); - } - } - // Animations. - if (root.animations) { - for (var animationName in root.animations) { - var animationMap = root.animations[animationName]; - this.readAnimation(animationMap, animationName, skeletonData); - } - } - return skeletonData; - }; - SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) { - var scale = this.scale; - name = this.getValue(map, "name", name); - var type = this.getValue(map, "type", "region"); - switch (type) { - case "region": { - var path = this.getValue(map, "path", name); - var region = this.attachmentLoader.newRegionAttachment(skin, name, path); - if (region == null) - return null; - region.path = path; - region.x = this.getValue(map, "x", 0) * scale; - region.y = this.getValue(map, "y", 0) * scale; - region.scaleX = this.getValue(map, "scaleX", 1); - region.scaleY = this.getValue(map, "scaleY", 1); - region.rotation = this.getValue(map, "rotation", 0); - region.width = map.width * scale; - region.height = map.height * scale; - var color = this.getValue(map, "color", null); - if (color != null) - region.color.setFromString(color); - // region.updateOffset(); - return region; - } - case "boundingbox": { - var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); - if (box == null) - return null; - this.readVertices(map, box, map.vertexCount << 1); - var color = this.getValue(map, "color", null); - if (color != null) - box.color.setFromString(color); - return box; - } - case "mesh": - case "linkedmesh": { - var path = this.getValue(map, "path", name); - var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); - if (mesh == null) - return null; - mesh.path = path; - var color = this.getValue(map, "color", null); - if (color != null) - mesh.color.setFromString(color); - mesh.width = this.getValue(map, "width", 0) * scale; - mesh.height = this.getValue(map, "height", 0) * scale; - var parent_3 = this.getValue(map, "parent", null); - if (parent_3 != null) { - this.linkedMeshes.push(new LinkedMesh$3(mesh, this.getValue(map, "skin", null), slotIndex, parent_3, this.getValue(map, "deform", true))); - return mesh; - } - var uvs = map.uvs; - this.readVertices(map, mesh, uvs.length); - mesh.triangles = map.triangles; - mesh.regionUVs = new Float32Array(uvs); - // mesh.updateUVs(); - mesh.edges = this.getValue(map, "edges", null); - mesh.hullLength = this.getValue(map, "hull", 0) * 2; - return mesh; - } - case "path": { - var path = this.attachmentLoader.newPathAttachment(skin, name); - if (path == null) - return null; - path.closed = this.getValue(map, "closed", false); - path.constantSpeed = this.getValue(map, "constantSpeed", true); - var vertexCount = map.vertexCount; - this.readVertices(map, path, vertexCount << 1); - var lengths = Utils.newArray(vertexCount / 3, 0); - for (var i = 0; i < map.lengths.length; i++) - lengths[i] = map.lengths[i] * scale; - path.lengths = lengths; - var color = this.getValue(map, "color", null); - if (color != null) - path.color.setFromString(color); - return path; - } - case "point": { - var point = this.attachmentLoader.newPointAttachment(skin, name); - if (point == null) - return null; - point.x = this.getValue(map, "x", 0) * scale; - point.y = this.getValue(map, "y", 0) * scale; - point.rotation = this.getValue(map, "rotation", 0); - var color = this.getValue(map, "color", null); - if (color != null) - point.color.setFromString(color); - return point; - } - case "clipping": { - var clip = this.attachmentLoader.newClippingAttachment(skin, name); - if (clip == null) - return null; - var end = this.getValue(map, "end", null); - if (end != null) { - var slot = skeletonData.findSlot(end); - if (slot == null) - throw new Error("Clipping end slot not found: " + end); - clip.endSlot = slot; - } - var vertexCount = map.vertexCount; - this.readVertices(map, clip, vertexCount << 1); - var color = this.getValue(map, "color", null); - if (color != null) - clip.color.setFromString(color); - return clip; - } - } - return null; - }; - SkeletonJson.prototype.readVertices = function (map, attachment, verticesLength) { - var scale = this.scale; - attachment.worldVerticesLength = verticesLength; - var vertices = map.vertices; - if (verticesLength == vertices.length) { - var scaledVertices = Utils.toFloatArray(vertices); - if (scale != 1) { - for (var i = 0, n = vertices.length; i < n; i++) - scaledVertices[i] *= scale; - } - attachment.vertices = scaledVertices; - return; - } - var weights = new Array(); - var bones = new Array(); - for (var i = 0, n = vertices.length; i < n;) { - var boneCount = vertices[i++]; - bones.push(boneCount); - for (var nn = i + boneCount * 4; i < nn; i += 4) { - bones.push(vertices[i]); - weights.push(vertices[i + 1] * scale); - weights.push(vertices[i + 2] * scale); - weights.push(vertices[i + 3]); - } - } - attachment.bones = bones; - attachment.vertices = Utils.toFloatArray(weights); - }; - SkeletonJson.prototype.readAnimation = function (map, name, skeletonData) { - var scale = this.scale; - var timelines = new Array(); - var duration = 0; - // Slot timelines. - if (map.slots) { - for (var slotName in map.slots) { - var slotMap = map.slots[slotName]; - var slotIndex = skeletonData.findSlotIndex(slotName); - if (slotIndex == -1) - throw new Error("Slot not found: " + slotName); - for (var timelineName in slotMap) { - var timelineMap = slotMap[timelineName]; - if (timelineName == "attachment") { - var timeline = new AttachmentTimeline$2(timelineMap.length); - timeline.slotIndex = slotIndex; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - } - else if (timelineName == "color") { - var timeline = new ColorTimeline$1(timelineMap.length); - timeline.slotIndex = slotIndex; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - var color = new Color(); - color.setFromString(valueMap.color || "ffffffff"); - timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * ColorTimeline$1.ENTRIES]); - } - else if (timelineName == "twoColor") { - var timeline = new TwoColorTimeline$1(timelineMap.length); - timeline.slotIndex = slotIndex; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - var light = new Color(); - var dark = new Color(); - light.setFromString(valueMap.light); - dark.setFromString(valueMap.dark); - timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TwoColorTimeline$1.ENTRIES]); - } - else - throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); - } - } - } - // Bone timelines. - if (map.bones) { - for (var boneName in map.bones) { - var boneMap = map.bones[boneName]; - var boneIndex = skeletonData.findBoneIndex(boneName); - if (boneIndex == -1) - throw new Error("Bone not found: " + boneName); - for (var timelineName in boneMap) { - var timelineMap = boneMap[timelineName]; - if (timelineName === "rotate") { - var timeline = new RotateTimeline$2(timelineMap.length); - timeline.boneIndex = boneIndex; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0)); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * RotateTimeline$2.ENTRIES]); - } - else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") { - var timeline = null; - var timelineScale = 1, defaultValue = 0; - if (timelineName === "scale") { - timeline = new ScaleTimeline$2(timelineMap.length); - defaultValue = 1; - } - else if (timelineName === "shear") - timeline = new ShearTimeline$2(timelineMap.length); - else { - timeline = new TranslateTimeline$2(timelineMap.length); - timelineScale = scale; - } - timeline.boneIndex = boneIndex; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - var x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue); - timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TranslateTimeline$2.ENTRIES]); - } - else - throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); - } - } - } - // IK constraint timelines. - if (map.ik) { - for (var constraintName in map.ik) { - var constraintMap = map.ik[constraintName]; - var constraint = skeletonData.findIkConstraint(constraintName); - var timeline = new IkConstraintTimeline$2(constraintMap.length); - timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(constraint); - var frameIndex = 0; - for (var i = 0; i < constraintMap.length; i++) { - var valueMap = constraintMap[i]; - timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "softness", 0) * scale, this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false)); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * IkConstraintTimeline$2.ENTRIES]); - } - } - // Transform constraint timelines. - if (map.transform) { - for (var constraintName in map.transform) { - var constraintMap = map.transform[constraintName]; - var constraint = skeletonData.findTransformConstraint(constraintName); - var timeline = new TransformConstraintTimeline$2(constraintMap.length); - timeline.transformConstraintIndex = skeletonData.transformConstraints.indexOf(constraint); - var frameIndex = 0; - for (var i = 0; i < constraintMap.length; i++) { - var valueMap = constraintMap[i]; - timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1)); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TransformConstraintTimeline$2.ENTRIES]); - } - } - // Path constraint timelines. - if (map.path) { - for (var constraintName in map.path) { - var constraintMap = map.path[constraintName]; - var index = skeletonData.findPathConstraintIndex(constraintName); - if (index == -1) - throw new Error("Path constraint not found: " + constraintName); - var data = skeletonData.pathConstraints[index]; - for (var timelineName in constraintMap) { - var timelineMap = constraintMap[timelineName]; - if (timelineName === "position" || timelineName === "spacing") { - var timeline = null; - var timelineScale = 1; - if (timelineName === "spacing") { - timeline = new PathConstraintSpacingTimeline$2(timelineMap.length); - if (data.spacingMode == SpacingMode$2.Length || data.spacingMode == SpacingMode$2.Fixed) - timelineScale = scale; - } - else { - timeline = new PathConstraintPositionTimeline$2(timelineMap.length); - if (data.positionMode == exports.PositionMode.Fixed) - timelineScale = scale; - } - timeline.pathConstraintIndex = index; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * PathConstraintPositionTimeline$2.ENTRIES]); - } - else if (timelineName === "mix") { - var timeline = new PathConstraintMixTimeline$2(timelineMap.length); - timeline.pathConstraintIndex = index; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1)); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * PathConstraintMixTimeline$2.ENTRIES]); - } - } - } - } - // Deform timelines. - if (map.deform) { - for (var deformName in map.deform) { - var deformMap = map.deform[deformName]; - var skin = skeletonData.findSkin(deformName); - if (skin == null) { - if (settings.FAIL_ON_NON_EXISTING_SKIN) { - throw new Error("Skin not found: " + deformName); - } - else { - continue; - } - } - for (var slotName in deformMap) { - var slotMap = deformMap[slotName]; - var slotIndex = skeletonData.findSlotIndex(slotName); - if (slotIndex == -1) - throw new Error("Slot not found: " + slotMap.name); - for (var timelineName in slotMap) { - var timelineMap = slotMap[timelineName]; - var attachment = skin.getAttachment(slotIndex, timelineName); - if (attachment == null) - throw new Error("Deform attachment not found: " + timelineMap.name); - var weighted = attachment.bones != null; - var vertices = attachment.vertices; - var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; - var timeline = new DeformTimeline$2(timelineMap.length); - timeline.slotIndex = slotIndex; - timeline.attachment = attachment; - var frameIndex = 0; - for (var j = 0; j < timelineMap.length; j++) { - var valueMap = timelineMap[j]; - var deform = void 0; - var verticesValue = this.getValue(valueMap, "vertices", null); - if (verticesValue == null) - deform = weighted ? Utils.newFloatArray(deformLength) : vertices; - else { - deform = Utils.newFloatArray(deformLength); - var start = this.getValue(valueMap, "offset", 0); - Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); - if (scale != 1) { - for (var i = start, n = i + verticesValue.length; i < n; i++) - deform[i] *= scale; - } - if (!weighted) { - for (var i = 0; i < deformLength; i++) - deform[i] += vertices[i]; - } - } - timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - } - } - } - } - // Draw order timeline. - var drawOrderNode = map.drawOrder; - if (drawOrderNode == null) - drawOrderNode = map.draworder; - if (drawOrderNode != null) { - var timeline = new DrawOrderTimeline$2(drawOrderNode.length); - var slotCount = skeletonData.slots.length; - var frameIndex = 0; - for (var j = 0; j < drawOrderNode.length; j++) { - var drawOrderMap = drawOrderNode[j]; - var drawOrder = null; - var offsets = this.getValue(drawOrderMap, "offsets", null); - if (offsets != null) { - drawOrder = Utils.newArray(slotCount, -1); - var unchanged = Utils.newArray(slotCount - offsets.length, 0); - var originalIndex = 0, unchangedIndex = 0; - for (var i = 0; i < offsets.length; i++) { - var offsetMap = offsets[i]; - var slotIndex = skeletonData.findSlotIndex(offsetMap.slot); - if (slotIndex == -1) - throw new Error("Slot not found: " + offsetMap.slot); - // Collect unchanged items. - while (originalIndex != slotIndex) - unchanged[unchangedIndex++] = originalIndex++; - // Set changed items. - drawOrder[originalIndex + offsetMap.offset] = originalIndex++; - } - // Collect remaining unchanged items. - while (originalIndex < slotCount) - unchanged[unchangedIndex++] = originalIndex++; - // Fill in unchanged items. - for (var i = slotCount - 1; i >= 0; i--) - if (drawOrder[i] == -1) - drawOrder[i] = unchanged[--unchangedIndex]; - } - timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - } - // Event timeline. - if (map.events) { - var timeline = new EventTimeline$2(map.events.length); - var frameIndex = 0; - for (var i = 0; i < map.events.length; i++) { - var eventMap = map.events[i]; - var eventData = skeletonData.findEvent(eventMap.name); - if (eventData == null) - throw new Error("Event not found: " + eventMap.name); - var event_1 = new Event$2(Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData); - event_1.intValue = this.getValue(eventMap, "int", eventData.intValue); - event_1.floatValue = this.getValue(eventMap, "float", eventData.floatValue); - event_1.stringValue = this.getValue(eventMap, "string", eventData.stringValue); - if (event_1.data.audioPath != null) { - event_1.volume = this.getValue(eventMap, "volume", 1); - event_1.balance = this.getValue(eventMap, "balance", 0); - } - timeline.setFrame(frameIndex++, event_1); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - } - if (isNaN(duration)) { - throw new Error("Error while parsing animation, duration is NaN"); - } - skeletonData.animations.push(new Animation$2(name, timelines, duration)); - }; - SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) { - if (!map.hasOwnProperty("curve")) - return; - if (map.curve === "stepped") - timeline.setStepped(frameIndex); - else { - var curve = map.curve; - timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1)); - } - }; - SkeletonJson.prototype.getValue = function (map, prop, defaultValue) { - return map[prop] !== undefined ? map[prop] : defaultValue; - }; - SkeletonJson.blendModeFromString = function (str) { - str = str.toLowerCase(); - if (str == "normal") - return constants.BLEND_MODES.NORMAL; - if (str == "additive") - return constants.BLEND_MODES.ADD; - if (str == "multiply") - return constants.BLEND_MODES.MULTIPLY; - if (str == "screen") - return constants.BLEND_MODES.SCREEN; - throw new Error("Unknown blend mode: " + str); - }; - SkeletonJson.positionModeFromString = function (str) { - str = str.toLowerCase(); - if (str == "fixed") - return exports.PositionMode.Fixed; - if (str == "percent") - return exports.PositionMode.Percent; - throw new Error("Unknown position mode: " + str); - }; - SkeletonJson.spacingModeFromString = function (str) { - str = str.toLowerCase(); - if (str == "length") - return SpacingMode$2.Length; - if (str == "fixed") - return SpacingMode$2.Fixed; - if (str == "percent") - return SpacingMode$2.Percent; - throw new Error("Unknown position mode: " + str); - }; - SkeletonJson.rotateModeFromString = function (str) { - str = str.toLowerCase(); - if (str == "tangent") - return exports.RotateMode.Tangent; - if (str == "chain") - return exports.RotateMode.Chain; - if (str == "chainscale") - return exports.RotateMode.ChainScale; - throw new Error("Unknown rotate mode: " + str); - }; - SkeletonJson.transformModeFromString = function (str) { - str = str.toLowerCase(); - if (str == "normal") - return exports.TransformMode.Normal; - if (str == "onlytranslation") - return exports.TransformMode.OnlyTranslation; - if (str == "norotationorreflection") - return exports.TransformMode.NoRotationOrReflection; - if (str == "noscale") - return exports.TransformMode.NoScale; - if (str == "noscaleorreflection") - return exports.TransformMode.NoScaleOrReflection; - throw new Error("Unknown transform mode: " + str); - }; - return SkeletonJson; - }()); - var LinkedMesh$3 = /** @class */ (function () { - function LinkedMesh(mesh, skin, slotIndex, parent, inheritDeform) { - this.mesh = mesh; - this.skin = skin; - this.slotIndex = slotIndex; - this.parent = parent; - this.inheritDeform = inheritDeform; - } - return LinkedMesh; - }()); - - /** - * @public - */ - var Spine$3 = /** @class */ (function (_super) { - __extends$3(Spine, _super); - function Spine() { - return _super !== null && _super.apply(this, arguments) || this; - } - Spine.prototype.createSkeleton = function (spineData) { - this.skeleton = new Skeleton$2(spineData); - this.skeleton.updateWorldTransform(); - this.stateData = new AnimationStateData$2(spineData); - this.state = new AnimationState$2(this.stateData); - }; - return Spine; - }(SpineBase)); - - var spine38 = /*#__PURE__*/Object.freeze({ - __proto__: null, - Animation: Animation$2, - AnimationState: AnimationState$2, - AnimationStateAdapter: AnimationStateAdapter$1, - AnimationStateData: AnimationStateData$2, - AtlasAttachmentLoader: AtlasAttachmentLoader$2, - Attachment: Attachment$2, - AttachmentTimeline: AttachmentTimeline$2, - Bone: Bone$2, - BoneData: BoneData$2, - BoundingBoxAttachment: BoundingBoxAttachment$2, - ClippingAttachment: ClippingAttachment$2, - ColorTimeline: ColorTimeline$1, - ConstraintData: ConstraintData$1, - CurveTimeline: CurveTimeline$2, - DeformTimeline: DeformTimeline$2, - DrawOrderTimeline: DrawOrderTimeline$2, - Event: Event$2, - EventData: EventData$2, - EventQueue: EventQueue$2, - EventTimeline: EventTimeline$2, - get EventType () { return EventType$2; }, - IkConstraint: IkConstraint$2, - IkConstraintData: IkConstraintData$2, - IkConstraintTimeline: IkConstraintTimeline$2, - JitterEffect: JitterEffect$1, - MeshAttachment: MeshAttachment$2, - PathAttachment: PathAttachment$2, - PathConstraint: PathConstraint$2, - PathConstraintData: PathConstraintData$2, - PathConstraintMixTimeline: PathConstraintMixTimeline$2, - PathConstraintPositionTimeline: PathConstraintPositionTimeline$2, - PathConstraintSpacingTimeline: PathConstraintSpacingTimeline$2, - PointAttachment: PointAttachment$2, - RegionAttachment: RegionAttachment$2, - RotateTimeline: RotateTimeline$2, - ScaleTimeline: ScaleTimeline$2, - ShearTimeline: ShearTimeline$2, - Skeleton: Skeleton$2, - SkeletonBinary: SkeletonBinary$1, - SkeletonBounds: SkeletonBounds$2, - SkeletonData: SkeletonData$2, - SkeletonJson: SkeletonJson$2, - Skin: Skin$2, - SkinEntry: SkinEntry$1, - Slot: Slot$2, - SlotData: SlotData$2, - get SpacingMode () { return SpacingMode$2; }, - Spine: Spine$3, - SwirlEffect: SwirlEffect$1, - get TimelineType () { return TimelineType$1; }, - TrackEntry: TrackEntry$2, - TransformConstraint: TransformConstraint$2, - TransformConstraintData: TransformConstraintData$2, - TransformConstraintTimeline: TransformConstraintTimeline$2, - TranslateTimeline: TranslateTimeline$2, - TwoColorTimeline: TwoColorTimeline$1, - VertexAttachment: VertexAttachment$2 - }); - - /* eslint-disable */ - - /*! ***************************************************************************** - Copyright (c) Microsoft Corporation. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. - ***************************************************************************** */ - /* global Reflect, Promise */ - - var extendStatics$2 = function(d, b) { - extendStatics$2 = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics$2(d, b); - }; - - function __extends$2(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics$2(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - } - - /** - * @public - */ - var Attachment$1 = /** @class */ (function () { - function Attachment(name) { - if (name == null) - throw new Error("name cannot be null."); - this.name = name; - } - return Attachment; - }()); - /** - * @public - */ - var VertexAttachment$1 = /** @class */ (function (_super) { - __extends$2(VertexAttachment, _super); - function VertexAttachment(name) { - var _this = _super.call(this, name) || this; - _this.id = (VertexAttachment.nextID++ & 65535) << 11; - _this.worldVerticesLength = 0; - return _this; - } - VertexAttachment.prototype.computeWorldVerticesOld = function (slot, worldVertices) { - this.computeWorldVertices(slot, 0, this.worldVerticesLength, worldVertices, 0, 2); - }; - /** Transforms local vertices to world coordinates. - * @param start The index of the first local vertex value to transform. Each vertex has 2 values, x and y. - * @param count The number of world vertex values to output. Must be <= {@link #getWorldVerticesLength()} - start. - * @param worldVertices The output world vertices. Must have a length >= offset + count. - * @param offset The worldVertices index to begin writing values. */ - VertexAttachment.prototype.computeWorldVertices = function (slot, start, count, worldVertices, offset, stride) { - count = offset + (count >> 1) * stride; - var skeleton = slot.bone.skeleton; - var deformArray = slot.attachmentVertices; - var vertices = this.vertices; - var bones = this.bones; - if (bones == null) { - if (deformArray.length > 0) - vertices = deformArray; - var mat = slot.bone.matrix; - var x = mat.tx; - var y = mat.ty; - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - for (var v_1 = start, w = offset; w < count; v_1 += 2, w += stride) { - var vx = vertices[v_1], vy = vertices[v_1 + 1]; - worldVertices[w] = vx * a + vy * b + x; - worldVertices[w + 1] = vx * c + vy * d + y; - } - return; - } - var v = 0, skip = 0; - for (var i = 0; i < start; i += 2) { - var n = bones[v]; - v += n + 1; - skip += n; - } - var skeletonBones = skeleton.bones; - if (deformArray.length == 0) { - for (var w = offset, b = skip * 3; w < count; w += stride) { - var wx = 0, wy = 0; - var n = bones[v++]; - n += v; - for (; v < n; v++, b += 3) { - var mat = skeletonBones[bones[v]].matrix; - var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; - wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; - wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; - } - worldVertices[w] = wx; - worldVertices[w + 1] = wy; - } - } - else { - var deform = deformArray; - for (var w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { - var wx = 0, wy = 0; - var n = bones[v++]; - n += v; - for (; v < n; v++, b += 3, f += 2) { - var mat = skeletonBones[bones[v]].matrix; - var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; - wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; - wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; - } - worldVertices[w] = wx; - worldVertices[w + 1] = wy; - } - } - }; - /** Returns true if a deform originally applied to the specified attachment should be applied to this attachment. */ - VertexAttachment.prototype.applyDeform = function (sourceAttachment) { - return this == sourceAttachment; - }; - VertexAttachment.nextID = 0; - return VertexAttachment; - }(Attachment$1)); - - /** - * @public - */ - var BoundingBoxAttachment$1 = /** @class */ (function (_super) { - __extends$2(BoundingBoxAttachment, _super); - function BoundingBoxAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.BoundingBox; - _this.color = new Color(1, 1, 1, 1); - return _this; - } - return BoundingBoxAttachment; - }(VertexAttachment$1)); - - /** - * @public - */ - var ClippingAttachment$1 = /** @class */ (function (_super) { - __extends$2(ClippingAttachment, _super); - function ClippingAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Clipping; - // Nonessential. - _this.color = new Color(0.2275, 0.2275, 0.8078, 1); // ce3a3aff - return _this; - } - return ClippingAttachment; - }(VertexAttachment$1)); - - /** - * @public - */ - var MeshAttachment$1 = /** @class */ (function (_super) { - __extends$2(MeshAttachment, _super); - function MeshAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Mesh; - _this.color = new Color(1, 1, 1, 1); - _this.inheritDeform = false; - _this.tempColor = new Color(0, 0, 0, 0); - return _this; - } - MeshAttachment.prototype.applyDeform = function (sourceAttachment) { - return this == sourceAttachment || (this.inheritDeform && this.parentMesh == sourceAttachment); - }; - MeshAttachment.prototype.getParentMesh = function () { - return this.parentMesh; - }; - /** @param parentMesh May be null. */ - MeshAttachment.prototype.setParentMesh = function (parentMesh) { - this.parentMesh = parentMesh; - if (parentMesh != null) { - this.bones = parentMesh.bones; - this.vertices = parentMesh.vertices; - this.worldVerticesLength = parentMesh.worldVerticesLength; - this.regionUVs = parentMesh.regionUVs; - this.triangles = parentMesh.triangles; - this.hullLength = parentMesh.hullLength; - this.worldVerticesLength = parentMesh.worldVerticesLength; - } - }; - return MeshAttachment; - }(VertexAttachment$1)); - - /** - * @public - */ - var PathAttachment$1 = /** @class */ (function (_super) { - __extends$2(PathAttachment, _super); - function PathAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Path; - _this.closed = false; - _this.constantSpeed = false; - _this.color = new Color(1, 1, 1, 1); - return _this; - } - return PathAttachment; - }(VertexAttachment$1)); - - /** - * @public - */ - var PointAttachment$1 = /** @class */ (function (_super) { - __extends$2(PointAttachment, _super); - function PointAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Point; - _this.color = new Color(0.38, 0.94, 0, 1); - return _this; - } - PointAttachment.prototype.computeWorldPosition = function (bone, point) { - var mat = bone.matrix; - point.x = this.x * mat.a + this.y * mat.c + bone.worldX; - point.y = this.x * mat.b + this.y * mat.d + bone.worldY; - return point; - }; - PointAttachment.prototype.computeWorldRotation = function (bone) { - var mat = bone.matrix; - var cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation); - var x = cos * mat.a + sin * mat.c; - var y = cos * mat.b + sin * mat.d; - return Math.atan2(y, x) * MathUtils.radDeg; - }; - return PointAttachment; - }(VertexAttachment$1)); - - /** - * @public - */ - var Slot$1 = /** @class */ (function () { - function Slot(data, bone) { - this.attachmentVertices = new Array(); - if (data == null) - throw new Error("data cannot be null."); - if (bone == null) - throw new Error("bone cannot be null."); - this.data = data; - this.bone = bone; - this.color = new Color(); - this.darkColor = data.darkColor == null ? null : new Color(); - this.setToSetupPose(); - this.blendMode = this.data.blendMode; - } - /** @return May be null. */ - Slot.prototype.getAttachment = function () { - return this.attachment; - }; - /** Sets the attachment and if it changed, resets {@link #getAttachmentTime()} and clears {@link #getAttachmentVertices()}. - * @param attachment May be null. */ - Slot.prototype.setAttachment = function (attachment) { - if (this.attachment == attachment) - return; - this.attachment = attachment; - this.attachmentTime = this.bone.skeleton.time; - this.attachmentVertices.length = 0; - }; - Slot.prototype.setAttachmentTime = function (time) { - this.attachmentTime = this.bone.skeleton.time - time; - }; - /** Returns the time since the attachment was set. */ - Slot.prototype.getAttachmentTime = function () { - return this.bone.skeleton.time - this.attachmentTime; - }; - Slot.prototype.setToSetupPose = function () { - this.color.setFromColor(this.data.color); - if (this.darkColor != null) - this.darkColor.setFromColor(this.data.darkColor); - if (this.data.attachmentName == null) - this.attachment = null; - else { - this.attachment = null; - this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName)); - } - }; - return Slot; - }()); - - /** - * @public - */ - var RegionAttachment$1 = /** @class */ (function (_super) { - __extends$2(RegionAttachment, _super); - function RegionAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Region; - _this.x = 0; - _this.y = 0; - _this.scaleX = 1; - _this.scaleY = 1; - _this.rotation = 0; - _this.width = 0; - _this.height = 0; - _this.color = new Color(1, 1, 1, 1); - _this.offset = Utils.newFloatArray(8); - _this.uvs = Utils.newFloatArray(8); - _this.tempColor = new Color(1, 1, 1, 1); - return _this; - } - RegionAttachment.prototype.updateOffset = function () { - var regionScaleX = this.width / this.region.originalWidth * this.scaleX; - var regionScaleY = this.height / this.region.originalHeight * this.scaleY; - var localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; - var localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; - var localX2 = localX + this.region.width * regionScaleX; - var localY2 = localY + this.region.height * regionScaleY; - var radians = this.rotation * Math.PI / 180; - var cos = Math.cos(radians); - var sin = Math.sin(radians); - var localXCos = localX * cos + this.x; - var localXSin = localX * sin; - var localYCos = localY * cos + this.y; - var localYSin = localY * sin; - var localX2Cos = localX2 * cos + this.x; - var localX2Sin = localX2 * sin; - var localY2Cos = localY2 * cos + this.y; - var localY2Sin = localY2 * sin; - var offset = this.offset; - offset[RegionAttachment.OX1] = localXCos - localYSin; - offset[RegionAttachment.OY1] = localYCos + localXSin; - offset[RegionAttachment.OX2] = localXCos - localY2Sin; - offset[RegionAttachment.OY2] = localY2Cos + localXSin; - offset[RegionAttachment.OX3] = localX2Cos - localY2Sin; - offset[RegionAttachment.OY3] = localY2Cos + localX2Sin; - offset[RegionAttachment.OX4] = localX2Cos - localYSin; - offset[RegionAttachment.OY4] = localYCos + localX2Sin; - }; - RegionAttachment.prototype.setRegion = function (region) { - this.region = region; - var uvs = this.uvs; - if (region.rotate) { - uvs[2] = region.u; - uvs[3] = region.v2; - uvs[4] = region.u; - uvs[5] = region.v; - uvs[6] = region.u2; - uvs[7] = region.v; - uvs[0] = region.u2; - uvs[1] = region.v2; - } - else { - uvs[0] = region.u; - uvs[1] = region.v2; - uvs[2] = region.u; - uvs[3] = region.v; - uvs[4] = region.u2; - uvs[5] = region.v; - uvs[6] = region.u2; - uvs[7] = region.v2; - } - }; - RegionAttachment.prototype.computeWorldVertices = function (bone, worldVertices, offset, stride) { - var vertexOffset = this.offset; - var mat = bone instanceof Slot$1 ? bone.bone.matrix : bone.matrix; - var x = mat.tx, y = mat.ty; - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var offsetX = 0, offsetY = 0; - offsetX = vertexOffset[RegionAttachment.OX1]; - offsetY = vertexOffset[RegionAttachment.OY1]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // br - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - offset += stride; - offsetX = vertexOffset[RegionAttachment.OX2]; - offsetY = vertexOffset[RegionAttachment.OY2]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // bl - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - offset += stride; - offsetX = vertexOffset[RegionAttachment.OX3]; - offsetY = vertexOffset[RegionAttachment.OY3]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // ul - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - offset += stride; - offsetX = vertexOffset[RegionAttachment.OX4]; - offsetY = vertexOffset[RegionAttachment.OY4]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // ur - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - }; - RegionAttachment.OX1 = 0; - RegionAttachment.OY1 = 1; - RegionAttachment.OX2 = 2; - RegionAttachment.OY2 = 3; - RegionAttachment.OX3 = 4; - RegionAttachment.OY3 = 5; - RegionAttachment.OX4 = 6; - RegionAttachment.OY4 = 7; - RegionAttachment.X1 = 0; - RegionAttachment.Y1 = 1; - RegionAttachment.C1R = 2; - RegionAttachment.C1G = 3; - RegionAttachment.C1B = 4; - RegionAttachment.C1A = 5; - RegionAttachment.U1 = 6; - RegionAttachment.V1 = 7; - RegionAttachment.X2 = 8; - RegionAttachment.Y2 = 9; - RegionAttachment.C2R = 10; - RegionAttachment.C2G = 11; - RegionAttachment.C2B = 12; - RegionAttachment.C2A = 13; - RegionAttachment.U2 = 14; - RegionAttachment.V2 = 15; - RegionAttachment.X3 = 16; - RegionAttachment.Y3 = 17; - RegionAttachment.C3R = 18; - RegionAttachment.C3G = 19; - RegionAttachment.C3B = 20; - RegionAttachment.C3A = 21; - RegionAttachment.U3 = 22; - RegionAttachment.V3 = 23; - RegionAttachment.X4 = 24; - RegionAttachment.Y4 = 25; - RegionAttachment.C4R = 26; - RegionAttachment.C4G = 27; - RegionAttachment.C4B = 28; - RegionAttachment.C4A = 29; - RegionAttachment.U4 = 30; - RegionAttachment.V4 = 31; - return RegionAttachment; - }(Attachment$1)); - - /** - * @public - */ - var JitterEffect = /** @class */ (function () { - function JitterEffect(jitterX, jitterY) { - this.jitterX = 0; - this.jitterY = 0; - this.jitterX = jitterX; - this.jitterY = jitterY; - } - JitterEffect.prototype.begin = function (skeleton) { - }; - JitterEffect.prototype.transform = function (position, uv, light, dark) { - position.x += MathUtils.randomTriangular(-this.jitterX, this.jitterY); - position.y += MathUtils.randomTriangular(-this.jitterX, this.jitterY); - }; - JitterEffect.prototype.end = function () { - }; - return JitterEffect; - }()); - - /** - * @public - */ - var SwirlEffect = /** @class */ (function () { - function SwirlEffect(radius) { - this.centerX = 0; - this.centerY = 0; - this.radius = 0; - this.angle = 0; - this.worldX = 0; - this.worldY = 0; - this.radius = radius; - } - SwirlEffect.prototype.begin = function (skeleton) { - this.worldX = skeleton.x + this.centerX; - this.worldY = skeleton.y + this.centerY; - }; - SwirlEffect.prototype.transform = function (position, uv, light, dark) { - var radAngle = this.angle * MathUtils.degreesToRadians; - var x = position.x - this.worldX; - var y = position.y - this.worldY; - var dist = Math.sqrt(x * x + y * y); - if (dist < this.radius) { - var theta = SwirlEffect.interpolation.apply(0, radAngle, (this.radius - dist) / this.radius); - var cos = Math.cos(theta); - var sin = Math.sin(theta); - position.x = cos * x - sin * y + this.worldX; - position.y = sin * x + cos * y + this.worldY; - } - }; - SwirlEffect.prototype.end = function () { - }; - SwirlEffect.interpolation = new PowOut(2); - return SwirlEffect; - }()); - - /** - * @public - */ - var Animation$1 = /** @class */ (function () { - function Animation(name, timelines, duration) { - if (name == null) - throw new Error("name cannot be null."); - if (timelines == null) - throw new Error("timelines cannot be null."); - this.name = name; - this.timelines = timelines; - this.duration = duration; - } - Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, blend, direction) { - if (skeleton == null) - throw new Error("skeleton cannot be null."); - if (loop && this.duration != 0) { - time %= this.duration; - if (lastTime > 0) - lastTime %= this.duration; - } - var timelines = this.timelines; - for (var i = 0, n = timelines.length; i < n; i++) - timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction); - }; - Animation.binarySearch = function (values, target, step) { - if (step === void 0) { step = 1; } - var low = 0; - var high = values.length / step - 2; - if (high == 0) - return step; - var current = high >>> 1; - while (true) { - if (values[(current + 1) * step] <= target) - low = current + 1; - else - high = current; - if (low == high) - return (low + 1) * step; - current = (low + high) >>> 1; - } - }; - Animation.linearSearch = function (values, target, step) { - for (var i = 0, last = values.length - step; i <= last; i += step) - if (values[i] > target) - return i; - return -1; - }; - return Animation; - }()); - /** - * @public - */ - var TimelineType; - (function (TimelineType) { - TimelineType[TimelineType["rotate"] = 0] = "rotate"; - TimelineType[TimelineType["translate"] = 1] = "translate"; - TimelineType[TimelineType["scale"] = 2] = "scale"; - TimelineType[TimelineType["shear"] = 3] = "shear"; - TimelineType[TimelineType["attachment"] = 4] = "attachment"; - TimelineType[TimelineType["color"] = 5] = "color"; - TimelineType[TimelineType["deform"] = 6] = "deform"; - TimelineType[TimelineType["event"] = 7] = "event"; - TimelineType[TimelineType["drawOrder"] = 8] = "drawOrder"; - TimelineType[TimelineType["ikConstraint"] = 9] = "ikConstraint"; - TimelineType[TimelineType["transformConstraint"] = 10] = "transformConstraint"; - TimelineType[TimelineType["pathConstraintPosition"] = 11] = "pathConstraintPosition"; - TimelineType[TimelineType["pathConstraintSpacing"] = 12] = "pathConstraintSpacing"; - TimelineType[TimelineType["pathConstraintMix"] = 13] = "pathConstraintMix"; - TimelineType[TimelineType["twoColor"] = 14] = "twoColor"; - })(TimelineType || (TimelineType = {})); - /** - * @public - */ - var CurveTimeline$1 = /** @class */ (function () { - function CurveTimeline(frameCount) { - if (frameCount <= 0) - throw new Error("frameCount must be > 0: " + frameCount); - this.curves = Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE); - } - CurveTimeline.prototype.getFrameCount = function () { - return this.curves.length / CurveTimeline.BEZIER_SIZE + 1; - }; - CurveTimeline.prototype.setLinear = function (frameIndex) { - this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.LINEAR; - }; - CurveTimeline.prototype.setStepped = function (frameIndex) { - this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.STEPPED; - }; - CurveTimeline.prototype.getCurveType = function (frameIndex) { - var index = frameIndex * CurveTimeline.BEZIER_SIZE; - if (index == this.curves.length) - return CurveTimeline.LINEAR; - var type = this.curves[index]; - if (type == CurveTimeline.LINEAR) - return CurveTimeline.LINEAR; - if (type == CurveTimeline.STEPPED) - return CurveTimeline.STEPPED; - return CurveTimeline.BEZIER; - }; - /** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next. - * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of - * the difference between the keyframe's values. */ - CurveTimeline.prototype.setCurve = function (frameIndex, cx1, cy1, cx2, cy2) { - var tmpx = (-cx1 * 2 + cx2) * 0.03, tmpy = (-cy1 * 2 + cy2) * 0.03; - var dddfx = ((cx1 - cx2) * 3 + 1) * 0.006, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006; - var ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy; - var dfx = cx1 * 0.3 + tmpx + dddfx * 0.16666667, dfy = cy1 * 0.3 + tmpy + dddfy * 0.16666667; - var i = frameIndex * CurveTimeline.BEZIER_SIZE; - var curves = this.curves; - curves[i++] = CurveTimeline.BEZIER; - var x = dfx, y = dfy; - for (var n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { - curves[i] = x; - curves[i + 1] = y; - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - x += dfx; - y += dfy; - } - }; - CurveTimeline.prototype.getCurvePercent = function (frameIndex, percent) { - percent = MathUtils.clamp(percent, 0, 1); - var curves = this.curves; - var i = frameIndex * CurveTimeline.BEZIER_SIZE; - var type = curves[i]; - if (type == CurveTimeline.LINEAR) - return percent; - if (type == CurveTimeline.STEPPED) - return 0; - i++; - var x = 0; - for (var start = i, n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { - x = curves[i]; - if (x >= percent) { - var prevX = void 0, prevY = void 0; - if (i == start) { - prevX = 0; - prevY = 0; - } - else { - prevX = curves[i - 2]; - prevY = curves[i - 1]; - } - return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX); - } - } - var y = curves[i - 1]; - return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1. - }; - CurveTimeline.LINEAR = 0; - CurveTimeline.STEPPED = 1; - CurveTimeline.BEZIER = 2; - CurveTimeline.BEZIER_SIZE = 10 * 2 - 1; - return CurveTimeline; - }()); - /** - * @public - */ - var RotateTimeline$1 = /** @class */ (function (_super) { - __extends$2(RotateTimeline, _super); - function RotateTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount << 1); - return _this; - } - RotateTimeline.prototype.getPropertyId = function () { - return (TimelineType.rotate << 24) + this.boneIndex; - }; - /** Sets the time and angle of the specified keyframe. */ - RotateTimeline.prototype.setFrame = function (frameIndex, time, degrees) { - frameIndex <<= 1; - this.frames[frameIndex] = time; - this.frames[frameIndex + RotateTimeline.ROTATION] = degrees; - }; - RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var frames = this.frames; - var bone = skeleton.bones[this.boneIndex]; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.rotation = bone.data.rotation; - return; - case exports.MixBlend.first: - var r_1 = bone.data.rotation - bone.rotation; - bone.rotation += (r_1 - (16384 - ((16384.499999999996 - r_1 / 360) | 0)) * 360) * alpha; - } - return; - } - if (time >= frames[frames.length - RotateTimeline.ENTRIES]) { // Time is after last frame. - var r_2 = frames[frames.length + RotateTimeline.PREV_ROTATION]; - switch (blend) { - case exports.MixBlend.setup: - bone.rotation = bone.data.rotation + r_2 * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - r_2 += bone.data.rotation - bone.rotation; - r_2 -= (16384 - ((16384.499999999996 - r_2 / 360) | 0)) * 360; // Wrap within -180 and 180. - case exports.MixBlend.add: - bone.rotation += r_2 * alpha; - } - return; - } - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, RotateTimeline.ENTRIES); - var prevRotation = frames[frame + RotateTimeline.PREV_ROTATION]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime)); - var r = frames[frame + RotateTimeline.ROTATION] - prevRotation; - r = prevRotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * percent; - switch (blend) { - case exports.MixBlend.setup: - bone.rotation = bone.data.rotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - r += bone.data.rotation - bone.rotation; - case exports.MixBlend.add: - bone.rotation += (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; - } - }; - RotateTimeline.ENTRIES = 2; - RotateTimeline.PREV_TIME = -2; - RotateTimeline.PREV_ROTATION = -1; - RotateTimeline.ROTATION = 1; - return RotateTimeline; - }(CurveTimeline$1)); - /** - * @public - */ - var TranslateTimeline$1 = /** @class */ (function (_super) { - __extends$2(TranslateTimeline, _super); - function TranslateTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES); - return _this; - } - TranslateTimeline.prototype.getPropertyId = function () { - return (TimelineType.translate << 24) + this.boneIndex; - }; - /** Sets the time and value of the specified keyframe. */ - TranslateTimeline.prototype.setFrame = function (frameIndex, time, x, y) { - frameIndex *= TranslateTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + TranslateTimeline.X] = x; - this.frames[frameIndex + TranslateTimeline.Y] = y; - }; - TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var frames = this.frames; - var bone = skeleton.bones[this.boneIndex]; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.x = bone.data.x; - bone.y = bone.data.y; - return; - case exports.MixBlend.first: - bone.x += (bone.data.x - bone.x) * alpha; - bone.y += (bone.data.y - bone.y) * alpha; - } - return; - } - var x = 0, y = 0; - if (time >= frames[frames.length - TranslateTimeline.ENTRIES]) { // Time is after last frame. - x = frames[frames.length + TranslateTimeline.PREV_X]; - y = frames[frames.length + TranslateTimeline.PREV_Y]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, TranslateTimeline.ENTRIES); - x = frames[frame + TranslateTimeline.PREV_X]; - y = frames[frame + TranslateTimeline.PREV_Y]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / TranslateTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TranslateTimeline.PREV_TIME] - frameTime)); - x += (frames[frame + TranslateTimeline.X] - x) * percent; - y += (frames[frame + TranslateTimeline.Y] - y) * percent; - } - switch (blend) { - case exports.MixBlend.setup: - bone.x = bone.data.x + x * alpha; - bone.y = bone.data.y + y * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bone.x += (bone.data.x + x - bone.x) * alpha; - bone.y += (bone.data.y + y - bone.y) * alpha; - break; - case exports.MixBlend.add: - bone.x += x * alpha; - bone.y += y * alpha; - } - }; - TranslateTimeline.ENTRIES = 3; - TranslateTimeline.PREV_TIME = -3; - TranslateTimeline.PREV_X = -2; - TranslateTimeline.PREV_Y = -1; - TranslateTimeline.X = 1; - TranslateTimeline.Y = 2; - return TranslateTimeline; - }(CurveTimeline$1)); - /** - * @public - */ - var ScaleTimeline$1 = /** @class */ (function (_super) { - __extends$2(ScaleTimeline, _super); - function ScaleTimeline(frameCount) { - return _super.call(this, frameCount) || this; - } - ScaleTimeline.prototype.getPropertyId = function () { - return (TimelineType.scale << 24) + this.boneIndex; - }; - ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var frames = this.frames; - var bone = skeleton.bones[this.boneIndex]; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.scaleX = bone.data.scaleX; - bone.scaleY = bone.data.scaleY; - return; - case exports.MixBlend.first: - bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; - bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; - } - return; - } - var x = 0, y = 0; - if (time >= frames[frames.length - ScaleTimeline.ENTRIES]) { // Time is after last frame. - x = frames[frames.length + ScaleTimeline.PREV_X] * bone.data.scaleX; - y = frames[frames.length + ScaleTimeline.PREV_Y] * bone.data.scaleY; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, ScaleTimeline.ENTRIES); - x = frames[frame + ScaleTimeline.PREV_X]; - y = frames[frame + ScaleTimeline.PREV_Y]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / ScaleTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ScaleTimeline.PREV_TIME] - frameTime)); - x = (x + (frames[frame + ScaleTimeline.X] - x) * percent) * bone.data.scaleX; - y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY; - } - if (alpha == 1) { - if (blend == exports.MixBlend.add) { - bone.scaleX += x - bone.data.scaleX; - bone.scaleY += y - bone.data.scaleY; - } - else { - bone.scaleX = x; - bone.scaleY = y; - } - } - else { - var bx = 0, by = 0; - if (direction == exports.MixDirection.mixOut) { - switch (blend) { - case exports.MixBlend.setup: - bx = bone.data.scaleX; - by = bone.data.scaleY; - bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; - bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bx = bone.scaleX; - by = bone.scaleY; - bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; - bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; - break; - case exports.MixBlend.add: - bx = bone.scaleX; - by = bone.scaleY; - bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bone.data.scaleX) * alpha; - bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - bone.data.scaleY) * alpha; - } - } - else { - switch (blend) { - case exports.MixBlend.setup: - bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x); - by = Math.abs(bone.data.scaleY) * MathUtils.signum(y); - bone.scaleX = bx + (x - bx) * alpha; - bone.scaleY = by + (y - by) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bx = Math.abs(bone.scaleX) * MathUtils.signum(x); - by = Math.abs(bone.scaleY) * MathUtils.signum(y); - bone.scaleX = bx + (x - bx) * alpha; - bone.scaleY = by + (y - by) * alpha; - break; - case exports.MixBlend.add: - bx = MathUtils.signum(x); - by = MathUtils.signum(y); - bone.scaleX = Math.abs(bone.scaleX) * bx + (x - Math.abs(bone.data.scaleX) * bx) * alpha; - bone.scaleY = Math.abs(bone.scaleY) * by + (y - Math.abs(bone.data.scaleY) * by) * alpha; - } - } - } - }; - return ScaleTimeline; - }(TranslateTimeline$1)); - /** - * @public - */ - var ShearTimeline$1 = /** @class */ (function (_super) { - __extends$2(ShearTimeline, _super); - function ShearTimeline(frameCount) { - return _super.call(this, frameCount) || this; - } - ShearTimeline.prototype.getPropertyId = function () { - return (TimelineType.shear << 24) + this.boneIndex; - }; - ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var frames = this.frames; - var bone = skeleton.bones[this.boneIndex]; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.shearX = bone.data.shearX; - bone.shearY = bone.data.shearY; - return; - case exports.MixBlend.first: - bone.shearX += (bone.data.shearX - bone.shearX) * alpha; - bone.shearY += (bone.data.shearY - bone.shearY) * alpha; - } - return; - } - var x = 0, y = 0; - if (time >= frames[frames.length - ShearTimeline.ENTRIES]) { // Time is after last frame. - x = frames[frames.length + ShearTimeline.PREV_X]; - y = frames[frames.length + ShearTimeline.PREV_Y]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, ShearTimeline.ENTRIES); - x = frames[frame + ShearTimeline.PREV_X]; - y = frames[frame + ShearTimeline.PREV_Y]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / ShearTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ShearTimeline.PREV_TIME] - frameTime)); - x = x + (frames[frame + ShearTimeline.X] - x) * percent; - y = y + (frames[frame + ShearTimeline.Y] - y) * percent; - } - switch (blend) { - case exports.MixBlend.setup: - bone.shearX = bone.data.shearX + x * alpha; - bone.shearY = bone.data.shearY + y * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; - bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; - break; - case exports.MixBlend.add: - bone.shearX += x * alpha; - bone.shearY += y * alpha; - } - }; - return ShearTimeline; - }(TranslateTimeline$1)); - /** - * @public - */ - var ColorTimeline = /** @class */ (function (_super) { - __extends$2(ColorTimeline, _super); - function ColorTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES); - return _this; - } - ColorTimeline.prototype.getPropertyId = function () { - return (TimelineType.color << 24) + this.slotIndex; - }; - /** Sets the time and value of the specified keyframe. */ - ColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a) { - frameIndex *= ColorTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + ColorTimeline.R] = r; - this.frames[frameIndex + ColorTimeline.G] = g; - this.frames[frameIndex + ColorTimeline.B] = b; - this.frames[frameIndex + ColorTimeline.A] = a; - }; - ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - slot.color.setFromColor(slot.data.color); - return; - case exports.MixBlend.first: - var color = slot.color, setup = slot.data.color; - color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha); - } - return; - } - var r = 0, g = 0, b = 0, a = 0; - if (time >= frames[frames.length - ColorTimeline.ENTRIES]) { // Time is after last frame. - var i = frames.length; - r = frames[i + ColorTimeline.PREV_R]; - g = frames[i + ColorTimeline.PREV_G]; - b = frames[i + ColorTimeline.PREV_B]; - a = frames[i + ColorTimeline.PREV_A]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, ColorTimeline.ENTRIES); - r = frames[frame + ColorTimeline.PREV_R]; - g = frames[frame + ColorTimeline.PREV_G]; - b = frames[frame + ColorTimeline.PREV_B]; - a = frames[frame + ColorTimeline.PREV_A]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / ColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ColorTimeline.PREV_TIME] - frameTime)); - r += (frames[frame + ColorTimeline.R] - r) * percent; - g += (frames[frame + ColorTimeline.G] - g) * percent; - b += (frames[frame + ColorTimeline.B] - b) * percent; - a += (frames[frame + ColorTimeline.A] - a) * percent; - } - if (alpha == 1) - slot.color.set(r, g, b, a); - else { - var color = slot.color; - if (blend == exports.MixBlend.setup) - color.setFromColor(slot.data.color); - color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha); - } - }; - ColorTimeline.ENTRIES = 5; - ColorTimeline.PREV_TIME = -5; - ColorTimeline.PREV_R = -4; - ColorTimeline.PREV_G = -3; - ColorTimeline.PREV_B = -2; - ColorTimeline.PREV_A = -1; - ColorTimeline.R = 1; - ColorTimeline.G = 2; - ColorTimeline.B = 3; - ColorTimeline.A = 4; - return ColorTimeline; - }(CurveTimeline$1)); - /** - * @public - */ - var TwoColorTimeline = /** @class */ (function (_super) { - __extends$2(TwoColorTimeline, _super); - function TwoColorTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES); - return _this; - } - TwoColorTimeline.prototype.getPropertyId = function () { - return (TimelineType.twoColor << 24) + this.slotIndex; - }; - /** Sets the time and value of the specified keyframe. */ - TwoColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a, r2, g2, b2) { - frameIndex *= TwoColorTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + TwoColorTimeline.R] = r; - this.frames[frameIndex + TwoColorTimeline.G] = g; - this.frames[frameIndex + TwoColorTimeline.B] = b; - this.frames[frameIndex + TwoColorTimeline.A] = a; - this.frames[frameIndex + TwoColorTimeline.R2] = r2; - this.frames[frameIndex + TwoColorTimeline.G2] = g2; - this.frames[frameIndex + TwoColorTimeline.B2] = b2; - }; - TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - slot.color.setFromColor(slot.data.color); - slot.darkColor.setFromColor(slot.data.darkColor); - return; - case exports.MixBlend.first: - var light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor; - light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha); - dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0); - } - return; - } - var r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; - if (time >= frames[frames.length - TwoColorTimeline.ENTRIES]) { // Time is after last frame. - var i = frames.length; - r = frames[i + TwoColorTimeline.PREV_R]; - g = frames[i + TwoColorTimeline.PREV_G]; - b = frames[i + TwoColorTimeline.PREV_B]; - a = frames[i + TwoColorTimeline.PREV_A]; - r2 = frames[i + TwoColorTimeline.PREV_R2]; - g2 = frames[i + TwoColorTimeline.PREV_G2]; - b2 = frames[i + TwoColorTimeline.PREV_B2]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, TwoColorTimeline.ENTRIES); - r = frames[frame + TwoColorTimeline.PREV_R]; - g = frames[frame + TwoColorTimeline.PREV_G]; - b = frames[frame + TwoColorTimeline.PREV_B]; - a = frames[frame + TwoColorTimeline.PREV_A]; - r2 = frames[frame + TwoColorTimeline.PREV_R2]; - g2 = frames[frame + TwoColorTimeline.PREV_G2]; - b2 = frames[frame + TwoColorTimeline.PREV_B2]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / TwoColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TwoColorTimeline.PREV_TIME] - frameTime)); - r += (frames[frame + TwoColorTimeline.R] - r) * percent; - g += (frames[frame + TwoColorTimeline.G] - g) * percent; - b += (frames[frame + TwoColorTimeline.B] - b) * percent; - a += (frames[frame + TwoColorTimeline.A] - a) * percent; - r2 += (frames[frame + TwoColorTimeline.R2] - r2) * percent; - g2 += (frames[frame + TwoColorTimeline.G2] - g2) * percent; - b2 += (frames[frame + TwoColorTimeline.B2] - b2) * percent; - } - if (alpha == 1) { - slot.color.set(r, g, b, a); - slot.darkColor.set(r2, g2, b2, 1); - } - else { - var light = slot.color, dark = slot.darkColor; - if (blend == exports.MixBlend.setup) { - light.setFromColor(slot.data.color); - dark.setFromColor(slot.data.darkColor); - } - light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha); - dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0); - } - }; - TwoColorTimeline.ENTRIES = 8; - TwoColorTimeline.PREV_TIME = -8; - TwoColorTimeline.PREV_R = -7; - TwoColorTimeline.PREV_G = -6; - TwoColorTimeline.PREV_B = -5; - TwoColorTimeline.PREV_A = -4; - TwoColorTimeline.PREV_R2 = -3; - TwoColorTimeline.PREV_G2 = -2; - TwoColorTimeline.PREV_B2 = -1; - TwoColorTimeline.R = 1; - TwoColorTimeline.G = 2; - TwoColorTimeline.B = 3; - TwoColorTimeline.A = 4; - TwoColorTimeline.R2 = 5; - TwoColorTimeline.G2 = 6; - TwoColorTimeline.B2 = 7; - return TwoColorTimeline; - }(CurveTimeline$1)); - /** - * @public - */ - var AttachmentTimeline$1 = /** @class */ (function () { - function AttachmentTimeline(frameCount) { - this.frames = Utils.newFloatArray(frameCount); - this.attachmentNames = new Array(frameCount); - } - AttachmentTimeline.prototype.getPropertyId = function () { - return (TimelineType.attachment << 24) + this.slotIndex; - }; - AttachmentTimeline.prototype.getFrameCount = function () { - return this.frames.length; - }; - /** Sets the time and value of the specified keyframe. */ - AttachmentTimeline.prototype.setFrame = function (frameIndex, time, attachmentName) { - this.frames[frameIndex] = time; - this.attachmentNames[frameIndex] = attachmentName; - }; - AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (direction == exports.MixDirection.mixOut && blend == exports.MixBlend.setup) { - var attachmentName_1 = slot.data.attachmentName; - slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1)); - return; - } - var frames = this.frames; - if (time < frames[0]) { - if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) { - var attachmentName_2 = slot.data.attachmentName; - slot.setAttachment(attachmentName_2 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_2)); - } - return; - } - var frameIndex = 0; - if (time >= frames[frames.length - 1]) // Time is after last frame. - frameIndex = frames.length - 1; - else - frameIndex = Animation$1.binarySearch(frames, time, 1) - 1; - var attachmentName = this.attachmentNames[frameIndex]; - skeleton.slots[this.slotIndex] - .setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); - }; - return AttachmentTimeline; - }()); - var zeros = null; - /** - * @public - */ - var DeformTimeline$1 = /** @class */ (function (_super) { - __extends$2(DeformTimeline, _super); - function DeformTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount); - _this.frameVertices = new Array(frameCount); - if (zeros == null) - zeros = Utils.newFloatArray(64); - return _this; - } - DeformTimeline.prototype.getPropertyId = function () { - return (TimelineType.deform << 27) + +this.attachment.id + this.slotIndex; - }; - /** Sets the time of the specified keyframe. */ - DeformTimeline.prototype.setFrame = function (frameIndex, time, vertices) { - this.frames[frameIndex] = time; - this.frameVertices[frameIndex] = vertices; - }; - DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - var slotAttachment = slot.getAttachment(); - if (!(slotAttachment instanceof VertexAttachment$1) || !slotAttachment.applyDeform(this.attachment)) - return; - var verticesArray = slot.attachmentVertices; - if (verticesArray.length == 0) - blend = exports.MixBlend.setup; - var frameVertices = this.frameVertices; - var vertexCount = frameVertices[0].length; - var frames = this.frames; - if (time < frames[0]) { - var vertexAttachment = slotAttachment; - switch (blend) { - case exports.MixBlend.setup: - verticesArray.length = 0; - return; - case exports.MixBlend.first: - if (alpha == 1) { - verticesArray.length = 0; - break; - } - var vertices_1 = Utils.setArraySize(verticesArray, vertexCount); - if (vertexAttachment.bones == null) { - // Unweighted vertex positions. - var setupVertices = vertexAttachment.vertices; - for (var i = 0; i < vertexCount; i++) - vertices_1[i] += (setupVertices[i] - vertices_1[i]) * alpha; - } - else { - // Weighted deform offsets. - alpha = 1 - alpha; - for (var i = 0; i < vertexCount; i++) - vertices_1[i] *= alpha; - } - } - return; - } - var vertices = Utils.setArraySize(verticesArray, vertexCount); - if (time >= frames[frames.length - 1]) { // Time is after last frame. - var lastVertices = frameVertices[frames.length - 1]; - if (alpha == 1) { - if (blend == exports.MixBlend.add) { - var vertexAttachment = slotAttachment; - if (vertexAttachment.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i = 0; i < vertexCount; i++) { - vertices[i] += lastVertices[i] - setupVertices[i]; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i = 0; i < vertexCount; i++) - vertices[i] += lastVertices[i]; - } - } - else { - Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount); - } - } - else { - switch (blend) { - case exports.MixBlend.setup: { - var vertexAttachment_1 = slotAttachment; - if (vertexAttachment_1.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment_1.vertices; - for (var i = 0; i < vertexCount; i++) { - var setup = setupVertices[i]; - vertices[i] = setup + (lastVertices[i] - setup) * alpha; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i = 0; i < vertexCount; i++) - vertices[i] = lastVertices[i] * alpha; - } - break; - } - case exports.MixBlend.first: - case exports.MixBlend.replace: - for (var i = 0; i < vertexCount; i++) - vertices[i] += (lastVertices[i] - vertices[i]) * alpha; - case exports.MixBlend.add: - var vertexAttachment = slotAttachment; - if (vertexAttachment.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i = 0; i < vertexCount; i++) { - vertices[i] += (lastVertices[i] - setupVertices[i]) * alpha; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i = 0; i < vertexCount; i++) - vertices[i] += lastVertices[i] * alpha; - } - } - } - return; - } - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time); - var prevVertices = frameVertices[frame - 1]; - var nextVertices = frameVertices[frame]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime)); - if (alpha == 1) { - if (blend == exports.MixBlend.add) { - var vertexAttachment = slotAttachment; - if (vertexAttachment.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i = 0; i < vertexCount; i++) { - var prev = prevVertices[i]; - vertices[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i]; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i = 0; i < vertexCount; i++) { - var prev = prevVertices[i]; - vertices[i] += prev + (nextVertices[i] - prev) * percent; - } - } - } - else { - for (var i = 0; i < vertexCount; i++) { - var prev = prevVertices[i]; - vertices[i] = prev + (nextVertices[i] - prev) * percent; - } - } - } - else { - switch (blend) { - case exports.MixBlend.setup: { - var vertexAttachment_2 = slotAttachment; - if (vertexAttachment_2.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment_2.vertices; - for (var i = 0; i < vertexCount; i++) { - var prev = prevVertices[i], setup = setupVertices[i]; - vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i = 0; i < vertexCount; i++) { - var prev = prevVertices[i]; - vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha; - } - } - break; - } - case exports.MixBlend.first: - case exports.MixBlend.replace: - for (var i = 0; i < vertexCount; i++) { - var prev = prevVertices[i]; - vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha; - } - break; - case exports.MixBlend.add: - var vertexAttachment = slotAttachment; - if (vertexAttachment.bones == null) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i = 0; i < vertexCount; i++) { - var prev = prevVertices[i]; - vertices[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i = 0; i < vertexCount; i++) { - var prev = prevVertices[i]; - vertices[i] += (prev + (nextVertices[i] - prev) * percent) * alpha; - } - } - } - } - }; - return DeformTimeline; - }(CurveTimeline$1)); - /** - * @public - */ - var EventTimeline$1 = /** @class */ (function () { - function EventTimeline(frameCount) { - this.frames = Utils.newFloatArray(frameCount); - this.events = new Array(frameCount); - } - EventTimeline.prototype.getPropertyId = function () { - return TimelineType.event << 24; - }; - EventTimeline.prototype.getFrameCount = function () { - return this.frames.length; - }; - /** Sets the time of the specified keyframe. */ - EventTimeline.prototype.setFrame = function (frameIndex, event) { - this.frames[frameIndex] = event.time; - this.events[frameIndex] = event; - }; - /** Fires events for frames > lastTime and <= time. */ - EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - if (firedEvents == null) - return; - var frames = this.frames; - var frameCount = this.frames.length; - if (lastTime > time) { // Fire events after last time for looped animations. - this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction); - lastTime = -1; - } - else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame. - return; - if (time < frames[0]) - return; // Time is before first frame. - var frame = 0; - if (lastTime < frames[0]) - frame = 0; - else { - frame = Animation$1.binarySearch(frames, lastTime); - var frameTime = frames[frame]; - while (frame > 0) { // Fire multiple events with the same frame. - if (frames[frame - 1] != frameTime) - break; - frame--; - } - } - for (; frame < frameCount && time >= frames[frame]; frame++) - firedEvents.push(this.events[frame]); - }; - return EventTimeline; - }()); - /** - * @public - */ - var DrawOrderTimeline$1 = /** @class */ (function () { - function DrawOrderTimeline(frameCount) { - this.frames = Utils.newFloatArray(frameCount); - this.drawOrders = new Array(frameCount); - } - DrawOrderTimeline.prototype.getPropertyId = function () { - return TimelineType.drawOrder << 24; - }; - DrawOrderTimeline.prototype.getFrameCount = function () { - return this.frames.length; - }; - /** Sets the time of the specified keyframe. - * @param drawOrder May be null to use bind pose draw order. */ - DrawOrderTimeline.prototype.setFrame = function (frameIndex, time, drawOrder) { - this.frames[frameIndex] = time; - this.drawOrders[frameIndex] = drawOrder; - }; - DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var drawOrder = skeleton.drawOrder; - var slots = skeleton.slots; - if (direction == exports.MixDirection.mixOut && blend == exports.MixBlend.setup) { - Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); - return; - } - var frames = this.frames; - if (time < frames[0]) { - if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) - Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); - return; - } - var frame = 0; - if (time >= frames[frames.length - 1]) // Time is after last frame. - frame = frames.length - 1; - else - frame = Animation$1.binarySearch(frames, time) - 1; - var drawOrderToSetupIndex = this.drawOrders[frame]; - if (drawOrderToSetupIndex == null) - Utils.arrayCopy(slots, 0, drawOrder, 0, slots.length); - else { - for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++) - drawOrder[i] = slots[drawOrderToSetupIndex[i]]; - } - }; - return DrawOrderTimeline; - }()); - /** - * @public - */ - var IkConstraintTimeline$1 = /** @class */ (function (_super) { - __extends$2(IkConstraintTimeline, _super); - function IkConstraintTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES); - return _this; - } - IkConstraintTimeline.prototype.getPropertyId = function () { - return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex; - }; - /** Sets the time, mix and bend direction of the specified keyframe. */ - IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection, compress, stretch) { - frameIndex *= IkConstraintTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; - this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; - this.frames[frameIndex + IkConstraintTimeline.COMPRESS] = compress ? 1 : 0; - this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0; - }; - IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var frames = this.frames; - var constraint = skeleton.ikConstraints[this.ikConstraintIndex]; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.mix = constraint.data.mix; - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - return; - case exports.MixBlend.first: - constraint.mix += (constraint.data.mix - constraint.mix) * alpha; - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - } - return; - } - if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { // Time is after last frame. - if (blend == exports.MixBlend.setup) { - constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; - if (direction == exports.MixDirection.mixOut) { - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - } - else { - constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; - constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; - constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; - } - } - else { - constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; - if (direction == exports.MixDirection.mixIn) { - constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; - constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; - constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; - } - } - return; - } - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, IkConstraintTimeline.ENTRIES); - var mix = frames[frame + IkConstraintTimeline.PREV_MIX]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); - if (blend == exports.MixBlend.setup) { - constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; - if (direction == exports.MixDirection.mixOut) { - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - } - else { - constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; - constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; - constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; - } - } - else { - constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; - if (direction == exports.MixDirection.mixIn) { - constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; - constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; - constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; - } - } - }; - IkConstraintTimeline.ENTRIES = 5; - IkConstraintTimeline.PREV_TIME = -5; - IkConstraintTimeline.PREV_MIX = -4; - IkConstraintTimeline.PREV_BEND_DIRECTION = -3; - IkConstraintTimeline.PREV_COMPRESS = -2; - IkConstraintTimeline.PREV_STRETCH = -1; - IkConstraintTimeline.MIX = 1; - IkConstraintTimeline.BEND_DIRECTION = 2; - IkConstraintTimeline.COMPRESS = 3; - IkConstraintTimeline.STRETCH = 4; - return IkConstraintTimeline; - }(CurveTimeline$1)); - /** - * @public - */ - var TransformConstraintTimeline$1 = /** @class */ (function (_super) { - __extends$2(TransformConstraintTimeline, _super); - function TransformConstraintTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES); - return _this; - } - TransformConstraintTimeline.prototype.getPropertyId = function () { - return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex; - }; - /** Sets the time and mixes of the specified keyframe. */ - TransformConstraintTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix, scaleMix, shearMix) { - frameIndex *= TransformConstraintTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + TransformConstraintTimeline.ROTATE] = rotateMix; - this.frames[frameIndex + TransformConstraintTimeline.TRANSLATE] = translateMix; - this.frames[frameIndex + TransformConstraintTimeline.SCALE] = scaleMix; - this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix; - }; - TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var frames = this.frames; - var constraint = skeleton.transformConstraints[this.transformConstraintIndex]; - if (time < frames[0]) { - var data = constraint.data; - switch (blend) { - case exports.MixBlend.setup: - constraint.rotateMix = data.rotateMix; - constraint.translateMix = data.translateMix; - constraint.scaleMix = data.scaleMix; - constraint.shearMix = data.shearMix; - return; - case exports.MixBlend.first: - constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha; - constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha; - constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha; - constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha; - } - return; - } - var rotate = 0, translate = 0, scale = 0, shear = 0; - if (time >= frames[frames.length - TransformConstraintTimeline.ENTRIES]) { // Time is after last frame. - var i = frames.length; - rotate = frames[i + TransformConstraintTimeline.PREV_ROTATE]; - translate = frames[i + TransformConstraintTimeline.PREV_TRANSLATE]; - scale = frames[i + TransformConstraintTimeline.PREV_SCALE]; - shear = frames[i + TransformConstraintTimeline.PREV_SHEAR]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, TransformConstraintTimeline.ENTRIES); - rotate = frames[frame + TransformConstraintTimeline.PREV_ROTATE]; - translate = frames[frame + TransformConstraintTimeline.PREV_TRANSLATE]; - scale = frames[frame + TransformConstraintTimeline.PREV_SCALE]; - shear = frames[frame + TransformConstraintTimeline.PREV_SHEAR]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / TransformConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TransformConstraintTimeline.PREV_TIME] - frameTime)); - rotate += (frames[frame + TransformConstraintTimeline.ROTATE] - rotate) * percent; - translate += (frames[frame + TransformConstraintTimeline.TRANSLATE] - translate) * percent; - scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent; - shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent; - } - if (blend == exports.MixBlend.setup) { - var data = constraint.data; - constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha; - constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha; - constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha; - constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha; - } - else { - constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; - constraint.translateMix += (translate - constraint.translateMix) * alpha; - constraint.scaleMix += (scale - constraint.scaleMix) * alpha; - constraint.shearMix += (shear - constraint.shearMix) * alpha; - } - }; - TransformConstraintTimeline.ENTRIES = 5; - TransformConstraintTimeline.PREV_TIME = -5; - TransformConstraintTimeline.PREV_ROTATE = -4; - TransformConstraintTimeline.PREV_TRANSLATE = -3; - TransformConstraintTimeline.PREV_SCALE = -2; - TransformConstraintTimeline.PREV_SHEAR = -1; - TransformConstraintTimeline.ROTATE = 1; - TransformConstraintTimeline.TRANSLATE = 2; - TransformConstraintTimeline.SCALE = 3; - TransformConstraintTimeline.SHEAR = 4; - return TransformConstraintTimeline; - }(CurveTimeline$1)); - /** - * @public - */ - var PathConstraintPositionTimeline$1 = /** @class */ (function (_super) { - __extends$2(PathConstraintPositionTimeline, _super); - function PathConstraintPositionTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES); - return _this; - } - PathConstraintPositionTimeline.prototype.getPropertyId = function () { - return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex; - }; - /** Sets the time and value of the specified keyframe. */ - PathConstraintPositionTimeline.prototype.setFrame = function (frameIndex, time, value) { - frameIndex *= PathConstraintPositionTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value; - }; - PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var frames = this.frames; - var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.position = constraint.data.position; - return; - case exports.MixBlend.first: - constraint.position += (constraint.data.position - constraint.position) * alpha; - } - return; - } - var position = 0; - if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES]) // Time is after last frame. - position = frames[frames.length + PathConstraintPositionTimeline.PREV_VALUE]; - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, PathConstraintPositionTimeline.ENTRIES); - position = frames[frame + PathConstraintPositionTimeline.PREV_VALUE]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime)); - position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent; - } - if (blend == exports.MixBlend.setup) - constraint.position = constraint.data.position + (position - constraint.data.position) * alpha; - else - constraint.position += (position - constraint.position) * alpha; - }; - PathConstraintPositionTimeline.ENTRIES = 2; - PathConstraintPositionTimeline.PREV_TIME = -2; - PathConstraintPositionTimeline.PREV_VALUE = -1; - PathConstraintPositionTimeline.VALUE = 1; - return PathConstraintPositionTimeline; - }(CurveTimeline$1)); - /** - * @public - */ - var PathConstraintSpacingTimeline$1 = /** @class */ (function (_super) { - __extends$2(PathConstraintSpacingTimeline, _super); - function PathConstraintSpacingTimeline(frameCount) { - return _super.call(this, frameCount) || this; - } - PathConstraintSpacingTimeline.prototype.getPropertyId = function () { - return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex; - }; - PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var frames = this.frames; - var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.spacing = constraint.data.spacing; - return; - case exports.MixBlend.first: - constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha; - } - return; - } - var spacing = 0; - if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES]) // Time is after last frame. - spacing = frames[frames.length + PathConstraintSpacingTimeline.PREV_VALUE]; - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, PathConstraintSpacingTimeline.ENTRIES); - spacing = frames[frame + PathConstraintSpacingTimeline.PREV_VALUE]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime)); - spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent; - } - if (blend == exports.MixBlend.setup) - constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha; - else - constraint.spacing += (spacing - constraint.spacing) * alpha; - }; - return PathConstraintSpacingTimeline; - }(PathConstraintPositionTimeline$1)); - /** - * @public - */ - var PathConstraintMixTimeline$1 = /** @class */ (function (_super) { - __extends$2(PathConstraintMixTimeline, _super); - function PathConstraintMixTimeline(frameCount) { - var _this = _super.call(this, frameCount) || this; - _this.frames = Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES); - return _this; - } - PathConstraintMixTimeline.prototype.getPropertyId = function () { - return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex; - }; - /** Sets the time and mixes of the specified keyframe. */ - PathConstraintMixTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix) { - frameIndex *= PathConstraintMixTimeline.ENTRIES; - this.frames[frameIndex] = time; - this.frames[frameIndex + PathConstraintMixTimeline.ROTATE] = rotateMix; - this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix; - }; - PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var frames = this.frames; - var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.rotateMix = constraint.data.rotateMix; - constraint.translateMix = constraint.data.translateMix; - return; - case exports.MixBlend.first: - constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha; - constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha; - } - return; - } - var rotate = 0, translate = 0; - if (time >= frames[frames.length - PathConstraintMixTimeline.ENTRIES]) { // Time is after last frame. - rotate = frames[frames.length + PathConstraintMixTimeline.PREV_ROTATE]; - translate = frames[frames.length + PathConstraintMixTimeline.PREV_TRANSLATE]; - } - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, PathConstraintMixTimeline.ENTRIES); - rotate = frames[frame + PathConstraintMixTimeline.PREV_ROTATE]; - translate = frames[frame + PathConstraintMixTimeline.PREV_TRANSLATE]; - var frameTime = frames[frame]; - var percent = this.getCurvePercent(frame / PathConstraintMixTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintMixTimeline.PREV_TIME] - frameTime)); - rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent; - translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent; - } - if (blend == exports.MixBlend.setup) { - constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha; - constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha; - } - else { - constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; - constraint.translateMix += (translate - constraint.translateMix) * alpha; - } - }; - PathConstraintMixTimeline.ENTRIES = 3; - PathConstraintMixTimeline.PREV_TIME = -3; - PathConstraintMixTimeline.PREV_ROTATE = -2; - PathConstraintMixTimeline.PREV_TRANSLATE = -1; - PathConstraintMixTimeline.ROTATE = 1; - PathConstraintMixTimeline.TRANSLATE = 2; - return PathConstraintMixTimeline; - }(CurveTimeline$1)); - - /** - * @public - */ - var AnimationState$1 = /** @class */ (function () { - function AnimationState(data) { - this.tracks = new Array(); - this.events = new Array(); - this.listeners = new Array(); - this.queue = new EventQueue$1(this); - this.propertyIDs = new IntSet(); - this.animationsChanged = false; - this.timeScale = 1; - this.trackEntryPool = new Pool(function () { return new TrackEntry$1(); }); - this.data = data; - } - AnimationState.prototype.update = function (delta) { - delta *= this.timeScale; - var tracks = this.tracks; - for (var i = 0, n = tracks.length; i < n; i++) { - var current = tracks[i]; - if (current == null) - continue; - current.animationLast = current.nextAnimationLast; - current.trackLast = current.nextTrackLast; - var currentDelta = delta * current.timeScale; - if (current.delay > 0) { - current.delay -= currentDelta; - if (current.delay > 0) - continue; - currentDelta = -current.delay; - current.delay = 0; - } - var next = current.next; - if (next != null) { - // When the next entry's delay is passed, change to the next entry, preserving leftover time. - var nextTime = current.trackLast - next.delay; - if (nextTime >= 0) { - next.delay = 0; - next.trackTime = current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale; - current.trackTime += currentDelta; - this.setCurrent(i, next, true); - while (next.mixingFrom != null) { - next.mixTime += delta; - next = next.mixingFrom; - } - continue; - } - } - else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) { - tracks[i] = null; - this.queue.end(current); - this.disposeNext(current); - continue; - } - if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) { - // End mixing from entries once all have completed. - var from = current.mixingFrom; - current.mixingFrom = null; - if (from != null) - from.mixingTo = null; - while (from != null) { - this.queue.end(from); - from = from.mixingFrom; - } - } - current.trackTime += currentDelta; - } - this.queue.drain(); - }; - AnimationState.prototype.updateMixingFrom = function (to, delta) { - var from = to.mixingFrom; - if (from == null) - return true; - var finished = this.updateMixingFrom(from, delta); - from.animationLast = from.nextAnimationLast; - from.trackLast = from.nextTrackLast; - // Require mixTime > 0 to ensure the mixing from entry was applied at least once. - if (to.mixTime > 0 && to.mixTime >= to.mixDuration) { - // Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame). - if (from.totalAlpha == 0 || to.mixDuration == 0) { - to.mixingFrom = from.mixingFrom; - if (from.mixingFrom != null) - from.mixingFrom.mixingTo = to; - to.interruptAlpha = from.interruptAlpha; - this.queue.end(from); - } - return finished; - } - from.trackTime += delta * from.timeScale; - to.mixTime += delta; - return false; - }; - AnimationState.prototype.apply = function (skeleton) { - if (skeleton == null) - throw new Error("skeleton cannot be null."); - if (this.animationsChanged) - this._animationsChanged(); - var events = this.events; - var tracks = this.tracks; - var applied = false; - for (var i = 0, n = tracks.length; i < n; i++) { - var current = tracks[i]; - if (current == null || current.delay > 0) - continue; - applied = true; - var blend = i == 0 ? exports.MixBlend.first : current.mixBlend; - // Apply mixing from entries first. - var mix = current.alpha; - if (current.mixingFrom != null) - mix *= this.applyMixingFrom(current, skeleton, blend); - else if (current.trackTime >= current.trackEnd && current.next == null) - mix = 0; - // Apply current entry. - var animationLast = current.animationLast, animationTime = current.getAnimationTime(); - var timelineCount = current.animation.timelines.length; - var timelines = current.animation.timelines; - if ((i == 0 && mix == 1) || blend == exports.MixBlend.add) { - for (var ii = 0; ii < timelineCount; ii++) { - // Fixes issue #302 on IOS9 where mix, blend sometimes became undefined and caused assets - // to sometimes stop rendering when using color correction, as their RGBA values become NaN. - // (https://github.com/pixijs/pixi-spine/issues/302) - Utils.webkit602BugfixHelper(mix, blend); - timelines[ii].apply(skeleton, animationLast, animationTime, events, mix, blend, exports.MixDirection.mixIn); - } - } - else { - var timelineMode = current.timelineMode; - var firstFrame = current.timelinesRotation.length == 0; - if (firstFrame) - Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null); - var timelinesRotation = current.timelinesRotation; - for (var ii = 0; ii < timelineCount; ii++) { - var timeline = timelines[ii]; - var timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : exports.MixBlend.setup; - if (timeline instanceof RotateTimeline$1) { - this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame); - } - else { - // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 - Utils.webkit602BugfixHelper(mix, blend); - timeline.apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, exports.MixDirection.mixIn); - } - } - } - this.queueEvents(current, animationTime); - events.length = 0; - current.nextAnimationLast = animationTime; - current.nextTrackLast = current.trackTime; - } - this.queue.drain(); - return applied; - }; - AnimationState.prototype.applyMixingFrom = function (to, skeleton, blend) { - var from = to.mixingFrom; - if (from.mixingFrom != null) - this.applyMixingFrom(from, skeleton, blend); - var mix = 0; - if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. - mix = 1; - if (blend == exports.MixBlend.first) - blend = exports.MixBlend.setup; - } - else { - mix = to.mixTime / to.mixDuration; - if (mix > 1) - mix = 1; - if (blend != exports.MixBlend.first) - blend = from.mixBlend; - } - var events = mix < from.eventThreshold ? this.events : null; - var attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold; - var animationLast = from.animationLast, animationTime = from.getAnimationTime(); - var timelineCount = from.animation.timelines.length; - var timelines = from.animation.timelines; - var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); - if (blend == exports.MixBlend.add) { - for (var i = 0; i < timelineCount; i++) - timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, exports.MixDirection.mixOut); - } - else { - var timelineMode = from.timelineMode; - var timelineHoldMix = from.timelineHoldMix; - var firstFrame = from.timelinesRotation.length == 0; - if (firstFrame) - Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null); - var timelinesRotation = from.timelinesRotation; - from.totalAlpha = 0; - for (var i = 0; i < timelineCount; i++) { - var timeline = timelines[i]; - var direction = exports.MixDirection.mixOut; - var timelineBlend = void 0; - var alpha = 0; - switch (timelineMode[i]) { - case AnimationState.SUBSEQUENT: - if (!attachments && timeline instanceof AttachmentTimeline$1) - continue; - if (!drawOrder && timeline instanceof DrawOrderTimeline$1) - continue; - timelineBlend = blend; - alpha = alphaMix; - break; - case AnimationState.FIRST: - timelineBlend = exports.MixBlend.setup; - alpha = alphaMix; - break; - case AnimationState.HOLD: - timelineBlend = exports.MixBlend.setup; - alpha = alphaHold; - break; - default: - timelineBlend = exports.MixBlend.setup; - var holdMix = timelineHoldMix[i]; - alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration); - break; - } - from.totalAlpha += alpha; - if (timeline instanceof RotateTimeline$1) - this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame); - else { - // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 - Utils.webkit602BugfixHelper(alpha, blend); - if (timelineBlend == exports.MixBlend.setup) { - if (timeline instanceof AttachmentTimeline$1) { - if (attachments) - direction = exports.MixDirection.mixOut; - } - else if (timeline instanceof DrawOrderTimeline$1) { - if (drawOrder) - direction = exports.MixDirection.mixOut; - } - } - timeline.apply(skeleton, animationLast, animationTime, events, alpha, timelineBlend, direction); - } - } - } - if (to.mixDuration > 0) - this.queueEvents(from, animationTime); - this.events.length = 0; - from.nextAnimationLast = animationTime; - from.nextTrackLast = from.trackTime; - return mix; - }; - AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) { - if (firstFrame) - timelinesRotation[i] = 0; - if (alpha == 1) { - timeline.apply(skeleton, 0, time, null, 1, blend, exports.MixDirection.mixIn); - return; - } - var rotateTimeline = timeline; - var frames = rotateTimeline.frames; - var bone = skeleton.bones[rotateTimeline.boneIndex]; - var r1 = 0, r2 = 0; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.rotation = bone.data.rotation; - default: - return; - case exports.MixBlend.first: - r1 = bone.rotation; - r2 = bone.data.rotation; - } - } - else { - r1 = blend == exports.MixBlend.setup ? bone.data.rotation : bone.rotation; - if (time >= frames[frames.length - RotateTimeline$1.ENTRIES]) // Time is after last frame. - r2 = bone.data.rotation + frames[frames.length + RotateTimeline$1.PREV_ROTATION]; - else { - // Interpolate between the previous frame and the current frame. - var frame = Animation$1.binarySearch(frames, time, RotateTimeline$1.ENTRIES); - var prevRotation = frames[frame + RotateTimeline$1.PREV_ROTATION]; - var frameTime = frames[frame]; - var percent = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline$1.PREV_TIME] - frameTime)); - r2 = frames[frame + RotateTimeline$1.ROTATION] - prevRotation; - r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; - r2 = prevRotation + r2 * percent + bone.data.rotation; - r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; - } - } - // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. - var total = 0, diff = r2 - r1; - diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360; - if (diff == 0) { - total = timelinesRotation[i]; - } - else { - var lastTotal = 0, lastDiff = 0; - if (firstFrame) { - lastTotal = 0; - lastDiff = diff; - } - else { - lastTotal = timelinesRotation[i]; // Angle and direction of mix, including loops. - lastDiff = timelinesRotation[i + 1]; // Difference between bones. - } - var current = diff > 0, dir = lastTotal >= 0; - // Detect cross at 0 (not 180). - if (MathUtils.signum(lastDiff) != MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) { - // A cross after a 360 rotation is a loop. - if (Math.abs(lastTotal) > 180) - lastTotal += 360 * MathUtils.signum(lastTotal); - dir = current; - } - total = diff + lastTotal - lastTotal % 360; // Store loops as part of lastTotal. - if (dir != current) - total += 360 * MathUtils.signum(lastTotal); - timelinesRotation[i] = total; - } - timelinesRotation[i + 1] = diff; - r1 += total * alpha; - bone.rotation = r1 - (16384 - ((16384.499999999996 - r1 / 360) | 0)) * 360; - }; - AnimationState.prototype.queueEvents = function (entry, animationTime) { - var animationStart = entry.animationStart, animationEnd = entry.animationEnd; - var duration = animationEnd - animationStart; - var trackLastWrapped = entry.trackLast % duration; - // Queue events before complete. - var events = this.events; - var i = 0, n = events.length; - for (; i < n; i++) { - var event_1 = events[i]; - if (event_1.time < trackLastWrapped) - break; - if (event_1.time > animationEnd) - continue; // Discard events outside animation start/end. - this.queue.event(entry, event_1); - } - // Queue complete if completed a loop iteration or the animation. - var complete = false; - if (entry.loop) - complete = duration == 0 || trackLastWrapped > entry.trackTime % duration; - else - complete = animationTime >= animationEnd && entry.animationLast < animationEnd; - if (complete) - this.queue.complete(entry); - // Queue events after complete. - for (; i < n; i++) { - var event_2 = events[i]; - if (event_2.time < animationStart) - continue; // Discard events outside animation start/end. - this.queue.event(entry, events[i]); - } - }; - AnimationState.prototype.clearTracks = function () { - var oldDrainDisabled = this.queue.drainDisabled; - this.queue.drainDisabled = true; - for (var i = 0, n = this.tracks.length; i < n; i++) - this.clearTrack(i); - this.tracks.length = 0; - this.queue.drainDisabled = oldDrainDisabled; - this.queue.drain(); - }; - AnimationState.prototype.clearTrack = function (trackIndex) { - if (trackIndex >= this.tracks.length) - return; - var current = this.tracks[trackIndex]; - if (current == null) - return; - this.queue.end(current); - this.disposeNext(current); - var entry = current; - while (true) { - var from = entry.mixingFrom; - if (from == null) - break; - this.queue.end(from); - entry.mixingFrom = null; - entry.mixingTo = null; - entry = from; - } - this.tracks[current.trackIndex] = null; - this.queue.drain(); - }; - AnimationState.prototype.setCurrent = function (index, current, interrupt) { - var from = this.expandToIndex(index); - this.tracks[index] = current; - if (from != null) { - if (interrupt) - this.queue.interrupt(from); - current.mixingFrom = from; - from.mixingTo = current; - current.mixTime = 0; - // Store the interrupted mix percentage. - if (from.mixingFrom != null && from.mixDuration > 0) - current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration); - from.timelinesRotation.length = 0; // Reset rotation for mixing out, in case entry was mixed in. - } - this.queue.start(current); - }; - AnimationState.prototype.setAnimation = function (trackIndex, animationName, loop) { - var animation = this.data.skeletonData.findAnimation(animationName); - if (animation == null) - throw new Error("Animation not found: " + animationName); - return this.setAnimationWith(trackIndex, animation, loop); - }; - AnimationState.prototype.setAnimationWith = function (trackIndex, animation, loop) { - if (animation == null) - throw new Error("animation cannot be null."); - var interrupt = true; - var current = this.expandToIndex(trackIndex); - if (current != null) { - if (current.nextTrackLast == -1) { - // Don't mix from an entry that was never applied. - this.tracks[trackIndex] = current.mixingFrom; - this.queue.interrupt(current); - this.queue.end(current); - this.disposeNext(current); - current = current.mixingFrom; - interrupt = false; - } - else - this.disposeNext(current); - } - var entry = this.trackEntry(trackIndex, animation, loop, current); - this.setCurrent(trackIndex, entry, interrupt); - this.queue.drain(); - return entry; - }; - AnimationState.prototype.addAnimation = function (trackIndex, animationName, loop, delay) { - var animation = this.data.skeletonData.findAnimation(animationName); - if (animation == null) - throw new Error("Animation not found: " + animationName); - return this.addAnimationWith(trackIndex, animation, loop, delay); - }; - AnimationState.prototype.addAnimationWith = function (trackIndex, animation, loop, delay) { - if (animation == null) - throw new Error("animation cannot be null."); - var last = this.expandToIndex(trackIndex); - if (last != null) { - while (last.next != null) - last = last.next; - } - var entry = this.trackEntry(trackIndex, animation, loop, last); - if (last == null) { - this.setCurrent(trackIndex, entry, true); - this.queue.drain(); - } - else { - last.next = entry; - if (delay <= 0) { - var duration = last.animationEnd - last.animationStart; - if (duration != 0) { - if (last.loop) - delay += duration * (1 + ((last.trackTime / duration) | 0)); - else - delay += Math.max(duration, last.trackTime); - delay -= this.data.getMix(last.animation, animation); - } - else - delay = last.trackTime; - } - } - entry.delay = delay; - return entry; - }; - AnimationState.prototype.setEmptyAnimation = function (trackIndex, mixDuration) { - var entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation, false); - entry.mixDuration = mixDuration; - entry.trackEnd = mixDuration; - return entry; - }; - AnimationState.prototype.addEmptyAnimation = function (trackIndex, mixDuration, delay) { - if (delay <= 0) - delay -= mixDuration; - var entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation, false, delay); - entry.mixDuration = mixDuration; - entry.trackEnd = mixDuration; - return entry; - }; - AnimationState.prototype.setEmptyAnimations = function (mixDuration) { - var oldDrainDisabled = this.queue.drainDisabled; - this.queue.drainDisabled = true; - for (var i = 0, n = this.tracks.length; i < n; i++) { - var current = this.tracks[i]; - if (current != null) - this.setEmptyAnimation(current.trackIndex, mixDuration); - } - this.queue.drainDisabled = oldDrainDisabled; - this.queue.drain(); - }; - AnimationState.prototype.expandToIndex = function (index) { - if (index < this.tracks.length) - return this.tracks[index]; - Utils.ensureArrayCapacity(this.tracks, index - this.tracks.length + 1, null); - this.tracks.length = index + 1; - return null; - }; - AnimationState.prototype.trackEntry = function (trackIndex, animation, loop, last) { - var entry = this.trackEntryPool.obtain(); - entry.trackIndex = trackIndex; - entry.animation = animation; - entry.loop = loop; - entry.holdPrevious = false; - entry.eventThreshold = 0; - entry.attachmentThreshold = 0; - entry.drawOrderThreshold = 0; - entry.animationStart = 0; - entry.animationEnd = animation.duration; - entry.animationLast = -1; - entry.nextAnimationLast = -1; - entry.delay = 0; - entry.trackTime = 0; - entry.trackLast = -1; - entry.nextTrackLast = -1; - entry.trackEnd = Number.MAX_VALUE; - entry.timeScale = 1; - entry.alpha = 1; - entry.interruptAlpha = 1; - entry.mixTime = 0; - entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation); - return entry; - }; - AnimationState.prototype.disposeNext = function (entry) { - var next = entry.next; - while (next != null) { - this.queue.dispose(next); - next = next.next; - } - entry.next = null; - }; - AnimationState.prototype._animationsChanged = function () { - this.animationsChanged = false; - this.propertyIDs.clear(); - for (var i = 0, n = this.tracks.length; i < n; i++) { - var entry = this.tracks[i]; - if (entry == null) - continue; - while (entry.mixingFrom != null) - entry = entry.mixingFrom; - do { - if (entry.mixingFrom == null || entry.mixBlend != exports.MixBlend.add) - this.setTimelineModes(entry); - entry = entry.mixingTo; - } while (entry != null); - } - }; - AnimationState.prototype.setTimelineModes = function (entry) { - var to = entry.mixingTo; - var timelines = entry.animation.timelines; - var timelinesCount = entry.animation.timelines.length; - var timelineMode = Utils.setArraySize(entry.timelineMode, timelinesCount); - entry.timelineHoldMix.length = 0; - var timelineDipMix = Utils.setArraySize(entry.timelineHoldMix, timelinesCount); - var propertyIDs = this.propertyIDs; - if (to != null && to.holdPrevious) { - for (var i = 0; i < timelinesCount; i++) { - propertyIDs.add(timelines[i].getPropertyId()); - timelineMode[i] = AnimationState.HOLD; - } - return; - } - outer: for (var i = 0; i < timelinesCount; i++) { - var id = timelines[i].getPropertyId(); - if (!propertyIDs.add(id)) - timelineMode[i] = AnimationState.SUBSEQUENT; - else if (to == null || !this.hasTimeline(to, id)) - timelineMode[i] = AnimationState.FIRST; - else { - for (var next = to.mixingTo; next != null; next = next.mixingTo) { - if (this.hasTimeline(next, id)) - continue; - if (entry.mixDuration > 0) { - timelineMode[i] = AnimationState.HOLD_MIX; - timelineDipMix[i] = next; - continue outer; - } - break; - } - timelineMode[i] = AnimationState.HOLD; - } - } - }; - AnimationState.prototype.hasTimeline = function (entry, id) { - var timelines = entry.animation.timelines; - for (var i = 0, n = timelines.length; i < n; i++) - if (timelines[i].getPropertyId() == id) - return true; - return false; - }; - AnimationState.prototype.getCurrent = function (trackIndex) { - if (trackIndex >= this.tracks.length) - return null; - return this.tracks[trackIndex]; - }; - AnimationState.prototype.addListener = function (listener) { - if (listener == null) - throw new Error("listener cannot be null."); - this.listeners.push(listener); - }; - /** Removes the listener added with {@link #addListener(AnimationStateListener)}. */ - AnimationState.prototype.removeListener = function (listener) { - var index = this.listeners.indexOf(listener); - if (index >= 0) - this.listeners.splice(index, 1); - }; - AnimationState.prototype.clearListeners = function () { - this.listeners.length = 0; - }; - AnimationState.prototype.clearListenerNotifications = function () { - this.queue.clear(); - }; - AnimationState.prototype.setAnimationByName = function (trackIndex, animationName, loop) { - if (!AnimationState.deprecatedWarning1) { - AnimationState.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on."); - } - this.setAnimation(trackIndex, animationName, loop); - }; - AnimationState.prototype.addAnimationByName = function (trackIndex, animationName, loop, delay) { - if (!AnimationState.deprecatedWarning2) { - AnimationState.deprecatedWarning2 = true; - console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on."); - } - this.addAnimation(trackIndex, animationName, loop, delay); - }; - AnimationState.prototype.hasAnimation = function (animationName) { - var animation = this.data.skeletonData.findAnimation(animationName); - return animation !== null; - }; - AnimationState.prototype.hasAnimationByName = function (animationName) { - if (!AnimationState.deprecatedWarning3) { - AnimationState.deprecatedWarning3 = true; - console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on."); - } - return this.hasAnimation(animationName); - }; - AnimationState.emptyAnimation = new Animation$1("", [], 0); - AnimationState.SUBSEQUENT = 0; - AnimationState.FIRST = 1; - AnimationState.HOLD = 2; - AnimationState.HOLD_MIX = 3; - AnimationState.deprecatedWarning1 = false; - AnimationState.deprecatedWarning2 = false; - AnimationState.deprecatedWarning3 = false; - return AnimationState; - }()); - /** - * @public - */ - var TrackEntry$1 = /** @class */ (function () { - function TrackEntry() { - this.mixBlend = exports.MixBlend.replace; - this.timelineMode = new Array(); - this.timelineHoldMix = new Array(); - this.timelinesRotation = new Array(); - } - TrackEntry.prototype.reset = function () { - this.next = null; - this.mixingFrom = null; - this.mixingTo = null; - this.animation = null; - this.listener = null; - this.timelineMode.length = 0; - this.timelineHoldMix.length = 0; - this.timelinesRotation.length = 0; - }; - TrackEntry.prototype.getAnimationTime = function () { - if (this.loop) { - var duration = this.animationEnd - this.animationStart; - if (duration == 0) - return this.animationStart; - return (this.trackTime % duration) + this.animationStart; - } - return Math.min(this.trackTime + this.animationStart, this.animationEnd); - }; - TrackEntry.prototype.setAnimationLast = function (animationLast) { - this.animationLast = animationLast; - this.nextAnimationLast = animationLast; - }; - TrackEntry.prototype.isComplete = function () { - return this.trackTime >= this.animationEnd - this.animationStart; - }; - TrackEntry.prototype.resetRotationDirections = function () { - this.timelinesRotation.length = 0; - }; - Object.defineProperty(TrackEntry.prototype, "time", { - get: function () { - if (!TrackEntry.deprecatedWarning1) { - TrackEntry.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); - } - return this.trackTime; - }, - set: function (value) { - if (!TrackEntry.deprecatedWarning1) { - TrackEntry.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); - } - this.trackTime = value; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TrackEntry.prototype, "endTime", { - get: function () { - if (!TrackEntry.deprecatedWarning2) { - TrackEntry.deprecatedWarning2 = true; - console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); - } - return this.trackTime; - }, - set: function (value) { - if (!TrackEntry.deprecatedWarning2) { - TrackEntry.deprecatedWarning2 = true; - console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); - } - this.trackTime = value; - }, - enumerable: false, - configurable: true - }); - TrackEntry.prototype.loopsCount = function () { - return Math.floor(this.trackTime / this.trackEnd); - }; - TrackEntry.deprecatedWarning1 = false; - TrackEntry.deprecatedWarning2 = false; - return TrackEntry; - }()); - /** - * @public - */ - var EventQueue$1 = /** @class */ (function () { - function EventQueue(animState) { - this.objects = []; - this.drainDisabled = false; - this.animState = animState; - } - EventQueue.prototype.start = function (entry) { - this.objects.push(EventType$1.start); - this.objects.push(entry); - this.animState.animationsChanged = true; - }; - EventQueue.prototype.interrupt = function (entry) { - this.objects.push(EventType$1.interrupt); - this.objects.push(entry); - }; - EventQueue.prototype.end = function (entry) { - this.objects.push(EventType$1.end); - this.objects.push(entry); - this.animState.animationsChanged = true; - }; - EventQueue.prototype.dispose = function (entry) { - this.objects.push(EventType$1.dispose); - this.objects.push(entry); - }; - EventQueue.prototype.complete = function (entry) { - this.objects.push(EventType$1.complete); - this.objects.push(entry); - }; - EventQueue.prototype.event = function (entry, event) { - this.objects.push(EventType$1.event); - this.objects.push(entry); - this.objects.push(event); - }; - EventQueue.prototype.deprecateStuff = function () { - if (!EventQueue.deprecatedWarning1) { - EventQueue.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: onComplete, onStart, onEnd, onEvent art deprecated, please use listeners from now on. 'state.addListener({ complete: function(track, event) { } })'"); - } - return true; - }; - EventQueue.prototype.drain = function () { - if (this.drainDisabled) - return; - this.drainDisabled = true; - var objects = this.objects; - var listeners = this.animState.listeners; - for (var i = 0; i < objects.length; i += 2) { - var type = objects[i]; - var entry = objects[i + 1]; - switch (type) { - case EventType$1.start: - if (entry.listener != null && entry.listener.start) - entry.listener.start(entry); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].start) - listeners[ii].start(entry); - //deprecation - entry.onStart && this.deprecateStuff() && entry.onStart(entry.trackIndex); - this.animState.onStart && this.deprecateStuff() && this.deprecateStuff && this.animState.onStart(entry.trackIndex); - break; - case EventType$1.interrupt: - if (entry.listener != null && entry.listener.interrupt) - entry.listener.interrupt(entry); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].interrupt) - listeners[ii].interrupt(entry); - break; - case EventType$1.end: - if (entry.listener != null && entry.listener.end) - entry.listener.end(entry); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].end) - listeners[ii].end(entry); - //deprecation - entry.onEnd && this.deprecateStuff() && entry.onEnd(entry.trackIndex); - this.animState.onEnd && this.deprecateStuff() && this.animState.onEnd(entry.trackIndex); - // Fall through. - case EventType$1.dispose: - if (entry.listener != null && entry.listener.dispose) - entry.listener.dispose(entry); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].dispose) - listeners[ii].dispose(entry); - this.animState.trackEntryPool.free(entry); - break; - case EventType$1.complete: - if (entry.listener != null && entry.listener.complete) - entry.listener.complete(entry); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].complete) - listeners[ii].complete(entry); - //deprecation - var count = MathUtils.toInt(entry.loopsCount()); - entry.onComplete && this.deprecateStuff() && entry.onComplete(entry.trackIndex, count); - this.animState.onComplete && this.deprecateStuff() && this.animState.onComplete(entry.trackIndex, count); - break; - case EventType$1.event: - var event_3 = objects[i++ + 2]; - if (entry.listener != null && entry.listener.event) - entry.listener.event(entry, event_3); - for (var ii = 0; ii < listeners.length; ii++) - if (listeners[ii].event) - listeners[ii].event(entry, event_3); - //deprecation - entry.onEvent && this.deprecateStuff() && entry.onEvent(entry.trackIndex, event_3); - this.animState.onEvent && this.deprecateStuff() && this.animState.onEvent(entry.trackIndex, event_3); - break; - } - } - this.clear(); - this.drainDisabled = false; - }; - EventQueue.prototype.clear = function () { - this.objects.length = 0; - }; - EventQueue.deprecatedWarning1 = false; - return EventQueue; - }()); - /** - * @public - */ - var EventType$1; - (function (EventType) { - EventType[EventType["start"] = 0] = "start"; - EventType[EventType["interrupt"] = 1] = "interrupt"; - EventType[EventType["end"] = 2] = "end"; - EventType[EventType["dispose"] = 3] = "dispose"; - EventType[EventType["complete"] = 4] = "complete"; - EventType[EventType["event"] = 5] = "event"; - })(EventType$1 || (EventType$1 = {})); - /** - * @public - */ - var AnimationStateAdapter2 = /** @class */ (function () { - function AnimationStateAdapter2() { - } - AnimationStateAdapter2.prototype.start = function (entry) { - }; - AnimationStateAdapter2.prototype.interrupt = function (entry) { - }; - AnimationStateAdapter2.prototype.end = function (entry) { - }; - AnimationStateAdapter2.prototype.dispose = function (entry) { - }; - AnimationStateAdapter2.prototype.complete = function (entry) { - }; - AnimationStateAdapter2.prototype.event = function (entry, event) { - }; - return AnimationStateAdapter2; - }()); - - /** - * @public - */ - var AnimationStateData$1 = /** @class */ (function () { - function AnimationStateData(skeletonData) { - this.animationToMixTime = {}; - this.defaultMix = 0; - if (skeletonData == null) - throw new Error("skeletonData cannot be null."); - this.skeletonData = skeletonData; - } - AnimationStateData.prototype.setMix = function (fromName, toName, duration) { - var from = this.skeletonData.findAnimation(fromName); - if (from == null) - throw new Error("Animation not found: " + fromName); - var to = this.skeletonData.findAnimation(toName); - if (to == null) - throw new Error("Animation not found: " + toName); - this.setMixWith(from, to, duration); - }; - AnimationStateData.prototype.setMixByName = function (fromName, toName, duration) { - if (!AnimationStateData.deprecatedWarning1) { - AnimationStateData.deprecatedWarning1 = true; - console.warn("Deprecation Warning: AnimationStateData.setMixByName is deprecated, please use setMix from now on."); - } - this.setMix(fromName, toName, duration); - }; - AnimationStateData.prototype.setMixWith = function (from, to, duration) { - if (from == null) - throw new Error("from cannot be null."); - if (to == null) - throw new Error("to cannot be null."); - var key = from.name + "." + to.name; - this.animationToMixTime[key] = duration; - }; - AnimationStateData.prototype.getMix = function (from, to) { - var key = from.name + "." + to.name; - var value = this.animationToMixTime[key]; - return value === undefined ? this.defaultMix : value; - }; - AnimationStateData.deprecatedWarning1 = false; - return AnimationStateData; - }()); - - /** - * @public - */ - var AtlasAttachmentLoader$1 = /** @class */ (function () { - function AtlasAttachmentLoader(atlas) { - this.atlas = atlas; - } - /** @return May be null to not load an attachment. */ - AtlasAttachmentLoader.prototype.newRegionAttachment = function (skin, name, path) { - var region = this.atlas.findRegion(path); - if (region == null) - throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); - var attachment = new RegionAttachment$1(name); - attachment.region = region; - return attachment; - }; - /** @return May be null to not load an attachment. */ - AtlasAttachmentLoader.prototype.newMeshAttachment = function (skin, name, path) { - var region = this.atlas.findRegion(path); - if (region == null) - throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); - var attachment = new MeshAttachment$1(name); - attachment.region = region; - return attachment; - }; - /** @return May be null to not load an attachment. */ - AtlasAttachmentLoader.prototype.newBoundingBoxAttachment = function (skin, name) { - return new BoundingBoxAttachment$1(name); - }; - /** @return May be null to not load an attachment */ - AtlasAttachmentLoader.prototype.newPathAttachment = function (skin, name) { - return new PathAttachment$1(name); - }; - AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) { - return new PointAttachment$1(name); - }; - AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) { - return new ClippingAttachment$1(name); - }; - return AtlasAttachmentLoader; - }()); - - /** - * @public - */ - var Bone$1 = /** @class */ (function () { - /** @param parent May be null. */ - function Bone(data, skeleton, parent) { - //be careful! Spine b,c is c,b in pixi matrix - this.matrix = new math.Matrix(); - this.children = new Array(); - this.x = 0; - this.y = 0; - this.rotation = 0; - this.scaleX = 0; - this.scaleY = 0; - this.shearX = 0; - this.shearY = 0; - this.ax = 0; - this.ay = 0; - this.arotation = 0; - this.ascaleX = 0; - this.ascaleY = 0; - this.ashearX = 0; - this.ashearY = 0; - this.appliedValid = false; - this.sorted = false; - /** NOT USED IN 3.7. Needed for the debug graph code */ - this.active = true; - if (data == null) - throw new Error("data cannot be null."); - if (skeleton == null) - throw new Error("skeleton cannot be null."); - this.data = data; - this.skeleton = skeleton; - this.parent = parent; - this.setToSetupPose(); - } - Object.defineProperty(Bone.prototype, "worldX", { - get: function () { - return this.matrix.tx; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Bone.prototype, "worldY", { - get: function () { - return this.matrix.ty; - }, - enumerable: false, - configurable: true - }); - /** Same as {@link #updateWorldTransform()}. This method exists for Bone to implement {@link Updatable}. */ - Bone.prototype.update = function () { - this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); - }; - /** Computes the world transform using the parent bone and this bone's local transform. */ - Bone.prototype.updateWorldTransform = function () { - this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); - }; - /** Computes the world transform using the parent bone and the specified local transform. */ - Bone.prototype.updateWorldTransformWith = function (x, y, rotation, scaleX, scaleY, shearX, shearY) { - this.ax = x; - this.ay = y; - this.arotation = rotation; - this.ascaleX = scaleX; - this.ascaleY = scaleY; - this.ashearX = shearX; - this.ashearY = shearY; - this.appliedValid = true; - var parent = this.parent; - var m = this.matrix; - var sx = this.skeleton.scaleX; - var sy = settings.yDown ? -this.skeleton.scaleY : this.skeleton.scaleY; - if (parent == null) { // Root bone. - var skeleton = this.skeleton; - var rotationY = rotation + 90 + shearY; - m.a = MathUtils.cosDeg(rotation + shearX) * scaleX * sx; - m.c = MathUtils.cosDeg(rotationY) * scaleY * sx; - m.b = MathUtils.sinDeg(rotation + shearX) * scaleX * sy; - m.d = MathUtils.sinDeg(rotationY) * scaleY * sy; - m.tx = x * sx + skeleton.x; - m.ty = y * sy + skeleton.y; - return; - } - var pa = parent.matrix.a, pb = parent.matrix.c, pc = parent.matrix.b, pd = parent.matrix.d; - m.tx = pa * x + pb * y + parent.matrix.tx; - m.ty = pc * x + pd * y + parent.matrix.ty; - switch (this.data.transformMode) { - case exports.TransformMode.Normal: { - var rotationY = rotation + 90 + shearY; - var la = MathUtils.cosDeg(rotation + shearX) * scaleX; - var lb = MathUtils.cosDeg(rotationY) * scaleY; - var lc = MathUtils.sinDeg(rotation + shearX) * scaleX; - var ld = MathUtils.sinDeg(rotationY) * scaleY; - m.a = pa * la + pb * lc; - m.c = pa * lb + pb * ld; - m.b = pc * la + pd * lc; - m.d = pc * lb + pd * ld; - return; - } - case exports.TransformMode.OnlyTranslation: { - var rotationY = rotation + 90 + shearY; - m.a = MathUtils.cosDeg(rotation + shearX) * scaleX; - m.c = MathUtils.cosDeg(rotationY) * scaleY; - m.b = MathUtils.sinDeg(rotation + shearX) * scaleX; - m.d = MathUtils.sinDeg(rotationY) * scaleY; - break; - } - case exports.TransformMode.NoRotationOrReflection: { - var s = pa * pa + pc * pc; - var prx = 0; - if (s > 0.0001) { - s = Math.abs(pa * pd - pb * pc) / s; - pb = pc * s; - pd = pa * s; - prx = Math.atan2(pc, pa) * MathUtils.radDeg; - } - else { - pa = 0; - pc = 0; - prx = 90 - Math.atan2(pd, pb) * MathUtils.radDeg; - } - var rx = rotation + shearX - prx; - var ry = rotation + shearY - prx + 90; - var la = MathUtils.cosDeg(rx) * scaleX; - var lb = MathUtils.cosDeg(ry) * scaleY; - var lc = MathUtils.sinDeg(rx) * scaleX; - var ld = MathUtils.sinDeg(ry) * scaleY; - m.a = pa * la - pb * lc; - m.c = pa * lb - pb * ld; - m.b = pc * la + pd * lc; - m.d = pc * lb + pd * ld; - break; - } - case exports.TransformMode.NoScale: - case exports.TransformMode.NoScaleOrReflection: { - var cos = MathUtils.cosDeg(rotation); - var sin = MathUtils.sinDeg(rotation); - var za = (pa * cos + pb * sin) / sx; - var zc = (pc * cos + pd * sin) / sy; - var s = Math.sqrt(za * za + zc * zc); - if (s > 0.00001) - s = 1 / s; - za *= s; - zc *= s; - s = Math.sqrt(za * za + zc * zc); - if (this.data.transformMode == exports.TransformMode.NoScale - && (pa * pd - pb * pc < 0) != (settings.yDown ? - (this.skeleton.scaleX < 0 != this.skeleton.scaleY > 0) : - (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0))) - s = -s; - var r = Math.PI / 2 + Math.atan2(zc, za); - var zb = Math.cos(r) * s; - var zd = Math.sin(r) * s; - var la = MathUtils.cosDeg(shearX) * scaleX; - var lb = MathUtils.cosDeg(90 + shearY) * scaleY; - var lc = MathUtils.sinDeg(shearX) * scaleX; - var ld = MathUtils.sinDeg(90 + shearY) * scaleY; - m.a = za * la + zb * lc; - m.c = za * lb + zb * ld; - m.b = zc * la + zd * lc; - m.d = zc * lb + zd * ld; - break; - } - } - m.a *= sx; - m.c *= sx; - m.b *= sy; - m.d *= sy; - }; - Bone.prototype.setToSetupPose = function () { - var data = this.data; - this.x = data.x; - this.y = data.y; - this.rotation = data.rotation; - this.scaleX = data.scaleX; - this.scaleY = data.scaleY; - this.shearX = data.shearX; - this.shearY = data.shearY; - }; - Bone.prototype.getWorldRotationX = function () { - return Math.atan2(this.matrix.b, this.matrix.a) * MathUtils.radDeg; - }; - Bone.prototype.getWorldRotationY = function () { - return Math.atan2(this.matrix.d, this.matrix.c) * MathUtils.radDeg; - }; - Bone.prototype.getWorldScaleX = function () { - var m = this.matrix; - return Math.sqrt(m.a * m.a + m.c * m.c); - }; - Bone.prototype.getWorldScaleY = function () { - var m = this.matrix; - return Math.sqrt(m.b * m.b + m.d * m.d); - }; - /** Computes the individual applied transform values from the world transform. This can be useful to perform processing using - * the applied transform after the world transform has been modified directly (eg, by a constraint). - *

- * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. */ - Bone.prototype.updateAppliedTransform = function () { - this.appliedValid = true; - var parent = this.parent; - var m = this.matrix; - if (parent == null) { - this.ax = m.tx; - this.ay = m.ty; - this.arotation = Math.atan2(m.b, m.a) * MathUtils.radDeg; - this.ascaleX = Math.sqrt(m.a * m.a + m.b * m.b); - this.ascaleY = Math.sqrt(m.c * m.c + m.d * m.d); - this.ashearX = 0; - this.ashearY = Math.atan2(m.a * m.c + m.b * m.d, m.a * m.d - m.b * m.c) * MathUtils.radDeg; - return; - } - var pm = parent.matrix; - var pid = 1 / (pm.a * pm.d - pm.b * pm.c); - var dx = m.tx - pm.tx, dy = m.ty - pm.ty; - this.ax = (dx * pm.d * pid - dy * pm.c * pid); - this.ay = (dy * pm.a * pid - dx * pm.b * pid); - var ia = pid * pm.d; - var id = pid * pm.a; - var ib = pid * pm.c; - var ic = pid * pm.b; - var ra = ia * m.a - ib * m.b; - var rb = ia * m.c - ib * m.d; - var rc = id * m.b - ic * m.a; - var rd = id * m.d - ic * m.c; - this.ashearX = 0; - this.ascaleX = Math.sqrt(ra * ra + rc * rc); - if (this.ascaleX > 0.0001) { - var det = ra * rd - rb * rc; - this.ascaleY = det / this.ascaleX; - this.ashearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg; - this.arotation = Math.atan2(rc, ra) * MathUtils.radDeg; - } - else { - this.ascaleX = 0; - this.ascaleY = Math.sqrt(rb * rb + rd * rd); - this.ashearY = 0; - this.arotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg; - } - }; - Bone.prototype.worldToLocal = function (world) { - var m = this.matrix; - var a = m.a, b = m.c, c = m.b, d = m.d; - var invDet = 1 / (a * d - b * c); - var x = world.x - m.tx, y = world.y - m.ty; - world.x = (x * d * invDet - y * b * invDet); - world.y = (y * a * invDet - x * c * invDet); - return world; - }; - Bone.prototype.localToWorld = function (local) { - var m = this.matrix; - var x = local.x, y = local.y; - local.x = x * m.a + y * m.c + m.tx; - local.y = x * m.b + y * m.d + m.ty; - return local; - }; - Bone.prototype.worldToLocalRotation = function (worldRotation) { - var sin = MathUtils.sinDeg(worldRotation), cos = MathUtils.cosDeg(worldRotation); - var mat = this.matrix; - return Math.atan2(mat.a * sin - mat.b * cos, mat.d * cos - mat.c * sin) * MathUtils.radDeg; - }; - Bone.prototype.localToWorldRotation = function (localRotation) { - var sin = MathUtils.sinDeg(localRotation), cos = MathUtils.cosDeg(localRotation); - var mat = this.matrix; - return Math.atan2(cos * mat.b + sin * mat.d, cos * mat.a + sin * mat.c) * MathUtils.radDeg; - }; - Bone.prototype.rotateWorld = function (degrees) { - var mat = this.matrix; - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var cos = MathUtils.cosDeg(degrees), sin = MathUtils.sinDeg(degrees); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - this.appliedValid = false; - }; - return Bone; - }()); - - /** - * @public - */ - var BoneData$1 = /** @class */ (function () { - function BoneData(index, name, parent) { - this.x = 0; - this.y = 0; - this.rotation = 0; - this.scaleX = 1; - this.scaleY = 1; - this.shearX = 0; - this.shearY = 0; - this.transformMode = exports.TransformMode.Normal; - if (index < 0) - throw new Error("index must be >= 0."); - if (name == null) - throw new Error("name cannot be null."); - this.index = index; - this.name = name; - this.parent = parent; - } - return BoneData; - }()); - - /** - * @public - */ - var Event$1 = /** @class */ (function () { - function Event(time, data) { - if (data == null) - throw new Error("data cannot be null."); - this.time = time; - this.data = data; - } - return Event; - }()); - - /** - * @public - */ - var EventData$1 = /** @class */ (function () { - function EventData(name) { - this.name = name; - } - return EventData; - }()); - - /** - * @public - */ - var IkConstraint$1 = /** @class */ (function () { - function IkConstraint(data, skeleton) { - this.bendDirection = 0; - this.compress = false; - this.stretch = false; - this.mix = 1; - if (data == null) - throw new Error("data cannot be null."); - if (skeleton == null) - throw new Error("skeleton cannot be null."); - this.data = data; - this.mix = data.mix; - this.bendDirection = data.bendDirection; - this.compress = data.compress; - this.stretch = data.stretch; - this.bones = new Array(); - for (var i = 0; i < data.bones.length; i++) - this.bones.push(skeleton.findBone(data.bones[i].name)); - this.target = skeleton.findBone(data.target.name); - } - IkConstraint.prototype.getOrder = function () { - return this.data.order; - }; - IkConstraint.prototype.apply = function () { - this.update(); - }; - IkConstraint.prototype.update = function () { - var target = this.target; - var bones = this.bones; - switch (bones.length) { - case 1: - this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix); - break; - case 2: - this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.mix); - break; - } - }; - /** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world - * coordinate system. */ - IkConstraint.prototype.apply1 = function (bone, targetX, targetY, compress, stretch, uniform, alpha) { - if (!bone.appliedValid) - bone.updateAppliedTransform(); - var p = bone.parent.matrix; - var id = 1 / (p.a * p.d - p.b * p.c); - var x = targetX - p.tx, y = targetY - p.ty; - var tx = (x * p.d - y * p.c) * id - bone.ax, ty = (y * p.a - x * p.b) * id - bone.ay; - var rotationIK = Math.atan2(ty, tx) * MathUtils.radDeg - bone.ashearX - bone.arotation; - if (bone.ascaleX < 0) - rotationIK += 180; - if (rotationIK > 180) - rotationIK -= 360; - else if (rotationIK < -180) - rotationIK += 360; - var sx = bone.ascaleX, sy = bone.ascaleY; - if (compress || stretch) { - var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty); - if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001) { - var s = (dd / b - 1) * alpha + 1; - sx *= s; - if (uniform) - sy *= s; - } - } - bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY); - }; - /** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The - * target is specified in the world coordinate system. - * @param child A direct descendant of the parent bone. */ - IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, alpha) { - if (alpha == 0) { - child.updateWorldTransform(); - return; - } - if (!parent.appliedValid) - parent.updateAppliedTransform(); - if (!child.appliedValid) - child.updateAppliedTransform(); - var px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX; - var pmat = parent.matrix; - var os1 = 0, os2 = 0, s2 = 0; - if (psx < 0) { - psx = -psx; - os1 = 180; - s2 = -1; - } - else { - os1 = 0; - s2 = 1; - } - if (psy < 0) { - psy = -psy; - s2 = -s2; - } - if (csx < 0) { - csx = -csx; - os2 = 180; - } - else - os2 = 0; - var cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = pmat.a, b = pmat.c, c = pmat.b, d = pmat.d; - var u = Math.abs(psx - psy) <= 0.0001; - if (!u) { - cy = 0; - cwx = a * cx + pmat.tx; - cwy = c * cx + pmat.ty; - } - else { - cy = child.ay; - cwx = a * cx + b * cy + pmat.tx; - cwy = c * cx + d * cy + pmat.ty; - } - var pp = parent.parent.matrix; - a = pp.a; - b = pp.c; - c = pp.b; - d = pp.d; - var id = 1 / (a * d - b * c), x = targetX - pp.tx, y = targetY - pp.ty; - var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py, dd = tx * tx + ty * ty; - x = cwx - pp.tx; - y = cwy - pp.ty; - var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; - var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0; - outer: if (u) { - l2 *= psx; - var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2); - if (cos < -1) - cos = -1; - else if (cos > 1) { - cos = 1; - if (stretch && l1 + l2 > 0.0001) - sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1; - } - a2 = Math.acos(cos) * bendDir; - a = l1 + l2 * cos; - b = l2 * Math.sin(a2); - a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b); - } - else { - a = psx * l2; - b = psy * l2; - var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx); - c = bb * l1 * l1 + aa * dd - aa * bb; - var c1 = -2 * bb * l1, c2 = bb - aa; - d = c1 * c1 - 4 * c2 * c; - if (d >= 0) { - var q = Math.sqrt(d); - if (c1 < 0) - q = -q; - q = -(c1 + q) / 2; - var r0 = q / c2, r1 = c / q; - var r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; - if (r * r <= dd) { - y = Math.sqrt(dd - r * r) * bendDir; - a1 = ta - Math.atan2(y, r); - a2 = Math.atan2(y / psy, (r - l1) / psx); - break outer; - } - } - var minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; - var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; - c = -a * l1 / (aa - bb); - if (c >= -1 && c <= 1) { - c = Math.acos(c); - x = a * Math.cos(c) + l1; - y = b * Math.sin(c); - d = x * x + y * y; - if (d < minDist) { - minAngle = c; - minDist = d; - minX = x; - minY = y; - } - if (d > maxDist) { - maxAngle = c; - maxDist = d; - maxX = x; - maxY = y; - } - } - if (dd <= (minDist + maxDist) / 2) { - a1 = ta - Math.atan2(minY * bendDir, minX); - a2 = minAngle * bendDir; - } - else { - a1 = ta - Math.atan2(maxY * bendDir, maxX); - a2 = maxAngle * bendDir; - } - } - var os = Math.atan2(cy, cx) * s2; - var rotation = parent.arotation; - a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation; - if (a1 > 180) - a1 -= 360; - else if (a1 < -180) - a1 += 360; - parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0); - rotation = child.arotation; - a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; - if (a2 > 180) - a2 -= 360; - else if (a2 < -180) - a2 += 360; - child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); - }; - return IkConstraint; - }()); - - /** - * @public - */ - var IkConstraintData$1 = /** @class */ (function () { - function IkConstraintData(name) { - this.order = 0; - this.bones = new Array(); - this.bendDirection = 1; - this.compress = false; - this.stretch = false; - this.uniform = false; - this.mix = 1; - this.name = name; - } - return IkConstraintData; - }()); - - /** - * @public - */ - var PathConstraintData$1 = /** @class */ (function () { - function PathConstraintData(name) { - this.order = 0; - this.bones = new Array(); - this.name = name; - } - return PathConstraintData; - }()); - /** - * @public - */ - var SpacingMode$1; - (function (SpacingMode) { - SpacingMode[SpacingMode["Length"] = 0] = "Length"; - SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed"; - SpacingMode[SpacingMode["Percent"] = 2] = "Percent"; - })(SpacingMode$1 || (SpacingMode$1 = {})); - - /** - * @public - */ - var PathConstraint$1 = /** @class */ (function () { - function PathConstraint(data, skeleton) { - this.position = 0; - this.spacing = 0; - this.rotateMix = 0; - this.translateMix = 0; - this.spaces = new Array(); - this.positions = new Array(); - this.world = new Array(); - this.curves = new Array(); - this.lengths = new Array(); - this.segments = new Array(); - if (data == null) - throw new Error("data cannot be null."); - if (skeleton == null) - throw new Error("skeleton cannot be null."); - this.data = data; - this.bones = new Array(); - for (var i = 0, n = data.bones.length; i < n; i++) - this.bones.push(skeleton.findBone(data.bones[i].name)); - this.target = skeleton.findSlot(data.target.name); - this.position = data.position; - this.spacing = data.spacing; - this.rotateMix = data.rotateMix; - this.translateMix = data.translateMix; - } - PathConstraint.prototype.apply = function () { - this.update(); - }; - PathConstraint.prototype.update = function () { - var attachment = this.target.getAttachment(); - if (!(attachment instanceof PathAttachment$1)) - return; - var rotateMix = this.rotateMix, translateMix = this.translateMix; - var translate = translateMix > 0, rotate = rotateMix > 0; - if (!translate && !rotate) - return; - var data = this.data; - var spacingMode = data.spacingMode; - var lengthSpacing = spacingMode == SpacingMode$1.Length; - var rotateMode = data.rotateMode; - var tangents = rotateMode == exports.RotateMode.Tangent, scale = rotateMode == exports.RotateMode.ChainScale; - var boneCount = this.bones.length, spacesCount = tangents ? boneCount : boneCount + 1; - var bones = this.bones; - var spaces = Utils.setArraySize(this.spaces, spacesCount), lengths = null; - var spacing = this.spacing; - if (scale || lengthSpacing) { - if (scale) - lengths = Utils.setArraySize(this.lengths, boneCount); - for (var i = 0, n = spacesCount - 1; i < n;) { - var bone = bones[i]; - var setupLength = bone.data.length; - if (setupLength < PathConstraint.epsilon) { - if (scale) - lengths[i] = 0; - spaces[++i] = 0; - } - else { - var x = setupLength * bone.matrix.a, y = setupLength * bone.matrix.b; - var length_1 = Math.sqrt(x * x + y * y); - if (scale) - lengths[i] = length_1; - spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length_1 / setupLength; - } - } - } - else { - for (var i = 1; i < spacesCount; i++) - spaces[i] = spacing; - } - var positions = this.computeWorldPositions(attachment, spacesCount, tangents, data.positionMode == exports.PositionMode.Percent, spacingMode == SpacingMode$1.Percent); - var boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; - var tip = false; - if (offsetRotation == 0) - tip = rotateMode == exports.RotateMode.Chain; - else { - tip = false; - var p = this.target.bone.matrix; - offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.degRad : -MathUtils.degRad; - } - for (var i = 0, p = 3; i < boneCount; i++, p += 3) { - var bone = bones[i]; - var mat = bone.matrix; - mat.tx += (boneX - mat.tx) * translateMix; - mat.ty += (boneY - mat.ty) * translateMix; - var x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; - if (scale) { - var length_2 = lengths[i]; - if (length_2 != 0) { - var s = (Math.sqrt(dx * dx + dy * dy) / length_2 - 1) * rotateMix + 1; - mat.a *= s; - mat.b *= s; - } - } - boneX = x; - boneY = y; - if (rotate) { - var a = mat.a, b = mat.c, c = mat.b, d = mat.d, r = 0, cos = 0, sin = 0; - if (tangents) - r = positions[p - 1]; - else if (spaces[i + 1] == 0) - r = positions[p + 2]; - else - r = Math.atan2(dy, dx); - r -= Math.atan2(c, a); - if (tip) { - cos = Math.cos(r); - sin = Math.sin(r); - var length_3 = bone.data.length; - boneX += (length_3 * (cos * a - sin * c) - dx) * rotateMix; - boneY += (length_3 * (sin * a + cos * c) - dy) * rotateMix; - } - else { - r += offsetRotation; - } - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) // - r += MathUtils.PI2; - r *= rotateMix; - cos = Math.cos(r); - sin = Math.sin(r); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - } - bone.appliedValid = false; - } - }; - PathConstraint.prototype.computeWorldPositions = function (path, spacesCount, tangents, percentPosition, percentSpacing) { - var target = this.target; - var position = this.position; - var spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = null; - var closed = path.closed; - var verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE; - if (!path.constantSpeed) { - var lengths = path.lengths; - curveCount -= closed ? 1 : 2; - var pathLength_1 = lengths[curveCount]; - if (percentPosition) - position *= pathLength_1; - if (percentSpacing) { - for (var i = 0; i < spacesCount; i++) - spaces[i] *= pathLength_1; - } - world = Utils.setArraySize(this.world, 8); - for (var i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { - var space = spaces[i]; - position += space; - var p = position; - if (closed) { - p %= pathLength_1; - if (p < 0) - p += pathLength_1; - curve = 0; - } - else if (p < 0) { - if (prevCurve != PathConstraint.BEFORE) { - prevCurve = PathConstraint.BEFORE; - path.computeWorldVertices(target, 2, 4, world, 0, 2); - } - this.addBeforePosition(p, world, 0, out, o); - continue; - } - else if (p > pathLength_1) { - if (prevCurve != PathConstraint.AFTER) { - prevCurve = PathConstraint.AFTER; - path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); - } - this.addAfterPosition(p - pathLength_1, world, 0, out, o); - continue; - } - // Determine curve containing position. - for (;; curve++) { - var length_4 = lengths[curve]; - if (p > length_4) - continue; - if (curve == 0) - p /= length_4; - else { - var prev = lengths[curve - 1]; - p = (p - prev) / (length_4 - prev); - } - break; - } - if (curve != prevCurve) { - prevCurve = curve; - if (closed && curve == curveCount) { - path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); - path.computeWorldVertices(target, 0, 4, world, 4, 2); - } - else - path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); - } - this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0)); - } - return out; - } - // World vertices. - if (closed) { - verticesLength += 2; - world = Utils.setArraySize(this.world, verticesLength); - path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); - path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); - world[verticesLength - 2] = world[0]; - world[verticesLength - 1] = world[1]; - } - else { - curveCount--; - verticesLength -= 4; - world = Utils.setArraySize(this.world, verticesLength); - path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); - } - // Curve lengths. - var curves = Utils.setArraySize(this.curves, curveCount); - var pathLength = 0; - var x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; - var tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0; - for (var i = 0, w = 2; i < curveCount; i++, w += 6) { - cx1 = world[w]; - cy1 = world[w + 1]; - cx2 = world[w + 2]; - cy2 = world[w + 3]; - x2 = world[w + 4]; - y2 = world[w + 5]; - tmpx = (x1 - cx1 * 2 + cx2) * 0.1875; - tmpy = (y1 - cy1 * 2 + cy2) * 0.1875; - dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375; - dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375; - ddfx = tmpx * 2 + dddfx; - ddfy = tmpy * 2 + dddfy; - dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667; - dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - dfx += ddfx; - dfy += ddfy; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - dfx += ddfx + dddfx; - dfy += ddfy + dddfy; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - curves[i] = pathLength; - x1 = x2; - y1 = y2; - } - if (percentPosition) - position *= pathLength; - if (percentSpacing) { - for (var i = 0; i < spacesCount; i++) - spaces[i] *= pathLength; - } - var segments = this.segments; - var curveLength = 0; - for (var i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { - var space = spaces[i]; - position += space; - var p = position; - if (closed) { - p %= pathLength; - if (p < 0) - p += pathLength; - curve = 0; - } - else if (p < 0) { - this.addBeforePosition(p, world, 0, out, o); - continue; - } - else if (p > pathLength) { - this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o); - continue; - } - // Determine curve containing position. - for (;; curve++) { - var length_5 = curves[curve]; - if (p > length_5) - continue; - if (curve == 0) - p /= length_5; - else { - var prev = curves[curve - 1]; - p = (p - prev) / (length_5 - prev); - } - break; - } - // Curve segment lengths. - if (curve != prevCurve) { - prevCurve = curve; - var ii = curve * 6; - x1 = world[ii]; - y1 = world[ii + 1]; - cx1 = world[ii + 2]; - cy1 = world[ii + 3]; - cx2 = world[ii + 4]; - cy2 = world[ii + 5]; - x2 = world[ii + 6]; - y2 = world[ii + 7]; - tmpx = (x1 - cx1 * 2 + cx2) * 0.03; - tmpy = (y1 - cy1 * 2 + cy2) * 0.03; - dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006; - dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006; - ddfx = tmpx * 2 + dddfx; - ddfy = tmpy * 2 + dddfy; - dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667; - dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667; - curveLength = Math.sqrt(dfx * dfx + dfy * dfy); - segments[0] = curveLength; - for (ii = 1; ii < 8; ii++) { - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - curveLength += Math.sqrt(dfx * dfx + dfy * dfy); - segments[ii] = curveLength; - } - dfx += ddfx; - dfy += ddfy; - curveLength += Math.sqrt(dfx * dfx + dfy * dfy); - segments[8] = curveLength; - dfx += ddfx + dddfx; - dfy += ddfy + dddfy; - curveLength += Math.sqrt(dfx * dfx + dfy * dfy); - segments[9] = curveLength; - segment = 0; - } - // Weight by segment length. - p *= curveLength; - for (;; segment++) { - var length_6 = segments[segment]; - if (p > length_6) - continue; - if (segment == 0) - p /= length_6; - else { - var prev = segments[segment - 1]; - p = segment + (p - prev) / (length_6 - prev); - } - break; - } - this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0)); - } - return out; - }; - PathConstraint.prototype.addBeforePosition = function (p, temp, i, out, o) { - var x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); - out[o] = x1 + p * Math.cos(r); - out[o + 1] = y1 + p * Math.sin(r); - out[o + 2] = r; - }; - PathConstraint.prototype.addAfterPosition = function (p, temp, i, out, o) { - var x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); - out[o] = x1 + p * Math.cos(r); - out[o + 1] = y1 + p * Math.sin(r); - out[o + 2] = r; - }; - PathConstraint.prototype.addCurvePosition = function (p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) { - if (p == 0 || isNaN(p)) - p = 0.0001; - var tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; - var ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; - var x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; - out[o] = x; - out[o + 1] = y; - if (tangents) - out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); - }; - PathConstraint.prototype.getOrder = function () { - return this.data.order; - }; - PathConstraint.NONE = -1; - PathConstraint.BEFORE = -2; - PathConstraint.AFTER = -3; - PathConstraint.epsilon = 0.00001; - return PathConstraint; - }()); - - /** - * @public - */ - var TransformConstraint$1 = /** @class */ (function () { - function TransformConstraint(data, skeleton) { - this.rotateMix = 0; - this.translateMix = 0; - this.scaleMix = 0; - this.shearMix = 0; - this.temp = new Vector2(); - if (data == null) - throw new Error("data cannot be null."); - if (skeleton == null) - throw new Error("skeleton cannot be null."); - this.data = data; - this.rotateMix = data.rotateMix; - this.translateMix = data.translateMix; - this.scaleMix = data.scaleMix; - this.shearMix = data.shearMix; - this.bones = new Array(); - for (var i = 0; i < data.bones.length; i++) - this.bones.push(skeleton.findBone(data.bones[i].name)); - this.target = skeleton.findBone(data.target.name); - } - TransformConstraint.prototype.apply = function () { - this.update(); - }; - TransformConstraint.prototype.update = function () { - if (this.data.local) { - if (this.data.relative) - this.applyRelativeLocal(); - else - this.applyAbsoluteLocal(); - } - else { - if (this.data.relative) - this.applyRelativeWorld(); - else - this.applyAbsoluteWorld(); - } - }; - TransformConstraint.prototype.applyAbsoluteWorld = function () { - var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; - var target = this.target; - var targetMat = target.matrix; - var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; - var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; - var offsetRotation = this.data.offsetRotation * degRadReflect; - var offsetShearY = this.data.offsetShearY * degRadReflect; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - var modified = false; - var mat = bone.matrix; - if (rotateMix != 0) { - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation; - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) - r += MathUtils.PI2; - r *= rotateMix; - var cos = Math.cos(r), sin = Math.sin(r); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - modified = true; - } - if (translateMix != 0) { - var temp = this.temp; - target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); - mat.tx += (temp.x - mat.tx) * translateMix; - mat.ty += (temp.y - mat.ty) * translateMix; - modified = true; - } - if (scaleMix > 0) { - var s = Math.sqrt(mat.a * mat.a + mat.b * mat.b); - var ts = Math.sqrt(ta * ta + tc * tc); - if (s > 0.00001) - s = (s + (ts - s + this.data.offsetScaleX) * scaleMix) / s; - mat.a *= s; - mat.b *= s; - s = Math.sqrt(mat.c * mat.c + mat.d * mat.d); - ts = Math.sqrt(tb * tb + td * td); - if (s > 0.00001) - s = (s + (ts - s + this.data.offsetScaleY) * scaleMix) / s; - mat.c *= s; - mat.d *= s; - modified = true; - } - if (shearMix > 0) { - var b = mat.c, d = mat.d; - var by = Math.atan2(d, b); - var r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(mat.b, mat.a)); - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) - r += MathUtils.PI2; - r = by + (r + offsetShearY) * shearMix; - var s = Math.sqrt(b * b + d * d); - mat.c = Math.cos(r) * s; - mat.d = Math.sin(r) * s; - modified = true; - } - if (modified) - bone.appliedValid = false; - } - }; - TransformConstraint.prototype.applyRelativeWorld = function () { - var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; - var target = this.target; - var targetMat = target.matrix; - var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; - var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; - var offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - var modified = false; - var mat = bone.matrix; - if (rotateMix != 0) { - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var r = Math.atan2(tc, ta) + offsetRotation; - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) - r += MathUtils.PI2; - r *= rotateMix; - var cos = Math.cos(r), sin = Math.sin(r); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - modified = true; - } - if (translateMix != 0) { - var temp = this.temp; - target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); - mat.tx += temp.x * translateMix; - mat.ty += temp.y * translateMix; - modified = true; - } - if (scaleMix > 0) { - var s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * scaleMix + 1; - mat.a *= s; - mat.b *= s; - s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1; - mat.c *= s; - mat.d *= s; - modified = true; - } - if (shearMix > 0) { - var r = Math.atan2(td, tb) - Math.atan2(tc, ta); - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) - r += MathUtils.PI2; - var b = mat.c, d = mat.d; - r = Math.atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * shearMix; - var s = Math.sqrt(b * b + d * d); - mat.c = Math.cos(r) * s; - mat.d = Math.sin(r) * s; - modified = true; - } - if (modified) - bone.appliedValid = false; - } - }; - TransformConstraint.prototype.applyAbsoluteLocal = function () { - var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; - var target = this.target; - if (!target.appliedValid) - target.updateAppliedTransform(); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (!bone.appliedValid) - bone.updateAppliedTransform(); - var rotation = bone.arotation; - if (rotateMix != 0) { - var r = target.arotation - rotation + this.data.offsetRotation; - r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; - rotation += r * rotateMix; - } - var x = bone.ax, y = bone.ay; - if (translateMix != 0) { - x += (target.ax - x + this.data.offsetX) * translateMix; - y += (target.ay - y + this.data.offsetY) * translateMix; - } - var scaleX = bone.ascaleX, scaleY = bone.ascaleY; - if (scaleMix > 0) { - if (scaleX > 0.00001) - scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * scaleMix) / scaleX; - if (scaleY > 0.00001) - scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * scaleMix) / scaleY; - } - var shearY = bone.ashearY; - if (shearMix > 0) { - var r = target.ashearY - shearY + this.data.offsetShearY; - r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; - bone.shearY += r * shearMix; - } - bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); - } - }; - TransformConstraint.prototype.applyRelativeLocal = function () { - var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; - var target = this.target; - if (!target.appliedValid) - target.updateAppliedTransform(); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (!bone.appliedValid) - bone.updateAppliedTransform(); - var rotation = bone.arotation; - if (rotateMix != 0) - rotation += (target.arotation + this.data.offsetRotation) * rotateMix; - var x = bone.ax, y = bone.ay; - if (translateMix != 0) { - x += (target.ax + this.data.offsetX) * translateMix; - y += (target.ay + this.data.offsetY) * translateMix; - } - var scaleX = bone.ascaleX, scaleY = bone.ascaleY; - if (scaleMix > 0) { - if (scaleX > 0.00001) - scaleX *= ((target.ascaleX - 1 + this.data.offsetScaleX) * scaleMix) + 1; - if (scaleY > 0.00001) - scaleY *= ((target.ascaleY - 1 + this.data.offsetScaleY) * scaleMix) + 1; - } - var shearY = bone.ashearY; - if (shearMix > 0) - shearY += (target.ashearY + this.data.offsetShearY) * shearMix; - bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); - } - }; - TransformConstraint.prototype.getOrder = function () { - return this.data.order; - }; - return TransformConstraint; - }()); - - /** - * @public - */ - var Skeleton$1 = /** @class */ (function () { - function Skeleton(data) { - this._updateCache = new Array(); - this.updateCacheReset = new Array(); - this.time = 0; - this.scaleX = 1; - this.scaleY = 1; - this.x = 0; - this.y = 0; - if (data == null) - throw new Error("data cannot be null."); - this.data = data; - this.bones = new Array(); - for (var i = 0; i < data.bones.length; i++) { - var boneData = data.bones[i]; - var bone = void 0; - if (boneData.parent == null) - bone = new Bone$1(boneData, this, null); - else { - var parent_1 = this.bones[boneData.parent.index]; - bone = new Bone$1(boneData, this, parent_1); - parent_1.children.push(bone); - } - this.bones.push(bone); - } - this.slots = new Array(); - this.drawOrder = new Array(); - for (var i = 0; i < data.slots.length; i++) { - var slotData = data.slots[i]; - var bone = this.bones[slotData.boneData.index]; - var slot = new Slot$1(slotData, bone); - this.slots.push(slot); - this.drawOrder.push(slot); - } - this.ikConstraints = new Array(); - for (var i = 0; i < data.ikConstraints.length; i++) { - var ikConstraintData = data.ikConstraints[i]; - this.ikConstraints.push(new IkConstraint$1(ikConstraintData, this)); - } - this.transformConstraints = new Array(); - for (var i = 0; i < data.transformConstraints.length; i++) { - var transformConstraintData = data.transformConstraints[i]; - this.transformConstraints.push(new TransformConstraint$1(transformConstraintData, this)); - } - this.pathConstraints = new Array(); - for (var i = 0; i < data.pathConstraints.length; i++) { - var pathConstraintData = data.pathConstraints[i]; - this.pathConstraints.push(new PathConstraint$1(pathConstraintData, this)); - } - this.color = new Color(1, 1, 1, 1); - this.updateCache(); - } - Skeleton.prototype.updateCache = function () { - var updateCache = this._updateCache; - updateCache.length = 0; - this.updateCacheReset.length = 0; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - bones[i].sorted = false; - // IK first, lowest hierarchy depth first. - var ikConstraints = this.ikConstraints; - var transformConstraints = this.transformConstraints; - var pathConstraints = this.pathConstraints; - var ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length; - var constraintCount = ikCount + transformCount + pathCount; - outer: for (var i = 0; i < constraintCount; i++) { - for (var ii = 0; ii < ikCount; ii++) { - var constraint = ikConstraints[ii]; - if (constraint.data.order == i) { - this.sortIkConstraint(constraint); - continue outer; - } - } - for (var ii = 0; ii < transformCount; ii++) { - var constraint = transformConstraints[ii]; - if (constraint.data.order == i) { - this.sortTransformConstraint(constraint); - continue outer; - } - } - for (var ii = 0; ii < pathCount; ii++) { - var constraint = pathConstraints[ii]; - if (constraint.data.order == i) { - this.sortPathConstraint(constraint); - continue outer; - } - } - } - for (var i = 0, n = bones.length; i < n; i++) - this.sortBone(bones[i]); - }; - Skeleton.prototype.sortIkConstraint = function (constraint) { - var target = constraint.target; - this.sortBone(target); - var constrained = constraint.bones; - var parent = constrained[0]; - this.sortBone(parent); - if (constrained.length > 1) { - var child = constrained[constrained.length - 1]; - if (!(this._updateCache.indexOf(child) > -1)) - this.updateCacheReset.push(child); - } - this._updateCache.push(constraint); - this.sortReset(parent.children); - constrained[constrained.length - 1].sorted = true; - }; - Skeleton.prototype.sortPathConstraint = function (constraint) { - var slot = constraint.target; - var slotIndex = slot.data.index; - var slotBone = slot.bone; - if (this.skin != null) - this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone); - if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin) - this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone); - for (var i = 0, n = this.data.skins.length; i < n; i++) - this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone); - var attachment = slot.getAttachment(); - if (attachment instanceof PathAttachment$1) - this.sortPathConstraintAttachmentWith(attachment, slotBone); - var constrained = constraint.bones; - var boneCount = constrained.length; - for (var i = 0; i < boneCount; i++) - this.sortBone(constrained[i]); - this._updateCache.push(constraint); - for (var i = 0; i < boneCount; i++) - this.sortReset(constrained[i].children); - for (var i = 0; i < boneCount; i++) - constrained[i].sorted = true; - }; - Skeleton.prototype.sortTransformConstraint = function (constraint) { - this.sortBone(constraint.target); - var constrained = constraint.bones; - var boneCount = constrained.length; - if (constraint.data.local) { - for (var i = 0; i < boneCount; i++) { - var child = constrained[i]; - this.sortBone(child.parent); - if (!(this._updateCache.indexOf(child) > -1)) - this.updateCacheReset.push(child); - } - } - else { - for (var i = 0; i < boneCount; i++) { - this.sortBone(constrained[i]); - } - } - this._updateCache.push(constraint); - for (var ii = 0; ii < boneCount; ii++) - this.sortReset(constrained[ii].children); - for (var ii = 0; ii < boneCount; ii++) - constrained[ii].sorted = true; - }; - Skeleton.prototype.sortPathConstraintAttachment = function (skin, slotIndex, slotBone) { - var attachments = skin.attachments[slotIndex]; - if (!attachments) - return; - for (var key in attachments) { - this.sortPathConstraintAttachmentWith(attachments[key], slotBone); - } - }; - Skeleton.prototype.sortPathConstraintAttachmentWith = function (attachment, slotBone) { - if (!(attachment instanceof PathAttachment$1)) - return; - var pathBones = attachment.bones; - if (pathBones == null) - this.sortBone(slotBone); - else { - var bones = this.bones; - var i = 0; - while (i < pathBones.length) { - var boneCount = pathBones[i++]; - for (var n = i + boneCount; i < n; i++) { - var boneIndex = pathBones[i]; - this.sortBone(bones[boneIndex]); - } - } - } - }; - Skeleton.prototype.sortBone = function (bone) { - if (bone.sorted) - return; - var parent = bone.parent; - if (parent != null) - this.sortBone(parent); - bone.sorted = true; - this._updateCache.push(bone); - }; - Skeleton.prototype.sortReset = function (bones) { - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (bone.sorted) - this.sortReset(bone.children); - bone.sorted = false; - } - }; - /** Updates the world transform for each bone and applies constraints. */ - Skeleton.prototype.updateWorldTransform = function () { - var updateCacheReset = this.updateCacheReset; - for (var i = 0, n = updateCacheReset.length; i < n; i++) { - var bone = updateCacheReset[i]; - bone.ax = bone.x; - bone.ay = bone.y; - bone.arotation = bone.rotation; - bone.ascaleX = bone.scaleX; - bone.ascaleY = bone.scaleY; - bone.ashearX = bone.shearX; - bone.ashearY = bone.shearY; - bone.appliedValid = true; - } - var updateCache = this._updateCache; - for (var i = 0, n = updateCache.length; i < n; i++) - updateCache[i].update(); - }; - /** Sets the bones, constraints, and slots to their setup pose values. */ - Skeleton.prototype.setToSetupPose = function () { - this.setBonesToSetupPose(); - this.setSlotsToSetupPose(); - }; - /** Sets the bones and constraints to their setup pose values. */ - Skeleton.prototype.setBonesToSetupPose = function () { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - bones[i].setToSetupPose(); - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) { - var constraint = ikConstraints[i]; - constraint.bendDirection = constraint.data.bendDirection; - constraint.mix = constraint.data.mix; - } - var transformConstraints = this.transformConstraints; - for (var i = 0, n = transformConstraints.length; i < n; i++) { - var constraint = transformConstraints[i]; - var data = constraint.data; - constraint.rotateMix = data.rotateMix; - constraint.translateMix = data.translateMix; - constraint.scaleMix = data.scaleMix; - constraint.shearMix = data.shearMix; - } - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) { - var constraint = pathConstraints[i]; - var data = constraint.data; - constraint.position = data.position; - constraint.spacing = data.spacing; - constraint.rotateMix = data.rotateMix; - constraint.translateMix = data.translateMix; - } - }; - Skeleton.prototype.setSlotsToSetupPose = function () { - var slots = this.slots; - Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length); - for (var i = 0, n = slots.length; i < n; i++) - slots[i].setToSetupPose(); - }; - /** @return May return null. */ - Skeleton.prototype.getRootBone = function () { - if (this.bones.length == 0) - return null; - return this.bones[0]; - }; - /** @return May be null. */ - Skeleton.prototype.findBone = function (boneName) { - if (boneName == null) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (bone.data.name == boneName) - return bone; - } - return null; - }; - /** @return -1 if the bone was not found. */ - Skeleton.prototype.findBoneIndex = function (boneName) { - if (boneName == null) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].data.name == boneName) - return i; - return -1; - }; - /** @return May be null. */ - Skeleton.prototype.findSlot = function (slotName) { - if (slotName == null) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.data.name == slotName) - return slot; - } - return null; - }; - /** @return -1 if the bone was not found. */ - Skeleton.prototype.findSlotIndex = function (slotName) { - if (slotName == null) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].data.name == slotName) - return i; - return -1; - }; - /** Sets a skin by name. - * @see #setSkin(Skin) */ - Skeleton.prototype.setSkinByName = function (skinName) { - var skin = this.data.findSkin(skinName); - if (skin == null) - throw new Error("Skin not found: " + skinName); - this.setSkin(skin); - }; - /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}. - * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no - * old skin, each slot's setup mode attachment is attached from the new skin. - * @param newSkin May be null. */ - Skeleton.prototype.setSkin = function (newSkin) { - if (newSkin != null) { - if (this.skin != null) - newSkin.attachAll(this, this.skin); - else { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - var name_1 = slot.data.attachmentName; - if (name_1 != null) { - var attachment = newSkin.getAttachment(i, name_1); - if (attachment != null) - slot.setAttachment(attachment); - } - } - } - } - this.skin = newSkin; - }; - /** @return May be null. */ - Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) { - return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName); - }; - /** @return May be null. */ - Skeleton.prototype.getAttachment = function (slotIndex, attachmentName) { - if (attachmentName == null) - throw new Error("attachmentName cannot be null."); - if (this.skin != null) { - var attachment = this.skin.getAttachment(slotIndex, attachmentName); - if (attachment != null) - return attachment; - } - if (this.data.defaultSkin != null) - return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); - return null; - }; - /** @param attachmentName May be null. */ - Skeleton.prototype.setAttachment = function (slotName, attachmentName) { - if (slotName == null) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.data.name == slotName) { - var attachment = null; - if (attachmentName != null) { - attachment = this.getAttachment(i, attachmentName); - if (attachment == null) - throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName); - } - slot.setAttachment(attachment); - return; - } - } - throw new Error("Slot not found: " + slotName); - }; - /** @return May be null. */ - Skeleton.prototype.findIkConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) { - var ikConstraint = ikConstraints[i]; - if (ikConstraint.data.name == constraintName) - return ikConstraint; - } - return null; - }; - /** @return May be null. */ - Skeleton.prototype.findTransformConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var transformConstraints = this.transformConstraints; - for (var i = 0, n = transformConstraints.length; i < n; i++) { - var constraint = transformConstraints[i]; - if (constraint.data.name == constraintName) - return constraint; - } - return null; - }; - /** @return May be null. */ - Skeleton.prototype.findPathConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) { - var constraint = pathConstraints[i]; - if (constraint.data.name == constraintName) - return constraint; - } - return null; - }; - /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. - * @param offset The distance from the skeleton origin to the bottom left corner of the AABB. - * @param size The width and height of the AABB. - * @param temp Working memory */ - Skeleton.prototype.getBounds = function (offset, size, temp) { - if (offset == null) - throw new Error("offset cannot be null."); - if (size == null) - throw new Error("size cannot be null."); - var drawOrder = this.drawOrder; - var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; - for (var i = 0, n = drawOrder.length; i < n; i++) { - var slot = drawOrder[i]; - var verticesLength = 0; - var vertices = null; - var attachment = slot.getAttachment(); - if (attachment instanceof RegionAttachment$1) { - verticesLength = 8; - vertices = Utils.setArraySize(temp, verticesLength, 0); - attachment.computeWorldVertices(slot.bone, vertices, 0, 2); - } - else if (attachment instanceof MeshAttachment$1) { - var mesh = attachment; - verticesLength = mesh.worldVerticesLength; - vertices = Utils.setArraySize(temp, verticesLength, 0); - mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2); - } - if (vertices != null) { - for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) { - var x = vertices[ii], y = vertices[ii + 1]; - minX = Math.min(minX, x); - minY = Math.min(minY, y); - maxX = Math.max(maxX, x); - maxY = Math.max(maxY, y); - } - } - } - offset.set(minX, minY); - size.set(maxX - minX, maxY - minY); - }; - Skeleton.prototype.update = function (delta) { - this.time += delta; - }; - Object.defineProperty(Skeleton.prototype, "flipX", { - get: function () { - return this.scaleX == -1; - }, - set: function (value) { - if (!Skeleton.deprecatedWarning1) { - Skeleton.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); - } - this.scaleX = value ? 1.0 : -1.0; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Skeleton.prototype, "flipY", { - get: function () { - return this.scaleY == -1; - }, - set: function (value) { - if (!Skeleton.deprecatedWarning1) { - Skeleton.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); - } - this.scaleY = value ? 1.0 : -1.0; - }, - enumerable: false, - configurable: true - }); - Skeleton.deprecatedWarning1 = false; - return Skeleton; - }()); - - /** Collects each visible {@link BoundingBoxAttachment} and computes the world vertices for its polygon. The polygon vertices are - * provided along with convenience methods for doing hit detection. - * @public - * */ - var SkeletonBounds$1 = /** @class */ (function (_super) { - __extends$2(SkeletonBounds, _super); - function SkeletonBounds() { - return _super !== null && _super.apply(this, arguments) || this; - } - return SkeletonBounds; - }(SkeletonBoundsBase)); - - /** - * @public - */ - var SkeletonData$1 = /** @class */ (function () { - function SkeletonData() { - this.bones = new Array(); // Ordered parents first. - this.slots = new Array(); // Setup pose draw order. - this.skins = new Array(); - this.events = new Array(); - this.animations = new Array(); - this.ikConstraints = new Array(); - this.transformConstraints = new Array(); - this.pathConstraints = new Array(); - // Nonessential - this.fps = 0; - } - SkeletonData.prototype.findBone = function (boneName) { - if (boneName == null) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (bone.name == boneName) - return bone; - } - return null; - }; - SkeletonData.prototype.findBoneIndex = function (boneName) { - if (boneName == null) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].name == boneName) - return i; - return -1; - }; - SkeletonData.prototype.findSlot = function (slotName) { - if (slotName == null) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.name == slotName) - return slot; - } - return null; - }; - SkeletonData.prototype.findSlotIndex = function (slotName) { - if (slotName == null) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].name == slotName) - return i; - return -1; - }; - SkeletonData.prototype.findSkin = function (skinName) { - if (skinName == null) - throw new Error("skinName cannot be null."); - var skins = this.skins; - for (var i = 0, n = skins.length; i < n; i++) { - var skin = skins[i]; - if (skin.name == skinName) - return skin; - } - return null; - }; - SkeletonData.prototype.findEvent = function (eventDataName) { - if (eventDataName == null) - throw new Error("eventDataName cannot be null."); - var events = this.events; - for (var i = 0, n = events.length; i < n; i++) { - var event_1 = events[i]; - if (event_1.name == eventDataName) - return event_1; - } - return null; - }; - SkeletonData.prototype.findAnimation = function (animationName) { - if (animationName == null) - throw new Error("animationName cannot be null."); - var animations = this.animations; - for (var i = 0, n = animations.length; i < n; i++) { - var animation = animations[i]; - if (animation.name == animationName) - return animation; - } - return null; - }; - SkeletonData.prototype.findIkConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) { - var constraint = ikConstraints[i]; - if (constraint.name == constraintName) - return constraint; - } - return null; - }; - SkeletonData.prototype.findTransformConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var transformConstraints = this.transformConstraints; - for (var i = 0, n = transformConstraints.length; i < n; i++) { - var constraint = transformConstraints[i]; - if (constraint.name == constraintName) - return constraint; - } - return null; - }; - SkeletonData.prototype.findPathConstraint = function (constraintName) { - if (constraintName == null) - throw new Error("constraintName cannot be null."); - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) { - var constraint = pathConstraints[i]; - if (constraint.name == constraintName) - return constraint; - } - return null; - }; - SkeletonData.prototype.findPathConstraintIndex = function (pathConstraintName) { - if (pathConstraintName == null) - throw new Error("pathConstraintName cannot be null."); - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) - if (pathConstraints[i].name == pathConstraintName) - return i; - return -1; - }; - return SkeletonData; - }()); - - /** - * @public - */ - var SlotData$1 = /** @class */ (function () { - function SlotData(index, name, boneData) { - this.color = new Color(1, 1, 1, 1); - if (index < 0) - throw new Error("index must be >= 0."); - if (name == null) - throw new Error("name cannot be null."); - if (boneData == null) - throw new Error("boneData cannot be null."); - this.index = index; - this.name = name; - this.boneData = boneData; - } - return SlotData; - }()); - - /** - * @public - */ - var TransformConstraintData$1 = /** @class */ (function () { - function TransformConstraintData(name) { - this.order = 0; - this.bones = new Array(); - this.rotateMix = 0; - this.translateMix = 0; - this.scaleMix = 0; - this.shearMix = 0; - this.offsetRotation = 0; - this.offsetX = 0; - this.offsetY = 0; - this.offsetScaleX = 0; - this.offsetScaleY = 0; - this.offsetShearY = 0; - this.relative = false; - this.local = false; - if (name == null) - throw new Error("name cannot be null."); - this.name = name; - } - return TransformConstraintData; - }()); - - /** - * @public - */ - var Skin$1 = /** @class */ (function () { - function Skin(name) { - this.attachments = new Array(); - if (name == null) - throw new Error("name cannot be null."); - this.name = name; - } - Skin.prototype.addAttachment = function (slotIndex, name, attachment) { - if (attachment == null) - throw new Error("attachment cannot be null."); - var attachments = this.attachments; - if (slotIndex >= attachments.length) - attachments.length = slotIndex + 1; - if (!attachments[slotIndex]) - attachments[slotIndex] = {}; - attachments[slotIndex][name] = attachment; - }; - /** @return May be null. */ - Skin.prototype.getAttachment = function (slotIndex, name) { - var dictionary = this.attachments[slotIndex]; - return dictionary ? dictionary[name] : null; - }; - /** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */ - Skin.prototype.attachAll = function (skeleton, oldSkin) { - var slotIndex = 0; - for (var i = 0; i < skeleton.slots.length; i++) { - var slot = skeleton.slots[i]; - var slotAttachment = slot.getAttachment(); - if (slotAttachment && slotIndex < oldSkin.attachments.length) { - var dictionary = oldSkin.attachments[slotIndex]; - for (var key in dictionary) { - var skinAttachment = dictionary[key]; - if (slotAttachment == skinAttachment) { - var attachment = this.getAttachment(slotIndex, key); - if (attachment != null) - slot.setAttachment(attachment); - break; - } - } - } - slotIndex++; - } - }; - return Skin; - }()); - - /** - * @public - */ - var SkeletonJson$1 = /** @class */ (function () { - function SkeletonJson(attachmentLoader) { - this.scale = 1; - this.linkedMeshes = new Array(); - this.attachmentLoader = attachmentLoader; - } - SkeletonJson.prototype.readSkeletonData = function (json) { - var scale = this.scale; - var skeletonData = new SkeletonData$1(); - var root = typeof (json) === "string" ? JSON.parse(json) : json; - // Skeleton - var skeletonMap = root.skeleton; - if (skeletonMap != null) { - skeletonData.hash = skeletonMap.hash; - skeletonData.version = skeletonMap.spine; - skeletonData.width = skeletonMap.width; - skeletonData.height = skeletonMap.height; - skeletonData.fps = skeletonMap.fps; - skeletonData.imagesPath = skeletonMap.images; - } - // Bones - if (root.bones) { - for (var i = 0; i < root.bones.length; i++) { - var boneMap = root.bones[i]; - var parent_1 = null; - var parentName = this.getValue(boneMap, "parent", null); - if (parentName != null) { - parent_1 = skeletonData.findBone(parentName); - if (parent_1 == null) - throw new Error("Parent bone not found: " + parentName); - } - var data = new BoneData$1(skeletonData.bones.length, boneMap.name, parent_1); - data.length = this.getValue(boneMap, "length", 0) * scale; - data.x = this.getValue(boneMap, "x", 0) * scale; - data.y = this.getValue(boneMap, "y", 0) * scale; - data.rotation = this.getValue(boneMap, "rotation", 0); - data.scaleX = this.getValue(boneMap, "scaleX", 1); - data.scaleY = this.getValue(boneMap, "scaleY", 1); - data.shearX = this.getValue(boneMap, "shearX", 0); - data.shearY = this.getValue(boneMap, "shearY", 0); - data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal")); - skeletonData.bones.push(data); - } - } - // Slots. - if (root.slots) { - for (var i = 0; i < root.slots.length; i++) { - var slotMap = root.slots[i]; - var slotName = slotMap.name; - var boneName = slotMap.bone; - var boneData = skeletonData.findBone(boneName); - if (boneData == null) - throw new Error("Slot bone not found: " + boneName); - var data = new SlotData$1(skeletonData.slots.length, slotName, boneData); - var color = this.getValue(slotMap, "color", null); - if (color != null) - data.color.setFromString(color); - var dark = this.getValue(slotMap, "dark", null); - if (dark != null) { - data.darkColor = new Color(1, 1, 1, 1); - data.darkColor.setFromString(dark); - } - data.attachmentName = this.getValue(slotMap, "attachment", null); - data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal")); - skeletonData.slots.push(data); - } - } - // IK constraints - if (root.ik) { - for (var i = 0; i < root.ik.length; i++) { - var constraintMap = root.ik[i]; - var data = new IkConstraintData$1(constraintMap.name); - data.order = this.getValue(constraintMap, "order", 0); - for (var j = 0; j < constraintMap.bones.length; j++) { - var boneName = constraintMap.bones[j]; - var bone = skeletonData.findBone(boneName); - if (bone == null) - throw new Error("IK bone not found: " + boneName); - data.bones.push(bone); - } - var targetName = constraintMap.target; - data.target = skeletonData.findBone(targetName); - if (data.target == null) - throw new Error("IK target bone not found: " + targetName); - data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; - data.mix = this.getValue(constraintMap, "mix", 1); - skeletonData.ikConstraints.push(data); - } - } - // Transform constraints. - if (root.transform) { - for (var i = 0; i < root.transform.length; i++) { - var constraintMap = root.transform[i]; - var data = new TransformConstraintData$1(constraintMap.name); - data.order = this.getValue(constraintMap, "order", 0); - for (var j = 0; j < constraintMap.bones.length; j++) { - var boneName = constraintMap.bones[j]; - var bone = skeletonData.findBone(boneName); - if (bone == null) - throw new Error("Transform constraint bone not found: " + boneName); - data.bones.push(bone); - } - var targetName = constraintMap.target; - data.target = skeletonData.findBone(targetName); - if (data.target == null) - throw new Error("Transform constraint target bone not found: " + targetName); - data.local = this.getValue(constraintMap, "local", false); - data.relative = this.getValue(constraintMap, "relative", false); - data.offsetRotation = this.getValue(constraintMap, "rotation", 0); - data.offsetX = this.getValue(constraintMap, "x", 0) * scale; - data.offsetY = this.getValue(constraintMap, "y", 0) * scale; - data.offsetScaleX = this.getValue(constraintMap, "scaleX", 0); - data.offsetScaleY = this.getValue(constraintMap, "scaleY", 0); - data.offsetShearY = this.getValue(constraintMap, "shearY", 0); - data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); - data.translateMix = this.getValue(constraintMap, "translateMix", 1); - data.scaleMix = this.getValue(constraintMap, "scaleMix", 1); - data.shearMix = this.getValue(constraintMap, "shearMix", 1); - skeletonData.transformConstraints.push(data); - } - } - // Path constraints. - if (root.path) { - for (var i = 0; i < root.path.length; i++) { - var constraintMap = root.path[i]; - var data = new PathConstraintData$1(constraintMap.name); - data.order = this.getValue(constraintMap, "order", 0); - for (var j = 0; j < constraintMap.bones.length; j++) { - var boneName = constraintMap.bones[j]; - var bone = skeletonData.findBone(boneName); - if (bone == null) - throw new Error("Transform constraint bone not found: " + boneName); - data.bones.push(bone); - } - var targetName = constraintMap.target; - data.target = skeletonData.findSlot(targetName); - if (data.target == null) - throw new Error("Path target slot not found: " + targetName); - data.positionMode = SkeletonJson.positionModeFromString(this.getValue(constraintMap, "positionMode", "percent")); - data.spacingMode = SkeletonJson.spacingModeFromString(this.getValue(constraintMap, "spacingMode", "length")); - data.rotateMode = SkeletonJson.rotateModeFromString(this.getValue(constraintMap, "rotateMode", "tangent")); - data.offsetRotation = this.getValue(constraintMap, "rotation", 0); - data.position = this.getValue(constraintMap, "position", 0); - if (data.positionMode == exports.PositionMode.Fixed) - data.position *= scale; - data.spacing = this.getValue(constraintMap, "spacing", 0); - if (data.spacingMode == SpacingMode$1.Length || data.spacingMode == SpacingMode$1.Fixed) - data.spacing *= scale; - data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); - data.translateMix = this.getValue(constraintMap, "translateMix", 1); - skeletonData.pathConstraints.push(data); - } - } - // Skins. - if (root.skins) { - for (var skinName in root.skins) { - var skinMap = root.skins[skinName]; - var skin = new Skin$1(skinName); - for (var slotName in skinMap) { - var slotIndex = skeletonData.findSlotIndex(slotName); - if (slotIndex == -1) - throw new Error("Slot not found: " + slotName); - var slotMap = skinMap[slotName]; - for (var entryName in slotMap) { - var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData); - if (attachment != null) - skin.addAttachment(slotIndex, entryName, attachment); - } - } - skeletonData.skins.push(skin); - if (skin.name == "default") - skeletonData.defaultSkin = skin; - } - } - // Linked meshes. - for (var i = 0, n = this.linkedMeshes.length; i < n; i++) { - var linkedMesh = this.linkedMeshes[i]; - var skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); - if (skin == null) - throw new Error("Skin not found: " + linkedMesh.skin); - var parent_2 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); - if (parent_2 == null) - throw new Error("Parent mesh not found: " + linkedMesh.parent); - linkedMesh.mesh.setParentMesh(parent_2); - //linkedMesh.mesh.updateUVs(); - } - this.linkedMeshes.length = 0; - // Events. - if (root.events) { - for (var eventName in root.events) { - var eventMap = root.events[eventName]; - var data = new EventData$1(eventName); - data.intValue = this.getValue(eventMap, "int", 0); - data.floatValue = this.getValue(eventMap, "float", 0); - data.stringValue = this.getValue(eventMap, "string", ""); - data.audioPath = this.getValue(eventMap, "audio", null); - if (data.audioPath != null) { - data.volume = this.getValue(eventMap, "volume", 1); - data.balance = this.getValue(eventMap, "balance", 0); - } - skeletonData.events.push(data); - } - } - // Animations. - if (root.animations) { - for (var animationName in root.animations) { - var animationMap = root.animations[animationName]; - this.readAnimation(animationMap, animationName, skeletonData); - } - } - return skeletonData; - }; - SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) { - var scale = this.scale; - name = this.getValue(map, "name", name); - var type = this.getValue(map, "type", "region"); - switch (type) { - case "region": { - var path = this.getValue(map, "path", name); - var region = this.attachmentLoader.newRegionAttachment(skin, name, path); - if (region == null) - return null; - region.path = path; - region.x = this.getValue(map, "x", 0) * scale; - region.y = this.getValue(map, "y", 0) * scale; - region.scaleX = this.getValue(map, "scaleX", 1); - region.scaleY = this.getValue(map, "scaleY", 1); - region.rotation = this.getValue(map, "rotation", 0); - region.width = map.width * scale; - region.height = map.height * scale; - var color = this.getValue(map, "color", null); - if (color != null) - region.color.setFromString(color); - //region.updateOffset(); - return region; - } - case "boundingbox": { - var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); - if (box == null) - return null; - this.readVertices(map, box, map.vertexCount << 1); - var color = this.getValue(map, "color", null); - if (color != null) - box.color.setFromString(color); - return box; - } - case "mesh": - case "linkedmesh": { - var path = this.getValue(map, "path", name); - var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); - if (mesh == null) - return null; - mesh.path = path; - var color = this.getValue(map, "color", null); - if (color != null) - mesh.color.setFromString(color); - var parent_3 = this.getValue(map, "parent", null); - if (parent_3 != null) { - mesh.inheritDeform = this.getValue(map, "deform", true); - this.linkedMeshes.push(new LinkedMesh$2(mesh, this.getValue(map, "skin", null), slotIndex, parent_3)); - return mesh; - } - var uvs = map.uvs; - this.readVertices(map, mesh, uvs.length); - mesh.triangles = map.triangles; - mesh.regionUVs = new Float32Array(uvs); - //mesh.updateUVs(); - mesh.hullLength = this.getValue(map, "hull", 0) * 2; - return mesh; - } - case "path": { - var path = this.attachmentLoader.newPathAttachment(skin, name); - if (path == null) - return null; - path.closed = this.getValue(map, "closed", false); - path.constantSpeed = this.getValue(map, "constantSpeed", true); - var vertexCount = map.vertexCount; - this.readVertices(map, path, vertexCount << 1); - var lengths = Utils.newArray(vertexCount / 3, 0); - for (var i = 0; i < map.lengths.length; i++) - lengths[i] = map.lengths[i] * scale; - path.lengths = lengths; - var color = this.getValue(map, "color", null); - if (color != null) - path.color.setFromString(color); - return path; - } - case "point": { - var point = this.attachmentLoader.newPointAttachment(skin, name); - if (point == null) - return null; - point.x = this.getValue(map, "x", 0) * scale; - point.y = this.getValue(map, "y", 0) * scale; - point.rotation = this.getValue(map, "rotation", 0); - var color = this.getValue(map, "color", null); - if (color != null) - point.color.setFromString(color); - return point; - } - case "clipping": { - var clip = this.attachmentLoader.newClippingAttachment(skin, name); - if (clip == null) - return null; - var end = this.getValue(map, "end", null); - if (end != null) { - var slot = skeletonData.findSlot(end); - if (slot == null) - throw new Error("Clipping end slot not found: " + end); - clip.endSlot = slot; - } - var vertexCount = map.vertexCount; - this.readVertices(map, clip, vertexCount << 1); - var color = this.getValue(map, "color", null); - if (color != null) - clip.color.setFromString(color); - return clip; - } - } - return null; - }; - SkeletonJson.prototype.readVertices = function (map, attachment, verticesLength) { - var scale = this.scale; - attachment.worldVerticesLength = verticesLength; - var vertices = map.vertices; - if (verticesLength == vertices.length) { - var scaledVertices = Utils.toFloatArray(vertices); - if (scale != 1) { - for (var i = 0, n = vertices.length; i < n; i++) - scaledVertices[i] *= scale; - } - attachment.vertices = scaledVertices; - return; - } - var weights = new Array(); - var bones = new Array(); - for (var i = 0, n = vertices.length; i < n;) { - var boneCount = vertices[i++]; - bones.push(boneCount); - for (var nn = i + boneCount * 4; i < nn; i += 4) { - bones.push(vertices[i]); - weights.push(vertices[i + 1] * scale); - weights.push(vertices[i + 2] * scale); - weights.push(vertices[i + 3]); - } - } - attachment.bones = bones; - attachment.vertices = Utils.toFloatArray(weights); - }; - SkeletonJson.prototype.readAnimation = function (map, name, skeletonData) { - var scale = this.scale; - var timelines = new Array(); - var duration = 0; - // Slot timelines. - if (map.slots) { - for (var slotName in map.slots) { - var slotMap = map.slots[slotName]; - var slotIndex = skeletonData.findSlotIndex(slotName); - if (slotIndex == -1) - throw new Error("Slot not found: " + slotName); - for (var timelineName in slotMap) { - var timelineMap = slotMap[timelineName]; - if (timelineName == "attachment") { - var timeline = new AttachmentTimeline$1(timelineMap.length); - timeline.slotIndex = slotIndex; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - timeline.setFrame(frameIndex++, valueMap.time, valueMap.name); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - } - else if (timelineName == "color") { - var timeline = new ColorTimeline(timelineMap.length); - timeline.slotIndex = slotIndex; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - var color = new Color(); - color.setFromString(valueMap.color || "ffffffff"); - timeline.setFrame(frameIndex, valueMap.time, color.r, color.g, color.b, color.a); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * ColorTimeline.ENTRIES]); - } - else if (timelineName == "twoColor") { - var timeline = new TwoColorTimeline(timelineMap.length); - timeline.slotIndex = slotIndex; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - var light = new Color(); - var dark = new Color(); - light.setFromString(valueMap.light); - dark.setFromString(valueMap.dark); - timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TwoColorTimeline.ENTRIES]); - } - else - throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); - } - } - } - // Bone timelines. - if (map.bones) { - for (var boneName in map.bones) { - var boneMap = map.bones[boneName]; - var boneIndex = skeletonData.findBoneIndex(boneName); - if (boneIndex == -1) - throw new Error("Bone not found: " + boneName); - for (var timelineName in boneMap) { - var timelineMap = boneMap[timelineName]; - if (timelineName === "rotate") { - var timeline = new RotateTimeline$1(timelineMap.length); - timeline.boneIndex = boneIndex; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - timeline.setFrame(frameIndex, valueMap.time, valueMap.angle); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * RotateTimeline$1.ENTRIES]); - } - else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") { - var timeline = null; - var timelineScale = 1; - if (timelineName === "scale") - timeline = new ScaleTimeline$1(timelineMap.length); - else if (timelineName === "shear") - timeline = new ShearTimeline$1(timelineMap.length); - else { - timeline = new TranslateTimeline$1(timelineMap.length); - timelineScale = scale; - } - timeline.boneIndex = boneIndex; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - var x = this.getValue(valueMap, "x", 0), y = this.getValue(valueMap, "y", 0); - timeline.setFrame(frameIndex, valueMap.time, x * timelineScale, y * timelineScale); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TranslateTimeline$1.ENTRIES]); - } - else - throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); - } - } - } - // IK constraint timelines. - if (map.ik) { - for (var constraintName in map.ik) { - var constraintMap = map.ik[constraintName]; - var constraint = skeletonData.findIkConstraint(constraintName); - var timeline = new IkConstraintTimeline$1(constraintMap.length); - timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(constraint); - var frameIndex = 0; - for (var i = 0; i < constraintMap.length; i++) { - var valueMap = constraintMap[i]; - timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false)); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * IkConstraintTimeline$1.ENTRIES]); - } - } - // Transform constraint timelines. - if (map.transform) { - for (var constraintName in map.transform) { - var constraintMap = map.transform[constraintName]; - var constraint = skeletonData.findTransformConstraint(constraintName); - var timeline = new TransformConstraintTimeline$1(constraintMap.length); - timeline.transformConstraintIndex = skeletonData.transformConstraints.indexOf(constraint); - var frameIndex = 0; - for (var i = 0; i < constraintMap.length; i++) { - var valueMap = constraintMap[i]; - timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1)); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TransformConstraintTimeline$1.ENTRIES]); - } - } - // Path constraint timelines. - if (map.paths) { - for (var constraintName in map.paths) { - var constraintMap = map.paths[constraintName]; - var index = skeletonData.findPathConstraintIndex(constraintName); - if (index == -1) - throw new Error("Path constraint not found: " + constraintName); - var data = skeletonData.pathConstraints[index]; - for (var timelineName in constraintMap) { - var timelineMap = constraintMap[timelineName]; - if (timelineName === "position" || timelineName === "spacing") { - var timeline = null; - var timelineScale = 1; - if (timelineName === "spacing") { - timeline = new PathConstraintSpacingTimeline$1(timelineMap.length); - if (data.spacingMode == SpacingMode$1.Length || data.spacingMode == SpacingMode$1.Fixed) - timelineScale = scale; - } - else { - timeline = new PathConstraintPositionTimeline$1(timelineMap.length); - if (data.positionMode == exports.PositionMode.Fixed) - timelineScale = scale; - } - timeline.pathConstraintIndex = index; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, timelineName, 0) * timelineScale); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * PathConstraintPositionTimeline$1.ENTRIES]); - } - else if (timelineName === "mix") { - var timeline = new PathConstraintMixTimeline$1(timelineMap.length); - timeline.pathConstraintIndex = index; - var frameIndex = 0; - for (var i = 0; i < timelineMap.length; i++) { - var valueMap = timelineMap[i]; - timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1)); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * PathConstraintMixTimeline$1.ENTRIES]); - } - } - } - } - // Deform timelines. - if (map.deform) { - for (var deformName in map.deform) { - var deformMap = map.deform[deformName]; - var skin = skeletonData.findSkin(deformName); - if (skin == null) { - if (settings.FAIL_ON_NON_EXISTING_SKIN) { - throw new Error("Skin not found: " + deformName); - } - else { - continue; - } - } - for (var slotName in deformMap) { - var slotMap = deformMap[slotName]; - var slotIndex = skeletonData.findSlotIndex(slotName); - if (slotIndex == -1) - throw new Error("Slot not found: " + slotMap.name); - for (var timelineName in slotMap) { - var timelineMap = slotMap[timelineName]; - var attachment = skin.getAttachment(slotIndex, timelineName); - if (attachment == null) - throw new Error("Deform attachment not found: " + timelineMap.name); - var weighted = attachment.bones != null; - var vertices = attachment.vertices; - var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; - var timeline = new DeformTimeline$1(timelineMap.length); - timeline.slotIndex = slotIndex; - timeline.attachment = attachment; - var frameIndex = 0; - for (var j = 0; j < timelineMap.length; j++) { - var valueMap = timelineMap[j]; - var deform = void 0; - var verticesValue = this.getValue(valueMap, "vertices", null); - if (verticesValue == null) - deform = weighted ? Utils.newFloatArray(deformLength) : vertices; - else { - deform = Utils.newFloatArray(deformLength); - var start = this.getValue(valueMap, "offset", 0); - Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); - if (scale != 1) { - for (var i = start, n = i + verticesValue.length; i < n; i++) - deform[i] *= scale; - } - if (!weighted) { - for (var i = 0; i < deformLength; i++) - deform[i] += vertices[i]; - } - } - timeline.setFrame(frameIndex, valueMap.time, deform); - this.readCurve(valueMap, timeline, frameIndex); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - } - } - } - } - // Draw order timeline. - var drawOrderNode = map.drawOrder; - if (drawOrderNode == null) - drawOrderNode = map.draworder; - if (drawOrderNode != null) { - var timeline = new DrawOrderTimeline$1(drawOrderNode.length); - var slotCount = skeletonData.slots.length; - var frameIndex = 0; - for (var j = 0; j < drawOrderNode.length; j++) { - var drawOrderMap = drawOrderNode[j]; - var drawOrder = null; - var offsets = this.getValue(drawOrderMap, "offsets", null); - if (offsets != null) { - drawOrder = Utils.newArray(slotCount, -1); - var unchanged = Utils.newArray(slotCount - offsets.length, 0); - var originalIndex = 0, unchangedIndex = 0; - for (var i = 0; i < offsets.length; i++) { - var offsetMap = offsets[i]; - var slotIndex = skeletonData.findSlotIndex(offsetMap.slot); - if (slotIndex == -1) - throw new Error("Slot not found: " + offsetMap.slot); - // Collect unchanged items. - while (originalIndex != slotIndex) - unchanged[unchangedIndex++] = originalIndex++; - // Set changed items. - drawOrder[originalIndex + offsetMap.offset] = originalIndex++; - } - // Collect remaining unchanged items. - while (originalIndex < slotCount) - unchanged[unchangedIndex++] = originalIndex++; - // Fill in unchanged items. - for (var i = slotCount - 1; i >= 0; i--) - if (drawOrder[i] == -1) - drawOrder[i] = unchanged[--unchangedIndex]; - } - timeline.setFrame(frameIndex++, drawOrderMap.time, drawOrder); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - } - // Event timeline. - if (map.events) { - var timeline = new EventTimeline$1(map.events.length); - var frameIndex = 0; - for (var i = 0; i < map.events.length; i++) { - var eventMap = map.events[i]; - var eventData = skeletonData.findEvent(eventMap.name); - if (eventData == null) - throw new Error("Event not found: " + eventMap.name); - var event_1 = new Event$1(Utils.toSinglePrecision(eventMap.time), eventData); - event_1.intValue = this.getValue(eventMap, "int", eventData.intValue); - event_1.floatValue = this.getValue(eventMap, "float", eventData.floatValue); - event_1.stringValue = this.getValue(eventMap, "string", eventData.stringValue); - if (event_1.data.audioPath != null) { - event_1.volume = this.getValue(eventMap, "volume", 1); - event_1.balance = this.getValue(eventMap, "balance", 0); - } - timeline.setFrame(frameIndex++, event_1); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - } - if (isNaN(duration)) { - throw new Error("Error while parsing animation, duration is NaN"); - } - skeletonData.animations.push(new Animation$1(name, timelines, duration)); - }; - SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) { - if (!map.curve) - return; - if (map.curve === "stepped") - timeline.setStepped(frameIndex); - else if (Object.prototype.toString.call(map.curve) === '[object Array]') { - var curve = map.curve; - timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]); - } - }; - SkeletonJson.prototype.getValue = function (map, prop, defaultValue) { - return map[prop] !== undefined ? map[prop] : defaultValue; - }; - SkeletonJson.blendModeFromString = function (str) { - str = str.toLowerCase(); - if (str == "normal") - return constants.BLEND_MODES.NORMAL; - if (str == "additive") - return constants.BLEND_MODES.ADD; - if (str == "multiply") - return constants.BLEND_MODES.MULTIPLY; - if (str == "screen") - return constants.BLEND_MODES.SCREEN; - throw new Error("Unknown blend mode: " + str); - }; - SkeletonJson.positionModeFromString = function (str) { - str = str.toLowerCase(); - if (str == "fixed") - return exports.PositionMode.Fixed; - if (str == "percent") - return exports.PositionMode.Percent; - throw new Error("Unknown position mode: " + str); - }; - SkeletonJson.spacingModeFromString = function (str) { - str = str.toLowerCase(); - if (str == "length") - return SpacingMode$1.Length; - if (str == "fixed") - return SpacingMode$1.Fixed; - if (str == "percent") - return SpacingMode$1.Percent; - throw new Error("Unknown position mode: " + str); - }; - SkeletonJson.rotateModeFromString = function (str) { - str = str.toLowerCase(); - if (str == "tangent") - return exports.RotateMode.Tangent; - if (str == "chain") - return exports.RotateMode.Chain; - if (str == "chainscale") - return exports.RotateMode.ChainScale; - throw new Error("Unknown rotate mode: " + str); - }; - SkeletonJson.transformModeFromString = function (str) { - str = str.toLowerCase(); - if (str == "normal") - return exports.TransformMode.Normal; - if (str == "onlytranslation") - return exports.TransformMode.OnlyTranslation; - if (str == "norotationorreflection") - return exports.TransformMode.NoRotationOrReflection; - if (str == "noscale") - return exports.TransformMode.NoScale; - if (str == "noscaleorreflection") - return exports.TransformMode.NoScaleOrReflection; - throw new Error("Unknown transform mode: " + str); - }; - return SkeletonJson; - }()); - var LinkedMesh$2 = /** @class */ (function () { - function LinkedMesh(mesh, skin, slotIndex, parent) { - this.mesh = mesh; - this.skin = skin; - this.slotIndex = slotIndex; - this.parent = parent; - } - return LinkedMesh; - }()); - - /** - * @public - */ - var Spine$2 = /** @class */ (function (_super) { - __extends$2(Spine, _super); - function Spine() { - return _super !== null && _super.apply(this, arguments) || this; - } - Spine.prototype.createSkeleton = function (spineData) { - this.skeleton = new Skeleton$1(spineData); - this.skeleton.updateWorldTransform(); - this.stateData = new AnimationStateData$1(spineData); - this.state = new AnimationState$1(this.stateData); - }; - return Spine; - }(SpineBase)); - - var spine37 = /*#__PURE__*/Object.freeze({ - __proto__: null, - Animation: Animation$1, - AnimationState: AnimationState$1, - AnimationStateAdapter2: AnimationStateAdapter2, - AnimationStateData: AnimationStateData$1, - AtlasAttachmentLoader: AtlasAttachmentLoader$1, - Attachment: Attachment$1, - AttachmentTimeline: AttachmentTimeline$1, - Bone: Bone$1, - BoneData: BoneData$1, - BoundingBoxAttachment: BoundingBoxAttachment$1, - ClippingAttachment: ClippingAttachment$1, - ColorTimeline: ColorTimeline, - CurveTimeline: CurveTimeline$1, - DeformTimeline: DeformTimeline$1, - DrawOrderTimeline: DrawOrderTimeline$1, - Event: Event$1, - EventData: EventData$1, - EventQueue: EventQueue$1, - EventTimeline: EventTimeline$1, - get EventType () { return EventType$1; }, - IkConstraint: IkConstraint$1, - IkConstraintData: IkConstraintData$1, - IkConstraintTimeline: IkConstraintTimeline$1, - JitterEffect: JitterEffect, - MeshAttachment: MeshAttachment$1, - PathAttachment: PathAttachment$1, - PathConstraint: PathConstraint$1, - PathConstraintData: PathConstraintData$1, - PathConstraintMixTimeline: PathConstraintMixTimeline$1, - PathConstraintPositionTimeline: PathConstraintPositionTimeline$1, - PathConstraintSpacingTimeline: PathConstraintSpacingTimeline$1, - PointAttachment: PointAttachment$1, - RegionAttachment: RegionAttachment$1, - RotateTimeline: RotateTimeline$1, - ScaleTimeline: ScaleTimeline$1, - ShearTimeline: ShearTimeline$1, - Skeleton: Skeleton$1, - SkeletonBounds: SkeletonBounds$1, - SkeletonData: SkeletonData$1, - SkeletonJson: SkeletonJson$1, - Skin: Skin$1, - Slot: Slot$1, - SlotData: SlotData$1, - get SpacingMode () { return SpacingMode$1; }, - Spine: Spine$2, - SwirlEffect: SwirlEffect, - get TimelineType () { return TimelineType; }, - TrackEntry: TrackEntry$1, - TransformConstraint: TransformConstraint$1, - TransformConstraintData: TransformConstraintData$1, - TransformConstraintTimeline: TransformConstraintTimeline$1, - TranslateTimeline: TranslateTimeline$1, - TwoColorTimeline: TwoColorTimeline, - VertexAttachment: VertexAttachment$1 - }); - - /* eslint-disable */ - - /*! ***************************************************************************** - Copyright (c) Microsoft Corporation. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. - ***************************************************************************** */ - /* global Reflect, Promise */ - - var extendStatics$1 = function(d, b) { - extendStatics$1 = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics$1(d, b); - }; - - function __extends$1(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics$1(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - } - - /** - * The base class for all attachments. - * @public - */ - var Attachment = /** @class */ (function () { - function Attachment(name) { - if (!name) - throw new Error("name cannot be null."); - this.name = name; - } - return Attachment; - }()); - /** - * Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by a slot's - * {@link Slot#deform}. - * @public - */ - var VertexAttachment = /** @class */ (function (_super) { - __extends$1(VertexAttachment, _super); - function VertexAttachment(name) { - var _this = _super.call(this, name) || this; - /** The unique ID for this attachment. */ - _this.id = VertexAttachment.nextID++; - /** The bones which affect the {@link #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 {@link Skeleton#bones}. Will be null - * if this attachment has no weights. */ - _this.bones = null; - /** 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. */ - _this.vertices = []; - /** The maximum number of world vertex values that can be output by - * {@link #computeWorldVertices()} using the `count` parameter. */ - _this.worldVerticesLength = 0; - /** Timelines for the timeline attachment are also applied to this attachment. - * May be null if no attachment-specific timelines should be applied. */ - _this.timelineAttachment = _this; - return _this; - } - VertexAttachment.prototype.computeWorldVerticesOld = function (slot, worldVertices) { - this.computeWorldVertices(slot, 0, this.worldVerticesLength, worldVertices, 0, 2); - }; - /** Transforms the attachment's local {@link #vertices} to world coordinates. If the slot's {@link Slot#deform} 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. - * @param start The index of the first {@link #vertices} value to transform. Each vertex has 2 values, x and y. - * @param count The number of world vertex values to output. Must be <= {@link #worldVerticesLength} - `start`. - * @param worldVertices The output world vertices. Must have a length >= `offset` + `count` * - * `stride` / 2. - * @param offset The `worldVertices` index to begin writing values. - * @param stride The number of `worldVertices` entries between the value pairs written. */ - VertexAttachment.prototype.computeWorldVertices = function (slot, start, count, worldVertices, offset, stride) { - count = offset + (count >> 1) * stride; - var skeleton = slot.bone.skeleton; - var deformArray = slot.deform; - var vertices = this.vertices; - var bones = this.bones; - if (!bones) { - if (deformArray.length > 0) - vertices = deformArray; - var mat = slot.bone.matrix; - var x = mat.tx; - var y = mat.ty; - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - for (var v_1 = start, w = offset; w < count; v_1 += 2, w += stride) { - var vx = vertices[v_1], vy = vertices[v_1 + 1]; - worldVertices[w] = vx * a + vy * b + x; - worldVertices[w + 1] = vx * c + vy * d + y; - } - return; - } - var v = 0, skip = 0; - for (var i = 0; i < start; i += 2) { - var n = bones[v]; - v += n + 1; - skip += n; - } - var skeletonBones = skeleton.bones; - if (deformArray.length == 0) { - for (var w = offset, b = skip * 3; w < count; w += stride) { - var wx = 0, wy = 0; - var n = bones[v++]; - n += v; - for (; v < n; v++, b += 3) { - var mat = skeletonBones[bones[v]].matrix; - var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; - wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; - wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; - } - worldVertices[w] = wx; - worldVertices[w + 1] = wy; - } - } - else { - var deform = deformArray; - for (var w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { - var wx = 0, wy = 0; - var n = bones[v++]; - n += v; - for (; v < n; v++, b += 3, f += 2) { - var mat = skeletonBones[bones[v]].matrix; - var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; - wx += (vx * mat.a + vy * mat.c + mat.tx) * weight; - wy += (vx * mat.b + vy * mat.d + mat.ty) * weight; - } - worldVertices[w] = wx; - worldVertices[w + 1] = wy; - } - } - }; - /** Does not copy id (generated) or name (set on construction). **/ - VertexAttachment.prototype.copyTo = function (attachment) { - if (this.bones) { - attachment.bones = new Array(this.bones.length); - Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length); - } - else - attachment.bones = null; - if (this.vertices) { - attachment.vertices = Utils.newFloatArray(this.vertices.length); - Utils.arrayCopy(this.vertices, 0, attachment.vertices, 0, this.vertices.length); - } - attachment.worldVerticesLength = this.worldVerticesLength; - attachment.timelineAttachment = this.timelineAttachment; - }; - VertexAttachment.nextID = 0; - return VertexAttachment; - }(Attachment)); - - /** - * @public - */ - var BoundingBoxAttachment = /** @class */ (function (_super) { - __extends$1(BoundingBoxAttachment, _super); - function BoundingBoxAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.BoundingBox; - _this.color = new Color(1, 1, 1, 1); - return _this; - } - BoundingBoxAttachment.prototype.copy = function () { - var copy = new BoundingBoxAttachment(this.name); - this.copyTo(copy); - copy.color.setFromColor(this.color); - return copy; - }; - return BoundingBoxAttachment; - }(VertexAttachment)); - - /** - * @public - */ - var ClippingAttachment = /** @class */ (function (_super) { - __extends$1(ClippingAttachment, _super); - function ClippingAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Clipping; - /** Clipping is performed between the clipping polygon's slot and the end slot. Returns null if clipping is done until the end of - * the skeleton's rendering. */ - _this.endSlot = null; - // Nonessential. - /** The color of the clipping polygon as it was in Spine. Available only when nonessential data was exported. Clipping polygons - * are not usually rendered at runtime. */ - _this.color = new Color(0.2275, 0.2275, 0.8078, 1); // ce3a3aff - return _this; - } - ClippingAttachment.prototype.copy = function () { - var copy = new ClippingAttachment(this.name); - this.copyTo(copy); - copy.endSlot = this.endSlot; - copy.color.setFromColor(this.color); - return copy; - }; - return ClippingAttachment; - }(VertexAttachment)); - - /** - * @public - */ - var MeshAttachment = /** @class */ (function (_super) { - __extends$1(MeshAttachment, _super); - function MeshAttachment(name, path) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Mesh; - _this.region = null; - /** Triplets of vertex indices which describe the mesh's triangulation. */ - _this.triangles = []; - /** The color to tint the mesh. */ - _this.color = new Color(1, 1, 1, 1); - /** The width of the mesh's image. Available only when nonessential data was exported. */ - _this.width = 0; - /** The height of the mesh's image. Available only when nonessential data was exported. */ - _this.height = 0; - /** The number of entries at the beginning of {@link #vertices} that make up the mesh hull. */ - _this.hullLength = 0; - /** Vertex index pairs describing edges for controling triangulation. Mesh triangles will never cross edges. Only available if - * nonessential data was exported. Triangulation is not performed at runtime. */ - _this.edges = []; - _this.parentMesh = null; - _this.sequence = null; - _this.tempColor = new Color(0, 0, 0, 0); - _this.path = path; - return _this; - } - /** The parent mesh if this is a linked mesh, else null. A linked mesh shares the {@link #bones}, {@link #vertices}, - * {@link #regionUVs}, {@link #triangles}, {@link #hullLength}, {@link #edges}, {@link #width}, and {@link #height} with the - * parent mesh, but may have a different {@link #name} or {@link #path} (and therefore a different texture). */ - MeshAttachment.prototype.getParentMesh = function () { - return this.parentMesh; - }; - /** @param parentMesh May be null. */ - MeshAttachment.prototype.setParentMesh = function (parentMesh) { - this.parentMesh = parentMesh; - if (parentMesh) { - this.bones = parentMesh.bones; - this.vertices = parentMesh.vertices; - this.worldVerticesLength = parentMesh.worldVerticesLength; - this.regionUVs = parentMesh.regionUVs; - this.triangles = parentMesh.triangles; - this.hullLength = parentMesh.hullLength; - this.worldVerticesLength = parentMesh.worldVerticesLength; - } - }; - MeshAttachment.prototype.copy = function () { - if (this.parentMesh) - return this.newLinkedMesh(); - var copy = new MeshAttachment(this.name, this.path); - copy.region = this.region; - copy.color.setFromColor(this.color); - this.copyTo(copy); - copy.regionUVs = new Float32Array(this.regionUVs.length); - Utils.arrayCopy(this.regionUVs, 0, copy.regionUVs, 0, this.regionUVs.length); - copy.triangles = new Array(this.triangles.length); - Utils.arrayCopy(this.triangles, 0, copy.triangles, 0, this.triangles.length); - copy.hullLength = this.hullLength; - copy.sequence = this.sequence != null ? this.sequence.copy() : null; - // Nonessential. - if (this.edges) { - copy.edges = new Array(this.edges.length); - Utils.arrayCopy(this.edges, 0, copy.edges, 0, this.edges.length); - } - copy.width = this.width; - copy.height = this.height; - return copy; - }; - MeshAttachment.prototype.computeWorldVertices = function (slot, start, count, worldVertices, offset, stride) { - if (this.sequence != null) - this.sequence.apply(slot, this); - _super.prototype.computeWorldVertices.call(this, slot, start, count, worldVertices, offset, stride); - }; - /** Returns a new mesh with the {@link #parentMesh} set to this mesh's parent mesh, if any, else to this mesh. **/ - MeshAttachment.prototype.newLinkedMesh = function () { - var copy = new MeshAttachment(this.name, this.path); - copy.region = this.region; - copy.color.setFromColor(this.color); - copy.timelineAttachment = this.timelineAttachment; - copy.setParentMesh(this.parentMesh ? this.parentMesh : this); - // if (copy.region != null) copy.updateRegion(); - return copy; - }; - return MeshAttachment; - }(VertexAttachment)); - - /** - * @public - */ - var PathAttachment = /** @class */ (function (_super) { - __extends$1(PathAttachment, _super); - function PathAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Path; - /** The lengths along the path in the setup pose from the start of the path to the end of each Bezier curve. */ - _this.lengths = []; - /** If true, the start and end knots are connected. */ - _this.closed = false; - /** If true, additional calculations are performed to make calculating positions along the path more accurate. If false, fewer - * calculations are performed but calculating positions along the path is less accurate. */ - _this.constantSpeed = false; - /** The color of the path as it was in Spine. Available only when nonessential data was exported. Paths are not usually - * rendered at runtime. */ - _this.color = new Color(1, 1, 1, 1); - return _this; - } - PathAttachment.prototype.copy = function () { - var copy = new PathAttachment(this.name); - this.copyTo(copy); - copy.lengths = new Array(this.lengths.length); - Utils.arrayCopy(this.lengths, 0, copy.lengths, 0, this.lengths.length); - copy.closed = closed; - copy.constantSpeed = this.constantSpeed; - copy.color.setFromColor(this.color); - return copy; - }; - return PathAttachment; - }(VertexAttachment)); - - /** - * @public - */ - var PointAttachment = /** @class */ (function (_super) { - __extends$1(PointAttachment, _super); - function PointAttachment(name) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Point; - _this.x = 0; - _this.y = 0; - _this.rotation = 0; - /** The color of the point attachment as it was in Spine. Available only when nonessential data was exported. Point attachments - * are not usually rendered at runtime. */ - _this.color = new Color(0.38, 0.94, 0, 1); - return _this; - } - PointAttachment.prototype.computeWorldPosition = function (bone, point) { - var mat = bone.matrix; - point.x = this.x * mat.a + this.y * mat.c + bone.worldX; - point.y = this.x * mat.b + this.y * mat.d + bone.worldY; - return point; - }; - PointAttachment.prototype.computeWorldRotation = function (bone) { - var mat = bone.matrix; - var cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation); - var x = cos * mat.a + sin * mat.c; - var y = cos * mat.b + sin * mat.d; - return Math.atan2(y, x) * MathUtils.radDeg; - }; - PointAttachment.prototype.copy = function () { - var copy = new PointAttachment(this.name); - copy.x = this.x; - copy.y = this.y; - copy.rotation = this.rotation; - copy.color.setFromColor(this.color); - return copy; - }; - return PointAttachment; - }(VertexAttachment)); - - /** - * @public - */ - var RegionAttachment = /** @class */ (function (_super) { - __extends$1(RegionAttachment, _super); - function RegionAttachment(name, path) { - var _this = _super.call(this, name) || this; - _this.type = exports.AttachmentType.Region; - /** The local x translation. */ - _this.x = 0; - /** The local y translation. */ - _this.y = 0; - /** The local scaleX. */ - _this.scaleX = 1; - /** The local scaleY. */ - _this.scaleY = 1; - /** The local rotation. */ - _this.rotation = 0; - /** The width of the region attachment in Spine. */ - _this.width = 0; - /** The height of the region attachment in Spine. */ - _this.height = 0; - /** The color to tint the region attachment. */ - _this.color = new Color(1, 1, 1, 1); - _this.rendererObject = null; - _this.region = null; - _this.sequence = null; - /** For each of the 4 vertices, a pair of x,y values that is the local position of the vertex. - * - * See {@link #updateOffset()}. */ - _this.offset = Utils.newFloatArray(8); - _this.uvs = Utils.newFloatArray(8); - _this.tempColor = new Color(1, 1, 1, 1); - _this.path = path; - return _this; - } - /** Calculates the {@link #offset} using the region settings. Must be called after changing region settings. */ - RegionAttachment.prototype.updateRegion = function () { - if (!this.region) - throw new Error("Region not set."); - var region = this.region; - var regionScaleX = this.width / this.region.originalWidth * this.scaleX; - var regionScaleY = this.height / this.region.originalHeight * this.scaleY; - var localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; - var localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; - var localX2 = localX + this.region.width * regionScaleX; - var localY2 = localY + this.region.height * regionScaleY; - var radians = this.rotation * Math.PI / 180; - var cos = Math.cos(radians); - var sin = Math.sin(radians); - var x = this.x, y = this.y; - var localXCos = localX * cos + x; - var localXSin = localX * sin; - var localYCos = localY * cos + y; - var localYSin = localY * sin; - var localX2Cos = localX2 * cos + x; - var localX2Sin = localX2 * sin; - var localY2Cos = localY2 * cos + y; - var localY2Sin = localY2 * sin; - var offset = this.offset; - offset[0] = localXCos - localYSin; - offset[1] = localYCos + localXSin; - offset[2] = localXCos - localY2Sin; - offset[3] = localY2Cos + localXSin; - offset[4] = localX2Cos - localY2Sin; - offset[5] = localY2Cos + localX2Sin; - offset[6] = localX2Cos - localYSin; - offset[7] = localYCos + localX2Sin; - var uvs = this.uvs; - if (region.degrees == 90) { - uvs[2] = region.u; - uvs[3] = region.v2; - uvs[4] = region.u; - uvs[5] = region.v; - uvs[6] = region.u2; - uvs[7] = region.v; - uvs[0] = region.u2; - uvs[1] = region.v2; - } - else { - uvs[0] = region.u; - uvs[1] = region.v2; - uvs[2] = region.u; - uvs[3] = region.v; - uvs[4] = region.u2; - uvs[5] = region.v; - uvs[6] = region.u2; - uvs[7] = region.v2; - } - }; - /** Transforms the attachment's four vertices to world coordinates. If the attachment has a {@link #sequence}, the region may - * be changed. - *

- * See World transforms in the Spine - * Runtimes Guide. - * @param worldVertices The output world vertices. Must have a length >= offset + 8. - * @param offset The worldVertices index to begin writing values. - * @param stride The number of worldVertices entries between the value pairs written. */ - RegionAttachment.prototype.computeWorldVertices = function (slot, worldVertices, offset, stride) { - if (this.sequence != null) - this.sequence.apply(slot, this); - var bone = slot.bone; - var vertexOffset = this.offset; - var mat = bone.matrix; - var x = mat.tx, y = mat.ty; - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var offsetX = 0, offsetY = 0; - offsetX = vertexOffset[0]; - offsetY = vertexOffset[1]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // br - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - offset += stride; - offsetX = vertexOffset[2]; - offsetY = vertexOffset[3]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // bl - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - offset += stride; - offsetX = vertexOffset[4]; - offsetY = vertexOffset[5]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // ul - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - offset += stride; - offsetX = vertexOffset[6]; - offsetY = vertexOffset[7]; - worldVertices[offset] = offsetX * a + offsetY * b + x; // ur - worldVertices[offset + 1] = offsetX * c + offsetY * d + y; - }; - RegionAttachment.prototype.copy = function () { - var copy = new RegionAttachment(this.name, this.path); - copy.region = this.region; - copy.rendererObject = this.rendererObject; - copy.x = this.x; - copy.y = this.y; - copy.scaleX = this.scaleX; - copy.scaleY = this.scaleY; - copy.rotation = this.rotation; - copy.width = this.width; - copy.height = this.height; - Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, 8); - Utils.arrayCopy(this.offset, 0, copy.offset, 0, 8); - copy.color.setFromColor(this.color); - copy.sequence = this.sequence != null ? this.sequence.copy() : null; - return copy; - }; - RegionAttachment.X1 = 0; - RegionAttachment.Y1 = 1; - RegionAttachment.C1R = 2; - RegionAttachment.C1G = 3; - RegionAttachment.C1B = 4; - RegionAttachment.C1A = 5; - RegionAttachment.U1 = 6; - RegionAttachment.V1 = 7; - RegionAttachment.X2 = 8; - RegionAttachment.Y2 = 9; - RegionAttachment.C2R = 10; - RegionAttachment.C2G = 11; - RegionAttachment.C2B = 12; - RegionAttachment.C2A = 13; - RegionAttachment.U2 = 14; - RegionAttachment.V2 = 15; - RegionAttachment.X3 = 16; - RegionAttachment.Y3 = 17; - RegionAttachment.C3R = 18; - RegionAttachment.C3G = 19; - RegionAttachment.C3B = 20; - RegionAttachment.C3A = 21; - RegionAttachment.U3 = 22; - RegionAttachment.V3 = 23; - RegionAttachment.X4 = 24; - RegionAttachment.Y4 = 25; - RegionAttachment.C4R = 26; - RegionAttachment.C4G = 27; - RegionAttachment.C4B = 28; - RegionAttachment.C4A = 29; - RegionAttachment.U4 = 30; - RegionAttachment.V4 = 31; - return RegionAttachment; - }(Attachment)); - - /** - * @public - */ - var Sequence = /** @class */ (function () { - function Sequence(count) { - this.id = Sequence.nextID(); - this.start = 0; - this.digits = 0; - /** The index of the region to show for the setup pose. */ - this.setupIndex = 0; - this.regions = new Array(count); - } - Sequence.prototype.copy = function () { - var copy = new Sequence(this.regions.length); - Utils.arrayCopy(this.regions, 0, copy.regions, 0, this.regions.length); - copy.start = this.start; - copy.digits = this.digits; - copy.setupIndex = this.setupIndex; - return copy; - }; - Sequence.prototype.apply = function (slot, attachment) { - var index = slot.sequenceIndex; - if (index == -1) - index = this.setupIndex; - if (index >= this.regions.length) - index = this.regions.length - 1; - var region = this.regions[index]; - if (attachment.region != region) { - attachment.region = region; - // attachment.updateRegion(); - } - }; - Sequence.prototype.getPath = function (basePath, index) { - var result = basePath; - var frame = (this.start + index).toString(); - for (var i = this.digits - frame.length; i > 0; i--) - result += "0"; - result += frame; - return result; - }; - Sequence.nextID = function () { - return Sequence._nextID++; - }; - Sequence._nextID = 0; - return Sequence; - }()); - /** - * @public - */ - var SequenceMode; - (function (SequenceMode) { - SequenceMode[SequenceMode["hold"] = 0] = "hold"; - SequenceMode[SequenceMode["once"] = 1] = "once"; - SequenceMode[SequenceMode["loop"] = 2] = "loop"; - SequenceMode[SequenceMode["pingpong"] = 3] = "pingpong"; - SequenceMode[SequenceMode["onceReverse"] = 4] = "onceReverse"; - SequenceMode[SequenceMode["loopReverse"] = 5] = "loopReverse"; - SequenceMode[SequenceMode["pingpongReverse"] = 6] = "pingpongReverse"; - })(SequenceMode || (SequenceMode = {})); - /** - * @public - */ - var SequenceModeValues = [ - SequenceMode.hold, - SequenceMode.once, - SequenceMode.loop, - SequenceMode.pingpong, - SequenceMode.onceReverse, - SequenceMode.loopReverse, - SequenceMode.pingpongReverse - ]; - - /** - * A simple container for a list of timelines and a name. - * @public - * */ - var Animation = /** @class */ (function () { - function Animation(name, timelines, duration) { - this.timelines = []; - this.timelineIds = new StringSet(); - if (!name) - throw new Error("name cannot be null."); - this.name = name; - this.setTimelines(timelines); - this.duration = duration; - } - Animation.prototype.setTimelines = function (timelines) { - if (!timelines) - throw new Error("timelines cannot be null."); - this.timelines = timelines; - this.timelineIds.clear(); - for (var i = 0; i < timelines.length; i++) - this.timelineIds.addAll(timelines[i].getPropertyIds()); - }; - Animation.prototype.hasTimeline = function (ids) { - for (var i = 0; i < ids.length; i++) - if (this.timelineIds.contains(ids[i])) - return true; - return false; - }; - /** Applies all the animation's timelines to the specified skeleton. - * - * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. - * @param loop If true, the animation repeats after {@link #getDuration()}. - * @param events May be null to ignore fired events. */ - Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, blend, direction) { - if (!skeleton) - throw new Error("skeleton cannot be null."); - if (loop && this.duration != 0) { - time %= this.duration; - if (lastTime > 0) - lastTime %= this.duration; - } - var timelines = this.timelines; - for (var i = 0, n = timelines.length; i < n; i++) - timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction); - }; - return Animation; - }()); - var Property = { - rotate: 0, - x: 1, - y: 2, - scaleX: 3, - scaleY: 4, - shearX: 5, - shearY: 6, - rgb: 7, - alpha: 8, - rgb2: 9, - attachment: 10, - deform: 11, - event: 12, - drawOrder: 13, - ikConstraint: 14, - transformConstraint: 15, - pathConstraintPosition: 16, - pathConstraintSpacing: 17, - pathConstraintMix: 18, - sequence: 19 - }; - /** The interface for all timelines. - * @public - * */ - var Timeline = /** @class */ (function () { - function Timeline(frameCount, propertyIds) { - this.propertyIds = propertyIds; - this.frames = Utils.newFloatArray(frameCount * this.getFrameEntries()); - } - Timeline.prototype.getPropertyIds = function () { - return this.propertyIds; - }; - Timeline.prototype.getFrameEntries = function () { - return 1; - }; - Timeline.prototype.getFrameCount = function () { - return this.frames.length / this.getFrameEntries(); - }; - Timeline.prototype.getDuration = function () { - return this.frames[this.frames.length - this.getFrameEntries()]; - }; - Timeline.search1 = function (frames, time) { - var n = frames.length; - for (var i = 1; i < n; i++) - if (frames[i] > time) - return i - 1; - return n - 1; - }; - Timeline.search = function (frames, time, step) { - var n = frames.length; - for (var i = step; i < n; i += step) - if (frames[i] > time) - return i - step; - return n - step; - }; - return Timeline; - }()); - /** The base class for timelines that use interpolation between key frame values. - * @public - * */ - var CurveTimeline = /** @class */ (function (_super) { - __extends$1(CurveTimeline, _super); - function CurveTimeline(frameCount, bezierCount, propertyIds) { - var _this = _super.call(this, frameCount, propertyIds) || this; - _this.curves = Utils.newFloatArray(frameCount + bezierCount * 18 /*BEZIER_SIZE*/); - _this.curves[frameCount - 1] = 1 /*STEPPED*/; - return _this; - } - /** Sets the specified key frame to linear interpolation. */ - CurveTimeline.prototype.setLinear = function (frame) { - this.curves[frame] = 0 /*LINEAR*/; - }; - /** Sets the specified key frame to stepped interpolation. */ - CurveTimeline.prototype.setStepped = function (frame) { - this.curves[frame] = 1 /*STEPPED*/; - }; - /** Shrinks the storage for Bezier curves, for use when bezierCount (specified in the constructor) was larger - * than the actual number of Bezier curves. */ - CurveTimeline.prototype.shrink = function (bezierCount) { - var size = this.getFrameCount() + bezierCount * 18 /*BEZIER_SIZE*/; - if (this.curves.length > size) { - var newCurves = Utils.newFloatArray(size); - Utils.arrayCopy(this.curves, 0, newCurves, 0, size); - this.curves = newCurves; - } - }; - /** Stores the segments for the specified Bezier curve. For timelines that modify multiple values, there may be more than - * one curve per frame. - * @param bezier The ordinal of this Bezier curve for this timeline, between 0 and bezierCount - 1 (specified - * in the constructor), inclusive. - * @param frame Between 0 and frameCount - 1, inclusive. - * @param value The index of the value for this frame that this curve is used for. - * @param time1 The time for the first key. - * @param value1 The value for the first key. - * @param cx1 The time for the first Bezier handle. - * @param cy1 The value for the first Bezier handle. - * @param cx2 The time of the second Bezier handle. - * @param cy2 The value for the second Bezier handle. - * @param time2 The time for the second key. - * @param value2 The value for the second key. */ - CurveTimeline.prototype.setBezier = function (bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2) { - var curves = this.curves; - var i = this.getFrameCount() + bezier * 18 /*BEZIER_SIZE*/; - if (value == 0) - curves[frame] = 2 /*BEZIER*/ + i; - var tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = (value1 - cy1 * 2 + cy2) * 0.03; - var dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006, dddy = ((cy1 - cy2) * 3 - value1 + value2) * 0.006; - var ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy; - var dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = (cy1 - value1) * 0.3 + tmpy + dddy * 0.16666667; - var x = time1 + dx, y = value1 + dy; - for (var n = i + 18 /*BEZIER_SIZE*/; i < n; i += 2) { - curves[i] = x; - curves[i + 1] = y; - dx += ddx; - dy += ddy; - ddx += dddx; - ddy += dddy; - x += dx; - y += dy; - } - }; - /** Returns the Bezier interpolated value for the specified time. - * @param frameIndex The index into {@link #getFrames()} for the values of the frame before time. - * @param valueOffset The offset from frameIndex to the value this curve is used for. - * @param i The index of the Bezier segments. See {@link #getCurveType(int)}. */ - CurveTimeline.prototype.getBezierValue = function (time, frameIndex, valueOffset, i) { - var curves = this.curves; - if (curves[i] > time) { - var x_1 = this.frames[frameIndex], y_1 = this.frames[frameIndex + valueOffset]; - return y_1 + (time - x_1) / (curves[i] - x_1) * (curves[i + 1] - y_1); - } - var n = i + 18 /*BEZIER_SIZE*/; - for (i += 2; i < n; i += 2) { - if (curves[i] >= time) { - var x_2 = curves[i - 2], y_2 = curves[i - 1]; - return y_2 + (time - x_2) / (curves[i] - x_2) * (curves[i + 1] - y_2); - } - } - frameIndex += this.getFrameEntries(); - var x = curves[n - 2], y = curves[n - 1]; - return y + (time - x) / (this.frames[frameIndex] - x) * (this.frames[frameIndex + valueOffset] - y); - }; - return CurveTimeline; - }(Timeline)); - /** - * @public - */ - var CurveTimeline1 = /** @class */ (function (_super) { - __extends$1(CurveTimeline1, _super); - function CurveTimeline1(frameCount, bezierCount, propertyId) { - return _super.call(this, frameCount, bezierCount, [propertyId]) || this; - } - CurveTimeline1.prototype.getFrameEntries = function () { - return 2 /*ENTRIES*/; - }; - /** Sets the time and value for the specified frame. - * @param frame Between 0 and frameCount, inclusive. - * @param time The frame time in seconds. */ - CurveTimeline1.prototype.setFrame = function (frame, time, value) { - frame <<= 1; - this.frames[frame] = time; - this.frames[frame + 1 /*VALUE*/] = value; - }; - /** Returns the interpolated value for the specified time. */ - CurveTimeline1.prototype.getCurveValue = function (time) { - var frames = this.frames; - var i = frames.length - 2; - for (var ii = 2; ii <= i; ii += 2) { - if (frames[ii] > time) { - i = ii - 2; - break; - } - } - var curveType = this.curves[i >> 1]; - switch (curveType) { - case 0 /*LINEAR*/: - var before = frames[i], value = frames[i + 1 /*VALUE*/]; - return value + (time - before) / (frames[i + 2 /*ENTRIES*/] - before) * (frames[i + 2 /*ENTRIES*/ + 1 /*VALUE*/] - value); - case 1 /*STEPPED*/: - return frames[i + 1 /*VALUE*/]; - } - return this.getBezierValue(time, i, 1 /*VALUE*/, curveType - 2 /*BEZIER*/); - }; - return CurveTimeline1; - }(CurveTimeline)); - /** The base class for a {@link CurveTimeline} which sets two properties. - * @public - * */ - var CurveTimeline2 = /** @class */ (function (_super) { - __extends$1(CurveTimeline2, _super); - /** @param bezierCount The maximum number of Bezier curves. See {@link #shrink(int)}. - * @param propertyIds Unique identifiers for the properties the timeline modifies. */ - function CurveTimeline2(frameCount, bezierCount, propertyId1, propertyId2) { - return _super.call(this, frameCount, bezierCount, [propertyId1, propertyId2]) || this; - } - CurveTimeline2.prototype.getFrameEntries = function () { - return 3 /*ENTRIES*/; - }; - /** Sets the time and values for the specified frame. - * @param frame Between 0 and frameCount, inclusive. - * @param time The frame time in seconds. */ - CurveTimeline2.prototype.setFrame = function (frame, time, value1, value2) { - frame *= 3 /*ENTRIES*/; - this.frames[frame] = time; - this.frames[frame + 1 /*VALUE1*/] = value1; - this.frames[frame + 2 /*VALUE2*/] = value2; - }; - return CurveTimeline2; - }(CurveTimeline)); - /** Changes a bone's local {@link Bone#rotation}. - * @public - * */ - var RotateTimeline = /** @class */ (function (_super) { - __extends$1(RotateTimeline, _super); - function RotateTimeline(frameCount, bezierCount, boneIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.rotate + "|" + boneIndex) || this; - _this.boneIndex = 0; - _this.boneIndex = boneIndex; - return _this; - } - RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.rotation = bone.data.rotation; - return; - case exports.MixBlend.first: - bone.rotation += (bone.data.rotation - bone.rotation) * alpha; - } - return; - } - var r = this.getCurveValue(time); - switch (blend) { - case exports.MixBlend.setup: - bone.rotation = bone.data.rotation + r * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - r += bone.data.rotation - bone.rotation; - case exports.MixBlend.add: - bone.rotation += r * alpha; - } - }; - return RotateTimeline; - }(CurveTimeline1)); - /** Changes a bone's local {@link Bone#x} and {@link Bone#y}. - * @public - * */ - var TranslateTimeline = /** @class */ (function (_super) { - __extends$1(TranslateTimeline, _super); - function TranslateTimeline(frameCount, bezierCount, boneIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.x + "|" + boneIndex, Property.y + "|" + boneIndex) || this; - _this.boneIndex = 0; - _this.boneIndex = boneIndex; - return _this; - } - TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.x = bone.data.x; - bone.y = bone.data.y; - return; - case exports.MixBlend.first: - bone.x += (bone.data.x - bone.x) * alpha; - bone.y += (bone.data.y - bone.y) * alpha; - } - return; - } - var x = 0, y = 0; - var i = Timeline.search(frames, time, 3 /*ENTRIES*/); - var curveType = this.curves[i / 3 /*ENTRIES*/]; - switch (curveType) { - case 0 /*LINEAR*/: - var before = frames[i]; - x = frames[i + 1 /*VALUE1*/]; - y = frames[i + 2 /*VALUE2*/]; - var t = (time - before) / (frames[i + 3 /*ENTRIES*/] - before); - x += (frames[i + 3 /*ENTRIES*/ + 1 /*VALUE1*/] - x) * t; - y += (frames[i + 3 /*ENTRIES*/ + 2 /*VALUE2*/] - y) * t; - break; - case 1 /*STEPPED*/: - x = frames[i + 1 /*VALUE1*/]; - y = frames[i + 2 /*VALUE2*/]; - break; - default: - x = this.getBezierValue(time, i, 1 /*VALUE1*/, curveType - 2 /*BEZIER*/); - y = this.getBezierValue(time, i, 2 /*VALUE2*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); - } - switch (blend) { - case exports.MixBlend.setup: - bone.x = bone.data.x + x * alpha; - bone.y = bone.data.y + y * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bone.x += (bone.data.x + x - bone.x) * alpha; - bone.y += (bone.data.y + y - bone.y) * alpha; - break; - case exports.MixBlend.add: - bone.x += x * alpha; - bone.y += y * alpha; - } - }; - return TranslateTimeline; - }(CurveTimeline2)); - /** Changes a bone's local {@link Bone#x}. - * @public - * */ - var TranslateXTimeline = /** @class */ (function (_super) { - __extends$1(TranslateXTimeline, _super); - function TranslateXTimeline(frameCount, bezierCount, boneIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.x + "|" + boneIndex) || this; - _this.boneIndex = 0; - _this.boneIndex = boneIndex; - return _this; - } - TranslateXTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.x = bone.data.x; - return; - case exports.MixBlend.first: - bone.x += (bone.data.x - bone.x) * alpha; - } - return; - } - var x = this.getCurveValue(time); - switch (blend) { - case exports.MixBlend.setup: - bone.x = bone.data.x + x * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bone.x += (bone.data.x + x - bone.x) * alpha; - break; - case exports.MixBlend.add: - bone.x += x * alpha; - } - }; - return TranslateXTimeline; - }(CurveTimeline1)); - /** Changes a bone's local {@link Bone#x}. - * @public - * */ - var TranslateYTimeline = /** @class */ (function (_super) { - __extends$1(TranslateYTimeline, _super); - function TranslateYTimeline(frameCount, bezierCount, boneIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.y + "|" + boneIndex) || this; - _this.boneIndex = 0; - _this.boneIndex = boneIndex; - return _this; - } - TranslateYTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.y = bone.data.y; - return; - case exports.MixBlend.first: - bone.y += (bone.data.y - bone.y) * alpha; - } - return; - } - var y = this.getCurveValue(time); - switch (blend) { - case exports.MixBlend.setup: - bone.y = bone.data.y + y * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bone.y += (bone.data.y + y - bone.y) * alpha; - break; - case exports.MixBlend.add: - bone.y += y * alpha; - } - }; - return TranslateYTimeline; - }(CurveTimeline1)); - /** Changes a bone's local {@link Bone#scaleX)} and {@link Bone#scaleY}. - * @public - * */ - var ScaleTimeline = /** @class */ (function (_super) { - __extends$1(ScaleTimeline, _super); - function ScaleTimeline(frameCount, bezierCount, boneIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.scaleX + "|" + boneIndex, Property.scaleY + "|" + boneIndex) || this; - _this.boneIndex = 0; - _this.boneIndex = boneIndex; - return _this; - } - ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.scaleX = bone.data.scaleX; - bone.scaleY = bone.data.scaleY; - return; - case exports.MixBlend.first: - bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; - bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; - } - return; - } - var x, y; - var i = Timeline.search(frames, time, 3 /*ENTRIES*/); - var curveType = this.curves[i / 3 /*ENTRIES*/]; - switch (curveType) { - case 0 /*LINEAR*/: - var before = frames[i]; - x = frames[i + 1 /*VALUE1*/]; - y = frames[i + 2 /*VALUE2*/]; - var t = (time - before) / (frames[i + 3 /*ENTRIES*/] - before); - x += (frames[i + 3 /*ENTRIES*/ + 1 /*VALUE1*/] - x) * t; - y += (frames[i + 3 /*ENTRIES*/ + 2 /*VALUE2*/] - y) * t; - break; - case 1 /*STEPPED*/: - x = frames[i + 1 /*VALUE1*/]; - y = frames[i + 2 /*VALUE2*/]; - break; - default: - x = this.getBezierValue(time, i, 1 /*VALUE1*/, curveType - 2 /*BEZIER*/); - y = this.getBezierValue(time, i, 2 /*VALUE2*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); - } - x *= bone.data.scaleX; - y *= bone.data.scaleY; - if (alpha == 1) { - if (blend == exports.MixBlend.add) { - bone.scaleX += x - bone.data.scaleX; - bone.scaleY += y - bone.data.scaleY; - } - else { - bone.scaleX = x; - bone.scaleY = y; - } - } - else { - var bx = 0, by = 0; - if (direction == exports.MixDirection.mixOut) { - switch (blend) { - case exports.MixBlend.setup: - bx = bone.data.scaleX; - by = bone.data.scaleY; - bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; - bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bx = bone.scaleX; - by = bone.scaleY; - bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; - bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; - break; - case exports.MixBlend.add: - bone.scaleX += (x - bone.data.scaleX) * alpha; - bone.scaleY += (y - bone.data.scaleY) * alpha; - } - } - else { - switch (blend) { - case exports.MixBlend.setup: - bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x); - by = Math.abs(bone.data.scaleY) * MathUtils.signum(y); - bone.scaleX = bx + (x - bx) * alpha; - bone.scaleY = by + (y - by) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bx = Math.abs(bone.scaleX) * MathUtils.signum(x); - by = Math.abs(bone.scaleY) * MathUtils.signum(y); - bone.scaleX = bx + (x - bx) * alpha; - bone.scaleY = by + (y - by) * alpha; - break; - case exports.MixBlend.add: - bone.scaleX += (x - bone.data.scaleX) * alpha; - bone.scaleY += (y - bone.data.scaleY) * alpha; - } - } - } - }; - return ScaleTimeline; - }(CurveTimeline2)); - /** Changes a bone's local {@link Bone#scaleX)} and {@link Bone#scaleY}. - * @public - * */ - var ScaleXTimeline = /** @class */ (function (_super) { - __extends$1(ScaleXTimeline, _super); - function ScaleXTimeline(frameCount, bezierCount, boneIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.scaleX + "|" + boneIndex) || this; - _this.boneIndex = 0; - _this.boneIndex = boneIndex; - return _this; - } - ScaleXTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.scaleX = bone.data.scaleX; - return; - case exports.MixBlend.first: - bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; - } - return; - } - var x = this.getCurveValue(time) * bone.data.scaleX; - if (alpha == 1) { - if (blend == exports.MixBlend.add) - bone.scaleX += x - bone.data.scaleX; - else - bone.scaleX = x; - } - else { - // Mixing out uses sign of setup or current pose, else use sign of key. - var bx = 0; - if (direction == exports.MixDirection.mixOut) { - switch (blend) { - case exports.MixBlend.setup: - bx = bone.data.scaleX; - bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bx = bone.scaleX; - bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; - break; - case exports.MixBlend.add: - bone.scaleX += (x - bone.data.scaleX) * alpha; - } - } - else { - switch (blend) { - case exports.MixBlend.setup: - bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x); - bone.scaleX = bx + (x - bx) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bx = Math.abs(bone.scaleX) * MathUtils.signum(x); - bone.scaleX = bx + (x - bx) * alpha; - break; - case exports.MixBlend.add: - bone.scaleX += (x - bone.data.scaleX) * alpha; - } - } - } - }; - return ScaleXTimeline; - }(CurveTimeline1)); - /** Changes a bone's local {@link Bone#scaleX)} and {@link Bone#scaleY}. - * @public - * */ - var ScaleYTimeline = /** @class */ (function (_super) { - __extends$1(ScaleYTimeline, _super); - function ScaleYTimeline(frameCount, bezierCount, boneIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.scaleY + "|" + boneIndex) || this; - _this.boneIndex = 0; - _this.boneIndex = boneIndex; - return _this; - } - ScaleYTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.scaleY = bone.data.scaleY; - return; - case exports.MixBlend.first: - bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; - } - return; - } - var y = this.getCurveValue(time) * bone.data.scaleY; - if (alpha == 1) { - if (blend == exports.MixBlend.add) - bone.scaleY += y - bone.data.scaleY; - else - bone.scaleY = y; - } - else { - // Mixing out uses sign of setup or current pose, else use sign of key. - var by = 0; - if (direction == exports.MixDirection.mixOut) { - switch (blend) { - case exports.MixBlend.setup: - by = bone.data.scaleY; - bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - by = bone.scaleY; - bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; - break; - case exports.MixBlend.add: - bone.scaleY += (y - bone.data.scaleY) * alpha; - } - } - else { - switch (blend) { - case exports.MixBlend.setup: - by = Math.abs(bone.data.scaleY) * MathUtils.signum(y); - bone.scaleY = by + (y - by) * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - by = Math.abs(bone.scaleY) * MathUtils.signum(y); - bone.scaleY = by + (y - by) * alpha; - break; - case exports.MixBlend.add: - bone.scaleY += (y - bone.data.scaleY) * alpha; - } - } - } - }; - return ScaleYTimeline; - }(CurveTimeline1)); - /** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. - * @public - * */ - var ShearTimeline = /** @class */ (function (_super) { - __extends$1(ShearTimeline, _super); - function ShearTimeline(frameCount, bezierCount, boneIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.shearX + "|" + boneIndex, Property.shearY + "|" + boneIndex) || this; - _this.boneIndex = 0; - _this.boneIndex = boneIndex; - return _this; - } - ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.shearX = bone.data.shearX; - bone.shearY = bone.data.shearY; - return; - case exports.MixBlend.first: - bone.shearX += (bone.data.shearX - bone.shearX) * alpha; - bone.shearY += (bone.data.shearY - bone.shearY) * alpha; - } - return; - } - var x = 0, y = 0; - var i = Timeline.search(frames, time, 3 /*ENTRIES*/); - var curveType = this.curves[i / 3 /*ENTRIES*/]; - switch (curveType) { - case 0 /*LINEAR*/: - var before = frames[i]; - x = frames[i + 1 /*VALUE1*/]; - y = frames[i + 2 /*VALUE2*/]; - var t = (time - before) / (frames[i + 3 /*ENTRIES*/] - before); - x += (frames[i + 3 /*ENTRIES*/ + 1 /*VALUE1*/] - x) * t; - y += (frames[i + 3 /*ENTRIES*/ + 2 /*VALUE2*/] - y) * t; - break; - case 1 /*STEPPED*/: - x = frames[i + 1 /*VALUE1*/]; - y = frames[i + 2 /*VALUE2*/]; - break; - default: - x = this.getBezierValue(time, i, 1 /*VALUE1*/, curveType - 2 /*BEZIER*/); - y = this.getBezierValue(time, i, 2 /*VALUE2*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); - } - switch (blend) { - case exports.MixBlend.setup: - bone.shearX = bone.data.shearX + x * alpha; - bone.shearY = bone.data.shearY + y * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; - bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; - break; - case exports.MixBlend.add: - bone.shearX += x * alpha; - bone.shearY += y * alpha; - } - }; - return ShearTimeline; - }(CurveTimeline2)); - /** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. - * @public - * */ - var ShearXTimeline = /** @class */ (function (_super) { - __extends$1(ShearXTimeline, _super); - function ShearXTimeline(frameCount, bezierCount, boneIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.shearX + "|" + boneIndex) || this; - _this.boneIndex = 0; - _this.boneIndex = boneIndex; - return _this; - } - ShearXTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.shearX = bone.data.shearX; - return; - case exports.MixBlend.first: - bone.shearX += (bone.data.shearX - bone.shearX) * alpha; - } - return; - } - var x = this.getCurveValue(time); - switch (blend) { - case exports.MixBlend.setup: - bone.shearX = bone.data.shearX + x * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; - break; - case exports.MixBlend.add: - bone.shearX += x * alpha; - } - }; - return ShearXTimeline; - }(CurveTimeline1)); - /** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. - * @public - * */ - var ShearYTimeline = /** @class */ (function (_super) { - __extends$1(ShearYTimeline, _super); - function ShearYTimeline(frameCount, bezierCount, boneIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.shearY + "|" + boneIndex) || this; - _this.boneIndex = 0; - _this.boneIndex = boneIndex; - return _this; - } - ShearYTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var bone = skeleton.bones[this.boneIndex]; - if (!bone.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.shearY = bone.data.shearY; - return; - case exports.MixBlend.first: - bone.shearY += (bone.data.shearY - bone.shearY) * alpha; - } - return; - } - var y = this.getCurveValue(time); - switch (blend) { - case exports.MixBlend.setup: - bone.shearY = bone.data.shearY + y * alpha; - break; - case exports.MixBlend.first: - case exports.MixBlend.replace: - bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; - break; - case exports.MixBlend.add: - bone.shearY += y * alpha; - } - }; - return ShearYTimeline; - }(CurveTimeline1)); - /** Changes a slot's {@link Slot#color}. - * @public - * */ - var RGBATimeline = /** @class */ (function (_super) { - __extends$1(RGBATimeline, _super); - function RGBATimeline(frameCount, bezierCount, slotIndex) { - var _this = _super.call(this, frameCount, bezierCount, [ - Property.rgb + "|" + slotIndex, - Property.alpha + "|" + slotIndex - ]) || this; - _this.slotIndex = 0; - _this.slotIndex = slotIndex; - return _this; - } - RGBATimeline.prototype.getFrameEntries = function () { - return 5 /*ENTRIES*/; - }; - /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ - RGBATimeline.prototype.setFrame = function (frame, time, r, g, b, a) { - frame *= 5 /*ENTRIES*/; - this.frames[frame] = time; - this.frames[frame + 1 /*R*/] = r; - this.frames[frame + 2 /*G*/] = g; - this.frames[frame + 3 /*B*/] = b; - this.frames[frame + 4 /*A*/] = a; - }; - RGBATimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - var frames = this.frames; - var color = slot.color; - if (time < frames[0]) { - var setup = slot.data.color; - switch (blend) { - case exports.MixBlend.setup: - color.setFromColor(setup); - return; - case exports.MixBlend.first: - color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha); - } - return; - } - var r = 0, g = 0, b = 0, a = 0; - var i = Timeline.search(frames, time, 5 /*ENTRIES*/); - var curveType = this.curves[i / 5 /*ENTRIES*/]; - switch (curveType) { - case 0 /*LINEAR*/: - var before = frames[i]; - r = frames[i + 1 /*R*/]; - g = frames[i + 2 /*G*/]; - b = frames[i + 3 /*B*/]; - a = frames[i + 4 /*A*/]; - var t = (time - before) / (frames[i + 5 /*ENTRIES*/] - before); - r += (frames[i + 5 /*ENTRIES*/ + 1 /*R*/] - r) * t; - g += (frames[i + 5 /*ENTRIES*/ + 2 /*G*/] - g) * t; - b += (frames[i + 5 /*ENTRIES*/ + 3 /*B*/] - b) * t; - a += (frames[i + 5 /*ENTRIES*/ + 4 /*A*/] - a) * t; - break; - case 1 /*STEPPED*/: - r = frames[i + 1 /*R*/]; - g = frames[i + 2 /*G*/]; - b = frames[i + 3 /*B*/]; - a = frames[i + 4 /*A*/]; - break; - default: - r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/); - g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); - b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); - a = this.getBezierValue(time, i, 4 /*A*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/); - } - if (alpha == 1) - color.set(r, g, b, a); - else { - if (blend == exports.MixBlend.setup) - color.setFromColor(slot.data.color); - color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha); - } - }; - return RGBATimeline; - }(CurveTimeline)); - /** Changes a slot's {@link Slot#color}. - * @public - * */ - var RGBTimeline = /** @class */ (function (_super) { - __extends$1(RGBTimeline, _super); - function RGBTimeline(frameCount, bezierCount, slotIndex) { - var _this = _super.call(this, frameCount, bezierCount, [ - Property.rgb + "|" + slotIndex - ]) || this; - _this.slotIndex = 0; - _this.slotIndex = slotIndex; - return _this; - } - RGBTimeline.prototype.getFrameEntries = function () { - return 4 /*ENTRIES*/; - }; - /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ - RGBTimeline.prototype.setFrame = function (frame, time, r, g, b) { - frame <<= 2; - this.frames[frame] = time; - this.frames[frame + 1 /*R*/] = r; - this.frames[frame + 2 /*G*/] = g; - this.frames[frame + 3 /*B*/] = b; - }; - RGBTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - var frames = this.frames; - var color = slot.color; - if (time < frames[0]) { - var setup = slot.data.color; - switch (blend) { - case exports.MixBlend.setup: - color.r = setup.r; - color.g = setup.g; - color.b = setup.b; - return; - case exports.MixBlend.first: - color.r += (setup.r - color.r) * alpha; - color.g += (setup.g - color.g) * alpha; - color.b += (setup.b - color.b) * alpha; - } - return; - } - var r = 0, g = 0, b = 0; - var i = Timeline.search(frames, time, 4 /*ENTRIES*/); - var curveType = this.curves[i >> 2]; - switch (curveType) { - case 0 /*LINEAR*/: - var before = frames[i]; - r = frames[i + 1 /*R*/]; - g = frames[i + 2 /*G*/]; - b = frames[i + 3 /*B*/]; - var t = (time - before) / (frames[i + 4 /*ENTRIES*/] - before); - r += (frames[i + 4 /*ENTRIES*/ + 1 /*R*/] - r) * t; - g += (frames[i + 4 /*ENTRIES*/ + 2 /*G*/] - g) * t; - b += (frames[i + 4 /*ENTRIES*/ + 3 /*B*/] - b) * t; - break; - case 1 /*STEPPED*/: - r = frames[i + 1 /*R*/]; - g = frames[i + 2 /*G*/]; - b = frames[i + 3 /*B*/]; - break; - default: - r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/); - g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); - b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); - } - if (alpha == 1) { - color.r = r; - color.g = g; - color.b = b; - } - else { - if (blend == exports.MixBlend.setup) { - var setup = slot.data.color; - color.r = setup.r; - color.g = setup.g; - color.b = setup.b; - } - color.r += (r - color.r) * alpha; - color.g += (g - color.g) * alpha; - color.b += (b - color.b) * alpha; - } - }; - return RGBTimeline; - }(CurveTimeline)); - /** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. - * @public - * */ - var AlphaTimeline = /** @class */ (function (_super) { - __extends$1(AlphaTimeline, _super); - function AlphaTimeline(frameCount, bezierCount, slotIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.alpha + "|" + slotIndex) || this; - _this.slotIndex = 0; - _this.slotIndex = slotIndex; - return _this; - } - AlphaTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - var color = slot.color; - if (time < this.frames[0]) { // Time is before first frame. - var setup = slot.data.color; - switch (blend) { - case exports.MixBlend.setup: - color.a = setup.a; - return; - case exports.MixBlend.first: - color.a += (setup.a - color.a) * alpha; - } - return; - } - var a = this.getCurveValue(time); - if (alpha == 1) - color.a = a; - else { - if (blend == exports.MixBlend.setup) - color.a = slot.data.color.a; - color.a += (a - color.a) * alpha; - } - }; - return AlphaTimeline; - }(CurveTimeline1)); - /** Changes a slot's {@link Slot#color} and {@link Slot#darkColor} for two color tinting. - * @public - * */ - var RGBA2Timeline = /** @class */ (function (_super) { - __extends$1(RGBA2Timeline, _super); - function RGBA2Timeline(frameCount, bezierCount, slotIndex) { - var _this = _super.call(this, frameCount, bezierCount, [ - Property.rgb + "|" + slotIndex, - Property.alpha + "|" + slotIndex, - Property.rgb2 + "|" + slotIndex - ]) || this; - _this.slotIndex = 0; - _this.slotIndex = slotIndex; - return _this; - } - RGBA2Timeline.prototype.getFrameEntries = function () { - return 8 /*ENTRIES*/; - }; - /** Sets the time in seconds, light, and dark colors for the specified key frame. */ - RGBA2Timeline.prototype.setFrame = function (frame, time, r, g, b, a, r2, g2, b2) { - frame <<= 3; - this.frames[frame] = time; - this.frames[frame + 1 /*R*/] = r; - this.frames[frame + 2 /*G*/] = g; - this.frames[frame + 3 /*B*/] = b; - this.frames[frame + 4 /*A*/] = a; - this.frames[frame + 5 /*R2*/] = r2; - this.frames[frame + 6 /*G2*/] = g2; - this.frames[frame + 7 /*B2*/] = b2; - }; - RGBA2Timeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - var frames = this.frames; - var light = slot.color, dark = slot.darkColor; - if (time < frames[0]) { - var setupLight = slot.data.color, setupDark = slot.data.darkColor; - switch (blend) { - case exports.MixBlend.setup: - light.setFromColor(setupLight); - dark.r = setupDark.r; - dark.g = setupDark.g; - dark.b = setupDark.b; - return; - case exports.MixBlend.first: - light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha); - dark.r += (setupDark.r - dark.r) * alpha; - dark.g += (setupDark.g - dark.g) * alpha; - dark.b += (setupDark.b - dark.b) * alpha; - } - return; - } - var r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; - var i = Timeline.search(frames, time, 8 /*ENTRIES*/); - var curveType = this.curves[i >> 3]; - switch (curveType) { - case 0 /*LINEAR*/: - var before = frames[i]; - r = frames[i + 1 /*R*/]; - g = frames[i + 2 /*G*/]; - b = frames[i + 3 /*B*/]; - a = frames[i + 4 /*A*/]; - r2 = frames[i + 5 /*R2*/]; - g2 = frames[i + 6 /*G2*/]; - b2 = frames[i + 7 /*B2*/]; - var t = (time - before) / (frames[i + 8 /*ENTRIES*/] - before); - r += (frames[i + 8 /*ENTRIES*/ + 1 /*R*/] - r) * t; - g += (frames[i + 8 /*ENTRIES*/ + 2 /*G*/] - g) * t; - b += (frames[i + 8 /*ENTRIES*/ + 3 /*B*/] - b) * t; - a += (frames[i + 8 /*ENTRIES*/ + 4 /*A*/] - a) * t; - r2 += (frames[i + 8 /*ENTRIES*/ + 5 /*R2*/] - r2) * t; - g2 += (frames[i + 8 /*ENTRIES*/ + 6 /*G2*/] - g2) * t; - b2 += (frames[i + 8 /*ENTRIES*/ + 7 /*B2*/] - b2) * t; - break; - case 1 /*STEPPED*/: - r = frames[i + 1 /*R*/]; - g = frames[i + 2 /*G*/]; - b = frames[i + 3 /*B*/]; - a = frames[i + 4 /*A*/]; - r2 = frames[i + 5 /*R2*/]; - g2 = frames[i + 6 /*G2*/]; - b2 = frames[i + 7 /*B2*/]; - break; - default: - r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/); - g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); - b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); - a = this.getBezierValue(time, i, 4 /*A*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/); - r2 = this.getBezierValue(time, i, 5 /*R2*/, curveType + 18 /*BEZIER_SIZE*/ * 4 - 2 /*BEZIER*/); - g2 = this.getBezierValue(time, i, 6 /*G2*/, curveType + 18 /*BEZIER_SIZE*/ * 5 - 2 /*BEZIER*/); - b2 = this.getBezierValue(time, i, 7 /*B2*/, curveType + 18 /*BEZIER_SIZE*/ * 6 - 2 /*BEZIER*/); - } - if (alpha == 1) { - light.set(r, g, b, a); - dark.r = r2; - dark.g = g2; - dark.b = b2; - } - else { - if (blend == exports.MixBlend.setup) { - light.setFromColor(slot.data.color); - var setupDark = slot.data.darkColor; - dark.r = setupDark.r; - dark.g = setupDark.g; - dark.b = setupDark.b; - } - light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha); - dark.r += (r2 - dark.r) * alpha; - dark.g += (g2 - dark.g) * alpha; - dark.b += (b2 - dark.b) * alpha; - } - }; - return RGBA2Timeline; - }(CurveTimeline)); - /** Changes a slot's {@link Slot#color} and {@link Slot#darkColor} for two color tinting. - * @public - * */ - var RGB2Timeline = /** @class */ (function (_super) { - __extends$1(RGB2Timeline, _super); - function RGB2Timeline(frameCount, bezierCount, slotIndex) { - var _this = _super.call(this, frameCount, bezierCount, [ - Property.rgb + "|" + slotIndex, - Property.rgb2 + "|" + slotIndex - ]) || this; - _this.slotIndex = 0; - _this.slotIndex = slotIndex; - return _this; - } - RGB2Timeline.prototype.getFrameEntries = function () { - return 7 /*ENTRIES*/; - }; - /** Sets the time in seconds, light, and dark colors for the specified key frame. */ - RGB2Timeline.prototype.setFrame = function (frame, time, r, g, b, r2, g2, b2) { - frame *= 7 /*ENTRIES*/; - this.frames[frame] = time; - this.frames[frame + 1 /*R*/] = r; - this.frames[frame + 2 /*G*/] = g; - this.frames[frame + 3 /*B*/] = b; - this.frames[frame + 4 /*R2*/] = r2; - this.frames[frame + 5 /*G2*/] = g2; - this.frames[frame + 6 /*B2*/] = b2; - }; - RGB2Timeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - var frames = this.frames; - var light = slot.color, dark = slot.darkColor; - if (time < frames[0]) { - var setupLight = slot.data.color, setupDark = slot.data.darkColor; - switch (blend) { - case exports.MixBlend.setup: - light.r = setupLight.r; - light.g = setupLight.g; - light.b = setupLight.b; - dark.r = setupDark.r; - dark.g = setupDark.g; - dark.b = setupDark.b; - return; - case exports.MixBlend.first: - light.r += (setupLight.r - light.r) * alpha; - light.g += (setupLight.g - light.g) * alpha; - light.b += (setupLight.b - light.b) * alpha; - dark.r += (setupDark.r - dark.r) * alpha; - dark.g += (setupDark.g - dark.g) * alpha; - dark.b += (setupDark.b - dark.b) * alpha; - } - return; - } - var r = 0, g = 0, b = 0, r2 = 0, g2 = 0, b2 = 0; - var i = Timeline.search(frames, time, 7 /*ENTRIES*/); - var curveType = this.curves[i / 7 /*ENTRIES*/]; - switch (curveType) { - case 0 /*LINEAR*/: - var before = frames[i]; - r = frames[i + 1 /*R*/]; - g = frames[i + 2 /*G*/]; - b = frames[i + 3 /*B*/]; - r2 = frames[i + 4 /*R2*/]; - g2 = frames[i + 5 /*G2*/]; - b2 = frames[i + 6 /*B2*/]; - var t = (time - before) / (frames[i + 7 /*ENTRIES*/] - before); - r += (frames[i + 7 /*ENTRIES*/ + 1 /*R*/] - r) * t; - g += (frames[i + 7 /*ENTRIES*/ + 2 /*G*/] - g) * t; - b += (frames[i + 7 /*ENTRIES*/ + 3 /*B*/] - b) * t; - r2 += (frames[i + 7 /*ENTRIES*/ + 4 /*R2*/] - r2) * t; - g2 += (frames[i + 7 /*ENTRIES*/ + 5 /*G2*/] - g2) * t; - b2 += (frames[i + 7 /*ENTRIES*/ + 6 /*B2*/] - b2) * t; - break; - case 1 /*STEPPED*/: - r = frames[i + 1 /*R*/]; - g = frames[i + 2 /*G*/]; - b = frames[i + 3 /*B*/]; - r2 = frames[i + 4 /*R2*/]; - g2 = frames[i + 5 /*G2*/]; - b2 = frames[i + 6 /*B2*/]; - break; - default: - r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/); - g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); - b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); - r2 = this.getBezierValue(time, i, 4 /*R2*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/); - g2 = this.getBezierValue(time, i, 5 /*G2*/, curveType + 18 /*BEZIER_SIZE*/ * 4 - 2 /*BEZIER*/); - b2 = this.getBezierValue(time, i, 6 /*B2*/, curveType + 18 /*BEZIER_SIZE*/ * 5 - 2 /*BEZIER*/); - } - if (alpha == 1) { - light.r = r; - light.g = g; - light.b = b; - dark.r = r2; - dark.g = g2; - dark.b = b2; - } - else { - if (blend == exports.MixBlend.setup) { - var setupLight = slot.data.color, setupDark = slot.data.darkColor; - light.r = setupLight.r; - light.g = setupLight.g; - light.b = setupLight.b; - dark.r = setupDark.r; - dark.g = setupDark.g; - dark.b = setupDark.b; - } - light.r += (r - light.r) * alpha; - light.g += (g - light.g) * alpha; - light.b += (b - light.b) * alpha; - dark.r += (r2 - dark.r) * alpha; - dark.g += (g2 - dark.g) * alpha; - dark.b += (b2 - dark.b) * alpha; - } - }; - return RGB2Timeline; - }(CurveTimeline)); - /** Changes a slot's {@link Slot#attachment}. - * @public - * */ - var AttachmentTimeline = /** @class */ (function (_super) { - __extends$1(AttachmentTimeline, _super); - function AttachmentTimeline(frameCount, slotIndex) { - var _this = _super.call(this, frameCount, [ - Property.attachment + "|" + slotIndex - ]) || this; - _this.slotIndex = 0; - _this.slotIndex = slotIndex; - _this.attachmentNames = new Array(frameCount); - return _this; - } - AttachmentTimeline.prototype.getFrameCount = function () { - return this.frames.length; - }; - /** Sets the time in seconds and the attachment name for the specified key frame. */ - AttachmentTimeline.prototype.setFrame = function (frame, time, attachmentName) { - this.frames[frame] = time; - this.attachmentNames[frame] = attachmentName; - }; - AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - if (direction == exports.MixDirection.mixOut) { - if (blend == exports.MixBlend.setup) - this.setAttachment(skeleton, slot, slot.data.attachmentName); - return; - } - if (time < this.frames[0]) { - if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) - this.setAttachment(skeleton, slot, slot.data.attachmentName); - return; - } - this.setAttachment(skeleton, slot, this.attachmentNames[Timeline.search1(this.frames, time)]); - }; - AttachmentTimeline.prototype.setAttachment = function (skeleton, slot, attachmentName) { - slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); - }; - return AttachmentTimeline; - }(Timeline)); - /** Changes a slot's {@link Slot#deform} to deform a {@link VertexAttachment}. - * @public - * */ - var DeformTimeline = /** @class */ (function (_super) { - __extends$1(DeformTimeline, _super); - function DeformTimeline(frameCount, bezierCount, slotIndex, attachment) { - var _this = _super.call(this, frameCount, bezierCount, [ - Property.deform + "|" + slotIndex + "|" + attachment.id - ]) || this; - _this.slotIndex = 0; - _this.slotIndex = slotIndex; - _this.attachment = attachment; - _this.vertices = new Array(frameCount); - return _this; - } - DeformTimeline.prototype.getFrameCount = function () { - return this.frames.length; - }; - /** Sets the time in seconds and the vertices for the specified key frame. - * @param vertices Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */ - DeformTimeline.prototype.setFrame = function (frame, time, vertices) { - this.frames[frame] = time; - this.vertices[frame] = vertices; - }; - /** @param value1 Ignored (0 is used for a deform timeline). - * @param value2 Ignored (1 is used for a deform timeline). */ - DeformTimeline.prototype.setBezier = function (bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2) { - var curves = this.curves; - var i = this.getFrameCount() + bezier * 18 /*BEZIER_SIZE*/; - if (value == 0) - curves[frame] = 2 /*BEZIER*/ + i; - var tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = cy2 * 0.03 - cy1 * 0.06; - var dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006, dddy = (cy1 - cy2 + 0.33333333) * 0.018; - var ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy; - var dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = cy1 * 0.3 + tmpy + dddy * 0.16666667; - var x = time1 + dx, y = dy; - for (var n = i + 18 /*BEZIER_SIZE*/; i < n; i += 2) { - curves[i] = x; - curves[i + 1] = y; - dx += ddx; - dy += ddy; - ddx += dddx; - ddy += dddy; - x += dx; - y += dy; - } - }; - DeformTimeline.prototype.getCurvePercent = function (time, frame) { - var curves = this.curves; - var i = curves[frame]; - switch (i) { - case 0 /*LINEAR*/: - var x_3 = this.frames[frame]; - return (time - x_3) / (this.frames[frame + this.getFrameEntries()] - x_3); - case 1 /*STEPPED*/: - return 0; - } - i -= 2 /*BEZIER*/; - if (curves[i] > time) { - var x_4 = this.frames[frame]; - return curves[i + 1] * (time - x_4) / (curves[i] - x_4); - } - var n = i + 18 /*BEZIER_SIZE*/; - for (i += 2; i < n; i += 2) { - if (curves[i] >= time) { - var x_5 = curves[i - 2], y_3 = curves[i - 1]; - return y_3 + (time - x_5) / (curves[i] - x_5) * (curves[i + 1] - y_3); - } - } - var x = curves[n - 2], y = curves[n - 1]; - return y + (1 - y) * (time - x) / (this.frames[frame + this.getFrameEntries()] - x); - }; - DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - var slotAttachment = slot.getAttachment(); - if (!slotAttachment) - return; - if (!(slotAttachment instanceof VertexAttachment) || slotAttachment.timelineAttachment != this.attachment) - return; - var deform = slot.deform; - if (deform.length == 0) - blend = exports.MixBlend.setup; - var vertices = this.vertices; - var vertexCount = vertices[0].length; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - deform.length = 0; - return; - case exports.MixBlend.first: - if (alpha == 1) { - deform.length = 0; - return; - } - deform.length = vertexCount; - var vertexAttachment = slotAttachment; - if (!vertexAttachment.bones) { - // Unweighted vertex positions. - var setupVertices = vertexAttachment.vertices; - for (var i = 0; i < vertexCount; i++) - deform[i] += (setupVertices[i] - deform[i]) * alpha; - } - else { - // Weighted deform offsets. - alpha = 1 - alpha; - for (var i = 0; i < vertexCount; i++) - deform[i] *= alpha; - } - } - return; - } - deform.length = vertexCount; - if (time >= frames[frames.length - 1]) { // Time is after last frame. - var lastVertices = vertices[frames.length - 1]; - if (alpha == 1) { - if (blend == exports.MixBlend.add) { - var vertexAttachment = slotAttachment; - if (!vertexAttachment.bones) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i_1 = 0; i_1 < vertexCount; i_1++) - deform[i_1] += lastVertices[i_1] - setupVertices[i_1]; - } - else { - // Weighted deform offsets, with alpha. - for (var i_2 = 0; i_2 < vertexCount; i_2++) - deform[i_2] += lastVertices[i_2]; - } - } - else - Utils.arrayCopy(lastVertices, 0, deform, 0, vertexCount); - } - else { - switch (blend) { - case exports.MixBlend.setup: { - var vertexAttachment_1 = slotAttachment; - if (!vertexAttachment_1.bones) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment_1.vertices; - for (var i_3 = 0; i_3 < vertexCount; i_3++) { - var setup = setupVertices[i_3]; - deform[i_3] = setup + (lastVertices[i_3] - setup) * alpha; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i_4 = 0; i_4 < vertexCount; i_4++) - deform[i_4] = lastVertices[i_4] * alpha; - } - break; - } - case exports.MixBlend.first: - case exports.MixBlend.replace: - for (var i_5 = 0; i_5 < vertexCount; i_5++) - deform[i_5] += (lastVertices[i_5] - deform[i_5]) * alpha; - break; - case exports.MixBlend.add: - var vertexAttachment = slotAttachment; - if (!vertexAttachment.bones) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i_6 = 0; i_6 < vertexCount; i_6++) - deform[i_6] += (lastVertices[i_6] - setupVertices[i_6]) * alpha; - } - else { - // Weighted deform offsets, with alpha. - for (var i_7 = 0; i_7 < vertexCount; i_7++) - deform[i_7] += lastVertices[i_7] * alpha; - } - } - } - return; - } - // Interpolate between the previous frame and the current frame. - var frame = Timeline.search1(frames, time); - var percent = this.getCurvePercent(time, frame); - var prevVertices = vertices[frame]; - var nextVertices = vertices[frame + 1]; - if (alpha == 1) { - if (blend == exports.MixBlend.add) { - var vertexAttachment = slotAttachment; - if (!vertexAttachment.bones) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i_8 = 0; i_8 < vertexCount; i_8++) { - var prev = prevVertices[i_8]; - deform[i_8] += prev + (nextVertices[i_8] - prev) * percent - setupVertices[i_8]; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i_9 = 0; i_9 < vertexCount; i_9++) { - var prev = prevVertices[i_9]; - deform[i_9] += prev + (nextVertices[i_9] - prev) * percent; - } - } - } - else { - for (var i_10 = 0; i_10 < vertexCount; i_10++) { - var prev = prevVertices[i_10]; - deform[i_10] = prev + (nextVertices[i_10] - prev) * percent; - } - } - } - else { - switch (blend) { - case exports.MixBlend.setup: { - var vertexAttachment_2 = slotAttachment; - if (!vertexAttachment_2.bones) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment_2.vertices; - for (var i_11 = 0; i_11 < vertexCount; i_11++) { - var prev = prevVertices[i_11], setup = setupVertices[i_11]; - deform[i_11] = setup + (prev + (nextVertices[i_11] - prev) * percent - setup) * alpha; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i_12 = 0; i_12 < vertexCount; i_12++) { - var prev = prevVertices[i_12]; - deform[i_12] = (prev + (nextVertices[i_12] - prev) * percent) * alpha; - } - } - break; - } - case exports.MixBlend.first: - case exports.MixBlend.replace: - for (var i_13 = 0; i_13 < vertexCount; i_13++) { - var prev = prevVertices[i_13]; - deform[i_13] += (prev + (nextVertices[i_13] - prev) * percent - deform[i_13]) * alpha; - } - break; - case exports.MixBlend.add: - var vertexAttachment = slotAttachment; - if (!vertexAttachment.bones) { - // Unweighted vertex positions, with alpha. - var setupVertices = vertexAttachment.vertices; - for (var i_14 = 0; i_14 < vertexCount; i_14++) { - var prev = prevVertices[i_14]; - deform[i_14] += (prev + (nextVertices[i_14] - prev) * percent - setupVertices[i_14]) * alpha; - } - } - else { - // Weighted deform offsets, with alpha. - for (var i_15 = 0; i_15 < vertexCount; i_15++) { - var prev = prevVertices[i_15]; - deform[i_15] += (prev + (nextVertices[i_15] - prev) * percent) * alpha; - } - } - } - } - }; - return DeformTimeline; - }(CurveTimeline)); - /** Fires an {@link Event} when specific animation times are reached. - * @public - * */ - var EventTimeline = /** @class */ (function (_super) { - __extends$1(EventTimeline, _super); - function EventTimeline(frameCount) { - var _this = _super.call(this, frameCount, EventTimeline.propertyIds) || this; - _this.events = new Array(frameCount); - return _this; - } - EventTimeline.prototype.getFrameCount = function () { - return this.frames.length; - }; - /** Sets the time in seconds and the event for the specified key frame. */ - EventTimeline.prototype.setFrame = function (frame, event) { - this.frames[frame] = event.time; - this.events[frame] = event; - }; - /** Fires events for frames > `lastTime` and <= `time`. */ - EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - if (!firedEvents) - return; - var frames = this.frames; - var frameCount = this.frames.length; - if (lastTime > time) { // Fire events after last time for looped animations. - this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction); - lastTime = -1; - } - else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame. - return; - if (time < frames[0]) - return; // Time is before first frame. - var i = 0; - if (lastTime < frames[0]) - i = 0; - else { - i = Timeline.search1(frames, lastTime) + 1; - var frameTime = frames[i]; - while (i > 0) { // Fire multiple events with the same frame. - if (frames[i - 1] != frameTime) - break; - i--; - } - } - for (; i < frameCount && time >= frames[i]; i++) - firedEvents.push(this.events[i]); - }; - EventTimeline.propertyIds = ["" + Property.event]; - return EventTimeline; - }(Timeline)); - /** Changes a skeleton's {@link Skeleton#drawOrder}. - * @public - * */ - var DrawOrderTimeline = /** @class */ (function (_super) { - __extends$1(DrawOrderTimeline, _super); - function DrawOrderTimeline(frameCount) { - var _this = _super.call(this, frameCount, DrawOrderTimeline.propertyIds) || this; - _this.drawOrders = new Array(frameCount); - return _this; - } - DrawOrderTimeline.prototype.getFrameCount = function () { - return this.frames.length; - }; - /** Sets the time in seconds and the draw order for the specified key frame. - * @param drawOrder For each slot in {@link Skeleton#slots}, the index of the new draw order. May be null to use setup pose - * draw order. */ - DrawOrderTimeline.prototype.setFrame = function (frame, time, drawOrder) { - this.frames[frame] = time; - this.drawOrders[frame] = drawOrder; - }; - DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - if (direction == exports.MixDirection.mixOut) { - if (blend == exports.MixBlend.setup) - Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); - return; - } - if (time < this.frames[0]) { - if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) - Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); - return; - } - var idx = Timeline.search1(this.frames, time); - var drawOrderToSetupIndex = this.drawOrders[idx]; - if (!drawOrderToSetupIndex) - Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); - else { - var drawOrder = skeleton.drawOrder; - var slots = skeleton.slots; - for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++) - drawOrder[i] = slots[drawOrderToSetupIndex[i]]; - } - }; - DrawOrderTimeline.propertyIds = ["" + Property.drawOrder]; - return DrawOrderTimeline; - }(Timeline)); - /** Changes an IK constraint's {@link IkConstraint#mix}, {@link IkConstraint#softness}, - * {@link IkConstraint#bendDirection}, {@link IkConstraint#stretch}, and {@link IkConstraint#compress}. - * @public - * */ - var IkConstraintTimeline = /** @class */ (function (_super) { - __extends$1(IkConstraintTimeline, _super); - function IkConstraintTimeline(frameCount, bezierCount, ikConstraintIndex) { - var _this = _super.call(this, frameCount, bezierCount, [ - Property.ikConstraint + "|" + ikConstraintIndex - ]) || this; - /** The index of the IK constraint slot in {@link Skeleton#ikConstraints} that will be changed. */ - _this.ikConstraintIndex = 0; - _this.ikConstraintIndex = ikConstraintIndex; - return _this; - } - IkConstraintTimeline.prototype.getFrameEntries = function () { - return 6 /*ENTRIES*/; - }; - /** Sets the time in seconds, mix, softness, bend direction, compress, and stretch for the specified key frame. */ - IkConstraintTimeline.prototype.setFrame = function (frame, time, mix, softness, bendDirection, compress, stretch) { - frame *= 6 /*ENTRIES*/; - this.frames[frame] = time; - this.frames[frame + 1 /*MIX*/] = mix; - this.frames[frame + 2 /*SOFTNESS*/] = softness; - this.frames[frame + 3 /*BEND_DIRECTION*/] = bendDirection; - this.frames[frame + 4 /*COMPRESS*/] = compress ? 1 : 0; - this.frames[frame + 5 /*STRETCH*/] = stretch ? 1 : 0; - }; - IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var constraint = skeleton.ikConstraints[this.ikConstraintIndex]; - if (!constraint.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.mix = constraint.data.mix; - constraint.softness = constraint.data.softness; - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - return; - case exports.MixBlend.first: - constraint.mix += (constraint.data.mix - constraint.mix) * alpha; - constraint.softness += (constraint.data.softness - constraint.softness) * alpha; - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - } - return; - } - var mix = 0, softness = 0; - var i = Timeline.search(frames, time, 6 /*ENTRIES*/); - var curveType = this.curves[i / 6 /*ENTRIES*/]; - switch (curveType) { - case 0 /*LINEAR*/: - var before = frames[i]; - mix = frames[i + 1 /*MIX*/]; - softness = frames[i + 2 /*SOFTNESS*/]; - var t = (time - before) / (frames[i + 6 /*ENTRIES*/] - before); - mix += (frames[i + 6 /*ENTRIES*/ + 1 /*MIX*/] - mix) * t; - softness += (frames[i + 6 /*ENTRIES*/ + 2 /*SOFTNESS*/] - softness) * t; - break; - case 1 /*STEPPED*/: - mix = frames[i + 1 /*MIX*/]; - softness = frames[i + 2 /*SOFTNESS*/]; - break; - default: - mix = this.getBezierValue(time, i, 1 /*MIX*/, curveType - 2 /*BEZIER*/); - softness = this.getBezierValue(time, i, 2 /*SOFTNESS*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); - } - if (blend == exports.MixBlend.setup) { - constraint.mix = constraint.data.mix + (mix - constraint.data.mix) * alpha; - constraint.softness = constraint.data.softness + (softness - constraint.data.softness) * alpha; - if (direction == exports.MixDirection.mixOut) { - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - } - else { - constraint.bendDirection = frames[i + 3 /*BEND_DIRECTION*/]; - constraint.compress = frames[i + 4 /*COMPRESS*/] != 0; - constraint.stretch = frames[i + 5 /*STRETCH*/] != 0; - } - } - else { - constraint.mix += (mix - constraint.mix) * alpha; - constraint.softness += (softness - constraint.softness) * alpha; - if (direction == exports.MixDirection.mixIn) { - constraint.bendDirection = frames[i + 3 /*BEND_DIRECTION*/]; - constraint.compress = frames[i + 4 /*COMPRESS*/] != 0; - constraint.stretch = frames[i + 5 /*STRETCH*/] != 0; - } - } - }; - return IkConstraintTimeline; - }(CurveTimeline)); - /** Changes a transform constraint's {@link TransformConstraint#rotateMix}, {@link TransformConstraint#translateMix}, - * {@link TransformConstraint#scaleMix}, and {@link TransformConstraint#shearMix}. - * @public - * */ - var TransformConstraintTimeline = /** @class */ (function (_super) { - __extends$1(TransformConstraintTimeline, _super); - function TransformConstraintTimeline(frameCount, bezierCount, transformConstraintIndex) { - var _this = _super.call(this, frameCount, bezierCount, [ - Property.transformConstraint + "|" + transformConstraintIndex - ]) || this; - /** The index of the transform constraint slot in {@link Skeleton#transformConstraints} that will be changed. */ - _this.transformConstraintIndex = 0; - _this.transformConstraintIndex = transformConstraintIndex; - return _this; - } - TransformConstraintTimeline.prototype.getFrameEntries = function () { - return 7 /*ENTRIES*/; - }; - /** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. */ - TransformConstraintTimeline.prototype.setFrame = function (frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY) { - var frames = this.frames; - frame *= 7 /*ENTRIES*/; - frames[frame] = time; - frames[frame + 1 /*ROTATE*/] = mixRotate; - frames[frame + 2 /*X*/] = mixX; - frames[frame + 3 /*Y*/] = mixY; - frames[frame + 4 /*SCALEX*/] = mixScaleX; - frames[frame + 5 /*SCALEY*/] = mixScaleY; - frames[frame + 6 /*SHEARY*/] = mixShearY; - }; - TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var constraint = skeleton.transformConstraints[this.transformConstraintIndex]; - if (!constraint.active) - return; - var frames = this.frames; - if (time < frames[0]) { - var data = constraint.data; - switch (blend) { - case exports.MixBlend.setup: - constraint.mixRotate = data.mixRotate; - constraint.mixX = data.mixX; - constraint.mixY = data.mixY; - constraint.mixScaleX = data.mixScaleX; - constraint.mixScaleY = data.mixScaleY; - constraint.mixShearY = data.mixShearY; - return; - case exports.MixBlend.first: - constraint.mixRotate += (data.mixRotate - constraint.mixRotate) * alpha; - constraint.mixX += (data.mixX - constraint.mixX) * alpha; - constraint.mixY += (data.mixY - constraint.mixY) * alpha; - constraint.mixScaleX += (data.mixScaleX - constraint.mixScaleX) * alpha; - constraint.mixScaleY += (data.mixScaleY - constraint.mixScaleY) * alpha; - constraint.mixShearY += (data.mixShearY - constraint.mixShearY) * alpha; - } - return; - } - var rotate, x, y, scaleX, scaleY, shearY; - var i = Timeline.search(frames, time, 7 /*ENTRIES*/); - var curveType = this.curves[i / 7 /*ENTRIES*/]; - switch (curveType) { - case 0 /*LINEAR*/: - var before = frames[i]; - rotate = frames[i + 1 /*ROTATE*/]; - x = frames[i + 2 /*X*/]; - y = frames[i + 3 /*Y*/]; - scaleX = frames[i + 4 /*SCALEX*/]; - scaleY = frames[i + 5 /*SCALEY*/]; - shearY = frames[i + 6 /*SHEARY*/]; - var t = (time - before) / (frames[i + 7 /*ENTRIES*/] - before); - rotate += (frames[i + 7 /*ENTRIES*/ + 1 /*ROTATE*/] - rotate) * t; - x += (frames[i + 7 /*ENTRIES*/ + 2 /*X*/] - x) * t; - y += (frames[i + 7 /*ENTRIES*/ + 3 /*Y*/] - y) * t; - scaleX += (frames[i + 7 /*ENTRIES*/ + 4 /*SCALEX*/] - scaleX) * t; - scaleY += (frames[i + 7 /*ENTRIES*/ + 5 /*SCALEY*/] - scaleY) * t; - shearY += (frames[i + 7 /*ENTRIES*/ + 6 /*SHEARY*/] - shearY) * t; - break; - case 1 /*STEPPED*/: - rotate = frames[i + 1 /*ROTATE*/]; - x = frames[i + 2 /*X*/]; - y = frames[i + 3 /*Y*/]; - scaleX = frames[i + 4 /*SCALEX*/]; - scaleY = frames[i + 5 /*SCALEY*/]; - shearY = frames[i + 6 /*SHEARY*/]; - break; - default: - rotate = this.getBezierValue(time, i, 1 /*ROTATE*/, curveType - 2 /*BEZIER*/); - x = this.getBezierValue(time, i, 2 /*X*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); - y = this.getBezierValue(time, i, 3 /*Y*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); - scaleX = this.getBezierValue(time, i, 4 /*SCALEX*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/); - scaleY = this.getBezierValue(time, i, 5 /*SCALEY*/, curveType + 18 /*BEZIER_SIZE*/ * 4 - 2 /*BEZIER*/); - shearY = this.getBezierValue(time, i, 6 /*SHEARY*/, curveType + 18 /*BEZIER_SIZE*/ * 5 - 2 /*BEZIER*/); - } - if (blend == exports.MixBlend.setup) { - var data = constraint.data; - constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha; - constraint.mixX = data.mixX + (x - data.mixX) * alpha; - constraint.mixY = data.mixY + (y - data.mixY) * alpha; - constraint.mixScaleX = data.mixScaleX + (scaleX - data.mixScaleX) * alpha; - constraint.mixScaleY = data.mixScaleY + (scaleY - data.mixScaleY) * alpha; - constraint.mixShearY = data.mixShearY + (shearY - data.mixShearY) * alpha; - } - else { - constraint.mixRotate += (rotate - constraint.mixRotate) * alpha; - constraint.mixX += (x - constraint.mixX) * alpha; - constraint.mixY += (y - constraint.mixY) * alpha; - constraint.mixScaleX += (scaleX - constraint.mixScaleX) * alpha; - constraint.mixScaleY += (scaleY - constraint.mixScaleY) * alpha; - constraint.mixShearY += (shearY - constraint.mixShearY) * alpha; - } - }; - return TransformConstraintTimeline; - }(CurveTimeline)); - /** Changes a path constraint's {@link PathConstraint#position}. - * @public - * */ - var PathConstraintPositionTimeline = /** @class */ (function (_super) { - __extends$1(PathConstraintPositionTimeline, _super); - function PathConstraintPositionTimeline(frameCount, bezierCount, pathConstraintIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.pathConstraintPosition + "|" + pathConstraintIndex) || this; - /** The index of the path constraint slot in {@link Skeleton#pathConstraints} that will be changed. */ - _this.pathConstraintIndex = 0; - _this.pathConstraintIndex = pathConstraintIndex; - return _this; - } - PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; - if (!constraint.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.position = constraint.data.position; - return; - case exports.MixBlend.first: - constraint.position += (constraint.data.position - constraint.position) * alpha; - } - return; - } - var position = this.getCurveValue(time); - if (blend == exports.MixBlend.setup) - constraint.position = constraint.data.position + (position - constraint.data.position) * alpha; - else - constraint.position += (position - constraint.position) * alpha; - }; - return PathConstraintPositionTimeline; - }(CurveTimeline1)); - /** Changes a path constraint's {@link PathConstraint#spacing}. - * @public - * */ - var PathConstraintSpacingTimeline = /** @class */ (function (_super) { - __extends$1(PathConstraintSpacingTimeline, _super); - function PathConstraintSpacingTimeline(frameCount, bezierCount, pathConstraintIndex) { - var _this = _super.call(this, frameCount, bezierCount, Property.pathConstraintSpacing + "|" + pathConstraintIndex) || this; - /** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */ - _this.pathConstraintIndex = 0; - _this.pathConstraintIndex = pathConstraintIndex; - return _this; - } - PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; - if (!constraint.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.spacing = constraint.data.spacing; - return; - case exports.MixBlend.first: - constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha; - } - return; - } - var spacing = this.getCurveValue(time); - if (blend == exports.MixBlend.setup) - constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha; - else - constraint.spacing += (spacing - constraint.spacing) * alpha; - }; - return PathConstraintSpacingTimeline; - }(CurveTimeline1)); - /** Changes a transform constraint's {@link PathConstraint#getMixRotate()}, {@link PathConstraint#getMixX()}, and - * {@link PathConstraint#getMixY()}. - * @public - * */ - var PathConstraintMixTimeline = /** @class */ (function (_super) { - __extends$1(PathConstraintMixTimeline, _super); - function PathConstraintMixTimeline(frameCount, bezierCount, pathConstraintIndex) { - var _this = _super.call(this, frameCount, bezierCount, [ - Property.pathConstraintMix + "|" + pathConstraintIndex - ]) || this; - /** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */ - _this.pathConstraintIndex = 0; - _this.pathConstraintIndex = pathConstraintIndex; - return _this; - } - PathConstraintMixTimeline.prototype.getFrameEntries = function () { - return 4 /*ENTRIES*/; - }; - PathConstraintMixTimeline.prototype.setFrame = function (frame, time, mixRotate, mixX, mixY) { - var frames = this.frames; - frame <<= 2; - frames[frame] = time; - frames[frame + 1 /*ROTATE*/] = mixRotate; - frames[frame + 2 /*X*/] = mixX; - frames[frame + 3 /*Y*/] = mixY; - }; - PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { - var constraint = skeleton.pathConstraints[this.pathConstraintIndex]; - if (!constraint.active) - return; - var frames = this.frames; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - constraint.mixRotate = constraint.data.mixRotate; - constraint.mixX = constraint.data.mixX; - constraint.mixY = constraint.data.mixY; - return; - case exports.MixBlend.first: - constraint.mixRotate += (constraint.data.mixRotate - constraint.mixRotate) * alpha; - constraint.mixX += (constraint.data.mixX - constraint.mixX) * alpha; - constraint.mixY += (constraint.data.mixY - constraint.mixY) * alpha; - } - return; - } - var rotate, x, y; - var i = Timeline.search(frames, time, 4 /*ENTRIES*/); - var curveType = this.curves[i >> 2]; - switch (curveType) { - case 0 /*LINEAR*/: - var before = frames[i]; - rotate = frames[i + 1 /*ROTATE*/]; - x = frames[i + 2 /*X*/]; - y = frames[i + 3 /*Y*/]; - var t = (time - before) / (frames[i + 4 /*ENTRIES*/] - before); - rotate += (frames[i + 4 /*ENTRIES*/ + 1 /*ROTATE*/] - rotate) * t; - x += (frames[i + 4 /*ENTRIES*/ + 2 /*X*/] - x) * t; - y += (frames[i + 4 /*ENTRIES*/ + 3 /*Y*/] - y) * t; - break; - case 1 /*STEPPED*/: - rotate = frames[i + 1 /*ROTATE*/]; - x = frames[i + 2 /*X*/]; - y = frames[i + 3 /*Y*/]; - break; - default: - rotate = this.getBezierValue(time, i, 1 /*ROTATE*/, curveType - 2 /*BEZIER*/); - x = this.getBezierValue(time, i, 2 /*X*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/); - y = this.getBezierValue(time, i, 3 /*Y*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/); - } - if (blend == exports.MixBlend.setup) { - var data = constraint.data; - constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha; - constraint.mixX = data.mixX + (x - data.mixX) * alpha; - constraint.mixY = data.mixY + (y - data.mixY) * alpha; - } - else { - constraint.mixRotate += (rotate - constraint.mixRotate) * alpha; - constraint.mixX += (x - constraint.mixX) * alpha; - constraint.mixY += (y - constraint.mixY) * alpha; - } - }; - return PathConstraintMixTimeline; - }(CurveTimeline)); - /** Changes a slot's {@link Slot#getSequenceIndex()} for an attachment's {@link Sequence}. - * @public - * */ - var SequenceTimeline = /** @class */ (function (_super) { - __extends$1(SequenceTimeline, _super); - function SequenceTimeline(frameCount, slotIndex, attachment) { - var _this = _super.call(this, frameCount, [ - Property.sequence + "|" + slotIndex + "|" + attachment.sequence.id - ]) || this; - _this.slotIndex = slotIndex; - _this.attachment = attachment; - return _this; - } - SequenceTimeline.prototype.getFrameEntries = function () { - return SequenceTimeline.ENTRIES; - }; - SequenceTimeline.prototype.getSlotIndex = function () { - return this.slotIndex; - }; - SequenceTimeline.prototype.getAttachment = function () { - return this.attachment; - }; - /** Sets the time, mode, index, and frame time for the specified frame. - * @param frame Between 0 and frameCount, inclusive. - * @param time Seconds between frames. */ - SequenceTimeline.prototype.setFrame = function (frame, time, mode, index, delay) { - var frames = this.frames; - frame *= SequenceTimeline.ENTRIES; - frames[frame] = time; - frames[frame + SequenceTimeline.MODE] = mode | (index << 4); - frames[frame + SequenceTimeline.DELAY] = delay; - }; - SequenceTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) { - var slot = skeleton.slots[this.slotIndex]; - if (!slot.bone.active) - return; - var slotAttachment = slot.attachment; - var attachment = this.attachment; - if (slotAttachment != attachment) { - if (!(slotAttachment instanceof VertexAttachment) - || slotAttachment.timelineAttachment != attachment) - return; - } - var frames = this.frames; - if (time < frames[0]) { // Time is before first frame. - if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) - slot.sequenceIndex = -1; - return; - } - var i = Timeline.search(frames, time, SequenceTimeline.ENTRIES); - var before = frames[i]; - var modeAndIndex = frames[i + SequenceTimeline.MODE]; - var delay = frames[i + SequenceTimeline.DELAY]; - if (!this.attachment.sequence) - return; - var index = modeAndIndex >> 4, count = this.attachment.sequence.regions.length; - var mode = SequenceModeValues[modeAndIndex & 0xf]; - if (mode != SequenceMode.hold) { - index += (((time - before) / delay + 0.00001) | 0); - switch (mode) { - case SequenceMode.once: - index = Math.min(count - 1, index); - break; - case SequenceMode.loop: - index %= count; - break; - case SequenceMode.pingpong: { - var n = (count << 1) - 2; - index = n == 0 ? 0 : index % n; - if (index >= count) - index = n - index; - break; - } - case SequenceMode.onceReverse: - index = Math.max(count - 1 - index, 0); - break; - case SequenceMode.loopReverse: - index = count - 1 - (index % count); - break; - case SequenceMode.pingpongReverse: { - var n = (count << 1) - 2; - index = n == 0 ? 0 : (index + count - 1) % n; - if (index >= count) - index = n - index; - } - } - } - slot.sequenceIndex = index; - }; - SequenceTimeline.ENTRIES = 3; - SequenceTimeline.MODE = 1; - SequenceTimeline.DELAY = 2; - return SequenceTimeline; - }(Timeline)); - - /** Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies - * multiple animations on top of each other (layering). - * - * See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. - * @public - * */ - var AnimationState = /** @class */ (function () { - function AnimationState(data) { - /** The list of tracks that currently have animations, which may contain null entries. */ - this.tracks = new Array(); - /** Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower - * or faster. Defaults to 1. - * - * See TrackEntry {@link TrackEntry#timeScale} for affecting a single animation. */ - this.timeScale = 1; - this.unkeyedState = 0; - this.events = new Array(); - this.listeners = new Array(); - this.queue = new EventQueue(this); - this.propertyIDs = new StringSet(); - this.animationsChanged = false; - this.trackEntryPool = new Pool(function () { return new TrackEntry(); }); - this.data = data; - } - AnimationState.emptyAnimation = function () { - return AnimationState._emptyAnimation; - }; - /** Increments each track entry {@link TrackEntry#trackTime()}, setting queued animations as current if needed. */ - AnimationState.prototype.update = function (delta) { - delta *= this.timeScale; - var tracks = this.tracks; - for (var i = 0, n = tracks.length; i < n; i++) { - var current = tracks[i]; - if (!current) - continue; - current.animationLast = current.nextAnimationLast; - current.trackLast = current.nextTrackLast; - var currentDelta = delta * current.timeScale; - if (current.delay > 0) { - current.delay -= currentDelta; - if (current.delay > 0) - continue; - currentDelta = -current.delay; - current.delay = 0; - } - var next = current.next; - if (next) { - // When the next entry's delay is passed, change to the next entry, preserving leftover time. - var nextTime = current.trackLast - next.delay; - if (nextTime >= 0) { - next.delay = 0; - next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale; - current.trackTime += currentDelta; - this.setCurrent(i, next, true); - while (next.mixingFrom) { - next.mixTime += delta; - next = next.mixingFrom; - } - continue; - } - } - else if (current.trackLast >= current.trackEnd && !current.mixingFrom) { - tracks[i] = null; - this.queue.end(current); - this.clearNext(current); - continue; - } - if (current.mixingFrom && this.updateMixingFrom(current, delta)) { - // End mixing from entries once all have completed. - var from = current.mixingFrom; - current.mixingFrom = null; - if (from) - from.mixingTo = null; - while (from) { - this.queue.end(from); - from = from.mixingFrom; - } - } - current.trackTime += currentDelta; - } - this.queue.drain(); - }; - /** Returns true when all mixing from entries are complete. */ - AnimationState.prototype.updateMixingFrom = function (to, delta) { - var from = to.mixingFrom; - if (!from) - return true; - var finished = this.updateMixingFrom(from, delta); - from.animationLast = from.nextAnimationLast; - from.trackLast = from.nextTrackLast; - // Require mixTime > 0 to ensure the mixing from entry was applied at least once. - if (to.mixTime > 0 && to.mixTime >= to.mixDuration) { - // Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame). - if (from.totalAlpha == 0 || to.mixDuration == 0) { - to.mixingFrom = from.mixingFrom; - if (from.mixingFrom) - from.mixingFrom.mixingTo = to; - to.interruptAlpha = from.interruptAlpha; - this.queue.end(from); - } - return finished; - } - from.trackTime += delta * from.timeScale; - to.mixTime += delta; - return false; - }; - /** Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the - * animation state can be applied to multiple skeletons to pose them identically. - * @returns True if any animations were applied. */ - AnimationState.prototype.apply = function (skeleton) { - if (!skeleton) - throw new Error("skeleton cannot be null."); - if (this.animationsChanged) - this._animationsChanged(); - var events = this.events; - var tracks = this.tracks; - var applied = false; - for (var i_1 = 0, n_1 = tracks.length; i_1 < n_1; i_1++) { - var current = tracks[i_1]; - if (!current || current.delay > 0) - continue; - applied = true; - var blend = i_1 == 0 ? exports.MixBlend.first : current.mixBlend; - // Apply mixing from entries first. - var mix = current.alpha; - if (current.mixingFrom) - mix *= this.applyMixingFrom(current, skeleton, blend); - else if (current.trackTime >= current.trackEnd && !current.next) - mix = 0; - // Apply current entry. - var animationLast = current.animationLast, animationTime = current.getAnimationTime(), applyTime = animationTime; - var applyEvents = events; - if (current.reverse) { - applyTime = current.animation.duration - applyTime; - applyEvents = null; - } - var timelines = current.animation.timelines; - var timelineCount = timelines.length; - if ((i_1 == 0 && mix == 1) || blend == exports.MixBlend.add) { - for (var ii = 0; ii < timelineCount; ii++) { - // Fixes issue #302 on IOS9 where mix, blend sometimes became undefined and caused assets - // to sometimes stop rendering when using color correction, as their RGBA values become NaN. - // (https://github.com/pixijs/pixi-spine/issues/302) - Utils.webkit602BugfixHelper(mix, blend); - var timeline = timelines[ii]; - if (timeline instanceof AttachmentTimeline) - this.applyAttachmentTimeline(timeline, skeleton, applyTime, blend, true); - else - timeline.apply(skeleton, animationLast, applyTime, applyEvents, mix, blend, exports.MixDirection.mixIn); - } - } - else { - var timelineMode = current.timelineMode; - var shortestRotation = current.shortestRotation; - var firstFrame = !shortestRotation && current.timelinesRotation.length != timelineCount << 1; - if (firstFrame) - current.timelinesRotation.length = timelineCount << 1; - for (var ii = 0; ii < timelineCount; ii++) { - var timeline_1 = timelines[ii]; - var timelineBlend = timelineMode[ii] == SUBSEQUENT ? blend : exports.MixBlend.setup; - if (!shortestRotation && timeline_1 instanceof RotateTimeline) { - this.applyRotateTimeline(timeline_1, skeleton, applyTime, mix, timelineBlend, current.timelinesRotation, ii << 1, firstFrame); - } - else if (timeline_1 instanceof AttachmentTimeline) { - this.applyAttachmentTimeline(timeline_1, skeleton, applyTime, blend, true); - } - else { - // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 - Utils.webkit602BugfixHelper(mix, blend); - timeline_1.apply(skeleton, animationLast, applyTime, applyEvents, mix, timelineBlend, exports.MixDirection.mixIn); - } - } - } - this.queueEvents(current, animationTime); - events.length = 0; - current.nextAnimationLast = animationTime; - current.nextTrackLast = current.trackTime; - } - // Set slots attachments to the setup pose, if needed. This occurs if an animation that is mixing out sets attachments so - // subsequent timelines see any deform, but the subsequent timelines don't set an attachment (eg they are also mixing out or - // the time is before the first key). - var setupState = this.unkeyedState + SETUP; - var slots = skeleton.slots; - for (var i = 0, n = skeleton.slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.attachmentState == setupState) { - var attachmentName = slot.data.attachmentName; - slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName)); - } - } - this.unkeyedState += 2; // Increasing after each use avoids the need to reset attachmentState for every slot. - this.queue.drain(); - return applied; - }; - AnimationState.prototype.applyMixingFrom = function (to, skeleton, blend) { - var from = to.mixingFrom; - if (from.mixingFrom) - this.applyMixingFrom(from, skeleton, blend); - var mix = 0; - if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. - mix = 1; - if (blend == exports.MixBlend.first) - blend = exports.MixBlend.setup; - } - else { - mix = to.mixTime / to.mixDuration; - if (mix > 1) - mix = 1; - if (blend != exports.MixBlend.first) - blend = from.mixBlend; - } - var attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold; - var timelines = from.animation.timelines; - var timelineCount = timelines.length; - var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); - var animationLast = from.animationLast, animationTime = from.getAnimationTime(), applyTime = animationTime; - var events = null; - if (from.reverse) - applyTime = from.animation.duration - applyTime; - else if (mix < from.eventThreshold) - events = this.events; - if (blend == exports.MixBlend.add) { - for (var i = 0; i < timelineCount; i++) - timelines[i].apply(skeleton, animationLast, applyTime, events, alphaMix, blend, exports.MixDirection.mixOut); - } - else { - var timelineMode = from.timelineMode; - var timelineHoldMix = from.timelineHoldMix; - var shortestRotation = from.shortestRotation; - var firstFrame = !shortestRotation && from.timelinesRotation.length != timelineCount << 1; - if (firstFrame) - from.timelinesRotation.length = timelineCount << 1; - from.totalAlpha = 0; - for (var i = 0; i < timelineCount; i++) { - var timeline = timelines[i]; - var direction = exports.MixDirection.mixOut; - var timelineBlend = void 0; - var alpha = 0; - switch (timelineMode[i]) { - case SUBSEQUENT: - if (!drawOrder && timeline instanceof DrawOrderTimeline) - continue; - timelineBlend = blend; - alpha = alphaMix; - break; - case FIRST: - timelineBlend = exports.MixBlend.setup; - alpha = alphaMix; - break; - case HOLD_SUBSEQUENT: - timelineBlend = blend; - alpha = alphaHold; - break; - case HOLD_FIRST: - timelineBlend = exports.MixBlend.setup; - alpha = alphaHold; - break; - default: - timelineBlend = exports.MixBlend.setup; - var holdMix = timelineHoldMix[i]; - alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration); - break; - } - from.totalAlpha += alpha; - if (!shortestRotation && timeline instanceof RotateTimeline) - this.applyRotateTimeline(timeline, skeleton, applyTime, alpha, timelineBlend, from.timelinesRotation, i << 1, firstFrame); - else if (timeline instanceof AttachmentTimeline) - this.applyAttachmentTimeline(timeline, skeleton, applyTime, timelineBlend, attachments); - else { - // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 - Utils.webkit602BugfixHelper(alpha, blend); - if (drawOrder && timeline instanceof DrawOrderTimeline && timelineBlend == exports.MixBlend.setup) - direction = exports.MixDirection.mixIn; - timeline.apply(skeleton, animationLast, applyTime, events, alpha, timelineBlend, direction); - } - } - } - if (to.mixDuration > 0) - this.queueEvents(from, animationTime); - this.events.length = 0; - from.nextAnimationLast = animationTime; - from.nextTrackLast = from.trackTime; - return mix; - }; - AnimationState.prototype.applyAttachmentTimeline = function (timeline, skeleton, time, blend, attachments) { - var slot = skeleton.slots[timeline.slotIndex]; - if (!slot.bone.active) - return; - if (time < timeline.frames[0]) { // Time is before first frame. - if (blend == exports.MixBlend.setup || blend == exports.MixBlend.first) - this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments); - } - else - this.setAttachment(skeleton, slot, timeline.attachmentNames[Timeline.search1(timeline.frames, time)], attachments); - // If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later. - if (slot.attachmentState <= this.unkeyedState) - slot.attachmentState = this.unkeyedState + SETUP; - }; - AnimationState.prototype.setAttachment = function (skeleton, slot, attachmentName, attachments) { - slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName)); - if (attachments) - slot.attachmentState = this.unkeyedState + CURRENT; - }; - AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) { - if (firstFrame) - timelinesRotation[i] = 0; - if (alpha == 1) { - timeline.apply(skeleton, 0, time, null, 1, blend, exports.MixDirection.mixIn); - return; - } - var bone = skeleton.bones[timeline.boneIndex]; - if (!bone.active) - return; - var frames = timeline.frames; - var r1 = 0, r2 = 0; - if (time < frames[0]) { - switch (blend) { - case exports.MixBlend.setup: - bone.rotation = bone.data.rotation; - default: - return; - case exports.MixBlend.first: - r1 = bone.rotation; - r2 = bone.data.rotation; - } - } - else { - r1 = blend == exports.MixBlend.setup ? bone.data.rotation : bone.rotation; - r2 = bone.data.rotation + timeline.getCurveValue(time); - } - // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. - var total = 0, diff = r2 - r1; - diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360; - if (diff == 0) { - total = timelinesRotation[i]; - } - else { - var lastTotal = 0, lastDiff = 0; - if (firstFrame) { - lastTotal = 0; - lastDiff = diff; - } - else { - lastTotal = timelinesRotation[i]; // Angle and direction of mix, including loops. - lastDiff = timelinesRotation[i + 1]; // Difference between bones. - } - var current = diff > 0, dir = lastTotal >= 0; - // Detect cross at 0 (not 180). - if (MathUtils.signum(lastDiff) != MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) { - // A cross after a 360 rotation is a loop. - if (Math.abs(lastTotal) > 180) - lastTotal += 360 * MathUtils.signum(lastTotal); - dir = current; - } - total = diff + lastTotal - lastTotal % 360; // Store loops as part of lastTotal. - if (dir != current) - total += 360 * MathUtils.signum(lastTotal); - timelinesRotation[i] = total; - } - timelinesRotation[i + 1] = diff; - bone.rotation = r1 + total * alpha; - }; - AnimationState.prototype.queueEvents = function (entry, animationTime) { - var animationStart = entry.animationStart, animationEnd = entry.animationEnd; - var duration = animationEnd - animationStart; - var trackLastWrapped = entry.trackLast % duration; - // Queue events before complete. - var events = this.events; - var i = 0, n = events.length; - for (; i < n; i++) { - var event_1 = events[i]; - if (event_1.time < trackLastWrapped) - break; - if (event_1.time > animationEnd) - continue; // Discard events outside animation start/end. - this.queue.event(entry, event_1); - } - // Queue complete if completed a loop iteration or the animation. - var complete = false; - if (entry.loop) - complete = duration == 0 || trackLastWrapped > entry.trackTime % duration; - else - complete = animationTime >= animationEnd && entry.animationLast < animationEnd; - if (complete) - this.queue.complete(entry); - // Queue events after complete. - for (; i < n; i++) { - var event_2 = events[i]; - if (event_2.time < animationStart) - continue; // Discard events outside animation start/end. - this.queue.event(entry, event_2); - } - }; - /** Removes all animations from all tracks, leaving skeletons in their current pose. - * - * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, - * rather than leaving them in their current pose. */ - AnimationState.prototype.clearTracks = function () { - var oldDrainDisabled = this.queue.drainDisabled; - this.queue.drainDisabled = true; - for (var i = 0, n = this.tracks.length; i < n; i++) - this.clearTrack(i); - this.tracks.length = 0; - this.queue.drainDisabled = oldDrainDisabled; - this.queue.drain(); - }; - /** Removes all animations from the track, leaving skeletons in their current pose. - * - * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, - * rather than leaving them in their current pose. */ - AnimationState.prototype.clearTrack = function (trackIndex) { - if (trackIndex >= this.tracks.length) - return; - var current = this.tracks[trackIndex]; - if (!current) - return; - this.queue.end(current); - this.clearNext(current); - var entry = current; - while (true) { - var from = entry.mixingFrom; - if (!from) - break; - this.queue.end(from); - entry.mixingFrom = null; - entry.mixingTo = null; - entry = from; - } - this.tracks[current.trackIndex] = null; - this.queue.drain(); - }; - AnimationState.prototype.setCurrent = function (index, current, interrupt) { - var from = this.expandToIndex(index); - this.tracks[index] = current; - current.previous = null; - if (from) { - if (interrupt) - this.queue.interrupt(from); - current.mixingFrom = from; - from.mixingTo = current; - current.mixTime = 0; - // Store the interrupted mix percentage. - if (from.mixingFrom && from.mixDuration > 0) - current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration); - from.timelinesRotation.length = 0; // Reset rotation for mixing out, in case entry was mixed in. - } - this.queue.start(current); - }; - /** Sets an animation by name. - * - * See {@link #setAnimationWith()}. */ - AnimationState.prototype.setAnimation = function (trackIndex, animationName, loop) { - if (loop === void 0) { loop = false; } - var animation = this.data.skeletonData.findAnimation(animationName); - if (!animation) - throw new Error("Animation not found: " + animationName); - return this.setAnimationWith(trackIndex, animation, loop); - }; - /** Sets the current animation for a track, discarding any queued animations. If the formerly current track entry was never - * applied to a skeleton, it is replaced (not mixed from). - * @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its - * duration. In either case {@link TrackEntry#trackEnd} determines when the track is cleared. - * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept - * after the {@link AnimationStateListener#dispose()} event occurs. */ - AnimationState.prototype.setAnimationWith = function (trackIndex, animation, loop) { - if (loop === void 0) { loop = false; } - if (!animation) - throw new Error("animation cannot be null."); - var interrupt = true; - var current = this.expandToIndex(trackIndex); - if (current) { - if (current.nextTrackLast == -1) { - // Don't mix from an entry that was never applied. - this.tracks[trackIndex] = current.mixingFrom; - this.queue.interrupt(current); - this.queue.end(current); - this.clearNext(current); - current = current.mixingFrom; - interrupt = false; - } - else - this.clearNext(current); - } - var entry = this.trackEntry(trackIndex, animation, loop, current); - this.setCurrent(trackIndex, entry, interrupt); - this.queue.drain(); - return entry; - }; - /** Queues an animation by name. - * - * See {@link #addAnimationWith()}. */ - AnimationState.prototype.addAnimation = function (trackIndex, animationName, loop, delay) { - if (loop === void 0) { loop = false; } - if (delay === void 0) { delay = 0; } - var animation = this.data.skeletonData.findAnimation(animationName); - if (!animation) - throw new Error("Animation not found: " + animationName); - return this.addAnimationWith(trackIndex, animation, loop, delay); - }; - /** Adds an animation to be played after the current or last queued animation for a track. If the track is empty, it is - * equivalent to calling {@link #setAnimationWith()}. - * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry - * minus any mix duration (from the {@link AnimationStateData}) plus the specified `delay` (ie the mix - * ends at (`delay` = 0) or before (`delay` < 0) the previous track entry duration). If the - * previous entry is looping, its next loop completion is used instead of its duration. - * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept - * after the {@link AnimationStateListener#dispose()} event occurs. */ - AnimationState.prototype.addAnimationWith = function (trackIndex, animation, loop, delay) { - if (loop === void 0) { loop = false; } - if (delay === void 0) { delay = 0; } - if (!animation) - throw new Error("animation cannot be null."); - var last = this.expandToIndex(trackIndex); - if (last) { - while (last.next) - last = last.next; - } - var entry = this.trackEntry(trackIndex, animation, loop, last); - if (!last) { - this.setCurrent(trackIndex, entry, true); - this.queue.drain(); - } - else { - last.next = entry; - entry.previous = last; - if (delay <= 0) - delay += last.getTrackComplete() - entry.mixDuration; - } - entry.delay = delay; - return entry; - }; - /** Sets an empty animation for a track, discarding any queued animations, and sets the track entry's - * {@link TrackEntry#mixduration}. An empty animation has no timelines and serves as a placeholder for mixing in or out. - * - * Mixing out is done by setting an empty animation with a mix duration using either {@link #setEmptyAnimation()}, - * {@link #setEmptyAnimations()}, or {@link #addEmptyAnimation()}. Mixing to an empty animation causes - * the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation - * transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of - * 0 still mixes out over one frame. - * - * Mixing in is done by first setting an empty animation, then adding an animation using - * {@link #addAnimation()} and on the returned track entry, set the - * {@link TrackEntry#setMixDuration()}. Mixing from an empty animation causes the new animation to be applied more and - * more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the - * setup pose value if no lower tracks key the property to the value keyed in the new animation. */ - AnimationState.prototype.setEmptyAnimation = function (trackIndex, mixDuration) { - if (mixDuration === void 0) { mixDuration = 0; } - var entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation(), false); - entry.mixDuration = mixDuration; - entry.trackEnd = mixDuration; - return entry; - }; - /** Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's - * {@link TrackEntry#mixDuration}. If the track is empty, it is equivalent to calling - * {@link #setEmptyAnimation()}. - * - * See {@link #setEmptyAnimation()}. - * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry - * minus any mix duration plus the specified `delay` (ie the mix ends at (`delay` = 0) or - * before (`delay` < 0) the previous track entry duration). If the previous entry is looping, its next - * loop completion is used instead of its duration. - * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept - * after the {@link AnimationStateListener#dispose()} event occurs. */ - AnimationState.prototype.addEmptyAnimation = function (trackIndex, mixDuration, delay) { - if (mixDuration === void 0) { mixDuration = 0; } - if (delay === void 0) { delay = 0; } - var entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation(), false, delay); - if (delay <= 0) - entry.delay += entry.mixDuration - mixDuration; - entry.mixDuration = mixDuration; - entry.trackEnd = mixDuration; - return entry; - }; - /** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix - * duration. */ - AnimationState.prototype.setEmptyAnimations = function (mixDuration) { - if (mixDuration === void 0) { mixDuration = 0; } - var oldDrainDisabled = this.queue.drainDisabled; - this.queue.drainDisabled = true; - for (var i = 0, n = this.tracks.length; i < n; i++) { - var current = this.tracks[i]; - if (current) - this.setEmptyAnimation(current.trackIndex, mixDuration); - } - this.queue.drainDisabled = oldDrainDisabled; - this.queue.drain(); - }; - AnimationState.prototype.expandToIndex = function (index) { - if (index < this.tracks.length) - return this.tracks[index]; - Utils.ensureArrayCapacity(this.tracks, index + 1, null); - this.tracks.length = index + 1; - return null; - }; - /** @param last May be null. */ - AnimationState.prototype.trackEntry = function (trackIndex, animation, loop, last) { - var entry = this.trackEntryPool.obtain(); - entry.reset(); - entry.trackIndex = trackIndex; - entry.animation = animation; - entry.loop = loop; - entry.holdPrevious = false; - entry.reverse = false; - entry.shortestRotation = false; - entry.eventThreshold = 0; - entry.attachmentThreshold = 0; - entry.drawOrderThreshold = 0; - entry.animationStart = 0; - entry.animationEnd = animation.duration; - entry.animationLast = -1; - entry.nextAnimationLast = -1; - entry.delay = 0; - entry.trackTime = 0; - entry.trackLast = -1; - entry.nextTrackLast = -1; - entry.trackEnd = Number.MAX_VALUE; - entry.timeScale = 1; - entry.alpha = 1; - entry.mixTime = 0; - entry.mixDuration = !last ? 0 : this.data.getMix(last.animation, animation); - entry.interruptAlpha = 1; - entry.totalAlpha = 0; - entry.mixBlend = exports.MixBlend.replace; - return entry; - }; - /** Removes the {@link TrackEntry#getNext() next entry} and all entries after it for the specified entry. */ - AnimationState.prototype.clearNext = function (entry) { - var next = entry.next; - while (next) { - this.queue.dispose(next); - next = next.next; - } - entry.next = null; - }; - AnimationState.prototype._animationsChanged = function () { - this.animationsChanged = false; - this.propertyIDs.clear(); - var tracks = this.tracks; - for (var i = 0, n = tracks.length; i < n; i++) { - var entry = tracks[i]; - if (!entry) - continue; - while (entry.mixingFrom) - entry = entry.mixingFrom; - do { - if (!entry.mixingTo || entry.mixBlend != exports.MixBlend.add) - this.computeHold(entry); - entry = entry.mixingTo; - } while (entry); - } - }; - AnimationState.prototype.computeHold = function (entry) { - var to = entry.mixingTo; - var timelines = entry.animation.timelines; - var timelinesCount = entry.animation.timelines.length; - var timelineMode = entry.timelineMode; - timelineMode.length = timelinesCount; - var timelineHoldMix = entry.timelineHoldMix; - timelineHoldMix.length = 0; - var propertyIDs = this.propertyIDs; - if (to && to.holdPrevious) { - for (var i = 0; i < timelinesCount; i++) - timelineMode[i] = propertyIDs.addAll(timelines[i].getPropertyIds()) ? HOLD_FIRST : HOLD_SUBSEQUENT; - return; - } - outer: for (var i = 0; i < timelinesCount; i++) { - var timeline = timelines[i]; - var ids = timeline.getPropertyIds(); - if (!propertyIDs.addAll(ids)) - timelineMode[i] = SUBSEQUENT; - else if (!to || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline - || timeline instanceof EventTimeline || !to.animation.hasTimeline(ids)) { - timelineMode[i] = FIRST; - } - else { - for (var next = to.mixingTo; next; next = next.mixingTo) { - if (next.animation.hasTimeline(ids)) - continue; - if (entry.mixDuration > 0) { - timelineMode[i] = HOLD_MIX; - timelineHoldMix[i] = next; - continue outer; - } - break; - } - timelineMode[i] = HOLD_FIRST; - } - } - }; - /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */ - AnimationState.prototype.getCurrent = function (trackIndex) { - if (trackIndex >= this.tracks.length) - return null; - return this.tracks[trackIndex]; - }; - /** Adds a listener to receive events for all track entries. */ - AnimationState.prototype.addListener = function (listener) { - if (!listener) - throw new Error("listener cannot be null."); - this.listeners.push(listener); - }; - /** Removes the listener added with {@link #addListener()}. */ - AnimationState.prototype.removeListener = function (listener) { - var index = this.listeners.indexOf(listener); - if (index >= 0) - this.listeners.splice(index, 1); - }; - /** Removes all listeners added with {@link #addListener()}. */ - AnimationState.prototype.clearListeners = function () { - this.listeners.length = 0; - }; - /** Discards all listener notifications that have not yet been delivered. This can be useful to call from an - * {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery - * are not wanted because new animations are being set. */ - AnimationState.prototype.clearListenerNotifications = function () { - this.queue.clear(); - }; - AnimationState.prototype.setAnimationByName = function (trackIndex, animationName, loop) { - if (!AnimationState.deprecatedWarning1) { - AnimationState.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on."); - } - this.setAnimation(trackIndex, animationName, loop); - }; - AnimationState.prototype.addAnimationByName = function (trackIndex, animationName, loop, delay) { - if (!AnimationState.deprecatedWarning2) { - AnimationState.deprecatedWarning2 = true; - console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on."); - } - this.addAnimation(trackIndex, animationName, loop, delay); - }; - AnimationState.prototype.hasAnimation = function (animationName) { - var animation = this.data.skeletonData.findAnimation(animationName); - return animation !== null; - }; - AnimationState.prototype.hasAnimationByName = function (animationName) { - if (!AnimationState.deprecatedWarning3) { - AnimationState.deprecatedWarning3 = true; - console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on."); - } - return this.hasAnimation(animationName); - }; - AnimationState._emptyAnimation = new Animation("", [], 0); - AnimationState.deprecatedWarning1 = false; - AnimationState.deprecatedWarning2 = false; - AnimationState.deprecatedWarning3 = false; - return AnimationState; - }()); - /** Stores settings and other state for the playback of an animation on an {@link AnimationState} track. - * - * References to a track entry must not be kept after the {@link AnimationStateListener#dispose()} event occurs. - * @public - * */ - var TrackEntry = /** @class */ (function () { - function TrackEntry() { - /** The animation to apply for this track entry. */ - this.animation = null; - this.previous = null; - /** The animation queued to start after this animation, or null. `next` makes up a linked list. */ - this.next = null; - /** The track entry for the previous animation when mixing from the previous animation to this animation, or null if no - * mixing is currently occuring. When mixing from multiple animations, `mixingFrom` makes up a linked list. */ - this.mixingFrom = null; - /** The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is - * currently occuring. When mixing to multiple animations, `mixingTo` makes up a linked list. */ - this.mixingTo = null; - /** The listener for events generated by this track entry, or null. - * - * A track entry returned from {@link AnimationState#setAnimation()} is already the current animation - * for the track, so the track entry listener {@link AnimationStateListener#start()} will not be called. */ - this.listener = null; - /** The index of the track where this track entry is either current or queued. - * - * See {@link AnimationState#getCurrent()}. */ - this.trackIndex = 0; - /** If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its - * duration. */ - this.loop = false; - /** If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead - * of being mixed out. - * - * When mixing between animations that key the same property, if a lower track also keys that property then the value will - * briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0% - * while the second animation mixes from 0% to 100%. Setting `holdPrevious` to true applies the first animation - * at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which - * keys the property, only when a higher track also keys the property. - * - * Snapping will occur if `holdPrevious` is true and this animation does not key all the same properties as the - * previous animation. */ - this.holdPrevious = false; - this.reverse = false; - this.shortestRotation = false; - /** When the mix percentage ({@link #mixTime} / {@link #mixDuration}) is less than the - * `eventThreshold`, event timelines are applied while this animation is being mixed out. Defaults to 0, so event - * timelines are not applied while this animation is being mixed out. */ - this.eventThreshold = 0; - /** When the mix percentage ({@link #mixtime} / {@link #mixDuration}) is less than the - * `attachmentThreshold`, attachment timelines are applied while this animation is being mixed out. Defaults to - * 0, so attachment timelines are not applied while this animation is being mixed out. */ - this.attachmentThreshold = 0; - /** When the mix percentage ({@link #mixTime} / {@link #mixDuration}) is less than the - * `drawOrderThreshold`, draw order timelines are applied while this animation is being mixed out. Defaults to 0, - * so draw order timelines are not applied while this animation is being mixed out. */ - this.drawOrderThreshold = 0; - /** Seconds when this animation starts, both initially and after looping. Defaults to 0. - * - * When changing the `animationStart` time, it often makes sense to set {@link #animationLast} to the same - * value to prevent timeline keys before the start time from triggering. */ - this.animationStart = 0; - /** Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will - * loop back to {@link #animationStart} at this time. Defaults to the animation {@link Animation#duration}. */ - this.animationEnd = 0; - /** The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this - * animation is applied, event timelines will fire all events between the `animationLast` time (exclusive) and - * `animationTime` (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation - * is applied. */ - this.animationLast = 0; - this.nextAnimationLast = 0; - /** Seconds to postpone playing the animation. When this track entry is the current track entry, `delay` - * postpones incrementing the {@link #trackTime}. When this track entry is queued, `delay` is the time from - * the start of the previous animation to when this track entry will become the current track entry (ie when the previous - * track entry {@link TrackEntry#trackTime} >= this track entry's `delay`). - * - * {@link #timeScale} affects the delay. */ - this.delay = 0; - /** Current time in seconds this track entry has been the current track entry. The track time determines - * {@link #animationTime}. The track time can be set to start the animation at a time other than 0, without affecting - * looping. */ - this.trackTime = 0; - this.trackLast = 0; - this.nextTrackLast = 0; - /** The track time in seconds when this animation will be removed from the track. Defaults to the highest possible float - * value, meaning the animation will be applied until a new animation is set or the track is cleared. If the track end time - * is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the - * properties keyed by the animation are set to the setup pose and the track is cleared. - * - * It may be desired to use {@link AnimationState#addEmptyAnimation()} rather than have the animation - * abruptly cease being applied. */ - this.trackEnd = 0; - /** Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or - * faster. Defaults to 1. - * - * {@link #mixTime} is not affected by track entry time scale, so {@link #mixDuration} may need to be adjusted to - * match the animation speed. - * - * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the - * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, assuming time scale to be 1. If - * the time scale is not 1, the delay may need to be adjusted. - * - * See AnimationState {@link AnimationState#timeScale} for affecting all animations. */ - this.timeScale = 0; - /** Values < 1 mix this animation with the skeleton's current pose (usually the pose resulting from lower tracks). Defaults - * to 1, which overwrites the skeleton's current pose with this animation. - * - * Typically track 0 is used to completely pose the skeleton, then alpha is used on higher tracks. It doesn't make sense to - * use alpha on track 0 if the skeleton pose is from the last frame render. */ - this.alpha = 0; - /** Seconds from 0 to the {@link #getMixDuration()} when mixing from the previous animation to this animation. May be - * slightly more than `mixDuration` when the mix is complete. */ - this.mixTime = 0; - /** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData - * {@link AnimationStateData#getMix()} based on the animation before this animation (if any). - * - * A mix duration of 0 still mixes out over one frame to provide the track entry being mixed out a chance to revert the - * properties it was animating. - * - * The `mixDuration` can be set manually rather than use the value from - * {@link AnimationStateData#getMix()}. In that case, the `mixDuration` can be set for a new - * track entry only before {@link AnimationState#update(float)} is first called. - * - * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the - * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, not a mix duration set - * afterward. */ - this.mixDuration = 0; - this.interruptAlpha = 0; - this.totalAlpha = 0; - /** Controls how properties keyed in the animation are mixed with lower tracks. Defaults to {@link MixBlend#replace}, which - * replaces the values from the lower tracks with the animation values. {@link MixBlend#add} adds the animation values to - * the values from the lower tracks. - * - * The `mixBlend` can be set for a new track entry only before {@link AnimationState#apply()} is first - * called. */ - this.mixBlend = exports.MixBlend.replace; - this.timelineMode = new Array(); - this.timelineHoldMix = new Array(); - this.timelinesRotation = new Array(); - } - TrackEntry.prototype.reset = function () { - this.next = null; - this.previous = null; - this.mixingFrom = null; - this.mixingTo = null; - this.animation = null; - this.listener = null; - this.timelineMode.length = 0; - this.timelineHoldMix.length = 0; - this.timelinesRotation.length = 0; - }; - /** Uses {@link #trackTime} to compute the `animationTime`, which is between {@link #animationStart} - * and {@link #animationEnd}. When the `trackTime` is 0, the `animationTime` is equal to the - * `animationStart` time. */ - TrackEntry.prototype.getAnimationTime = function () { - if (this.loop) { - var duration = this.animationEnd - this.animationStart; - if (duration == 0) - return this.animationStart; - return (this.trackTime % duration) + this.animationStart; - } - return Math.min(this.trackTime + this.animationStart, this.animationEnd); - }; - TrackEntry.prototype.setAnimationLast = function (animationLast) { - this.animationLast = animationLast; - this.nextAnimationLast = animationLast; - }; - /** Returns true if at least one loop has been completed. - * - * See {@link AnimationStateListener#complete()}. */ - TrackEntry.prototype.isComplete = function () { - return this.trackTime >= this.animationEnd - this.animationStart; - }; - /** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the - * long way around when using {@link #alpha} and starting animations on other tracks. - * - * Mixing with {@link MixBlend#replace} involves finding a rotation between two others, which has two possible solutions: - * the short way or the long way around. The two rotations likely change over time, so which direction is the short or long - * way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the - * long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. */ - TrackEntry.prototype.resetRotationDirections = function () { - this.timelinesRotation.length = 0; - }; - TrackEntry.prototype.getTrackComplete = function () { - var duration = this.animationEnd - this.animationStart; - if (duration != 0) { - if (this.loop) - return duration * (1 + ((this.trackTime / duration) | 0)); // Completion of next loop. - if (this.trackTime < duration) - return duration; // Before duration. - } - return this.trackTime; // Next update. - }; - Object.defineProperty(TrackEntry.prototype, "time", { - get: function () { - if (!TrackEntry.deprecatedWarning1) { - TrackEntry.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); - } - return this.trackTime; - }, - set: function (value) { - if (!TrackEntry.deprecatedWarning1) { - TrackEntry.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on."); - } - this.trackTime = value; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(TrackEntry.prototype, "endTime", { - get: function () { - if (!TrackEntry.deprecatedWarning2) { - TrackEntry.deprecatedWarning2 = true; - console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); - } - return this.trackTime; - }, - set: function (value) { - if (!TrackEntry.deprecatedWarning2) { - TrackEntry.deprecatedWarning2 = true; - console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on."); - } - this.trackTime = value; - }, - enumerable: false, - configurable: true - }); - TrackEntry.prototype.loopsCount = function () { - return Math.floor(this.trackTime / this.trackEnd); - }; - TrackEntry.deprecatedWarning1 = false; - TrackEntry.deprecatedWarning2 = false; - return TrackEntry; - }()); - /** - * @public - */ - var EventQueue = /** @class */ (function () { - function EventQueue(animState) { - this.objects = []; - this.drainDisabled = false; - this.animState = animState; - } - EventQueue.prototype.start = function (entry) { - this.objects.push(EventType.start); - this.objects.push(entry); - this.animState.animationsChanged = true; - }; - EventQueue.prototype.interrupt = function (entry) { - this.objects.push(EventType.interrupt); - this.objects.push(entry); - }; - EventQueue.prototype.end = function (entry) { - this.objects.push(EventType.end); - this.objects.push(entry); - this.animState.animationsChanged = true; - }; - EventQueue.prototype.dispose = function (entry) { - this.objects.push(EventType.dispose); - this.objects.push(entry); - }; - EventQueue.prototype.complete = function (entry) { - this.objects.push(EventType.complete); - this.objects.push(entry); - }; - EventQueue.prototype.event = function (entry, event) { - this.objects.push(EventType.event); - this.objects.push(entry); - this.objects.push(event); - }; - EventQueue.prototype.drain = function () { - if (this.drainDisabled) - return; - this.drainDisabled = true; - var objects = this.objects; - var listeners = this.animState.listeners; - for (var i = 0; i < objects.length; i += 2) { - var type = objects[i]; - var entry = objects[i + 1]; - switch (type) { - case EventType.start: - if (entry.listener && entry.listener.start) - entry.listener.start(entry); - for (var ii = 0; ii < listeners.length; ii++) { - var listener = listeners[ii]; - if (listener.start) - listener.start(entry); - } - break; - case EventType.interrupt: - if (entry.listener && entry.listener.interrupt) - entry.listener.interrupt(entry); - for (var ii = 0; ii < listeners.length; ii++) { - var listener = listeners[ii]; - if (listener.interrupt) - listener.interrupt(entry); - } - break; - case EventType.end: - if (entry.listener && entry.listener.end) - entry.listener.end(entry); - for (var ii = 0; ii < listeners.length; ii++) { - var listener = listeners[ii]; - if (listener.end) - listener.end(entry); - } - // Fall through. - case EventType.dispose: - if (entry.listener && entry.listener.dispose) - entry.listener.dispose(entry); - for (var ii = 0; ii < listeners.length; ii++) { - var listener = listeners[ii]; - if (listener.dispose) - listener.dispose(entry); - } - this.animState.trackEntryPool.free(entry); - break; - case EventType.complete: - if (entry.listener && entry.listener.complete) - entry.listener.complete(entry); - for (var ii = 0; ii < listeners.length; ii++) { - var listener = listeners[ii]; - if (listener.complete) - listener.complete(entry); - } - break; - case EventType.event: - var event_3 = objects[i++ + 2]; - if (entry.listener && entry.listener.event) - entry.listener.event(entry, event_3); - for (var ii = 0; ii < listeners.length; ii++) { - var listener = listeners[ii]; - if (listener.event) - listener.event(entry, event_3); - } - break; - } - } - this.clear(); - this.drainDisabled = false; - }; - EventQueue.prototype.clear = function () { - this.objects.length = 0; - }; - return EventQueue; - }()); - /** - * @public - */ - var EventType; - (function (EventType) { - EventType[EventType["start"] = 0] = "start"; - EventType[EventType["interrupt"] = 1] = "interrupt"; - EventType[EventType["end"] = 2] = "end"; - EventType[EventType["dispose"] = 3] = "dispose"; - EventType[EventType["complete"] = 4] = "complete"; - EventType[EventType["event"] = 5] = "event"; - })(EventType || (EventType = {})); - /** - * @public - */ - var AnimationStateAdapter = /** @class */ (function () { - function AnimationStateAdapter() { - } - AnimationStateAdapter.prototype.start = function (entry) { - }; - AnimationStateAdapter.prototype.interrupt = function (entry) { - }; - AnimationStateAdapter.prototype.end = function (entry) { - }; - AnimationStateAdapter.prototype.dispose = function (entry) { - }; - AnimationStateAdapter.prototype.complete = function (entry) { - }; - AnimationStateAdapter.prototype.event = function (entry, event) { - }; - return AnimationStateAdapter; - }()); - /** 1. A previously applied timeline has set this property. - * - * Result: Mix from the current pose to the timeline pose. */ - var SUBSEQUENT = 0; - /** 1. This is the first timeline to set this property. - * 2. The next track entry applied after this one does not have a timeline to set this property. - * - * Result: Mix from the setup pose to the timeline pose. */ - var FIRST = 1; - /** 1) A previously applied timeline has set this property.
- * 2) The next track entry to be applied does have a timeline to set this property.
- * 3) The next track entry after that one does not have a timeline to set this property.
- * Result: Mix from the current pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading - * animations that key the same property. A subsequent timeline will set this property using a mix. */ - var HOLD_SUBSEQUENT = 2; - /** 1) This is the first timeline to set this property.
- * 2) The next track entry to be applied does have a timeline to set this property.
- * 3) The next track entry after that one does not have a timeline to set this property.
- * Result: Mix from the setup pose to the timeline pose, but do not mix out. This avoids "dipping" when crossfading animations - * that key the same property. A subsequent timeline will set this property using a mix. */ - var HOLD_FIRST = 3; - /** 1. This is the first timeline to set this property. - * 2. The next track entry to be applied does have a timeline to set this property. - * 3. The next track entry after that one does have a timeline to set this property. - * 4. timelineHoldMix stores the first subsequent track entry that does not have a timeline to set this property. - * - * Result: The same as HOLD except the mix percentage from the timelineHoldMix track entry is used. This handles when more than - * 2 track entries in a row have a timeline that sets the same property. - * - * Eg, A -> B -> C -> D where A, B, and C have a timeline setting same property, but D does not. When A is applied, to avoid - * "dipping" A is not mixed out, however D (the first entry that doesn't set the property) mixing in is used to mix out A - * (which affects B and C). Without using D to mix out, A would be applied fully until mixing completes, then snap into - * place. */ - var HOLD_MIX = 4; - var SETUP = 1; - var CURRENT = 2; - - /** Stores mix (crossfade) durations to be applied when {@link AnimationState} animations are changed. - * @public - * */ - var AnimationStateData = /** @class */ (function () { - function AnimationStateData(skeletonData) { - this.animationToMixTime = {}; - /** The mix duration to use when no mix duration has been defined between two animations. */ - this.defaultMix = 0; - if (!skeletonData) - throw new Error("skeletonData cannot be null."); - this.skeletonData = skeletonData; - } - /** Sets a mix duration by animation name. - * - * See {@link #setMixWith()}. */ - AnimationStateData.prototype.setMix = function (fromName, toName, duration) { - var from = this.skeletonData.findAnimation(fromName); - if (!from) - throw new Error("Animation not found: " + fromName); - var to = this.skeletonData.findAnimation(toName); - if (!to) - throw new Error("Animation not found: " + toName); - this.setMixWith(from, to, duration); - }; - /** Sets the mix duration when changing from the specified animation to the other. - * - * See {@link TrackEntry#mixDuration}. */ - AnimationStateData.prototype.setMixWith = function (from, to, duration) { - if (!from) - throw new Error("from cannot be null."); - if (!to) - throw new Error("to cannot be null."); - var key = from.name + "." + to.name; - this.animationToMixTime[key] = duration; - }; - /** Returns the mix duration to use when changing from the specified animation to the other, or the {@link #defaultMix} if - * no mix duration has been set. */ - AnimationStateData.prototype.getMix = function (from, to) { - var key = from.name + "." + to.name; - var value = this.animationToMixTime[key]; - return value === undefined ? this.defaultMix : value; - }; - return AnimationStateData; - }()); - - /** - * @public - */ - var AtlasAttachmentLoader = /** @class */ (function () { - function AtlasAttachmentLoader(atlas) { - this.atlas = atlas; - } - AtlasAttachmentLoader.prototype.loadSequence = function (name, basePath, sequence) { - var regions = sequence.regions; - for (var i = 0, n = regions.length; i < n; i++) { - var path = sequence.getPath(basePath, i); - var region = this.atlas.findRegion(path); - if (region == null) - throw new Error("Region not found in atlas: " + path + " (sequence: " + name + ")"); - regions[i] = region; - regions[i].renderObject = regions[i]; - } - }; - AtlasAttachmentLoader.prototype.newRegionAttachment = function (skin, name, path, sequence) { - var attachment = new RegionAttachment(name, path); - if (sequence != null) { - this.loadSequence(name, path, sequence); - } - else { - var region = this.atlas.findRegion(path); - if (!region) - throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); - region.renderObject = region; - attachment.region = region; - } - return attachment; - }; - AtlasAttachmentLoader.prototype.newMeshAttachment = function (skin, name, path, sequence) { - var attachment = new MeshAttachment(name, path); - if (sequence != null) { - this.loadSequence(name, path, sequence); - } - else { - var region = this.atlas.findRegion(path); - if (!region) - throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); - region.renderObject = region; - attachment.region = region; - } - return attachment; - }; - AtlasAttachmentLoader.prototype.newBoundingBoxAttachment = function (skin, name) { - return new BoundingBoxAttachment(name); - }; - AtlasAttachmentLoader.prototype.newPathAttachment = function (skin, name) { - return new PathAttachment(name); - }; - AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) { - return new PointAttachment(name); - }; - AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) { - return new ClippingAttachment(name); - }; - return AtlasAttachmentLoader; - }()); - - /** 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. - * @public - * */ - var Bone = /** @class */ (function () { - /** @param parent May be null. */ - function Bone(data, skeleton, parent) { - //be careful! Spine b,c is c,b in pixi matrix - this.matrix = new math.Matrix(); - /** The parent bone, or null if this is the root bone. */ - this.parent = null; - /** The immediate children of this bone. */ - this.children = new Array(); - /** The local x translation. */ - this.x = 0; - /** The local y translation. */ - this.y = 0; - /** The local rotation in degrees, counter clockwise. */ - this.rotation = 0; - /** The local scaleX. */ - this.scaleX = 0; - /** The local scaleY. */ - this.scaleY = 0; - /** The local shearX. */ - this.shearX = 0; - /** The local shearY. */ - this.shearY = 0; - /** The applied local x translation. */ - this.ax = 0; - /** The applied local y translation. */ - this.ay = 0; - /** The applied local rotation in degrees, counter clockwise. */ - this.arotation = 0; - /** The applied local scaleX. */ - this.ascaleX = 0; - /** The applied local scaleY. */ - this.ascaleY = 0; - /** The applied local shearX. */ - this.ashearX = 0; - /** The applied local shearY. */ - this.ashearY = 0; - this.sorted = false; - this.active = false; - if (!data) - throw new Error("data cannot be null."); - if (!skeleton) - throw new Error("skeleton cannot be null."); - this.data = data; - this.skeleton = skeleton; - this.parent = parent; - this.setToSetupPose(); - } - Object.defineProperty(Bone.prototype, "worldX", { - get: function () { - return this.matrix.tx; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Bone.prototype, "worldY", { - get: function () { - return this.matrix.ty; - }, - enumerable: false, - configurable: true - }); - /** Returns false when the bone has not been computed because {@link BoneData#skinRequired} is true and the - * {@link Skeleton#skin active skin} does not {@link Skin#bones contain} this bone. */ - Bone.prototype.isActive = function () { - return this.active; - }; - /** Computes the world transform using the parent bone and this bone's local applied transform. */ - Bone.prototype.update = function () { - this.updateWorldTransformWith(this.ax, this.ay, this.arotation, this.ascaleX, this.ascaleY, this.ashearX, this.ashearY); - }; - /** Computes the world transform using the parent bone and this bone's local transform. - * - * See {@link #updateWorldTransformWith()}. */ - Bone.prototype.updateWorldTransform = function () { - this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); - }; - /** 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 transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine - * Runtimes Guide. */ - Bone.prototype.updateWorldTransformWith = function (x, y, rotation, scaleX, scaleY, shearX, shearY) { - this.ax = x; - this.ay = y; - this.arotation = rotation; - this.ascaleX = scaleX; - this.ascaleY = scaleY; - this.ashearX = shearX; - this.ashearY = shearY; - var parent = this.parent; - var m = this.matrix; - var sx = this.skeleton.scaleX; - var sy = settings.yDown ? -this.skeleton.scaleY : this.skeleton.scaleY; - if (!parent) { // Root bone. - var skeleton = this.skeleton; - var rotationY = rotation + 90 + shearY; - m.a = MathUtils.cosDeg(rotation + shearX) * scaleX * sx; - m.c = MathUtils.cosDeg(rotationY) * scaleY * sx; - m.b = MathUtils.sinDeg(rotation + shearX) * scaleX * sy; - m.d = MathUtils.sinDeg(rotationY) * scaleY * sy; - m.tx = x * sx + skeleton.x; - m.ty = y * sy + skeleton.y; - return; - } - var pa = parent.matrix.a, pb = parent.matrix.c, pc = parent.matrix.b, pd = parent.matrix.d; - m.tx = pa * x + pb * y + parent.matrix.tx; - m.ty = pc * x + pd * y + parent.matrix.ty; - switch (this.data.transformMode) { - case exports.TransformMode.Normal: { - var rotationY = rotation + 90 + shearY; - var la = MathUtils.cosDeg(rotation + shearX) * scaleX; - var lb = MathUtils.cosDeg(rotationY) * scaleY; - var lc = MathUtils.sinDeg(rotation + shearX) * scaleX; - var ld = MathUtils.sinDeg(rotationY) * scaleY; - m.a = pa * la + pb * lc; - m.c = pa * lb + pb * ld; - m.b = pc * la + pd * lc; - m.d = pc * lb + pd * ld; - return; - } - case exports.TransformMode.OnlyTranslation: { - var rotationY = rotation + 90 + shearY; - m.a = MathUtils.cosDeg(rotation + shearX) * scaleX; - m.c = MathUtils.cosDeg(rotationY) * scaleY; - m.b = MathUtils.sinDeg(rotation + shearX) * scaleX; - m.d = MathUtils.sinDeg(rotationY) * scaleY; - break; - } - case exports.TransformMode.NoRotationOrReflection: { - var s = pa * pa + pc * pc; - var prx = 0; - if (s > 0.0001) { - s = Math.abs(pa * pd - pb * pc) / s; - pa /= sx; - pc /= sy; - pb = pc * s; - pd = pa * s; - prx = Math.atan2(pc, pa) * MathUtils.radDeg; - } - else { - pa = 0; - pc = 0; - prx = 90 - Math.atan2(pd, pb) * MathUtils.radDeg; - } - var rx = rotation + shearX - prx; - var ry = rotation + shearY - prx + 90; - var la = MathUtils.cosDeg(rx) * scaleX; - var lb = MathUtils.cosDeg(ry) * scaleY; - var lc = MathUtils.sinDeg(rx) * scaleX; - var ld = MathUtils.sinDeg(ry) * scaleY; - m.a = pa * la - pb * lc; - m.c = pa * lb - pb * ld; - m.b = pc * la + pd * lc; - m.d = pc * lb + pd * ld; - break; - } - case exports.TransformMode.NoScale: - case exports.TransformMode.NoScaleOrReflection: { - var cos = MathUtils.cosDeg(rotation); - var sin = MathUtils.sinDeg(rotation); - var za = (pa * cos + pb * sin) / sx; - var zc = (pc * cos + pd * sin) / sy; - var s = Math.sqrt(za * za + zc * zc); - if (s > 0.00001) - s = 1 / s; - za *= s; - zc *= s; - s = Math.sqrt(za * za + zc * zc); - if (this.data.transformMode == exports.TransformMode.NoScale - && (pa * pd - pb * pc < 0) != (sx < 0 != sy < 0)) - s = -s; - var r = Math.PI / 2 + Math.atan2(zc, za); - var zb = Math.cos(r) * s; - var zd = Math.sin(r) * s; - var la = MathUtils.cosDeg(shearX) * scaleX; - var lb = MathUtils.cosDeg(90 + shearY) * scaleY; - var lc = MathUtils.sinDeg(shearX) * scaleX; - var ld = MathUtils.sinDeg(90 + shearY) * scaleY; - m.a = za * la + zb * lc; - m.c = za * lb + zb * ld; - m.b = zc * la + zd * lc; - m.d = zc * lb + zd * ld; - break; - } - } - m.a *= sx; - m.c *= sx; - m.b *= sy; - m.d *= sy; - }; - /** Sets this bone's local transform to the setup pose. */ - Bone.prototype.setToSetupPose = function () { - var data = this.data; - this.x = data.x; - this.y = data.y; - this.rotation = data.rotation; - this.scaleX = data.scaleX; - this.scaleY = data.scaleY; - this.shearX = data.shearX; - this.shearY = data.shearY; - }; - /** The world rotation for the X axis, calculated using {@link #a} and {@link #c}. */ - Bone.prototype.getWorldRotationX = function () { - return Math.atan2(this.matrix.b, this.matrix.a) * MathUtils.radDeg; - }; - /** The world rotation for the Y axis, calculated using {@link #b} and {@link #d}. */ - Bone.prototype.getWorldRotationY = function () { - return Math.atan2(this.matrix.d, this.matrix.c) * MathUtils.radDeg; - }; - /** The magnitude (always positive) of the world scale X, calculated using {@link #a} and {@link #c}. */ - Bone.prototype.getWorldScaleX = function () { - var m = this.matrix; - return Math.sqrt(m.a * m.a + m.b * m.b); - }; - /** The magnitude (always positive) of the world scale Y, calculated using {@link #b} and {@link #d}. */ - Bone.prototype.getWorldScaleY = function () { - var m = this.matrix; - return Math.sqrt(m.c * m.c + m.d * m.d); - }; - /** Computes the applied transform values from the world transform. - * - * If the world transform is modified (by a constraint, {@link #rotateWorld(float)}, 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 other - * constraints). - * - * 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. */ - Bone.prototype.updateAppliedTransform = function () { - var parent = this.parent; - var m = this.matrix; - if (!parent) { - this.ax = m.tx - this.skeleton.x; - this.ay = m.ty - this.skeleton.y; - this.arotation = Math.atan2(m.b, m.a) * MathUtils.radDeg; - this.ascaleX = Math.sqrt(m.a * m.a + m.b * m.b); - this.ascaleY = Math.sqrt(m.c * m.c + m.d * m.d); - this.ashearX = 0; - this.ashearY = Math.atan2(m.a * m.c + m.b * m.d, m.a * m.d - m.b * m.c) * MathUtils.radDeg; - return; - } - var pm = parent.matrix; - var pid = 1 / (pm.a * pm.d - pm.b * pm.c); - var dx = m.tx - pm.tx, dy = m.ty - pm.ty; - this.ax = (dx * pm.d * pid - dy * pm.c * pid); - this.ay = (dy * pm.a * pid - dx * pm.b * pid); - var ia = pid * pm.d; - var id = pid * pm.a; - var ib = pid * pm.c; - var ic = pid * pm.b; - var ra = ia * m.a - ib * m.b; - var rb = ia * m.c - ib * m.d; - var rc = id * m.b - ic * m.a; - var rd = id * m.d - ic * m.c; - this.ashearX = 0; - this.ascaleX = Math.sqrt(ra * ra + rc * rc); - if (this.ascaleX > 0.0001) { - var det = ra * rd - rb * rc; - this.ascaleY = det / this.ascaleX; - this.ashearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg; - this.arotation = Math.atan2(rc, ra) * MathUtils.radDeg; - } - else { - this.ascaleX = 0; - this.ascaleY = Math.sqrt(rb * rb + rd * rd); - this.ashearY = 0; - this.arotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg; - } - }; - /** Transforms a point from world coordinates to the bone's local coordinates. */ - Bone.prototype.worldToLocal = function (world) { - var m = this.matrix; - var a = m.a, b = m.c, c = m.b, d = m.d; - var invDet = 1 / (a * d - b * c); - var x = world.x - m.tx, y = world.y - m.ty; - world.x = (x * d * invDet - y * b * invDet); - world.y = (y * a * invDet - x * c * invDet); - return world; - }; - /** Transforms a point from the bone's local coordinates to world coordinates. */ - Bone.prototype.localToWorld = function (local) { - var m = this.matrix; - var x = local.x, y = local.y; - local.x = x * m.a + y * m.c + m.tx; - local.y = x * m.b + y * m.d + m.ty; - return local; - }; - /** Transforms a world rotation to a local rotation. */ - Bone.prototype.worldToLocalRotation = function (worldRotation) { - var sin = MathUtils.sinDeg(worldRotation), cos = MathUtils.cosDeg(worldRotation); - var mat = this.matrix; - return Math.atan2(mat.a * sin - mat.b * cos, mat.d * cos - mat.c * sin) * MathUtils.radDeg; - }; - /** Transforms a local rotation to a world rotation. */ - Bone.prototype.localToWorldRotation = function (localRotation) { - localRotation -= this.rotation - this.shearX; - var sin = MathUtils.sinDeg(localRotation), cos = MathUtils.cosDeg(localRotation); - var mat = this.matrix; - return Math.atan2(cos * mat.b + sin * mat.d, cos * mat.a + sin * mat.c) * MathUtils.radDeg; - }; - /** Rotates the world transform the specified amount. - *

- * After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and {@link #update()} will - * need to be called on any child bones, recursively. */ - Bone.prototype.rotateWorld = function (degrees) { - var mat = this.matrix; - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var cos = MathUtils.cosDeg(degrees), sin = MathUtils.sinDeg(degrees); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - }; - return Bone; - }()); - - /** Stores the setup pose for a {@link Bone}. - * @public - * */ - var BoneData = /** @class */ (function () { - function BoneData(index, name, parent) { - /** The index of the bone in {@link Skeleton#getBones()}. */ - this.index = 0; - /** @returns May be null. */ - this.parent = null; - /** The bone's length. */ - this.length = 0; - /** The local x translation. */ - this.x = 0; - /** The local y translation. */ - this.y = 0; - /** The local rotation. */ - this.rotation = 0; - /** The local scaleX. */ - this.scaleX = 1; - /** The local scaleY. */ - this.scaleY = 1; - /** The local shearX. */ - this.shearX = 0; - /** The local shearX. */ - this.shearY = 0; - /** The transform mode for how parent world transforms affect this bone. */ - this.transformMode = exports.TransformMode.Normal; - /** When true, {@link Skeleton#updateWorldTransform()} only updates this bone if the {@link Skeleton#skin} contains this - * bone. - * @see Skin#bones */ - this.skinRequired = false; - /** The color of the bone as it was in Spine. Available only when nonessential data was exported. Bones are not usually - * rendered at runtime. */ - this.color = new Color(); - if (index < 0) - throw new Error("index must be >= 0."); - if (!name) - throw new Error("name cannot be null."); - this.index = index; - this.name = name; - this.parent = parent; - } - return BoneData; - }()); - - /** The base class for all constraint datas. - * @public - * */ - var ConstraintData = /** @class */ (function () { - function ConstraintData(name, order, skinRequired) { - this.name = name; - this.order = order; - this.skinRequired = skinRequired; - } - return ConstraintData; - }()); - - /** Stores the current pose values for an {@link Event}. - * - * See Timeline {@link Timeline#apply()}, - * AnimationStateListener {@link AnimationStateListener#event()}, and - * [Events](http://esotericsoftware.com/spine-events) in the Spine User Guide. - * @public - * */ - var Event = /** @class */ (function () { - function Event(time, data) { - this.intValue = 0; - this.floatValue = 0; - this.stringValue = null; - this.time = 0; - this.volume = 0; - this.balance = 0; - if (!data) - throw new Error("data cannot be null."); - this.time = time; - this.data = data; - } - return Event; - }()); - - /** Stores the setup pose values for an {@link Event}. - * - * See [Events](http://esotericsoftware.com/spine-events) in the Spine User Guide. - * @public - * */ - var EventData = /** @class */ (function () { - function EventData(name) { - this.intValue = 0; - this.floatValue = 0; - this.stringValue = null; - this.audioPath = null; - this.volume = 0; - this.balance = 0; - this.name = name; - } - return EventData; - }()); - - /** Stores the current pose for an IK constraint. An IK constraint adjusts the rotation of 1 or 2 constrained bones so the tip of - * the last bone is as close to the target bone as possible. - * - * See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. - * @public - * */ - var IkConstraint = /** @class */ (function () { - function IkConstraint(data, skeleton) { - /** Controls the bend direction of the IK bones, either 1 or -1. */ - this.bendDirection = 0; - /** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */ - this.compress = false; - /** When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained - * and the parent bone has local nonuniform scale, stretch is not applied. */ - this.stretch = false; - /** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */ - this.mix = 1; - /** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */ - this.softness = 0; - this.active = false; - if (!data) - throw new Error("data cannot be null."); - if (!skeleton) - throw new Error("skeleton cannot be null."); - this.data = data; - this.mix = data.mix; - this.softness = data.softness; - this.bendDirection = data.bendDirection; - this.compress = data.compress; - this.stretch = data.stretch; - this.bones = new Array(); - for (var i = 0; i < data.bones.length; i++) { - var bone = skeleton.findBone(data.bones[i].name); - if (!bone) - throw new Error("Couldn't find bone " + data.bones[i].name); - this.bones.push(bone); - } - var target = skeleton.findBone(data.target.name); - if (!target) - throw new Error("Couldn't find bone " + data.target.name); - this.target = target; - } - IkConstraint.prototype.isActive = function () { - return this.active; - }; - IkConstraint.prototype.update = function () { - if (this.mix == 0) - return; - var target = this.target; - var bones = this.bones; - switch (bones.length) { - case 1: - this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix); - break; - case 2: - this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.data.uniform, this.softness, this.mix); - break; - } - }; - /** Applies 1 bone IK. The target is specified in the world coordinate system. */ - IkConstraint.prototype.apply1 = function (bone, targetX, targetY, compress, stretch, uniform, alpha) { - var p = bone.parent.matrix; - if (!p) - throw new Error("IK bone must have parent."); - var pa = p.a, pb = p.c, pc = p.b, pd = p.d; - var rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0; - var skelX = bone.skeleton.scaleX; - var skelY = settings.yDown ? -bone.skeleton.scaleY : bone.skeleton.scaleY; - switch (bone.data.transformMode) { - case exports.TransformMode.OnlyTranslation: - tx = targetX - bone.worldX; - ty = targetY - bone.worldY; - //TODO: possible bug in spine-ts runtime! - if (settings.yDown) { - ty = -ty; - } - break; - case exports.TransformMode.NoRotationOrReflection: - var s = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc); - var sa = pa / skelX; - var sc = pc / skelY; - pb = -sc * s * skelX; - pd = sa * s * skelY; - rotationIK += Math.atan2(sc, sa) * MathUtils.radDeg; - // Fall through - default: - var x = targetX - p.tx, y = targetY - p.ty; - var d = pa * pd - pb * pc; - tx = (x * pd - y * pb) / d - bone.ax; - ty = (y * pa - x * pc) / d - bone.ay; - } - rotationIK += Math.atan2(ty, tx) * MathUtils.radDeg; - if (bone.ascaleX < 0) - rotationIK += 180; - if (rotationIK > 180) - rotationIK -= 360; - else if (rotationIK < -180) - rotationIK += 360; - var sx = bone.ascaleX, sy = bone.ascaleY; - if (compress || stretch) { - switch (bone.data.transformMode) { - case exports.TransformMode.NoScale: - case exports.TransformMode.NoScaleOrReflection: - tx = targetX - bone.worldX; - ty = targetY - bone.worldY; - } - var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty); - if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001) { - var s = (dd / b - 1) * alpha + 1; - sx *= s; - if (uniform) - sy *= s; - } - } - bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY); - }; - /** Applies 2 bone IK. The target is specified in the world coordinate system. - * @param child A direct descendant of the parent bone. */ - IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, uniform, softness, alpha) { - var px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, sx = psx, sy = psy, csx = child.ascaleX; - var pmat = parent.matrix; - var os1 = 0, os2 = 0, s2 = 0; - if (psx < 0) { - psx = -psx; - os1 = 180; - s2 = -1; - } - else { - os1 = 0; - s2 = 1; - } - if (psy < 0) { - psy = -psy; - s2 = -s2; - } - if (csx < 0) { - csx = -csx; - os2 = 180; - } - else - os2 = 0; - var cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = pmat.a, b = pmat.c, c = pmat.b, d = pmat.d; - var u = Math.abs(psx - psy) <= 0.0001; - if (!u || stretch) { - cy = 0; - cwx = a * cx + pmat.tx; - cwy = c * cx + pmat.ty; - } - else { - cy = child.ay; - cwx = a * cx + b * cy + pmat.tx; - cwy = c * cx + d * cy + pmat.ty; - } - var pp = parent.parent.matrix; - if (!pp) - throw new Error("IK parent must itself have a parent."); - a = pp.a; - b = pp.c; - c = pp.b; - d = pp.d; - var id = 1 / (a * d - b * c), x = cwx - pp.tx, y = cwy - pp.ty; - var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; - var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2; - if (l1 < 0.0001) { - this.apply1(parent, targetX, targetY, false, stretch, false, alpha); - child.updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); - return; - } - x = targetX - pp.tx; - y = targetY - pp.ty; - var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; - var dd = tx * tx + ty * ty; - if (softness != 0) { - softness *= psx * (csx + 1) * 0.5; - var td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness; - if (sd > 0) { - var p = Math.min(1, sd / (softness * 2)) - 1; - p = (sd - softness * (1 - p * p)) / td; - tx -= p * tx; - ty -= p * ty; - dd = tx * tx + ty * ty; - } - } - outer: if (u) { - l2 *= psx; - var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2); - if (cos < -1) { - cos = -1; - a2 = Math.PI * bendDir; - } - else if (cos > 1) { - cos = 1; - a2 = 0; - if (stretch) { - a = (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1; - sx *= a; - if (uniform) - sy *= a; - } - } - else - a2 = Math.acos(cos) * bendDir; - a = l1 + l2 * cos; - b = l2 * Math.sin(a2); - a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b); - } - else { - a = psx * l2; - b = psy * l2; - var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx); - c = bb * l1 * l1 + aa * dd - aa * bb; - var c1 = -2 * bb * l1, c2 = bb - aa; - d = c1 * c1 - 4 * c2 * c; - if (d >= 0) { - var q = Math.sqrt(d); - if (c1 < 0) - q = -q; - q = -(c1 + q) * 0.5; - var r0 = q / c2, r1 = c / q; - var r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; - if (r * r <= dd) { - y = Math.sqrt(dd - r * r) * bendDir; - a1 = ta - Math.atan2(y, r); - a2 = Math.atan2(y / psy, (r - l1) / psx); - break outer; - } - } - var minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; - var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; - c = -a * l1 / (aa - bb); - if (c >= -1 && c <= 1) { - c = Math.acos(c); - x = a * Math.cos(c) + l1; - y = b * Math.sin(c); - d = x * x + y * y; - if (d < minDist) { - minAngle = c; - minDist = d; - minX = x; - minY = y; - } - if (d > maxDist) { - maxAngle = c; - maxDist = d; - maxX = x; - maxY = y; - } - } - if (dd <= (minDist + maxDist) * 0.5) { - a1 = ta - Math.atan2(minY * bendDir, minX); - a2 = minAngle * bendDir; - } - else { - a1 = ta - Math.atan2(maxY * bendDir, maxX); - a2 = maxAngle * bendDir; - } - } - var os = Math.atan2(cy, cx) * s2; - var rotation = parent.arotation; - a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation; - if (a1 > 180) - a1 -= 360; - else if (a1 < -180) // - a1 += 360; - parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, sy, 0, 0); - rotation = child.arotation; - a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; - if (a2 > 180) - a2 -= 360; - else if (a2 < -180) // - a2 += 360; - child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); - }; - return IkConstraint; - }()); - - /** Stores the setup pose for an {@link IkConstraint}. - *

- * See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. - * @public - * */ - var IkConstraintData = /** @class */ (function (_super) { - __extends$1(IkConstraintData, _super); - function IkConstraintData(name) { - var _this = _super.call(this, name, 0, false) || this; - /** The bones that are constrained by this IK constraint. */ - _this.bones = new Array(); - /** The bone that is the IK target. */ - _this._target = null; - /** Controls the bend direction of the IK bones, either 1 or -1. */ - _this.bendDirection = 1; - /** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */ - _this.compress = false; - /** When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained - * and the parent bone has local nonuniform scale, stretch is not applied. */ - _this.stretch = false; - /** When true, only a single bone is being constrained, and {@link #getCompress()} or {@link #getStretch()} is used, the bone - * is scaled on both the X and Y axes. */ - _this.uniform = false; - /** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */ - _this.mix = 1; - /** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */ - _this.softness = 0; - return _this; - } - Object.defineProperty(IkConstraintData.prototype, "target", { - get: function () { - if (!this._target) - throw new Error("BoneData not set."); - else - return this._target; - }, - set: function (boneData) { this._target = boneData; }, - enumerable: false, - configurable: true - }); - return IkConstraintData; - }(ConstraintData)); - - /** Stores the setup pose for a {@link PathConstraint}. - * - * See [Path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. - * @public - * */ - var PathConstraintData = /** @class */ (function (_super) { - __extends$1(PathConstraintData, _super); - function PathConstraintData(name) { - var _this = _super.call(this, name, 0, false) || this; - /** The bones that will be modified by this path constraint. */ - _this.bones = new Array(); - /** The slot whose path attachment will be used to constrained the bones. */ - _this._target = null; - /** The mode for positioning the first bone on the path. */ - _this.positionMode = exports.PositionMode.Fixed; - /** The mode for positioning the bones after the first bone on the path. */ - _this.spacingMode = SpacingMode.Fixed; - /** The mode for adjusting the rotation of the bones. */ - _this.rotateMode = exports.RotateMode.Chain; - /** An offset added to the constrained bone rotation. */ - _this.offsetRotation = 0; - /** The position along the path. */ - _this.position = 0; - /** The spacing between bones. */ - _this.spacing = 0; - _this.mixRotate = 0; - _this.mixX = 0; - _this.mixY = 0; - return _this; - } - Object.defineProperty(PathConstraintData.prototype, "target", { - get: function () { - if (!this._target) - throw new Error("SlotData not set."); - else - return this._target; - }, - set: function (slotData) { this._target = slotData; }, - enumerable: false, - configurable: true - }); - return PathConstraintData; - }(ConstraintData)); - /** Controls how bones after the first bone are positioned along the path. - * - * [Spacing mode](http://esotericsoftware.com/spine-path-constraints#Spacing-mode) in the Spine User Guide. - * @public - * */ - var SpacingMode; - (function (SpacingMode) { - SpacingMode[SpacingMode["Length"] = 0] = "Length"; - SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed"; - SpacingMode[SpacingMode["Percent"] = 2] = "Percent"; - SpacingMode[SpacingMode["Proportional"] = 3] = "Proportional"; - })(SpacingMode || (SpacingMode = {})); - - /** Stores the current pose for a path constraint. A path constraint adjusts the rotation, translation, and scale of the - * constrained bones so they follow a {@link PathAttachment}. - * - * See [Path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. - * @public - * */ - var PathConstraint = /** @class */ (function () { - function PathConstraint(data, skeleton) { - /** The position along the path. */ - this.position = 0; - /** The spacing between bones. */ - this.spacing = 0; - this.mixRotate = 0; - this.mixX = 0; - this.mixY = 0; - this.spaces = new Array(); - this.positions = new Array(); - this.world = new Array(); - this.curves = new Array(); - this.lengths = new Array(); - this.segments = new Array(); - this.active = false; - if (!data) - throw new Error("data cannot be null."); - if (!skeleton) - throw new Error("skeleton cannot be null."); - this.data = data; - this.bones = new Array(); - for (var i = 0, n = data.bones.length; i < n; i++) { - var bone = skeleton.findBone(data.bones[i].name); - if (!bone) - throw new Error("Couldn't find bone " + data.bones[i].name + "."); - this.bones.push(bone); - } - var target = skeleton.findSlot(data.target.name); - if (!target) - throw new Error("Couldn't find target bone " + data.target.name); - this.target = target; - this.position = data.position; - this.spacing = data.spacing; - this.mixRotate = data.mixRotate; - this.mixX = data.mixX; - this.mixY = data.mixY; - } - PathConstraint.prototype.isActive = function () { - return this.active; - }; - PathConstraint.prototype.update = function () { - var attachment = this.target.getAttachment(); - if (!(attachment instanceof PathAttachment)) - return; - var mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY; - if (mixRotate == 0 && mixX == 0 && mixY == 0) - return; - var data = this.data; - var tangents = data.rotateMode == exports.RotateMode.Tangent, scale = data.rotateMode == exports.RotateMode.ChainScale; - var bones = this.bones; - var boneCount = bones.length, spacesCount = tangents ? boneCount : boneCount + 1; - var spaces = Utils.setArraySize(this.spaces, spacesCount), lengths = scale ? this.lengths = Utils.setArraySize(this.lengths, boneCount) : []; - var spacing = this.spacing; - switch (data.spacingMode) { - case SpacingMode.Percent: - if (scale) { - for (var i = 0, n = spacesCount - 1; i < n; i++) { - var bone = bones[i]; - var setupLength = bone.data.length; - if (setupLength < PathConstraint.epsilon) - lengths[i] = 0; - else { - var x = setupLength * bone.matrix.a, y = setupLength * bone.matrix.b; - lengths[i] = Math.sqrt(x * x + y * y); - } - } - } - Utils.arrayFill(spaces, 1, spacesCount, spacing); - break; - case SpacingMode.Proportional: - var sum = 0; - for (var i = 0, n = spacesCount - 1; i < n;) { - var bone = bones[i]; - var setupLength = bone.data.length; - if (setupLength < PathConstraint.epsilon) { - if (scale) - lengths[i] = 0; - spaces[++i] = spacing; - } - else { - var x = setupLength * bone.matrix.a, y = setupLength * bone.matrix.b; - var length_1 = Math.sqrt(x * x + y * y); - if (scale) - lengths[i] = length_1; - spaces[++i] = length_1; - sum += length_1; - } - } - if (sum > 0) { - sum = spacesCount / sum * spacing; - for (var i = 1; i < spacesCount; i++) - spaces[i] *= sum; - } - break; - default: - var lengthSpacing = data.spacingMode == SpacingMode.Length; - for (var i = 0, n = spacesCount - 1; i < n;) { - var bone = bones[i]; - var setupLength = bone.data.length; - if (setupLength < PathConstraint.epsilon) { - if (scale) - lengths[i] = 0; - spaces[++i] = spacing; - } - else { - var x = setupLength * bone.matrix.a, y = setupLength * bone.matrix.b; - var length_2 = Math.sqrt(x * x + y * y); - if (scale) - lengths[i] = length_2; - spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length_2 / setupLength; - } - } - } - var positions = this.computeWorldPositions(attachment, spacesCount, tangents); - var boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; - var tip = false; - if (offsetRotation == 0) - tip = data.rotateMode == exports.RotateMode.Chain; - else { - tip = false; - var p = this.target.bone.matrix; - offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.degRad : -MathUtils.degRad; - } - for (var i = 0, p = 3; i < boneCount; i++, p += 3) { - var bone = bones[i]; - var mat = bone.matrix; - mat.tx += (boneX - mat.tx) * mixX; - mat.ty += (boneY - mat.ty) * mixY; - var x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; - if (scale) { - var length_3 = lengths[i]; - if (length_3 != 0) { - var s = (Math.sqrt(dx * dx + dy * dy) / length_3 - 1) * mixRotate + 1; - mat.a *= s; - mat.b *= s; - } - } - boneX = x; - boneY = y; - if (mixRotate > 0) { - var a = mat.a, b = mat.c, c = mat.b, d = mat.d, r = 0, cos = 0, sin = 0; - if (tangents) - r = positions[p - 1]; - else if (spaces[i + 1] == 0) - r = positions[p + 2]; - else - r = Math.atan2(dy, dx); - r -= Math.atan2(c, a); - if (tip) { - cos = Math.cos(r); - sin = Math.sin(r); - var length_4 = bone.data.length; - boneX += (length_4 * (cos * a - sin * c) - dx) * mixRotate; - boneY += (length_4 * (sin * a + cos * c) - dy) * mixRotate; - } - else { - r += offsetRotation; - } - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) // - r += MathUtils.PI2; - r *= mixRotate; - cos = Math.cos(r); - sin = Math.sin(r); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - } - bone.updateAppliedTransform(); - } - }; - PathConstraint.prototype.computeWorldPositions = function (path, spacesCount, tangents) { - var target = this.target; - var position = this.position; - var spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = this.world; - var closed = path.closed; - var verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE; - if (!path.constantSpeed) { - var lengths = path.lengths; - curveCount -= closed ? 1 : 2; - var pathLength_1 = lengths[curveCount]; - if (this.data.positionMode == exports.PositionMode.Percent) - position *= pathLength_1; - var multiplier_1; - switch (this.data.spacingMode) { - case SpacingMode.Percent: - multiplier_1 = pathLength_1; - break; - case SpacingMode.Proportional: - multiplier_1 = pathLength_1 / spacesCount; - break; - default: - multiplier_1 = 1; - } - world = Utils.setArraySize(this.world, 8); - for (var i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { - var space = spaces[i] * multiplier_1; - position += space; - var p = position; - if (closed) { - p %= pathLength_1; - if (p < 0) - p += pathLength_1; - curve = 0; - } - else if (p < 0) { - if (prevCurve != PathConstraint.BEFORE) { - prevCurve = PathConstraint.BEFORE; - path.computeWorldVertices(target, 2, 4, world, 0, 2); - } - this.addBeforePosition(p, world, 0, out, o); - continue; - } - else if (p > pathLength_1) { - if (prevCurve != PathConstraint.AFTER) { - prevCurve = PathConstraint.AFTER; - path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); - } - this.addAfterPosition(p - pathLength_1, world, 0, out, o); - continue; - } - // Determine curve containing position. - for (;; curve++) { - var length_5 = lengths[curve]; - if (p > length_5) - continue; - if (curve == 0) - p /= length_5; - else { - var prev = lengths[curve - 1]; - p = (p - prev) / (length_5 - prev); - } - break; - } - if (curve != prevCurve) { - prevCurve = curve; - if (closed && curve == curveCount) { - path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); - path.computeWorldVertices(target, 0, 4, world, 4, 2); - } - else - path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); - } - this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0)); - } - return out; - } - // World vertices. - if (closed) { - verticesLength += 2; - world = Utils.setArraySize(this.world, verticesLength); - path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); - path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); - world[verticesLength - 2] = world[0]; - world[verticesLength - 1] = world[1]; - } - else { - curveCount--; - verticesLength -= 4; - world = Utils.setArraySize(this.world, verticesLength); - path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); - } - // Curve lengths. - var curves = Utils.setArraySize(this.curves, curveCount); - var pathLength = 0; - var x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; - var tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0; - for (var i = 0, w = 2; i < curveCount; i++, w += 6) { - cx1 = world[w]; - cy1 = world[w + 1]; - cx2 = world[w + 2]; - cy2 = world[w + 3]; - x2 = world[w + 4]; - y2 = world[w + 5]; - tmpx = (x1 - cx1 * 2 + cx2) * 0.1875; - tmpy = (y1 - cy1 * 2 + cy2) * 0.1875; - dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375; - dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375; - ddfx = tmpx * 2 + dddfx; - ddfy = tmpy * 2 + dddfy; - dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667; - dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - dfx += ddfx; - dfy += ddfy; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - dfx += ddfx + dddfx; - dfy += ddfy + dddfy; - pathLength += Math.sqrt(dfx * dfx + dfy * dfy); - curves[i] = pathLength; - x1 = x2; - y1 = y2; - } - if (this.data.positionMode == exports.PositionMode.Percent) - position *= pathLength; - var multiplier; - switch (this.data.spacingMode) { - case SpacingMode.Percent: - multiplier = pathLength; - break; - case SpacingMode.Proportional: - multiplier = pathLength / spacesCount; - break; - default: - multiplier = 1; - } - var segments = this.segments; - var curveLength = 0; - for (var i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { - var space = spaces[i] * multiplier; - position += space; - var p = position; - if (closed) { - p %= pathLength; - if (p < 0) - p += pathLength; - curve = 0; - } - else if (p < 0) { - this.addBeforePosition(p, world, 0, out, o); - continue; - } - else if (p > pathLength) { - this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o); - continue; - } - // Determine curve containing position. - for (;; curve++) { - var length_6 = curves[curve]; - if (p > length_6) - continue; - if (curve == 0) - p /= length_6; - else { - var prev = curves[curve - 1]; - p = (p - prev) / (length_6 - prev); - } - break; - } - // Curve segment lengths. - if (curve != prevCurve) { - prevCurve = curve; - var ii = curve * 6; - x1 = world[ii]; - y1 = world[ii + 1]; - cx1 = world[ii + 2]; - cy1 = world[ii + 3]; - cx2 = world[ii + 4]; - cy2 = world[ii + 5]; - x2 = world[ii + 6]; - y2 = world[ii + 7]; - tmpx = (x1 - cx1 * 2 + cx2) * 0.03; - tmpy = (y1 - cy1 * 2 + cy2) * 0.03; - dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006; - dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006; - ddfx = tmpx * 2 + dddfx; - ddfy = tmpy * 2 + dddfy; - dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667; - dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667; - curveLength = Math.sqrt(dfx * dfx + dfy * dfy); - segments[0] = curveLength; - for (ii = 1; ii < 8; ii++) { - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - curveLength += Math.sqrt(dfx * dfx + dfy * dfy); - segments[ii] = curveLength; - } - dfx += ddfx; - dfy += ddfy; - curveLength += Math.sqrt(dfx * dfx + dfy * dfy); - segments[8] = curveLength; - dfx += ddfx + dddfx; - dfy += ddfy + dddfy; - curveLength += Math.sqrt(dfx * dfx + dfy * dfy); - segments[9] = curveLength; - segment = 0; - } - // Weight by segment length. - p *= curveLength; - for (;; segment++) { - var length_7 = segments[segment]; - if (p > length_7) - continue; - if (segment == 0) - p /= length_7; - else { - var prev = segments[segment - 1]; - p = segment + (p - prev) / (length_7 - prev); - } - break; - } - this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0)); - } - return out; - }; - PathConstraint.prototype.addBeforePosition = function (p, temp, i, out, o) { - var x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); - out[o] = x1 + p * Math.cos(r); - out[o + 1] = y1 + p * Math.sin(r); - out[o + 2] = r; - }; - PathConstraint.prototype.addAfterPosition = function (p, temp, i, out, o) { - var x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); - out[o] = x1 + p * Math.cos(r); - out[o + 1] = y1 + p * Math.sin(r); - out[o + 2] = r; - }; - PathConstraint.prototype.addCurvePosition = function (p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) { - if (p == 0 || isNaN(p)) { - out[o] = x1; - out[o + 1] = y1; - out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); - return; - } - var tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; - var ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; - var x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; - out[o] = x; - out[o + 1] = y; - if (tangents) { - if (p < 0.001) - out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); - else - out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); - } - }; - PathConstraint.NONE = -1; - PathConstraint.BEFORE = -2; - PathConstraint.AFTER = -3; - PathConstraint.epsilon = 0.00001; - return PathConstraint; - }()); - - /** Stores a slot's current pose. Slots organize attachments for {@link Skeleton#drawOrder} 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. - * @public - * */ - var Slot = /** @class */ (function () { - function Slot(data, bone) { - /** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark - * color's alpha is not used. */ - this.darkColor = null; - this.attachment = null; - this.attachmentState = 0; - /** The index of the texture region to display when the slot's attachment has a {@link Sequence}. -1 represents the - * {@link Sequence#getSetupIndex()}. */ - this.sequenceIndex = -1; - /** Values to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a - * weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions. - * - * See {@link VertexAttachment#computeWorldVertices()} and {@link DeformTimeline}. */ - this.deform = new Array(); - if (!data) - throw new Error("data cannot be null."); - if (!bone) - throw new Error("bone cannot be null."); - this.data = data; - this.bone = bone; - this.color = new Color(); - this.darkColor = !data.darkColor ? null : new Color(); - this.setToSetupPose(); - this.blendMode = this.data.blendMode; - } - /** The skeleton this slot belongs to. */ - Slot.prototype.getSkeleton = function () { - return this.bone.skeleton; - }; - /** The current attachment for the slot, or null if the slot has no attachment. */ - Slot.prototype.getAttachment = function () { - return this.attachment; - }; - /** Sets the slot's attachment and, if the attachment changed, resets {@link #sequenceIndex} and clears the {@link #deform}. - * The deform is not cleared if the old attachment has the same {@link VertexAttachment#getTimelineAttachment()} as the - * specified attachment. */ - Slot.prototype.setAttachment = function (attachment) { - if (this.attachment == attachment) - return; - if (!(attachment instanceof VertexAttachment) || !(this.attachment instanceof VertexAttachment) - || attachment.timelineAttachment != this.attachment.timelineAttachment) { - this.deform.length = 0; - } - this.attachment = attachment; - this.sequenceIndex = -1; - }; - /** Sets this slot to the setup pose. */ - Slot.prototype.setToSetupPose = function () { - this.color.setFromColor(this.data.color); - if (this.darkColor) - this.darkColor.setFromColor(this.data.darkColor); - if (!this.data.attachmentName) - this.attachment = null; - else { - this.attachment = null; - this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName)); - } - }; - return Slot; - }()); - - /** Stores the current pose for a transform constraint. A transform constraint adjusts the world transform of the constrained - * bones to match that of the target bone. - * - * See [Transform constraints](http://esotericsoftware.com/spine-transform-constraints) in the Spine User Guide. - * @public - * */ - var TransformConstraint = /** @class */ (function () { - function TransformConstraint(data, skeleton) { - this.mixRotate = 0; - this.mixX = 0; - this.mixY = 0; - this.mixScaleX = 0; - this.mixScaleY = 0; - this.mixShearY = 0; - this.temp = new Vector2(); - this.active = false; - if (!data) - throw new Error("data cannot be null."); - if (!skeleton) - throw new Error("skeleton cannot be null."); - this.data = data; - this.mixRotate = data.mixRotate; - this.mixX = data.mixX; - this.mixY = data.mixY; - this.mixScaleX = data.mixScaleX; - this.mixScaleY = data.mixScaleY; - this.mixShearY = data.mixShearY; - this.bones = new Array(); - for (var i = 0; i < data.bones.length; i++) { - var bone = skeleton.findBone(data.bones[i].name); - if (!bone) - throw new Error("Couldn't find bone " + data.bones[i].name + "."); - this.bones.push(bone); - } - var target = skeleton.findBone(data.target.name); - if (!target) - throw new Error("Couldn't find target bone " + data.target.name + "."); - this.target = target; - } - TransformConstraint.prototype.isActive = function () { - return this.active; - }; - TransformConstraint.prototype.update = function () { - if (this.mixRotate == 0 && this.mixX == 0 && this.mixY == 0 && this.mixScaleX == 0 && this.mixScaleX == 0 && this.mixShearY == 0) - return; - if (this.data.local) { - if (this.data.relative) - this.applyRelativeLocal(); - else - this.applyAbsoluteLocal(); - } - else { - if (this.data.relative) - this.applyRelativeWorld(); - else - this.applyAbsoluteWorld(); - } - }; - TransformConstraint.prototype.applyAbsoluteWorld = function () { - var mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; - var translate = mixX != 0 || mixY != 0; - var target = this.target; - var targetMat = target.matrix; - var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; - var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; - var offsetRotation = this.data.offsetRotation * degRadReflect; - var offsetShearY = this.data.offsetShearY * degRadReflect; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - var mat = bone.matrix; - if (mixRotate != 0) { - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation; - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) // - r += MathUtils.PI2; - r *= mixRotate; - var cos = Math.cos(r), sin = Math.sin(r); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - } - if (translate) { - var temp = this.temp; - target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); - mat.tx += (temp.x - mat.tx) * mixX; - mat.ty += (temp.y - mat.ty) * mixY; - } - if (mixScaleX != 0) { - var s = Math.sqrt(mat.a * mat.a + mat.b * mat.b); - if (s != 0) - s = (s + (Math.sqrt(ta * ta + tc * tc) - s + this.data.offsetScaleX) * mixScaleX) / s; - mat.a *= s; - mat.b *= s; - } - if (mixScaleY != 0) { - var s = Math.sqrt(mat.c * mat.c + mat.d * mat.d); - if (s != 0) - s = (s + (Math.sqrt(tb * tb + td * td) - s + this.data.offsetScaleY) * mixScaleY) / s; - mat.c *= s; - mat.d *= s; - } - if (mixShearY > 0) { - var b = mat.c, d = mat.d; - var by = Math.atan2(d, b); - var r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(mat.b, mat.a)); - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) // - r += MathUtils.PI2; - r = by + (r + offsetShearY) * mixShearY; - var s = Math.sqrt(b * b + d * d); - mat.c = Math.cos(r) * s; - mat.d = Math.sin(r) * s; - } - bone.updateAppliedTransform(); - } - }; - TransformConstraint.prototype.applyRelativeWorld = function () { - var mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; - var translate = mixX != 0 || mixY != 0; - var target = this.target; - var targetMat = target.matrix; - var ta = targetMat.a, tb = targetMat.c, tc = targetMat.b, td = targetMat.d; - var degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; - var offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - var mat = bone.matrix; - if (mixRotate != 0) { - var a = mat.a, b = mat.c, c = mat.b, d = mat.d; - var r = Math.atan2(tc, ta) + offsetRotation; - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) // - r += MathUtils.PI2; - r *= mixRotate; - var cos = Math.cos(r), sin = Math.sin(r); - mat.a = cos * a - sin * c; - mat.c = cos * b - sin * d; - mat.b = sin * a + cos * c; - mat.d = sin * b + cos * d; - } - if (translate) { - var temp = this.temp; - target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); - mat.tx += temp.x * mixX; - mat.ty += temp.y * mixY; - } - if (mixScaleX != 0) { - var s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * mixScaleX + 1; - mat.a *= s; - mat.b *= s; - } - if (mixScaleY != 0) { - var s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * mixScaleY + 1; - mat.c *= s; - mat.d *= s; - } - if (mixShearY > 0) { - var r = Math.atan2(td, tb) - Math.atan2(tc, ta); - if (r > MathUtils.PI) - r -= MathUtils.PI2; - else if (r < -MathUtils.PI) // - r += MathUtils.PI2; - var b = mat.c, d = mat.d; - r = Math.atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * mixShearY; - var s = Math.sqrt(b * b + d * d); - mat.c = Math.cos(r) * s; - mat.d = Math.sin(r) * s; - } - bone.updateAppliedTransform(); - } - }; - TransformConstraint.prototype.applyAbsoluteLocal = function () { - var mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; - var target = this.target; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - var rotation = bone.arotation; - if (mixRotate != 0) { - var r = target.arotation - rotation + this.data.offsetRotation; - r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; - rotation += r * mixRotate; - } - var x = bone.ax, y = bone.ay; - x += (target.ax - x + this.data.offsetX) * mixX; - y += (target.ay - y + this.data.offsetY) * mixY; - var scaleX = bone.ascaleX, scaleY = bone.ascaleY; - if (mixScaleX != 0 && scaleX != 0) - scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * mixScaleX) / scaleX; - if (mixScaleY != 0 && scaleY != 0) - scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * mixScaleY) / scaleY; - var shearY = bone.ashearY; - if (mixShearY != 0) { - var r = target.ashearY - shearY + this.data.offsetShearY; - r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; - shearY += r * mixShearY; - } - bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); - } - }; - TransformConstraint.prototype.applyRelativeLocal = function () { - var mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; - var target = this.target; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - var rotation = bone.arotation + (target.arotation + this.data.offsetRotation) * mixRotate; - var x = bone.ax + (target.ax + this.data.offsetX) * mixX; - var y = bone.ay + (target.ay + this.data.offsetY) * mixY; - var scaleX = bone.ascaleX * (((target.ascaleX - 1 + this.data.offsetScaleX) * mixScaleX) + 1); - var scaleY = bone.ascaleY * (((target.ascaleY - 1 + this.data.offsetScaleY) * mixScaleY) + 1); - var shearY = bone.ashearY + (target.ashearY + this.data.offsetShearY) * mixShearY; - bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); - } - }; - return TransformConstraint; - }()); - - /** Stores the current pose for a skeleton. - * - * See [Instance objects](http://esotericsoftware.com/spine-runtime-architecture#Instance-objects) in the Spine Runtimes Guide. - * @public - * */ - var Skeleton = /** @class */ (function () { - function Skeleton(data) { - /** The list of bones and constraints, sorted in the order they should be updated, as computed by {@link #updateCache()}. */ - this._updateCache = new Array(); - /** The skeleton's current skin. May be null. */ - this.skin = null; - /** Scales the entire skeleton on the X axis. This affects all bones, even if the bone's transform mode disallows scale - * inheritance. */ - this.scaleX = 1; - /** Scales the entire skeleton on the Y axis. This affects all bones, even if the bone's transform mode disallows scale - * inheritance. */ - this.scaleY = 1; - /** Sets the skeleton X position, which is added to the root bone worldX position. */ - this.x = 0; - /** Sets the skeleton Y position, which is added to the root bone worldY position. */ - this.y = 0; - if (!data) - throw new Error("data cannot be null."); - this.data = data; - this.bones = new Array(); - for (var i = 0; i < data.bones.length; i++) { - var boneData = data.bones[i]; - var bone = void 0; - if (!boneData.parent) - bone = new Bone(boneData, this, null); - else { - var parent_1 = this.bones[boneData.parent.index]; - bone = new Bone(boneData, this, parent_1); - parent_1.children.push(bone); - } - this.bones.push(bone); - } - this.slots = new Array(); - this.drawOrder = new Array(); - for (var i = 0; i < data.slots.length; i++) { - var slotData = data.slots[i]; - var bone = this.bones[slotData.boneData.index]; - var slot = new Slot(slotData, bone); - this.slots.push(slot); - this.drawOrder.push(slot); - } - this.ikConstraints = new Array(); - for (var i = 0; i < data.ikConstraints.length; i++) { - var ikConstraintData = data.ikConstraints[i]; - this.ikConstraints.push(new IkConstraint(ikConstraintData, this)); - } - this.transformConstraints = new Array(); - for (var i = 0; i < data.transformConstraints.length; i++) { - var transformConstraintData = data.transformConstraints[i]; - this.transformConstraints.push(new TransformConstraint(transformConstraintData, this)); - } - this.pathConstraints = new Array(); - for (var i = 0; i < data.pathConstraints.length; i++) { - var pathConstraintData = data.pathConstraints[i]; - this.pathConstraints.push(new PathConstraint(pathConstraintData, this)); - } - this.color = new Color(1, 1, 1, 1); - this.updateCache(); - } - /** Caches information about bones and constraints. Must be called if the {@link #getSkin()} is modified or if bones, - * constraints, or weighted path attachments are added or removed. */ - Skeleton.prototype.updateCache = function () { - var updateCache = this._updateCache; - updateCache.length = 0; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - bone.sorted = bone.data.skinRequired; - bone.active = !bone.sorted; - } - if (this.skin) { - var skinBones = this.skin.bones; - for (var i = 0, n = this.skin.bones.length; i < n; i++) { - var bone = this.bones[skinBones[i].index]; - do { - bone.sorted = false; - bone.active = true; - bone = bone.parent; - } while (bone); - } - } - // IK first, lowest hierarchy depth first. - var ikConstraints = this.ikConstraints; - var transformConstraints = this.transformConstraints; - var pathConstraints = this.pathConstraints; - var ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length; - var constraintCount = ikCount + transformCount + pathCount; - outer: for (var i = 0; i < constraintCount; i++) { - for (var ii = 0; ii < ikCount; ii++) { - var constraint = ikConstraints[ii]; - if (constraint.data.order == i) { - this.sortIkConstraint(constraint); - continue outer; - } - } - for (var ii = 0; ii < transformCount; ii++) { - var constraint = transformConstraints[ii]; - if (constraint.data.order == i) { - this.sortTransformConstraint(constraint); - continue outer; - } - } - for (var ii = 0; ii < pathCount; ii++) { - var constraint = pathConstraints[ii]; - if (constraint.data.order == i) { - this.sortPathConstraint(constraint); - continue outer; - } - } - } - for (var i = 0, n = bones.length; i < n; i++) - this.sortBone(bones[i]); - }; - Skeleton.prototype.sortIkConstraint = function (constraint) { - constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true))); - if (!constraint.active) - return; - var target = constraint.target; - this.sortBone(target); - var constrained = constraint.bones; - var parent = constrained[0]; - this.sortBone(parent); - if (constrained.length == 1) { - this._updateCache.push(constraint); - this.sortReset(parent.children); - } - else { - var child = constrained[constrained.length - 1]; - this.sortBone(child); - this._updateCache.push(constraint); - this.sortReset(parent.children); - child.sorted = true; - } - }; - Skeleton.prototype.sortPathConstraint = function (constraint) { - constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true))); - if (!constraint.active) - return; - var slot = constraint.target; - var slotIndex = slot.data.index; - var slotBone = slot.bone; - if (this.skin) - this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone); - if (this.data.defaultSkin && this.data.defaultSkin != this.skin) - this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone); - for (var i = 0, n = this.data.skins.length; i < n; i++) - this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone); - var attachment = slot.getAttachment(); - if (attachment instanceof PathAttachment) - this.sortPathConstraintAttachmentWith(attachment, slotBone); - var constrained = constraint.bones; - var boneCount = constrained.length; - for (var i = 0; i < boneCount; i++) - this.sortBone(constrained[i]); - this._updateCache.push(constraint); - for (var i = 0; i < boneCount; i++) - this.sortReset(constrained[i].children); - for (var i = 0; i < boneCount; i++) - constrained[i].sorted = true; - }; - Skeleton.prototype.sortTransformConstraint = function (constraint) { - constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true))); - if (!constraint.active) - return; - this.sortBone(constraint.target); - var constrained = constraint.bones; - var boneCount = constrained.length; - if (constraint.data.local) { - for (var i = 0; i < boneCount; i++) { - var child = constrained[i]; - this.sortBone(child.parent); - this.sortBone(child); - } - } - else { - for (var i = 0; i < boneCount; i++) { - this.sortBone(constrained[i]); - } - } - this._updateCache.push(constraint); - for (var i = 0; i < boneCount; i++) - this.sortReset(constrained[i].children); - for (var i = 0; i < boneCount; i++) - constrained[i].sorted = true; - }; - Skeleton.prototype.sortPathConstraintAttachment = function (skin, slotIndex, slotBone) { - var attachments = skin.attachments[slotIndex]; - if (!attachments) - return; - for (var key in attachments) { - this.sortPathConstraintAttachmentWith(attachments[key], slotBone); - } - }; - Skeleton.prototype.sortPathConstraintAttachmentWith = function (attachment, slotBone) { - if (!(attachment instanceof PathAttachment)) - return; - var pathBones = attachment.bones; - if (!pathBones) - this.sortBone(slotBone); - else { - var bones = this.bones; - for (var i = 0, n = pathBones.length; i < n;) { - var nn = pathBones[i++]; - nn += i; - while (i < nn) - this.sortBone(bones[pathBones[i++]]); - } - } - }; - Skeleton.prototype.sortBone = function (bone) { - if (!bone) - return; - if (bone.sorted) - return; - var parent = bone.parent; - if (parent) - this.sortBone(parent); - bone.sorted = true; - this._updateCache.push(bone); - }; - Skeleton.prototype.sortReset = function (bones) { - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (!bone.active) - continue; - if (bone.sorted) - this.sortReset(bone.children); - bone.sorted = false; - } - }; - /** Updates the world transform for each bone and applies all constraints. - * - * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine - * Runtimes Guide. */ - Skeleton.prototype.updateWorldTransform = function () { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - bone.ax = bone.x; - bone.ay = bone.y; - bone.arotation = bone.rotation; - bone.ascaleX = bone.scaleX; - bone.ascaleY = bone.scaleY; - bone.ashearX = bone.shearX; - bone.ashearY = bone.shearY; - } - var updateCache = this._updateCache; - for (var i = 0, n = updateCache.length; i < n; i++) - updateCache[i].update(); - }; - Skeleton.prototype.updateWorldTransformWith = function (parent) { - // Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection. - var rootBone = this.getRootBone(); - var pa = parent.matrix.a, pb = parent.matrix.c, pc = parent.matrix.b, pd = parent.matrix.d; - rootBone.matrix.tx = pa * this.x + pb * this.y + parent.worldX; - rootBone.matrix.ty = pc * this.x + pd * this.y + parent.worldY; - var rotationY = rootBone.rotation + 90 + rootBone.shearY; - var la = MathUtils.cosDeg(rootBone.rotation + rootBone.shearX) * rootBone.scaleX; - var lb = MathUtils.cosDeg(rotationY) * rootBone.scaleY; - var lc = MathUtils.sinDeg(rootBone.rotation + rootBone.shearX) * rootBone.scaleX; - var ld = MathUtils.sinDeg(rotationY) * rootBone.scaleY; - var sx = this.scaleX; - var sy = settings.yDown ? -this.scaleY : this.scaleY; - rootBone.matrix.a = (pa * la + pb * lc) * sx; - rootBone.matrix.c = (pa * lb + pb * ld) * sx; - rootBone.matrix.b = (pc * la + pd * lc) * sy; - rootBone.matrix.d = (pc * lb + pd * ld) * sy; - // Update everything except root bone. - var updateCache = this._updateCache; - for (var i = 0, n = updateCache.length; i < n; i++) { - var updatable = updateCache[i]; - if (updatable != rootBone) - updatable.update(); - } - }; - /** Sets the bones, constraints, and slots to their setup pose values. */ - Skeleton.prototype.setToSetupPose = function () { - this.setBonesToSetupPose(); - this.setSlotsToSetupPose(); - }; - /** Sets the bones and constraints to their setup pose values. */ - Skeleton.prototype.setBonesToSetupPose = function () { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - bones[i].setToSetupPose(); - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) { - var constraint = ikConstraints[i]; - constraint.mix = constraint.data.mix; - constraint.softness = constraint.data.softness; - constraint.bendDirection = constraint.data.bendDirection; - constraint.compress = constraint.data.compress; - constraint.stretch = constraint.data.stretch; - } - var transformConstraints = this.transformConstraints; - for (var i = 0, n = transformConstraints.length; i < n; i++) { - var constraint = transformConstraints[i]; - var data = constraint.data; - constraint.mixRotate = data.mixRotate; - constraint.mixX = data.mixX; - constraint.mixY = data.mixY; - constraint.mixScaleX = data.mixScaleX; - constraint.mixScaleY = data.mixScaleY; - constraint.mixShearY = data.mixShearY; - } - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) { - var constraint = pathConstraints[i]; - var data = constraint.data; - constraint.position = data.position; - constraint.spacing = data.spacing; - constraint.mixRotate = data.mixRotate; - constraint.mixX = data.mixX; - constraint.mixY = data.mixY; - } - }; - /** Sets the slots and draw order to their setup pose values. */ - Skeleton.prototype.setSlotsToSetupPose = function () { - var slots = this.slots; - Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length); - for (var i = 0, n = slots.length; i < n; i++) - slots[i].setToSetupPose(); - }; - /** @returns May return null. */ - Skeleton.prototype.getRootBone = function () { - if (this.bones.length == 0) - return null; - return this.bones[0]; - }; - /** @returns May be null. */ - Skeleton.prototype.findBone = function (boneName) { - if (!boneName) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (bone.data.name == boneName) - return bone; - } - return null; - }; - /** @returns -1 if the bone was not found. */ - Skeleton.prototype.findBoneIndex = function (boneName) { - if (!boneName) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].data.name == boneName) - return i; - return -1; - }; - /** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it - * repeatedly. - * @returns May be null. */ - Skeleton.prototype.findSlot = function (slotName) { - if (!slotName) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.data.name == slotName) - return slot; - } - return null; - }; - /** @returns -1 if the bone was not found. */ - Skeleton.prototype.findSlotIndex = function (slotName) { - if (!slotName) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].data.name == slotName) - return i; - return -1; - }; - /** Sets a skin by name. - * - * See {@link #setSkin()}. */ - Skeleton.prototype.setSkinByName = function (skinName) { - var skin = this.data.findSkin(skinName); - if (!skin) - throw new Error("Skin not found: " + skinName); - this.setSkin(skin); - }; - /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#defaultSkin default skin}. If the - * skin is changed, {@link #updateCache()} is called. - * - * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no - * old skin, each slot's setup mode attachment is attached from the new skin. - * - * After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling - * {@link #setSlotsToSetupPose()}. Also, often {@link AnimationState#apply()} is called before the next time the - * skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin. - * @param newSkin May be null. */ - Skeleton.prototype.setSkin = function (newSkin) { - if (newSkin == this.skin) - return; - if (newSkin) { - if (this.skin) - newSkin.attachAll(this, this.skin); - else { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - var name_1 = slot.data.attachmentName; - if (name_1) { - var attachment = newSkin.getAttachment(i, name_1); - if (attachment) - slot.setAttachment(attachment); - } - } - } - } - this.skin = newSkin; - this.updateCache(); - }; - /** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot name and attachment - * name. - * - * See {@link #getAttachment()}. - * @returns May be null. */ - Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) { - var slot = this.data.findSlot(slotName); - if (!slot) - throw new Error("Can't find slot with name " + slotName); - return this.getAttachment(slot.index, attachmentName); - }; - /** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot index and - * attachment name. First the skin is checked and if the attachment was not found, the default skin is checked. - * - * See [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide. - * @returns May be null. */ - Skeleton.prototype.getAttachment = function (slotIndex, attachmentName) { - if (!attachmentName) - throw new Error("attachmentName cannot be null."); - if (this.skin) { - var attachment = this.skin.getAttachment(slotIndex, attachmentName); - if (attachment) - return attachment; - } - if (this.data.defaultSkin) - return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); - return null; - }; - /** A convenience method to set an attachment by finding the slot with {@link #findSlot()}, finding the attachment with - * {@link #getAttachment()}, then setting the slot's {@link Slot#attachment}. - * @param attachmentName May be null to clear the slot's attachment. */ - Skeleton.prototype.setAttachment = function (slotName, attachmentName) { - if (!slotName) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.data.name == slotName) { - var attachment = null; - if (attachmentName) { - attachment = this.getAttachment(i, attachmentName); - if (!attachment) - throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName); - } - slot.setAttachment(attachment); - return; - } - } - throw new Error("Slot not found: " + slotName); - }; - /** 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 repeatedly. - * @return May be null. */ - Skeleton.prototype.findIkConstraint = function (constraintName) { - if (!constraintName) - throw new Error("constraintName cannot be null."); - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) { - var ikConstraint = ikConstraints[i]; - if (ikConstraint.data.name == constraintName) - return ikConstraint; - } - return null; - }; - /** 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 repeatedly. - * @return May be null. */ - Skeleton.prototype.findTransformConstraint = function (constraintName) { - if (!constraintName) - throw new Error("constraintName cannot be null."); - var transformConstraints = this.transformConstraints; - for (var i = 0, n = transformConstraints.length; i < n; i++) { - var constraint = transformConstraints[i]; - if (constraint.data.name == constraintName) - return constraint; - } - return null; - }; - /** 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 repeatedly. - * @return May be null. */ - Skeleton.prototype.findPathConstraint = function (constraintName) { - if (!constraintName) - throw new Error("constraintName cannot be null."); - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) { - var constraint = pathConstraints[i]; - if (constraint.data.name == constraintName) - return constraint; - } - return null; - }; - /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose as `{ x: number, y: number, width: number, height: number }`. - * Note that this method will create temporary objects which can add to garbage collection pressure. Use `getBounds()` if garbage collection is a concern. */ - Skeleton.prototype.getBoundsRect = function () { - var offset = new Vector2(); - var size = new Vector2(); - this.getBounds(offset, size); - return { x: offset.x, y: offset.y, width: size.x, height: size.y }; - }; - /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. - * @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB. - * @param size An output value, the width and height of the AABB. - * @param temp Working memory to temporarily store attachments' computed world vertices. */ - Skeleton.prototype.getBounds = function (offset, size, temp) { - if (temp === void 0) { temp = new Array(2); } - if (!offset) - throw new Error("offset cannot be null."); - if (!size) - throw new Error("size cannot be null."); - var drawOrder = this.drawOrder; - var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; - for (var i = 0, n = drawOrder.length; i < n; i++) { - var slot = drawOrder[i]; - if (!slot.bone.active) - continue; - var verticesLength = 0; - var vertices = null; - var attachment = slot.getAttachment(); - if (attachment instanceof RegionAttachment) { - verticesLength = 8; - vertices = Utils.setArraySize(temp, verticesLength, 0); - attachment.computeWorldVertices(slot, vertices, 0, 2); - } - else if (attachment instanceof MeshAttachment) { - var mesh = attachment; - verticesLength = mesh.worldVerticesLength; - vertices = Utils.setArraySize(temp, verticesLength, 0); - mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2); - } - if (vertices) { - for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) { - var x = vertices[ii], y = vertices[ii + 1]; - minX = Math.min(minX, x); - minY = Math.min(minY, y); - maxX = Math.max(maxX, x); - maxY = Math.max(maxY, y); - } - } - } - offset.set(minX, minY); - size.set(maxX - minX, maxY - minY); - }; - Object.defineProperty(Skeleton.prototype, "flipX", { - get: function () { - return this.scaleX == -1; - }, - set: function (value) { - if (!Skeleton.deprecatedWarning1) { - Skeleton.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); - } - this.scaleX = value ? 1.0 : -1.0; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Skeleton.prototype, "flipY", { - get: function () { - return this.scaleY == -1; - }, - set: function (value) { - if (!Skeleton.deprecatedWarning1) { - Skeleton.deprecatedWarning1 = true; - console.warn("Spine Deprecation Warning: `Skeleton.flipX/flipY` was deprecated, please use scaleX/scaleY"); - } - this.scaleY = value ? 1.0 : -1.0; - }, - enumerable: false, - configurable: true - }); - Skeleton.deprecatedWarning1 = false; - return Skeleton; - }()); - - /** Stores the setup pose and all of the stateless data for a skeleton. - * - * See [Data objects](http://esotericsoftware.com/spine-runtime-architecture#Data-objects) in the Spine Runtimes - * Guide. - * @public - * */ - var SkeletonData = /** @class */ (function () { - function SkeletonData() { - /** The skeleton's name, which by default is the name of the skeleton data file, if possible. May be null. */ - this.name = null; - /** The skeleton's bones, sorted parent first. The root bone is always the first bone. */ - this.bones = new Array(); // Ordered parents first. - /** The skeleton's slots. */ - this.slots = new Array(); // Setup pose draw order. - this.skins = new Array(); - /** The skeleton's default skin. By default this skin contains all attachments that were not in a skin in Spine. - * - * See {@link Skeleton#getAttachmentByName()}. - * May be null. */ - this.defaultSkin = null; - /** The skeleton's events. */ - this.events = new Array(); - /** The skeleton's animations. */ - this.animations = new Array(); - /** The skeleton's IK constraints. */ - this.ikConstraints = new Array(); - /** The skeleton's transform constraints. */ - this.transformConstraints = new Array(); - /** The skeleton's path constraints. */ - this.pathConstraints = new Array(); - /** The X coordinate of the skeleton's axis aligned bounding box in the setup pose. */ - this.x = 0; - /** The Y coordinate of the skeleton's axis aligned bounding box in the setup pose. */ - this.y = 0; - /** The width of the skeleton's axis aligned bounding box in the setup pose. */ - this.width = 0; - /** The height of the skeleton's axis aligned bounding box in the setup pose. */ - this.height = 0; - /** The Spine version used to export the skeleton data, or null. */ - this.version = null; - /** The skeleton data hash. This value will change if any of the skeleton data has changed. May be null. */ - this.hash = null; - // Nonessential - /** The dopesheet FPS in Spine. Available only when nonessential data was exported. */ - this.fps = 0; - /** The path to the images directory as defined in Spine. Available only when nonessential data was exported. May be null. */ - this.imagesPath = null; - /** The path to the audio directory as defined in Spine. Available only when nonessential data was exported. May be null. */ - this.audioPath = null; - } - /** 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. - * @returns May be null. */ - SkeletonData.prototype.findBone = function (boneName) { - if (!boneName) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - if (bone.name == boneName) - return bone; - } - return null; - }; - /** removed from spine-ts runtime **/ - SkeletonData.prototype.findBoneIndex = function (boneName) { - if (!boneName) - throw new Error("boneName cannot be null."); - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].name == boneName) - return i; - return -1; - }; - /** 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. - * @returns May be null. */ - SkeletonData.prototype.findSlot = function (slotName) { - if (!slotName) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.name == slotName) - return slot; - } - return null; - }; - /** removed from spine-ts runtime **/ - SkeletonData.prototype.findSlotIndex = function (slotName) { - if (!slotName) - throw new Error("slotName cannot be null."); - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].name == slotName) - return i; - return -1; - }; - /** 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. - * @returns May be null. */ - SkeletonData.prototype.findSkin = function (skinName) { - if (!skinName) - throw new Error("skinName cannot be null."); - var skins = this.skins; - for (var i = 0, n = skins.length; i < n; i++) { - var skin = skins[i]; - if (skin.name == skinName) - return skin; - } - return null; - }; - /** 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. - * @returns May be null. */ - SkeletonData.prototype.findEvent = function (eventDataName) { - if (!eventDataName) - throw new Error("eventDataName cannot be null."); - var events = this.events; - for (var i = 0, n = events.length; i < n; i++) { - var event_1 = events[i]; - if (event_1.name == eventDataName) - return event_1; - } - return null; - }; - /** 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. - * @returns May be null. */ - SkeletonData.prototype.findAnimation = function (animationName) { - if (!animationName) - throw new Error("animationName cannot be null."); - var animations = this.animations; - for (var i = 0, n = animations.length; i < n; i++) { - var animation = animations[i]; - if (animation.name == animationName) - return animation; - } - return null; - }; - /** 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. - * @return May be null. */ - SkeletonData.prototype.findIkConstraint = function (constraintName) { - if (!constraintName) - throw new Error("constraintName cannot be null."); - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) { - var constraint = ikConstraints[i]; - if (constraint.name == constraintName) - return constraint; - } - return null; - }; - /** 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. - * @return May be null. */ - SkeletonData.prototype.findTransformConstraint = function (constraintName) { - if (!constraintName) - throw new Error("constraintName cannot be null."); - var transformConstraints = this.transformConstraints; - for (var i = 0, n = transformConstraints.length; i < n; i++) { - var constraint = transformConstraints[i]; - if (constraint.name == constraintName) - return constraint; - } - return null; - }; - /** 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. - * @return May be null. */ - SkeletonData.prototype.findPathConstraint = function (constraintName) { - if (!constraintName) - throw new Error("constraintName cannot be null."); - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) { - var constraint = pathConstraints[i]; - if (constraint.name == constraintName) - return constraint; - } - return null; - }; - /** removed from spine-ts runtime **/ SkeletonData.prototype.findPathConstraintIndex = function (pathConstraintName) { - if (pathConstraintName == null) - throw new Error("pathConstraintName cannot be null."); - var pathConstraints = this.pathConstraints; - for (var i = 0, n = pathConstraints.length; i < n; i++) - if (pathConstraints[i].name == pathConstraintName) - return i; - return -1; - }; - return SkeletonData; - }()); - - /** Stores the setup pose for a {@link Slot}. - * @public - * */ - var SlotData = /** @class */ (function () { - function SlotData(index, name, boneData) { - /** The index of the slot in {@link Skeleton#getSlots()}. */ - this.index = 0; - /** The color used to tint the slot's attachment. If {@link #getDarkColor()} is set, this is used as the light color for two - * color tinting. */ - this.color = new Color(1, 1, 1, 1); - /** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark - * color's alpha is not used. */ - this.darkColor = null; - /** The name of the attachment that is visible for this slot in the setup pose, or null if no attachment is visible. */ - this.attachmentName = null; - /** The blend mode for drawing the slot's attachment. */ - this.blendMode = constants.BLEND_MODES.NORMAL; - if (index < 0) - throw new Error("index must be >= 0."); - if (!name) - throw new Error("name cannot be null."); - if (!boneData) - throw new Error("boneData cannot be null."); - this.index = index; - this.name = name; - this.boneData = boneData; - } - return SlotData; - }()); - - /** Stores the setup pose for a {@link TransformConstraint}. - * - * See [Transform constraints](http://esotericsoftware.com/spine-transform-constraints) in the Spine User Guide. - * @public - * */ - var TransformConstraintData = /** @class */ (function (_super) { - __extends$1(TransformConstraintData, _super); - function TransformConstraintData(name) { - var _this = _super.call(this, name, 0, false) || this; - /** The bones that will be modified by this transform constraint. */ - _this.bones = new Array(); - /** The target bone whose world transform will be copied to the constrained bones. */ - _this._target = null; - _this.mixRotate = 0; - _this.mixX = 0; - _this.mixY = 0; - _this.mixScaleX = 0; - _this.mixScaleY = 0; - _this.mixShearY = 0; - /** An offset added to the constrained bone rotation. */ - _this.offsetRotation = 0; - /** An offset added to the constrained bone X translation. */ - _this.offsetX = 0; - /** An offset added to the constrained bone Y translation. */ - _this.offsetY = 0; - /** An offset added to the constrained bone scaleX. */ - _this.offsetScaleX = 0; - /** An offset added to the constrained bone scaleY. */ - _this.offsetScaleY = 0; - /** An offset added to the constrained bone shearY. */ - _this.offsetShearY = 0; - _this.relative = false; - _this.local = false; - return _this; - } - Object.defineProperty(TransformConstraintData.prototype, "target", { - get: function () { - if (!this._target) - throw new Error("BoneData not set."); - else - return this._target; - }, - set: function (boneData) { this._target = boneData; }, - enumerable: false, - configurable: true - }); - return TransformConstraintData; - }(ConstraintData)); - - /** Stores an entry in the skin consisting of the slot index, name, and attachment - * @public - * **/ - var SkinEntry = /** @class */ (function () { - function SkinEntry(slotIndex, name, attachment) { - this.slotIndex = slotIndex; - this.name = name; - this.attachment = attachment; - } - return SkinEntry; - }()); - /** Stores attachments by slot index and attachment name. - * - * See SkeletonData {@link SkeletonData#defaultSkin}, Skeleton {@link Skeleton#skin}, and - * [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide. - * @public - * */ - var Skin = /** @class */ (function () { - function Skin(name) { - this.attachments = new Array(); - this.bones = Array(); - this.constraints = new Array(); - if (!name) - throw new Error("name cannot be null."); - this.name = name; - } - /** Adds an attachment to the skin for the specified slot index and name. */ - Skin.prototype.setAttachment = function (slotIndex, name, attachment) { - if (!attachment) - throw new Error("attachment cannot be null."); - var attachments = this.attachments; - if (slotIndex >= attachments.length) - attachments.length = slotIndex + 1; - if (!attachments[slotIndex]) - attachments[slotIndex] = {}; - attachments[slotIndex][name] = attachment; - }; - /** Adds all attachments, bones, and constraints from the specified skin to this skin. */ - Skin.prototype.addSkin = function (skin) { - for (var i = 0; i < skin.bones.length; i++) { - var bone = skin.bones[i]; - var contained = false; - for (var ii = 0; ii < this.bones.length; ii++) { - if (this.bones[ii] == bone) { - contained = true; - break; - } - } - if (!contained) - this.bones.push(bone); - } - for (var i = 0; i < skin.constraints.length; i++) { - var constraint = skin.constraints[i]; - var contained = false; - for (var ii = 0; ii < this.constraints.length; ii++) { - if (this.constraints[ii] == constraint) { - contained = true; - break; - } - } - if (!contained) - this.constraints.push(constraint); - } - var attachments = skin.getAttachments(); - for (var i = 0; i < attachments.length; i++) { - var attachment = attachments[i]; - this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); - } - }; - /** 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. */ - Skin.prototype.copySkin = function (skin) { - for (var i = 0; i < skin.bones.length; i++) { - var bone = skin.bones[i]; - var contained = false; - for (var ii = 0; ii < this.bones.length; ii++) { - if (this.bones[ii] == bone) { - contained = true; - break; - } - } - if (!contained) - this.bones.push(bone); - } - for (var i = 0; i < skin.constraints.length; i++) { - var constraint = skin.constraints[i]; - var contained = false; - for (var ii = 0; ii < this.constraints.length; ii++) { - if (this.constraints[ii] == constraint) { - contained = true; - break; - } - } - if (!contained) - this.constraints.push(constraint); - } - var attachments = skin.getAttachments(); - for (var i = 0; i < attachments.length; i++) { - var attachment = attachments[i]; - if (!attachment.attachment) - continue; - if (attachment.attachment instanceof MeshAttachment) { - attachment.attachment = attachment.attachment.newLinkedMesh(); - this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); - } - else { - attachment.attachment = attachment.attachment.copy(); - this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); - } - } - }; - /** Returns the attachment for the specified slot index and name, or null. */ - Skin.prototype.getAttachment = function (slotIndex, name) { - var dictionary = this.attachments[slotIndex]; - return dictionary ? dictionary[name] : null; - }; - /** Removes the attachment in the skin for the specified slot index and name, if any. */ - Skin.prototype.removeAttachment = function (slotIndex, name) { - var dictionary = this.attachments[slotIndex]; - if (dictionary) - delete dictionary[name]; - }; - /** Returns all attachments in this skin. */ - Skin.prototype.getAttachments = function () { - var entries = new Array(); - for (var i = 0; i < this.attachments.length; i++) { - var slotAttachments = this.attachments[i]; - if (slotAttachments) { - for (var name_1 in slotAttachments) { - var attachment = slotAttachments[name_1]; - if (attachment) - entries.push(new SkinEntry(i, name_1, attachment)); - } - } - } - return entries; - }; - /** Returns all attachments in this skin for the specified slot index. */ - Skin.prototype.getAttachmentsForSlot = function (slotIndex, attachments) { - var slotAttachments = this.attachments[slotIndex]; - if (slotAttachments) { - for (var name_2 in slotAttachments) { - var attachment = slotAttachments[name_2]; - if (attachment) - attachments.push(new SkinEntry(slotIndex, name_2, attachment)); - } - } - }; - /** Clears all attachments, bones, and constraints. */ - Skin.prototype.clear = function () { - this.attachments.length = 0; - this.bones.length = 0; - this.constraints.length = 0; - }; - /** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */ - Skin.prototype.attachAll = function (skeleton, oldSkin) { - var slotIndex = 0; - for (var i = 0; i < skeleton.slots.length; i++) { - var slot = skeleton.slots[i]; - var slotAttachment = slot.getAttachment(); - if (slotAttachment && slotIndex < oldSkin.attachments.length) { - var dictionary = oldSkin.attachments[slotIndex]; - for (var key in dictionary) { - var skinAttachment = dictionary[key]; - if (slotAttachment == skinAttachment) { - var attachment = this.getAttachment(slotIndex, key); - if (attachment) - slot.setAttachment(attachment); - break; - } - } - } - slotIndex++; - } - }; - return Skin; - }()); - - /** Loads skeleton data in the Spine binary format. - * - * See [Spine binary format](http://esotericsoftware.com/spine-binary-format) and - * [JSON and binary data](http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data) in the Spine - * Runtimes Guide. - * @public - * */ - var SkeletonBinary = /** @class */ (function () { - function SkeletonBinary(attachmentLoader) { - this.ver40 = false; - /** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at - * runtime than were used in Spine. - * - * See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */ - this.scale = 1; - this.linkedMeshes = new Array(); - this.attachmentLoader = attachmentLoader; - } - SkeletonBinary.prototype.readSkeletonData = function (binary) { - var scale = this.scale; - var skeletonData = new SkeletonData(); - skeletonData.name = ""; // BOZO - var input = new BinaryInput(binary); - var lowHash = input.readInt32(); - var highHash = input.readInt32(); - skeletonData.hash = highHash == 0 && lowHash == 0 ? null : highHash.toString(16) + lowHash.toString(16); - skeletonData.version = input.readString(); - var verShort = skeletonData.version.substr(0, 3); - if (verShort !== '4.0' && verShort !== '4.1') { - var error = "Spine 4.1 loader cant load version " + skeletonData.version + ". Please configure your pixi-spine bundle"; - console.error(error); - } - this.ver40 = verShort === '4.0'; - skeletonData.x = input.readFloat(); - skeletonData.y = input.readFloat(); - skeletonData.width = input.readFloat(); - skeletonData.height = input.readFloat(); - var nonessential = input.readBoolean(); - if (nonessential) { - skeletonData.fps = input.readFloat(); - skeletonData.imagesPath = input.readString(); - skeletonData.audioPath = input.readString(); - } - var n = 0; - // Strings. - n = input.readInt(true); - for (var i = 0; i < n; i++) { - var str = input.readString(); - if (!str) - throw new Error("String in string table must not be null."); - input.strings.push(str); - } - // Bones. - n = input.readInt(true); - for (var i = 0; i < n; i++) { - var name_1 = input.readString(); - if (!name_1) - throw new Error("Bone name must not be null."); - var parent_1 = i == 0 ? null : skeletonData.bones[input.readInt(true)]; - var data = new BoneData(i, name_1, parent_1); - data.rotation = input.readFloat(); - data.x = input.readFloat() * scale; - data.y = input.readFloat() * scale; - data.scaleX = input.readFloat(); - data.scaleY = input.readFloat(); - data.shearX = input.readFloat(); - data.shearY = input.readFloat(); - data.length = input.readFloat() * scale; - data.transformMode = input.readInt(true); - data.skinRequired = input.readBoolean(); - if (nonessential) - Color.rgba8888ToColor(data.color, input.readInt32()); - skeletonData.bones.push(data); - } - // Slots. - n = input.readInt(true); - for (var i = 0; i < n; i++) { - var slotName = input.readString(); - if (!slotName) - throw new Error("Slot name must not be null."); - var boneData = skeletonData.bones[input.readInt(true)]; - var data = new SlotData(i, slotName, boneData); - Color.rgba8888ToColor(data.color, input.readInt32()); - var darkColor = input.readInt32(); - if (darkColor != -1) - Color.rgb888ToColor(data.darkColor = new Color(), darkColor); - data.attachmentName = input.readStringRef(); - data.blendMode = input.readInt(true); - skeletonData.slots.push(data); - } - // IK constraints. - n = input.readInt(true); - for (var i = 0, nn = void 0; i < n; i++) { - var name_2 = input.readString(); - if (!name_2) - throw new Error("IK constraint data name must not be null."); - var data = new IkConstraintData(name_2); - data.order = input.readInt(true); - data.skinRequired = input.readBoolean(); - nn = input.readInt(true); - for (var ii = 0; ii < nn; ii++) - data.bones.push(skeletonData.bones[input.readInt(true)]); - data.target = skeletonData.bones[input.readInt(true)]; - data.mix = input.readFloat(); - data.softness = input.readFloat() * scale; - data.bendDirection = input.readByte(); - data.compress = input.readBoolean(); - data.stretch = input.readBoolean(); - data.uniform = input.readBoolean(); - skeletonData.ikConstraints.push(data); - } - // Transform constraints. - n = input.readInt(true); - for (var i = 0, nn = void 0; i < n; i++) { - var name_3 = input.readString(); - if (!name_3) - throw new Error("Transform constraint data name must not be null."); - var data = new TransformConstraintData(name_3); - data.order = input.readInt(true); - data.skinRequired = input.readBoolean(); - nn = input.readInt(true); - for (var ii = 0; ii < nn; ii++) - data.bones.push(skeletonData.bones[input.readInt(true)]); - data.target = skeletonData.bones[input.readInt(true)]; - data.local = input.readBoolean(); - data.relative = input.readBoolean(); - data.offsetRotation = input.readFloat(); - data.offsetX = input.readFloat() * scale; - data.offsetY = input.readFloat() * scale; - data.offsetScaleX = input.readFloat(); - data.offsetScaleY = input.readFloat(); - data.offsetShearY = input.readFloat(); - data.mixRotate = input.readFloat(); - data.mixX = input.readFloat(); - data.mixY = input.readFloat(); - data.mixScaleX = input.readFloat(); - data.mixScaleY = input.readFloat(); - data.mixShearY = input.readFloat(); - skeletonData.transformConstraints.push(data); - } - // Path constraints. - n = input.readInt(true); - for (var i = 0, nn = void 0; i < n; i++) { - var name_4 = input.readString(); - if (!name_4) - throw new Error("Path constraint data name must not be null."); - var data = new PathConstraintData(name_4); - data.order = input.readInt(true); - data.skinRequired = input.readBoolean(); - nn = input.readInt(true); - for (var ii = 0; ii < nn; ii++) - data.bones.push(skeletonData.bones[input.readInt(true)]); - data.target = skeletonData.slots[input.readInt(true)]; - data.positionMode = input.readInt(true); - data.spacingMode = input.readInt(true); - data.rotateMode = input.readInt(true); - data.offsetRotation = input.readFloat(); - data.position = input.readFloat(); - if (data.positionMode == exports.PositionMode.Fixed) - data.position *= scale; - data.spacing = input.readFloat(); - if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) - data.spacing *= scale; - data.mixRotate = input.readFloat(); - data.mixX = input.readFloat(); - data.mixY = input.readFloat(); - skeletonData.pathConstraints.push(data); - } - // Default skin. - var defaultSkin = this.readSkin(input, skeletonData, true, nonessential); - if (defaultSkin) { - skeletonData.defaultSkin = defaultSkin; - skeletonData.skins.push(defaultSkin); - } - // Skins. - { - var i = skeletonData.skins.length; - Utils.setArraySize(skeletonData.skins, n = i + input.readInt(true)); - for (; i < n; i++) { - var skin = this.readSkin(input, skeletonData, false, nonessential); - if (!skin) - throw new Error("readSkin() should not have returned null."); - skeletonData.skins[i] = skin; - } - } - // Linked meshes. - n = this.linkedMeshes.length; - for (var i = 0; i < n; i++) { - var linkedMesh = this.linkedMeshes[i]; - var skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); - if (!skin) - throw new Error("Not skin found for linked mesh."); - if (!linkedMesh.parent) - throw new Error("Linked mesh parent must not be null"); - var parent_2 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); - if (!parent_2) - throw new Error("Parent mesh not found: " + linkedMesh.parent); - linkedMesh.mesh.timelineAttachment = linkedMesh.inheritTimeline ? parent_2 : linkedMesh.mesh; - linkedMesh.mesh.setParentMesh(parent_2); - // if (linkedMesh.mesh.region != null) linkedMesh.mesh.updateRegion(); - } - this.linkedMeshes.length = 0; - // Events. - n = input.readInt(true); - for (var i = 0; i < n; i++) { - var eventName = input.readStringRef(); - if (!eventName) - throw new Error; - var data = new EventData(eventName); - data.intValue = input.readInt(false); - data.floatValue = input.readFloat(); - data.stringValue = input.readString(); - data.audioPath = input.readString(); - if (data.audioPath) { - data.volume = input.readFloat(); - data.balance = input.readFloat(); - } - skeletonData.events.push(data); - } - // Animations. - n = input.readInt(true); - for (var i = 0; i < n; i++) { - var animationName = input.readString(); - if (!animationName) - throw new Error("Animatio name must not be null."); - skeletonData.animations.push(this.readAnimation(input, animationName, skeletonData)); - } - return skeletonData; - }; - SkeletonBinary.prototype.readSkin = function (input, skeletonData, defaultSkin, nonessential) { - var skin = null; - var slotCount = 0; - if (defaultSkin) { - slotCount = input.readInt(true); - if (slotCount == 0) - return null; - skin = new Skin("default"); - } - else { - var skinName = input.readStringRef(); - if (!skinName) - throw new Error("Skin name must not be null."); - skin = new Skin(skinName); - skin.bones.length = input.readInt(true); - for (var i = 0, n = skin.bones.length; i < n; i++) - skin.bones[i] = skeletonData.bones[input.readInt(true)]; - for (var i = 0, n = input.readInt(true); i < n; i++) - skin.constraints.push(skeletonData.ikConstraints[input.readInt(true)]); - for (var i = 0, n = input.readInt(true); i < n; i++) - skin.constraints.push(skeletonData.transformConstraints[input.readInt(true)]); - for (var i = 0, n = input.readInt(true); i < n; i++) - skin.constraints.push(skeletonData.pathConstraints[input.readInt(true)]); - slotCount = input.readInt(true); - } - for (var i = 0; i < slotCount; i++) { - var slotIndex = input.readInt(true); - for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { - var name_5 = input.readStringRef(); - if (!name_5) - throw new Error("Attachment name must not be null"); - var attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name_5, nonessential); - if (attachment) - skin.setAttachment(slotIndex, name_5, attachment); - } - } - return skin; - }; - SkeletonBinary.prototype.readAttachment = function (input, skeletonData, skin, slotIndex, attachmentName, nonessential) { - var scale = this.scale; - var name = input.readStringRef(); - if (!name) - name = attachmentName; - switch (input.readByte()) { - case exports.AttachmentType.Region: { - var path = input.readStringRef(); - var rotation = input.readFloat(); - var x = input.readFloat(); - var y = input.readFloat(); - var scaleX = input.readFloat(); - var scaleY = input.readFloat(); - var width = input.readFloat(); - var height = input.readFloat(); - var color = input.readInt32(); - var sequence = this.readSequence(input); - if (!path) - path = name; - var region = this.attachmentLoader.newRegionAttachment(skin, name, path, sequence); - if (!region) - return null; - region.path = path; - region.x = x * scale; - region.y = y * scale; - region.scaleX = scaleX; - region.scaleY = scaleY; - region.rotation = rotation; - region.width = width * scale; - region.height = height * scale; - Color.rgba8888ToColor(region.color, color); - region.sequence = sequence; - if (sequence == null) - region.updateRegion(); - return region; - } - case exports.AttachmentType.BoundingBox: { - var vertexCount = input.readInt(true); - var vertices = this.readVertices(input, vertexCount); - var color = nonessential ? input.readInt32() : 0; - var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); - if (!box) - return null; - box.worldVerticesLength = vertexCount << 1; - box.vertices = vertices.vertices; - box.bones = vertices.bones; - if (nonessential) - Color.rgba8888ToColor(box.color, color); - return box; - } - case exports.AttachmentType.Mesh: { - var path = input.readStringRef(); - var color = input.readInt32(); - var vertexCount = input.readInt(true); - var uvs = this.readFloatArray(input, vertexCount << 1, 1); - var triangles = this.readShortArray(input); - var vertices = this.readVertices(input, vertexCount); - var hullLength = input.readInt(true); - var sequence = this.readSequence(input); - var edges = []; - var width = 0, height = 0; - if (nonessential) { - edges = this.readShortArray(input); - width = input.readFloat(); - height = input.readFloat(); - } - if (!path) - path = name; - var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); - if (!mesh) - return null; - mesh.path = path; - Color.rgba8888ToColor(mesh.color, color); - mesh.bones = vertices.bones; - mesh.vertices = vertices.vertices; - mesh.worldVerticesLength = vertexCount << 1; - mesh.triangles = triangles; - mesh.regionUVs = new Float32Array(uvs); - // if (sequence == null) mesh.updateRegion(); - mesh.hullLength = hullLength << 1; - mesh.sequence = sequence; - if (nonessential) { - mesh.edges = edges; - mesh.width = width * scale; - mesh.height = height * scale; - } - return mesh; - } - case exports.AttachmentType.LinkedMesh: { - var path = input.readStringRef(); - var color = input.readInt32(); - var skinName = input.readStringRef(); - var parent_3 = input.readStringRef(); - var inheritTimelines = input.readBoolean(); - var sequence = this.readSequence(input); - var width = 0, height = 0; - if (nonessential) { - width = input.readFloat(); - height = input.readFloat(); - } - if (!path) - path = name; - var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); - if (!mesh) - return null; - mesh.path = path; - Color.rgba8888ToColor(mesh.color, color); - mesh.sequence = sequence; - if (nonessential) { - mesh.width = width * scale; - mesh.height = height * scale; - } - this.linkedMeshes.push(new LinkedMesh$1(mesh, skinName, slotIndex, parent_3, inheritTimelines)); - return mesh; - } - case exports.AttachmentType.Path: { - var closed_1 = input.readBoolean(); - var constantSpeed = input.readBoolean(); - var vertexCount = input.readInt(true); - var vertices = this.readVertices(input, vertexCount); - var lengths = Utils.newArray(vertexCount / 3, 0); - for (var i = 0, n = lengths.length; i < n; i++) - lengths[i] = input.readFloat() * scale; - var color = nonessential ? input.readInt32() : 0; - var path = this.attachmentLoader.newPathAttachment(skin, name); - if (!path) - return null; - path.closed = closed_1; - path.constantSpeed = constantSpeed; - path.worldVerticesLength = vertexCount << 1; - path.vertices = vertices.vertices; - path.bones = vertices.bones; - path.lengths = lengths; - if (nonessential) - Color.rgba8888ToColor(path.color, color); - return path; - } - case exports.AttachmentType.Point: { - var rotation = input.readFloat(); - var x = input.readFloat(); - var y = input.readFloat(); - var color = nonessential ? input.readInt32() : 0; - var point = this.attachmentLoader.newPointAttachment(skin, name); - if (!point) - return null; - point.x = x * scale; - point.y = y * scale; - point.rotation = rotation; - if (nonessential) - Color.rgba8888ToColor(point.color, color); - return point; - } - case exports.AttachmentType.Clipping: { - var endSlotIndex = input.readInt(true); - var vertexCount = input.readInt(true); - var vertices = this.readVertices(input, vertexCount); - var color = nonessential ? input.readInt32() : 0; - var clip = this.attachmentLoader.newClippingAttachment(skin, name); - if (!clip) - return null; - clip.endSlot = skeletonData.slots[endSlotIndex]; - clip.worldVerticesLength = vertexCount << 1; - clip.vertices = vertices.vertices; - clip.bones = vertices.bones; - if (nonessential) - Color.rgba8888ToColor(clip.color, color); - return clip; - } - } - return null; - }; - SkeletonBinary.prototype.readSequence = function (input) { - if (this.ver40 || !input.readBoolean()) - return null; - var sequence = new Sequence(input.readInt(true)); - sequence.start = input.readInt(true); - sequence.digits = input.readInt(true); - sequence.setupIndex = input.readInt(true); - return sequence; - }; - SkeletonBinary.prototype.readDeformTimelineType = function (input) { - if (this.ver40) - return ATTACHMENT_DEFORM; - return input.readByte(); - }; - SkeletonBinary.prototype.readVertices = function (input, vertexCount) { - var scale = this.scale; - var verticesLength = vertexCount << 1; - var vertices = new Vertices(); - if (!input.readBoolean()) { - vertices.vertices = this.readFloatArray(input, verticesLength, scale); - return vertices; - } - var weights = new Array(); - var bonesArray = new Array(); - for (var i = 0; i < vertexCount; i++) { - var boneCount = input.readInt(true); - bonesArray.push(boneCount); - for (var ii = 0; ii < boneCount; ii++) { - bonesArray.push(input.readInt(true)); - weights.push(input.readFloat() * scale); - weights.push(input.readFloat() * scale); - weights.push(input.readFloat()); - } - } - vertices.vertices = Utils.toFloatArray(weights); - vertices.bones = bonesArray; - return vertices; - }; - SkeletonBinary.prototype.readFloatArray = function (input, n, scale) { - var array = new Array(n); - if (scale == 1) { - for (var i = 0; i < n; i++) - array[i] = input.readFloat(); - } - else { - for (var i = 0; i < n; i++) - array[i] = input.readFloat() * scale; - } - return array; - }; - SkeletonBinary.prototype.readShortArray = function (input) { - var n = input.readInt(true); - var array = new Array(n); - for (var i = 0; i < n; i++) - array[i] = input.readShort(); - return array; - }; - SkeletonBinary.prototype.readAnimation = function (input, name, skeletonData) { - input.readInt(true); // Number of timelines. - var timelines = new Array(); - var scale = this.scale; - // Slot timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var slotIndex = input.readInt(true); - for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { - var timelineType = input.readByte(); - var frameCount = input.readInt(true); - var frameLast = frameCount - 1; - switch (timelineType) { - case SLOT_ATTACHMENT: { - var timeline = new AttachmentTimeline(frameCount, slotIndex); - for (var frame = 0; frame < frameCount; frame++) - timeline.setFrame(frame, input.readFloat(), input.readStringRef()); - timelines.push(timeline); - break; - } - case SLOT_RGBA: { - var bezierCount = input.readInt(true); - var timeline = new RGBATimeline(frameCount, bezierCount, slotIndex); - var time = input.readFloat(); - var r = input.readUnsignedByte() / 255.0; - var g = input.readUnsignedByte() / 255.0; - var b = input.readUnsignedByte() / 255.0; - var a = input.readUnsignedByte() / 255.0; - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, r, g, b, a); - if (frame == frameLast) - break; - var time2 = input.readFloat(); - var r2 = input.readUnsignedByte() / 255.0; - var g2 = input.readUnsignedByte() / 255.0; - var b2 = input.readUnsignedByte() / 255.0; - var a2 = input.readUnsignedByte() / 255.0; - switch (input.readByte()) { - case CURVE_STEPPED: - timeline.setStepped(frame); - break; - case CURVE_BEZIER: - setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1); - setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1); - setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1); - setBezier(input, timeline, bezier++, frame, 3, time, time2, a, a2, 1); - } - time = time2; - r = r2; - g = g2; - b = b2; - a = a2; - } - timelines.push(timeline); - break; - } - case SLOT_RGB: { - var bezierCount = input.readInt(true); - var timeline = new RGBTimeline(frameCount, bezierCount, slotIndex); - var time = input.readFloat(); - var r = input.readUnsignedByte() / 255.0; - var g = input.readUnsignedByte() / 255.0; - var b = input.readUnsignedByte() / 255.0; - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, r, g, b); - if (frame == frameLast) - break; - var time2 = input.readFloat(); - var r2 = input.readUnsignedByte() / 255.0; - var g2 = input.readUnsignedByte() / 255.0; - var b2 = input.readUnsignedByte() / 255.0; - switch (input.readByte()) { - case CURVE_STEPPED: - timeline.setStepped(frame); - break; - case CURVE_BEZIER: - setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1); - setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1); - setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1); - } - time = time2; - r = r2; - g = g2; - b = b2; - } - timelines.push(timeline); - break; - } - case SLOT_RGBA2: { - var bezierCount = input.readInt(true); - var timeline = new RGBA2Timeline(frameCount, bezierCount, slotIndex); - var time = input.readFloat(); - var r = input.readUnsignedByte() / 255.0; - var g = input.readUnsignedByte() / 255.0; - var b = input.readUnsignedByte() / 255.0; - var a = input.readUnsignedByte() / 255.0; - var r2 = input.readUnsignedByte() / 255.0; - var g2 = input.readUnsignedByte() / 255.0; - var b2 = input.readUnsignedByte() / 255.0; - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, r, g, b, a, r2, g2, b2); - if (frame == frameLast) - break; - var time2 = input.readFloat(); - var nr = input.readUnsignedByte() / 255.0; - var ng = input.readUnsignedByte() / 255.0; - var nb = input.readUnsignedByte() / 255.0; - var na = input.readUnsignedByte() / 255.0; - var nr2 = input.readUnsignedByte() / 255.0; - var ng2 = input.readUnsignedByte() / 255.0; - var nb2 = input.readUnsignedByte() / 255.0; - switch (input.readByte()) { - case CURVE_STEPPED: - timeline.setStepped(frame); - break; - case CURVE_BEZIER: - setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1); - setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1); - setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1); - setBezier(input, timeline, bezier++, frame, 3, time, time2, a, na, 1); - setBezier(input, timeline, bezier++, frame, 4, time, time2, r2, nr2, 1); - setBezier(input, timeline, bezier++, frame, 5, time, time2, g2, ng2, 1); - setBezier(input, timeline, bezier++, frame, 6, time, time2, b2, nb2, 1); - } - time = time2; - r = nr; - g = ng; - b = nb; - a = na; - r2 = nr2; - g2 = ng2; - b2 = nb2; - } - timelines.push(timeline); - break; - } - case SLOT_RGB2: { - var bezierCount = input.readInt(true); - var timeline = new RGB2Timeline(frameCount, bezierCount, slotIndex); - var time = input.readFloat(); - var r = input.readUnsignedByte() / 255.0; - var g = input.readUnsignedByte() / 255.0; - var b = input.readUnsignedByte() / 255.0; - var r2 = input.readUnsignedByte() / 255.0; - var g2 = input.readUnsignedByte() / 255.0; - var b2 = input.readUnsignedByte() / 255.0; - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, r, g, b, r2, g2, b2); - if (frame == frameLast) - break; - var time2 = input.readFloat(); - var nr = input.readUnsignedByte() / 255.0; - var ng = input.readUnsignedByte() / 255.0; - var nb = input.readUnsignedByte() / 255.0; - var nr2 = input.readUnsignedByte() / 255.0; - var ng2 = input.readUnsignedByte() / 255.0; - var nb2 = input.readUnsignedByte() / 255.0; - switch (input.readByte()) { - case CURVE_STEPPED: - timeline.setStepped(frame); - break; - case CURVE_BEZIER: - setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1); - setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1); - setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1); - setBezier(input, timeline, bezier++, frame, 3, time, time2, r2, nr2, 1); - setBezier(input, timeline, bezier++, frame, 4, time, time2, g2, ng2, 1); - setBezier(input, timeline, bezier++, frame, 5, time, time2, b2, nb2, 1); - } - time = time2; - r = nr; - g = ng; - b = nb; - r2 = nr2; - g2 = ng2; - b2 = nb2; - } - timelines.push(timeline); - break; - } - case SLOT_ALPHA: { - var timeline = new AlphaTimeline(frameCount, input.readInt(true), slotIndex); - var time = input.readFloat(), a = input.readUnsignedByte() / 255; - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, a); - if (frame == frameLast) - break; - var time2 = input.readFloat(); - var a2 = input.readUnsignedByte() / 255; - switch (input.readByte()) { - case CURVE_STEPPED: - timeline.setStepped(frame); - break; - case CURVE_BEZIER: - setBezier(input, timeline, bezier++, frame, 0, time, time2, a, a2, 1); - } - time = time2; - a = a2; - } - timelines.push(timeline); - } - } - } - } - // Bone timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var boneIndex = input.readInt(true); - for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { - var type = input.readByte(), frameCount = input.readInt(true), bezierCount = input.readInt(true); - switch (type) { - case BONE_ROTATE: - timelines.push(readTimeline1$1(input, new RotateTimeline(frameCount, bezierCount, boneIndex), 1)); - break; - case BONE_TRANSLATE: - timelines.push(readTimeline2$1(input, new TranslateTimeline(frameCount, bezierCount, boneIndex), scale)); - break; - case BONE_TRANSLATEX: - timelines.push(readTimeline1$1(input, new TranslateXTimeline(frameCount, bezierCount, boneIndex), scale)); - break; - case BONE_TRANSLATEY: - timelines.push(readTimeline1$1(input, new TranslateYTimeline(frameCount, bezierCount, boneIndex), scale)); - break; - case BONE_SCALE: - timelines.push(readTimeline2$1(input, new ScaleTimeline(frameCount, bezierCount, boneIndex), 1)); - break; - case BONE_SCALEX: - timelines.push(readTimeline1$1(input, new ScaleXTimeline(frameCount, bezierCount, boneIndex), 1)); - break; - case BONE_SCALEY: - timelines.push(readTimeline1$1(input, new ScaleYTimeline(frameCount, bezierCount, boneIndex), 1)); - break; - case BONE_SHEAR: - timelines.push(readTimeline2$1(input, new ShearTimeline(frameCount, bezierCount, boneIndex), 1)); - break; - case BONE_SHEARX: - timelines.push(readTimeline1$1(input, new ShearXTimeline(frameCount, bezierCount, boneIndex), 1)); - break; - case BONE_SHEARY: - timelines.push(readTimeline1$1(input, new ShearYTimeline(frameCount, bezierCount, boneIndex), 1)); - } - } - } - // IK constraint timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1; - var timeline = new IkConstraintTimeline(frameCount, input.readInt(true), index); - var time = input.readFloat(), mix = input.readFloat(), softness = input.readFloat() * scale; - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, mix, softness, input.readByte(), input.readBoolean(), input.readBoolean()); - if (frame == frameLast) - break; - var time2 = input.readFloat(), mix2 = input.readFloat(), softness2 = input.readFloat() * scale; - switch (input.readByte()) { - case CURVE_STEPPED: - timeline.setStepped(frame); - break; - case CURVE_BEZIER: - setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2, 1); - setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2, scale); - } - time = time2; - mix = mix2; - softness = softness2; - } - timelines.push(timeline); - } - // Transform constraint timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1; - var timeline = new TransformConstraintTimeline(frameCount, input.readInt(true), index); - var time = input.readFloat(), mixRotate = input.readFloat(), mixX = input.readFloat(), mixY = input.readFloat(), mixScaleX = input.readFloat(), mixScaleY = input.readFloat(), mixShearY = input.readFloat(); - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY); - if (frame == frameLast) - break; - var time2 = input.readFloat(), mixRotate2 = input.readFloat(), mixX2 = input.readFloat(), mixY2 = input.readFloat(), mixScaleX2 = input.readFloat(), mixScaleY2 = input.readFloat(), mixShearY2 = input.readFloat(); - switch (input.readByte()) { - case CURVE_STEPPED: - timeline.setStepped(frame); - break; - case CURVE_BEZIER: - setBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1); - setBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1); - setBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1); - setBezier(input, timeline, bezier++, frame, 3, time, time2, mixScaleX, mixScaleX2, 1); - setBezier(input, timeline, bezier++, frame, 4, time, time2, mixScaleY, mixScaleY2, 1); - setBezier(input, timeline, bezier++, frame, 5, time, time2, mixShearY, mixShearY2, 1); - } - time = time2; - mixRotate = mixRotate2; - mixX = mixX2; - mixY = mixY2; - mixScaleX = mixScaleX2; - mixScaleY = mixScaleY2; - mixShearY = mixShearY2; - } - timelines.push(timeline); - } - // Path constraint timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var index = input.readInt(true); - var data = skeletonData.pathConstraints[index]; - for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { - switch (input.readByte()) { - case PATH_POSITION: - timelines - .push(readTimeline1$1(input, new PathConstraintPositionTimeline(input.readInt(true), input.readInt(true), index), data.positionMode == exports.PositionMode.Fixed ? scale : 1)); - break; - case PATH_SPACING: - timelines - .push(readTimeline1$1(input, new PathConstraintSpacingTimeline(input.readInt(true), input.readInt(true), index), data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1)); - break; - case PATH_MIX: - var timeline = new PathConstraintMixTimeline(input.readInt(true), input.readInt(true), index); - var time = input.readFloat(), mixRotate = input.readFloat(), mixX = input.readFloat(), mixY = input.readFloat(); - for (var frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1;; frame++) { - timeline.setFrame(frame, time, mixRotate, mixX, mixY); - if (frame == frameLast) - break; - var time2 = input.readFloat(), mixRotate2 = input.readFloat(), mixX2 = input.readFloat(), mixY2 = input.readFloat(); - switch (input.readByte()) { - case CURVE_STEPPED: - timeline.setStepped(frame); - break; - case CURVE_BEZIER: - setBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1); - setBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1); - setBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1); - } - time = time2; - mixRotate = mixRotate2; - mixX = mixX2; - mixY = mixY2; - } - timelines.push(timeline); - } - } - } - // Deform timelines. - for (var i = 0, n = input.readInt(true); i < n; i++) { - var skin = skeletonData.skins[input.readInt(true)]; - for (var ii = 0, nn = input.readInt(true); ii < nn; ii++) { - var slotIndex = input.readInt(true); - for (var iii = 0, nnn = input.readInt(true); iii < nnn; iii++) { - var attachmentName = input.readStringRef(); - if (!attachmentName) - throw new Error("attachmentName must not be null."); - var attachment = skin.getAttachment(slotIndex, attachmentName); - var timelineType = this.readDeformTimelineType(input); - var frameCount = input.readInt(true); - var frameLast = frameCount - 1; - switch (timelineType) { - case ATTACHMENT_DEFORM: { - var vertexAttachment = attachment; - var weighted = vertexAttachment.bones; - var vertices = vertexAttachment.vertices; - var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; - var bezierCount = input.readInt(true); - var timeline = new DeformTimeline(frameCount, bezierCount, slotIndex, vertexAttachment); - var time = input.readFloat(); - for (var frame = 0, bezier = 0;; frame++) { - var deform = void 0; - var end = input.readInt(true); - if (end == 0) - deform = weighted ? Utils.newFloatArray(deformLength) : vertices; - else { - deform = Utils.newFloatArray(deformLength); - var start = input.readInt(true); - end += start; - if (scale == 1) { - for (var v = start; v < end; v++) - deform[v] = input.readFloat(); - } - else { - for (var v = start; v < end; v++) - deform[v] = input.readFloat() * scale; - } - if (!weighted) { - for (var v = 0, vn = deform.length; v < vn; v++) - deform[v] += vertices[v]; - } - } - timeline.setFrame(frame, time, deform); - if (frame == frameLast) - break; - var time2 = input.readFloat(); - switch (input.readByte()) { - case CURVE_STEPPED: - timeline.setStepped(frame); - break; - case CURVE_BEZIER: - setBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1); - } - time = time2; - } - timelines.push(timeline); - break; - } - case ATTACHMENT_SEQUENCE: { - var timeline = new SequenceTimeline(frameCount, slotIndex, attachment); - for (var frame = 0; frame < frameCount; frame++) { - var time = input.readFloat(); - var modeAndIndex = input.readInt32(); - timeline.setFrame(frame, time, SequenceModeValues[modeAndIndex & 0xf], modeAndIndex >> 4, input.readFloat()); - } - timelines.push(timeline); - break; - } - } - } - } - } - // Draw order timeline. - var drawOrderCount = input.readInt(true); - if (drawOrderCount > 0) { - var timeline = new DrawOrderTimeline(drawOrderCount); - var slotCount = skeletonData.slots.length; - for (var i = 0; i < drawOrderCount; i++) { - var time = input.readFloat(); - var offsetCount = input.readInt(true); - var drawOrder = Utils.newArray(slotCount, 0); - for (var ii = slotCount - 1; ii >= 0; ii--) - drawOrder[ii] = -1; - var unchanged = Utils.newArray(slotCount - offsetCount, 0); - var originalIndex = 0, unchangedIndex = 0; - for (var ii = 0; ii < offsetCount; ii++) { - var slotIndex = input.readInt(true); - // Collect unchanged items. - while (originalIndex != slotIndex) - unchanged[unchangedIndex++] = originalIndex++; - // Set changed items. - drawOrder[originalIndex + input.readInt(true)] = originalIndex++; - } - // Collect remaining unchanged items. - while (originalIndex < slotCount) - unchanged[unchangedIndex++] = originalIndex++; - // Fill in unchanged items. - for (var ii = slotCount - 1; ii >= 0; ii--) - if (drawOrder[ii] == -1) - drawOrder[ii] = unchanged[--unchangedIndex]; - timeline.setFrame(i, time, drawOrder); - } - timelines.push(timeline); - } - // Event timeline. - var eventCount = input.readInt(true); - if (eventCount > 0) { - var timeline = new EventTimeline(eventCount); - for (var i = 0; i < eventCount; i++) { - var time = input.readFloat(); - var eventData = skeletonData.events[input.readInt(true)]; - var event_1 = new Event(time, eventData); - event_1.intValue = input.readInt(false); - event_1.floatValue = input.readFloat(); - event_1.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue; - if (event_1.data.audioPath) { - event_1.volume = input.readFloat(); - event_1.balance = input.readFloat(); - } - timeline.setFrame(i, event_1); - } - timelines.push(timeline); - } - var duration = 0; - for (var i = 0, n = timelines.length; i < n; i++) - duration = Math.max(duration, timelines[i].getDuration()); - return new Animation(name, timelines, duration); - }; - SkeletonBinary.BlendModeValues = [constants.BLEND_MODES.NORMAL, constants.BLEND_MODES.ADD, constants.BLEND_MODES.MULTIPLY, constants.BLEND_MODES.SCREEN]; - return SkeletonBinary; - }()); - var LinkedMesh$1 = /** @class */ (function () { - function LinkedMesh(mesh, skin, slotIndex, parent, inheritDeform) { - this.mesh = mesh; - this.skin = skin; - this.slotIndex = slotIndex; - this.parent = parent; - this.inheritTimeline = inheritDeform; - } - return LinkedMesh; - }()); - var Vertices = /** @class */ (function () { - function Vertices(bones, vertices) { - if (bones === void 0) { bones = null; } - if (vertices === void 0) { vertices = null; } - this.bones = bones; - this.vertices = vertices; - } - return Vertices; - }()); - function readTimeline1$1(input, timeline, scale) { - var time = input.readFloat(), value = input.readFloat() * scale; - for (var frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1;; frame++) { - timeline.setFrame(frame, time, value); - if (frame == frameLast) - break; - var time2 = input.readFloat(), value2 = input.readFloat() * scale; - switch (input.readByte()) { - case CURVE_STEPPED: - timeline.setStepped(frame); - break; - case CURVE_BEZIER: - setBezier(input, timeline, bezier++, frame, 0, time, time2, value, value2, scale); - } - time = time2; - value = value2; - } - return timeline; - } - function readTimeline2$1(input, timeline, scale) { - var time = input.readFloat(), value1 = input.readFloat() * scale, value2 = input.readFloat() * scale; - for (var frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1;; frame++) { - timeline.setFrame(frame, time, value1, value2); - if (frame == frameLast) - break; - var time2 = input.readFloat(), nvalue1 = input.readFloat() * scale, nvalue2 = input.readFloat() * scale; - switch (input.readByte()) { - case CURVE_STEPPED: - timeline.setStepped(frame); - break; - case CURVE_BEZIER: - setBezier(input, timeline, bezier++, frame, 0, time, time2, value1, nvalue1, scale); - setBezier(input, timeline, bezier++, frame, 1, time, time2, value2, nvalue2, scale); - } - time = time2; - value1 = nvalue1; - value2 = nvalue2; - } - return timeline; - } - function setBezier(input, timeline, bezier, frame, value, time1, time2, value1, value2, scale) { - timeline.setBezier(bezier, frame, value, time1, value1, input.readFloat(), input.readFloat() * scale, input.readFloat(), input.readFloat() * scale, time2, value2); - } - var BONE_ROTATE = 0; - var BONE_TRANSLATE = 1; - var BONE_TRANSLATEX = 2; - var BONE_TRANSLATEY = 3; - var BONE_SCALE = 4; - var BONE_SCALEX = 5; - var BONE_SCALEY = 6; - var BONE_SHEAR = 7; - var BONE_SHEARX = 8; - var BONE_SHEARY = 9; - var SLOT_ATTACHMENT = 0; - var SLOT_RGBA = 1; - var SLOT_RGB = 2; - var SLOT_RGBA2 = 3; - var SLOT_RGB2 = 4; - var SLOT_ALPHA = 5; - var ATTACHMENT_DEFORM = 0; - var ATTACHMENT_SEQUENCE = 1; - var PATH_POSITION = 0; - var PATH_SPACING = 1; - var PATH_MIX = 2; - // const CURVE_LINEAR = 0; - var CURVE_STEPPED = 1; - var CURVE_BEZIER = 2; - - /** Collects each visible {@link BoundingBoxAttachment} and computes the world vertices for its polygon. The polygon vertices are - * provided along with convenience methods for doing hit detection. - * @public - * */ - var SkeletonBounds = /** @class */ (function (_super) { - __extends$1(SkeletonBounds, _super); - function SkeletonBounds() { - return _super !== null && _super.apply(this, arguments) || this; - } - return SkeletonBounds; - }(SkeletonBoundsBase)); - - /** Loads skeleton data in the Spine JSON format. - * - * See [Spine JSON format](http://esotericsoftware.com/spine-json-format) and - * [JSON and binary data](http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data) in the Spine - * Runtimes Guide. - * @public - * */ - var SkeletonJson = /** @class */ (function () { - function SkeletonJson(attachmentLoader) { - /** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at - * runtime than were used in Spine. - * - * See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */ - this.scale = 1; - this.linkedMeshes = new Array(); - this.attachmentLoader = attachmentLoader; - } - SkeletonJson.prototype.readSkeletonData = function (json) { - var scale = this.scale; - var skeletonData = new SkeletonData(); - var root = typeof (json) === "string" ? JSON.parse(json) : json; - // Skeleton - var skeletonMap = root.skeleton; - if (skeletonMap) { - skeletonData.hash = skeletonMap.hash; - skeletonData.version = skeletonMap.spine; - var verShort = skeletonData.version.substr(0, 3); - if (verShort !== '4.0' && verShort !== '4.1') { - var error = "Spine 4.1 loader cant load version " + skeletonMap.spine + ". Please configure your pixi-spine bundle"; - console.error(error); - } - skeletonData.x = skeletonMap.x; - skeletonData.y = skeletonMap.y; - skeletonData.width = skeletonMap.width; - skeletonData.height = skeletonMap.height; - skeletonData.fps = skeletonMap.fps; - skeletonData.imagesPath = skeletonMap.images; - } - // Bones - if (root.bones) { - for (var i = 0; i < root.bones.length; i++) { - var boneMap = root.bones[i]; - var parent_1 = null; - var parentName = getValue(boneMap, "parent", null); - if (parentName != null) { - parent_1 = skeletonData.findBone(parentName); - if (parent_1 == null) - throw new Error("Parent bone not found: " + parentName); - } - var data = new BoneData(skeletonData.bones.length, boneMap.name, parent_1); - data.length = getValue(boneMap, "length", 0) * scale; - data.x = getValue(boneMap, "x", 0) * scale; - data.y = getValue(boneMap, "y", 0) * scale; - data.rotation = getValue(boneMap, "rotation", 0); - data.scaleX = getValue(boneMap, "scaleX", 1); - data.scaleY = getValue(boneMap, "scaleY", 1); - data.shearX = getValue(boneMap, "shearX", 0); - data.shearY = getValue(boneMap, "shearY", 0); - data.transformMode = Utils.enumValue(exports.TransformMode, getValue(boneMap, "transform", "Normal")); - data.skinRequired = getValue(boneMap, "skin", false); - var color = getValue(boneMap, "color", null); - if (color) - data.color.setFromString(color); - skeletonData.bones.push(data); - } - } - // Slots. - if (root.slots) { - for (var i = 0; i < root.slots.length; i++) { - var slotMap = root.slots[i]; - var boneData = skeletonData.findBone(slotMap.bone); - if (!boneData) - throw new Error("Couldn't find bone " + slotMap.bone + " for slot " + slotMap.name); - var data = new SlotData(skeletonData.slots.length, slotMap.name, boneData); - var color = getValue(slotMap, "color", null); - if (color) - data.color.setFromString(color); - var dark = getValue(slotMap, "dark", null); - if (dark) - data.darkColor = Color.fromString(dark); - data.attachmentName = getValue(slotMap, "attachment", null); - data.blendMode = SkeletonJson.blendModeFromString(getValue(slotMap, "blend", "normal")); - skeletonData.slots.push(data); - } - } - // IK constraints - if (root.ik) { - for (var i = 0; i < root.ik.length; i++) { - var constraintMap = root.ik[i]; - var data = new IkConstraintData(constraintMap.name); - data.order = getValue(constraintMap, "order", 0); - data.skinRequired = getValue(constraintMap, "skin", false); - for (var ii = 0; ii < constraintMap.bones.length; ii++) { - var boneName = constraintMap.bones[ii]; - var bone = skeletonData.findBone(boneName); - if (bone == null) - throw new Error("IK bone not found: " + boneName); - data.bones.push(bone); - } - data.target = skeletonData.findBone(constraintMap.target); - data.mix = getValue(constraintMap, "mix", 1); - data.softness = getValue(constraintMap, "softness", 0) * scale; - data.bendDirection = getValue(constraintMap, "bendPositive", true) ? 1 : -1; - data.compress = getValue(constraintMap, "compress", false); - data.stretch = getValue(constraintMap, "stretch", false); - data.uniform = getValue(constraintMap, "uniform", false); - skeletonData.ikConstraints.push(data); - } - } - // Transform constraints. - if (root.transform) { - for (var i = 0; i < root.transform.length; i++) { - var constraintMap = root.transform[i]; - var data = new TransformConstraintData(constraintMap.name); - data.order = getValue(constraintMap, "order", 0); - data.skinRequired = getValue(constraintMap, "skin", false); - for (var ii = 0; ii < constraintMap.bones.length; ii++) { - var boneName = constraintMap.bones[ii]; - var bone = skeletonData.findBone(boneName); - if (!bone) - throw new Error("Couldn't find bone " + boneName + " for transform constraint " + constraintMap.name + "."); - data.bones.push(bone); - } - var targetName = constraintMap.target; - var target = skeletonData.findBone(targetName); - if (!target) - throw new Error("Couldn't find target bone " + targetName + " for transform constraint " + constraintMap.name + "."); - data.target = target; - data.local = getValue(constraintMap, "local", false); - data.relative = getValue(constraintMap, "relative", false); - data.offsetRotation = getValue(constraintMap, "rotation", 0); - data.offsetX = getValue(constraintMap, "x", 0) * scale; - data.offsetY = getValue(constraintMap, "y", 0) * scale; - data.offsetScaleX = getValue(constraintMap, "scaleX", 0); - data.offsetScaleY = getValue(constraintMap, "scaleY", 0); - data.offsetShearY = getValue(constraintMap, "shearY", 0); - data.mixRotate = getValue(constraintMap, "mixRotate", 1); - data.mixX = getValue(constraintMap, "mixX", 1); - data.mixY = getValue(constraintMap, "mixY", data.mixX); - data.mixScaleX = getValue(constraintMap, "mixScaleX", 1); - data.mixScaleY = getValue(constraintMap, "mixScaleY", data.mixScaleX); - data.mixShearY = getValue(constraintMap, "mixShearY", 1); - skeletonData.transformConstraints.push(data); - } - } - // Path constraints. - if (root.path) { - for (var i = 0; i < root.path.length; i++) { - var constraintMap = root.path[i]; - var data = new PathConstraintData(constraintMap.name); - data.order = getValue(constraintMap, "order", 0); - data.skinRequired = getValue(constraintMap, "skin", false); - for (var ii = 0; ii < constraintMap.bones.length; ii++) { - var boneName = constraintMap.bones[ii]; - var bone = skeletonData.findBone(boneName); - if (!bone) - throw new Error("Couldn't find bone " + boneName + " for path constraint " + constraintMap.name + "."); - data.bones.push(bone); - } - var targetName = constraintMap.target; - var target = skeletonData.findSlot(targetName); - if (!target) - throw new Error("Couldn't find target slot " + targetName + " for path constraint " + constraintMap.name + "."); - data.target = target; - data.positionMode = Utils.enumValue(exports.PositionMode, getValue(constraintMap, "positionMode", "Percent")); - data.spacingMode = Utils.enumValue(SpacingMode, getValue(constraintMap, "spacingMode", "Length")); - data.rotateMode = Utils.enumValue(exports.RotateMode, getValue(constraintMap, "rotateMode", "Tangent")); - data.offsetRotation = getValue(constraintMap, "rotation", 0); - data.position = getValue(constraintMap, "position", 0); - if (data.positionMode == exports.PositionMode.Fixed) - data.position *= scale; - data.spacing = getValue(constraintMap, "spacing", 0); - if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) - data.spacing *= scale; - data.mixRotate = getValue(constraintMap, "mixRotate", 1); - data.mixX = getValue(constraintMap, "mixX", 1); - data.mixY = getValue(constraintMap, "mixY", data.mixX); - skeletonData.pathConstraints.push(data); - } - } - // Skins. - if (root.skins) { - for (var i = 0; i < root.skins.length; i++) { - var skinMap = root.skins[i]; - var skin = new Skin(skinMap.name); - if (skinMap.bones) { - for (var ii = 0; ii < skinMap.bones.length; ii++) { - var boneName = skinMap.bones[ii]; - var bone = skeletonData.findBone(boneName); - if (!bone) - throw new Error("Couldn't find bone " + boneName + " for skin " + skinMap.name + "."); - skin.bones.push(bone); - } - } - if (skinMap.ik) { - for (var ii = 0; ii < skinMap.ik.length; ii++) { - var constraintName = skinMap.ik[ii]; - var constraint = skeletonData.findIkConstraint(constraintName); - if (!constraint) - throw new Error("Couldn't find IK constraint " + constraintName + " for skin " + skinMap.name + "."); - skin.constraints.push(constraint); - } - } - if (skinMap.transform) { - for (var ii = 0; ii < skinMap.transform.length; ii++) { - var constraintName = skinMap.transform[ii]; - var constraint = skeletonData.findTransformConstraint(constraintName); - if (!constraint) - throw new Error("Couldn't find transform constraint " + constraintName + " for skin " + skinMap.name + "."); - skin.constraints.push(constraint); - } - } - if (skinMap.path) { - for (var ii = 0; ii < skinMap.path.length; ii++) { - var constraintName = skinMap.path[ii]; - var constraint = skeletonData.findPathConstraint(constraintName); - if (!constraint) - throw new Error("Couldn't find path constraint " + constraintName + " for skin " + skinMap.name + "."); - skin.constraints.push(constraint); - } - } - for (var slotName in skinMap.attachments) { - var slot = skeletonData.findSlot(slotName); - if (!slot) - throw new Error("Couldn't find slot " + slotName + " for skin " + skinMap.name + "."); - var slotMap = skinMap.attachments[slotName]; - for (var entryName in slotMap) { - var attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData); - if (attachment) - skin.setAttachment(slot.index, entryName, attachment); - } - } - skeletonData.skins.push(skin); - if (skin.name == "default") - skeletonData.defaultSkin = skin; - } - } - // Linked meshes. - for (var i = 0, n = this.linkedMeshes.length; i < n; i++) { - var linkedMesh = this.linkedMeshes[i]; - var skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); - if (!skin) - throw new Error("Skin not found: " + linkedMesh.skin); - var parent_2 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); - if (!parent_2) - throw new Error("Parent mesh not found: " + linkedMesh.parent); - linkedMesh.mesh.timelineAttachment = linkedMesh.inheritTimeline ? parent_2 : linkedMesh.mesh; - linkedMesh.mesh.setParentMesh(parent_2); - // if (linkedMesh.mesh.region != null) linkedMesh.mesh.updateRegion(); - } - this.linkedMeshes.length = 0; - // Events. - if (root.events) { - for (var eventName in root.events) { - var eventMap = root.events[eventName]; - var data = new EventData(eventName); - data.intValue = getValue(eventMap, "int", 0); - data.floatValue = getValue(eventMap, "float", 0); - data.stringValue = getValue(eventMap, "string", ""); - data.audioPath = getValue(eventMap, "audio", null); - if (data.audioPath) { - data.volume = getValue(eventMap, "volume", 1); - data.balance = getValue(eventMap, "balance", 0); - } - skeletonData.events.push(data); - } - } - // Animations. - if (root.animations) { - for (var animationName in root.animations) { - var animationMap = root.animations[animationName]; - this.readAnimation(animationMap, animationName, skeletonData); - } - } - return skeletonData; - }; - SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) { - var scale = this.scale; - name = getValue(map, "name", name); - switch (getValue(map, "type", "region")) { - case "region": { - var path = getValue(map, "path", name); - var sequence = this.readSequence(getValue(map, "sequence", null)); - var region = this.attachmentLoader.newRegionAttachment(skin, name, path, sequence); - if (!region) - return null; - region.path = path; - region.x = getValue(map, "x", 0) * scale; - region.y = getValue(map, "y", 0) * scale; - region.scaleX = getValue(map, "scaleX", 1); - region.scaleY = getValue(map, "scaleY", 1); - region.rotation = getValue(map, "rotation", 0); - region.width = map.width * scale; - region.height = map.height * scale; - region.sequence = sequence; - var color = getValue(map, "color", null); - if (color) - region.color.setFromString(color); - // if (region.region != null) region.updateRegion(); - return region; - } - case "boundingbox": { - var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); - if (!box) - return null; - this.readVertices(map, box, map.vertexCount << 1); - var color = getValue(map, "color", null); - if (color) - box.color.setFromString(color); - return box; - } - case "mesh": - case "linkedmesh": { - var path = getValue(map, "path", name); - var sequence = this.readSequence(getValue(map, "sequence", null)); - var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); - if (!mesh) - return null; - mesh.path = path; - var color = getValue(map, "color", null); - if (color) - mesh.color.setFromString(color); - mesh.width = getValue(map, "width", 0) * scale; - mesh.height = getValue(map, "height", 0) * scale; - mesh.sequence = sequence; - var parent_3 = getValue(map, "parent", null); - if (parent_3) { - this.linkedMeshes.push(new LinkedMesh(mesh, getValue(map, "skin", null), slotIndex, parent_3, getValue(map, "timelines", true))); - return mesh; - } - var uvs = map.uvs; - this.readVertices(map, mesh, uvs.length); - mesh.triangles = map.triangles; - mesh.regionUVs = new Float32Array(uvs); - // if (mesh.region != null) mesh.updateRegion(); - mesh.edges = getValue(map, "edges", null); - mesh.hullLength = getValue(map, "hull", 0) * 2; - return mesh; - } - case "path": { - var path = this.attachmentLoader.newPathAttachment(skin, name); - if (!path) - return null; - path.closed = getValue(map, "closed", false); - path.constantSpeed = getValue(map, "constantSpeed", true); - var vertexCount = map.vertexCount; - this.readVertices(map, path, vertexCount << 1); - var lengths = Utils.newArray(vertexCount / 3, 0); - for (var i = 0; i < map.lengths.length; i++) - lengths[i] = map.lengths[i] * scale; - path.lengths = lengths; - var color = getValue(map, "color", null); - if (color) - path.color.setFromString(color); - return path; - } - case "point": { - var point = this.attachmentLoader.newPointAttachment(skin, name); - if (!point) - return null; - point.x = getValue(map, "x", 0) * scale; - point.y = getValue(map, "y", 0) * scale; - point.rotation = getValue(map, "rotation", 0); - var color = getValue(map, "color", null); - if (color) - point.color.setFromString(color); - return point; - } - case "clipping": { - var clip = this.attachmentLoader.newClippingAttachment(skin, name); - if (!clip) - return null; - var end = getValue(map, "end", null); - if (end != null) { - var slot = skeletonData.findSlot(end); - if (slot == null) - throw new Error("Clipping end slot not found: " + end); - clip.endSlot = slot; - } - var vertexCount = map.vertexCount; - this.readVertices(map, clip, vertexCount << 1); - var color = getValue(map, "color", null); - if (color) - clip.color.setFromString(color); - return clip; - } - } - return null; - }; - SkeletonJson.prototype.readSequence = function (map) { - if (map == null) - return null; - var sequence = new Sequence(getValue(map, "count", 0)); - sequence.start = getValue(map, "start", 1); - sequence.digits = getValue(map, "digits", 0); - sequence.setupIndex = getValue(map, "setup", 0); - return sequence; - }; - SkeletonJson.prototype.readVertices = function (map, attachment, verticesLength) { - var scale = this.scale; - attachment.worldVerticesLength = verticesLength; - var vertices = map.vertices; - if (verticesLength == vertices.length) { - var scaledVertices = Utils.toFloatArray(vertices); - if (scale != 1) { - for (var i = 0, n = vertices.length; i < n; i++) - scaledVertices[i] *= scale; - } - attachment.vertices = scaledVertices; - return; - } - var weights = new Array(); - var bones = new Array(); - for (var i = 0, n = vertices.length; i < n;) { - var boneCount = vertices[i++]; - bones.push(boneCount); - for (var nn = i + boneCount * 4; i < nn; i += 4) { - bones.push(vertices[i]); - weights.push(vertices[i + 1] * scale); - weights.push(vertices[i + 2] * scale); - weights.push(vertices[i + 3]); - } - } - attachment.bones = bones; - attachment.vertices = Utils.toFloatArray(weights); - }; - SkeletonJson.prototype.readAnimation = function (map, name, skeletonData) { - var scale = this.scale; - var timelines = new Array(); - // Slot timelines. - if (map.slots) { - for (var slotName in map.slots) { - var slotMap = map.slots[slotName]; - var slot = skeletonData.findSlot(slotName); - if (!slot) - throw new Error("Slot not found: " + slotName); - var slotIndex = slot.index; - for (var timelineName in slotMap) { - var timelineMap = slotMap[timelineName]; - if (!timelineMap) - continue; - var frames_1 = timelineMap.length; - if (timelineName == "attachment") { - var timeline = new AttachmentTimeline(frames_1, slotIndex); - for (var frame = 0; frame < frames_1; frame++) { - var keyMap = timelineMap[frame]; - timeline.setFrame(frame, getValue(keyMap, "time", 0), getValue(keyMap, "name", null)); - } - timelines.push(timeline); - } - else if (timelineName == "rgba") { - var timeline = new RGBATimeline(frames_1, frames_1 << 2, slotIndex); - var keyMap = timelineMap[0]; - var time = getValue(keyMap, "time", 0); - var color = Color.fromString(keyMap.color); - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, color.r, color.g, color.b, color.a); - var nextMap = timelineMap[frame + 1]; - if (!nextMap) { - timeline.shrink(bezier); - break; - } - var time2 = getValue(nextMap, "time", 0); - var newColor = Color.fromString(nextMap.color); - var curve = keyMap.curve; - if (curve) { - bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); - bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); - bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); - bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1); - } - time = time2; - color = newColor; - keyMap = nextMap; - } - timelines.push(timeline); - } - else if (timelineName == "rgb") { - var timeline = new RGBTimeline(frames_1, frames_1 * 3, slotIndex); - var keyMap = timelineMap[0]; - var time = getValue(keyMap, "time", 0); - var color = Color.fromString(keyMap.color); - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, color.r, color.g, color.b); - var nextMap = timelineMap[frame + 1]; - if (!nextMap) { - timeline.shrink(bezier); - break; - } - var time2 = getValue(nextMap, "time", 0); - var newColor = Color.fromString(nextMap.color); - var curve = keyMap.curve; - if (curve) { - bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); - bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); - bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); - } - time = time2; - color = newColor; - keyMap = nextMap; - } - timelines.push(timeline); - } - else if (timelineName == "alpha") { - timelines.push(readTimeline1(timelineMap, new AlphaTimeline(frames_1, frames_1, slotIndex), 0, 1)); - } - else if (timelineName == "rgba2") { - var timeline = new RGBA2Timeline(frames_1, frames_1 * 7, slotIndex); - var keyMap = timelineMap[0]; - var time = getValue(keyMap, "time", 0); - var color = Color.fromString(keyMap.light); - var color2 = Color.fromString(keyMap.dark); - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, color.r, color.g, color.b, color.a, color2.r, color2.g, color2.b); - var nextMap = timelineMap[frame + 1]; - if (!nextMap) { - timeline.shrink(bezier); - break; - } - var time2 = getValue(nextMap, "time", 0); - var newColor = Color.fromString(nextMap.light); - var newColor2 = Color.fromString(nextMap.dark); - var curve = keyMap.curve; - if (curve) { - bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); - bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); - bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); - bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1); - bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.r, newColor2.r, 1); - bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.g, newColor2.g, 1); - bezier = readCurve(curve, timeline, bezier, frame, 6, time, time2, color2.b, newColor2.b, 1); - } - time = time2; - color = newColor; - color2 = newColor2; - keyMap = nextMap; - } - timelines.push(timeline); - } - else if (timelineName == "rgb2") { - var timeline = new RGB2Timeline(frames_1, frames_1 * 6, slotIndex); - var keyMap = timelineMap[0]; - var time = getValue(keyMap, "time", 0); - var color = Color.fromString(keyMap.light); - var color2 = Color.fromString(keyMap.dark); - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, color.r, color.g, color.b, color2.r, color2.g, color2.b); - var nextMap = timelineMap[frame + 1]; - if (!nextMap) { - timeline.shrink(bezier); - break; - } - var time2 = getValue(nextMap, "time", 0); - var newColor = Color.fromString(nextMap.light); - var newColor2 = Color.fromString(nextMap.dark); - var curve = keyMap.curve; - if (curve) { - bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); - bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); - bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); - bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color2.r, newColor2.r, 1); - bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.g, newColor2.g, 1); - bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.b, newColor2.b, 1); - } - time = time2; - color = newColor; - color2 = newColor2; - keyMap = nextMap; - } - timelines.push(timeline); - } - } - } - } - // Bone timelines. - if (map.bones) { - for (var boneName in map.bones) { - var boneMap = map.bones[boneName]; - var bone = skeletonData.findBone(boneName); - if (!bone) - throw new Error("Bone not found: " + boneName); - var boneIndex = bone.index; - for (var timelineName in boneMap) { - var timelineMap = boneMap[timelineName]; - var frames_2 = timelineMap.length; - if (frames_2 == 0) - continue; - if (timelineName === "rotate") { - timelines.push(readTimeline1(timelineMap, new RotateTimeline(frames_2, frames_2, boneIndex), 0, 1)); - } - else if (timelineName === "translate") { - var timeline = new TranslateTimeline(frames_2, frames_2 << 1, boneIndex); - timelines.push(readTimeline2(timelineMap, timeline, "x", "y", 0, scale)); - } - else if (timelineName === "translatex") { - var timeline = new TranslateXTimeline(frames_2, frames_2, boneIndex); - timelines.push(readTimeline1(timelineMap, timeline, 0, scale)); - } - else if (timelineName === "translatey") { - var timeline = new TranslateYTimeline(frames_2, frames_2, boneIndex); - timelines.push(readTimeline1(timelineMap, timeline, 0, scale)); - } - else if (timelineName === "scale") { - var timeline = new ScaleTimeline(frames_2, frames_2 << 1, boneIndex); - timelines.push(readTimeline2(timelineMap, timeline, "x", "y", 1, 1)); - } - else if (timelineName === "scalex") { - var timeline = new ScaleXTimeline(frames_2, frames_2, boneIndex); - timelines.push(readTimeline1(timelineMap, timeline, 1, 1)); - } - else if (timelineName === "scaley") { - var timeline = new ScaleYTimeline(frames_2, frames_2, boneIndex); - timelines.push(readTimeline1(timelineMap, timeline, 1, 1)); - } - else if (timelineName === "shear") { - var timeline = new ShearTimeline(frames_2, frames_2 << 1, boneIndex); - timelines.push(readTimeline2(timelineMap, timeline, "x", "y", 0, 1)); - } - else if (timelineName === "shearx") { - var timeline = new ShearXTimeline(frames_2, frames_2, boneIndex); - timelines.push(readTimeline1(timelineMap, timeline, 0, 1)); - } - else if (timelineName === "sheary") { - var timeline = new ShearYTimeline(frames_2, frames_2, boneIndex); - timelines.push(readTimeline1(timelineMap, timeline, 0, 1)); - } - } - } - } - // IK constraint timelines. - if (map.ik) { - for (var constraintName in map.ik) { - var constraintMap = map.ik[constraintName]; - var keyMap = constraintMap[0]; - if (!keyMap) - continue; - var constraint = skeletonData.findIkConstraint(constraintName); - if (!constraint) - throw new Error("IK Constraint not found: " + constraintName); - var constraintIndex = skeletonData.ikConstraints.indexOf(constraint); - var timeline = new IkConstraintTimeline(constraintMap.length, constraintMap.length << 1, constraintIndex); - var time = getValue(keyMap, "time", 0); - var mix = getValue(keyMap, "mix", 1); - var softness = getValue(keyMap, "softness", 0) * scale; - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, mix, softness, getValue(keyMap, "bendPositive", true) ? 1 : -1, getValue(keyMap, "compress", false), getValue(keyMap, "stretch", false)); - var nextMap = constraintMap[frame + 1]; - if (!nextMap) { - timeline.shrink(bezier); - break; - } - var time2 = getValue(nextMap, "time", 0); - var mix2 = getValue(nextMap, "mix", 1); - var softness2 = getValue(nextMap, "softness", 0) * scale; - var curve = keyMap.curve; - if (curve) { - bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mix, mix2, 1); - bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, softness, softness2, scale); - } - time = time2; - mix = mix2; - softness = softness2; - keyMap = nextMap; - } - timelines.push(timeline); - } - } - // Transform constraint timelines. - if (map.transform) { - for (var constraintName in map.transform) { - var timelineMap = map.transform[constraintName]; - var keyMap = timelineMap[0]; - if (!keyMap) - continue; - var constraint = skeletonData.findTransformConstraint(constraintName); - if (!constraint) - throw new Error("Transform constraint not found: " + constraintName); - var constraintIndex = skeletonData.transformConstraints.indexOf(constraint); - var timeline = new TransformConstraintTimeline(timelineMap.length, timelineMap.length * 6, constraintIndex); - var time = getValue(keyMap, "time", 0); - var mixRotate = getValue(keyMap, "mixRotate", 1); - var mixX = getValue(keyMap, "mixX", 1); - var mixY = getValue(keyMap, "mixY", mixX); - var mixScaleX = getValue(keyMap, "mixScaleX", 1); - var mixScaleY = getValue(keyMap, "mixScaleY", mixScaleX); - var mixShearY = getValue(keyMap, "mixShearY", 1); - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY); - var nextMap = timelineMap[frame + 1]; - if (!nextMap) { - timeline.shrink(bezier); - break; - } - var time2 = getValue(nextMap, "time", 0); - var mixRotate2 = getValue(nextMap, "mixRotate", 1); - var mixX2 = getValue(nextMap, "mixX", 1); - var mixY2 = getValue(nextMap, "mixY", mixX2); - var mixScaleX2 = getValue(nextMap, "mixScaleX", 1); - var mixScaleY2 = getValue(nextMap, "mixScaleY", mixScaleX2); - var mixShearY2 = getValue(nextMap, "mixShearY", 1); - var curve = keyMap.curve; - if (curve) { - bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1); - bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1); - bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1); - bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, mixScaleX, mixScaleX2, 1); - bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, mixScaleY, mixScaleY2, 1); - bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, mixShearY, mixShearY2, 1); - } - time = time2; - mixRotate = mixRotate2; - mixX = mixX2; - mixY = mixY2; - mixScaleX = mixScaleX2; - mixScaleY = mixScaleY2; - mixScaleX = mixScaleX2; - keyMap = nextMap; - } - timelines.push(timeline); - } - } - // Path constraint timelines. - if (map.path) { - for (var constraintName in map.path) { - var constraintMap = map.path[constraintName]; - var constraint = skeletonData.findPathConstraint(constraintName); - if (!constraint) - throw new Error("Path constraint not found: " + constraintName); - var constraintIndex = skeletonData.pathConstraints.indexOf(constraint); - for (var timelineName in constraintMap) { - var timelineMap = constraintMap[timelineName]; - var keyMap = timelineMap[0]; - if (!keyMap) - continue; - var frames_3 = timelineMap.length; - if (timelineName === "position") { - var timeline = new PathConstraintPositionTimeline(frames_3, frames_3, constraintIndex); - timelines.push(readTimeline1(timelineMap, timeline, 0, constraint.positionMode == exports.PositionMode.Fixed ? scale : 1)); - } - else if (timelineName === "spacing") { - var timeline = new PathConstraintSpacingTimeline(frames_3, frames_3, constraintIndex); - timelines.push(readTimeline1(timelineMap, timeline, 0, constraint.spacingMode == SpacingMode.Length || constraint.spacingMode == SpacingMode.Fixed ? scale : 1)); - } - else if (timelineName === "mix") { - var timeline = new PathConstraintMixTimeline(frames_3, frames_3 * 3, constraintIndex); - var time = getValue(keyMap, "time", 0); - var mixRotate = getValue(keyMap, "mixRotate", 1); - var mixX = getValue(keyMap, "mixX", 1); - var mixY = getValue(keyMap, "mixY", mixX); - for (var frame = 0, bezier = 0;; frame++) { - timeline.setFrame(frame, time, mixRotate, mixX, mixY); - var nextMap = timelineMap[frame + 1]; - if (!nextMap) { - timeline.shrink(bezier); - break; - } - var time2 = getValue(nextMap, "time", 0); - var mixRotate2 = getValue(nextMap, "mixRotate", 1); - var mixX2 = getValue(nextMap, "mixX", 1); - var mixY2 = getValue(nextMap, "mixY", mixX2); - var curve = keyMap.curve; - if (curve) { - bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1); - bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1); - bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1); - } - time = time2; - mixRotate = mixRotate2; - mixX = mixX2; - mixY = mixY2; - keyMap = nextMap; - } - timelines.push(timeline); - } - } - } - } - // ver40 compatibility - if (map.deform) { - map.attachments = {}; - for (var deformName in map.deform) { - var deformMap = map.deform[deformName]; - var outMap = map.attachments[deformName] = {}; - for (var slotName in deformMap) { - var slotMap = deformMap[slotName]; - var outMap2 = outMap[slotName] = {}; - for (var innerMapName in slotMap) { - outMap2[innerMapName] = { - deform: slotMap[innerMapName] - }; - } - } - } - } - // Attachment timelines. - if (map.attachments) { - for (var attachmentsName in map.attachments) { - var attachmentsMap = map.attachments[attachmentsName]; - var skin = skeletonData.findSkin(attachmentsName); - if (skin == null) { - if (settings.FAIL_ON_NON_EXISTING_SKIN) { - throw new Error("Skin not found: " + attachmentsName); - } - else { - continue; - } - } - for (var slotMapName in attachmentsMap) { - var slotMap = attachmentsMap[slotMapName]; - var slot = skeletonData.findSlot(slotMapName); - if (!slot) - throw new Error("Slot not found: " + slotMapName); - var slotIndex = slot.index; - for (var attachmentMapName in slotMap) { - var attachmentMap = slotMap[attachmentMapName]; - var attachment = skin.getAttachment(slotIndex, attachmentMapName); - for (var timelineMapName in attachmentMap) { - var timelineMap = attachmentMap[timelineMapName]; - var keyMap = timelineMap[0]; - if (!keyMap) - continue; - if (timelineMapName == "deform") { - var weighted = attachment.bones; - var vertices = attachment.vertices; - var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; - var timeline = new DeformTimeline(timelineMap.length, timelineMap.length, slotIndex, attachment); - var time = getValue(keyMap, "time", 0); - for (var frame = 0, bezier = 0;; frame++) { - var deform = void 0; - var verticesValue = getValue(keyMap, "vertices", null); - if (!verticesValue) - deform = weighted ? Utils.newFloatArray(deformLength) : vertices; - else { - deform = Utils.newFloatArray(deformLength); - var start = getValue(keyMap, "offset", 0); - Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); - if (scale != 1) { - for (var i = start, n = i + verticesValue.length; i < n; i++) - deform[i] *= scale; - } - if (!weighted) { - for (var i = 0; i < deformLength; i++) - deform[i] += vertices[i]; - } - } - timeline.setFrame(frame, time, deform); - var nextMap = timelineMap[frame + 1]; - if (!nextMap) { - timeline.shrink(bezier); - break; - } - var time2 = getValue(nextMap, "time", 0); - var curve = keyMap.curve; - if (curve) - bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1); - time = time2; - keyMap = nextMap; - } - timelines.push(timeline); - } - else if (timelineMapName == "sequence") { - var timeline = new SequenceTimeline(timelineMap.length, slotIndex, attachment); - var lastDelay = 0; - for (var frame = 0; frame < timelineMap.length; frame++) { - var delay = getValue(keyMap, "delay", lastDelay); - var time = getValue(keyMap, "time", 0); - var mode = SequenceMode[getValue(keyMap, "mode", "hold")]; - var index = getValue(keyMap, "index", 0); - timeline.setFrame(frame, time, mode, index, delay); - lastDelay = delay; - keyMap = timelineMap[frame + 1]; - } - timelines.push(timeline); - } - } - } - } - } - } - // Draw order timelines. - if (map.drawOrder) { - var timeline = new DrawOrderTimeline(map.drawOrder.length); - var slotCount = skeletonData.slots.length; - var frame = 0; - for (var i = 0; i < map.drawOrder.length; i++, frame++) { - var drawOrderMap = map.drawOrder[i]; - var drawOrder = null; - var offsets = getValue(drawOrderMap, "offsets", null); - if (offsets) { - drawOrder = Utils.newArray(slotCount, -1); - var unchanged = Utils.newArray(slotCount - offsets.length, 0); - var originalIndex = 0, unchangedIndex = 0; - for (var ii = 0; ii < offsets.length; ii++) { - var offsetMap = offsets[ii]; - var slot = skeletonData.findSlot(offsetMap.slot); - if (!slot) - throw new Error("Slot not found: " + slot); - var slotIndex = slot.index; - // Collect unchanged items. - while (originalIndex != slotIndex) - unchanged[unchangedIndex++] = originalIndex++; - // Set changed items. - drawOrder[originalIndex + offsetMap.offset] = originalIndex++; - } - // Collect remaining unchanged items. - while (originalIndex < slotCount) - unchanged[unchangedIndex++] = originalIndex++; - // Fill in unchanged items. - for (var ii = slotCount - 1; ii >= 0; ii--) - if (drawOrder[ii] == -1) - drawOrder[ii] = unchanged[--unchangedIndex]; - } - timeline.setFrame(frame, getValue(drawOrderMap, "time", 0), drawOrder); - } - timelines.push(timeline); - } - // Event timelines. - if (map.events) { - var timeline = new EventTimeline(map.events.length); - var frame = 0; - for (var i = 0; i < map.events.length; i++, frame++) { - var eventMap = map.events[i]; - var eventData = skeletonData.findEvent(eventMap.name); - if (!eventData) - throw new Error("Event not found: " + eventMap.name); - var event_1 = new Event(Utils.toSinglePrecision(getValue(eventMap, "time", 0)), eventData); - event_1.intValue = getValue(eventMap, "int", eventData.intValue); - event_1.floatValue = getValue(eventMap, "float", eventData.floatValue); - event_1.stringValue = getValue(eventMap, "string", eventData.stringValue); - if (event_1.data.audioPath) { - event_1.volume = getValue(eventMap, "volume", 1); - event_1.balance = getValue(eventMap, "balance", 0); - } - timeline.setFrame(frame, event_1); - } - timelines.push(timeline); - } - var duration = 0; - for (var i = 0, n = timelines.length; i < n; i++) - duration = Math.max(duration, timelines[i].getDuration()); - if (isNaN(duration)) { - throw new Error("Error while parsing animation, duration is NaN"); - } - skeletonData.animations.push(new Animation(name, timelines, duration)); - }; - SkeletonJson.blendModeFromString = function (str) { - str = str.toLowerCase(); - if (str == "normal") - return constants.BLEND_MODES.NORMAL; - if (str == "additive") - return constants.BLEND_MODES.ADD; - if (str == "multiply") - return constants.BLEND_MODES.MULTIPLY; - if (str == "screen") - return constants.BLEND_MODES.SCREEN; - throw new Error("Unknown blend mode: " + str); - }; - return SkeletonJson; - }()); - var LinkedMesh = /** @class */ (function () { - function LinkedMesh(mesh, skin, slotIndex, parent, inheritDeform) { - this.mesh = mesh; - this.skin = skin; - this.slotIndex = slotIndex; - this.parent = parent; - this.inheritTimeline = inheritDeform; - } - return LinkedMesh; - }()); - function readTimeline1(keys, timeline, defaultValue, scale) { - var keyMap = keys[0]; - var time = getValue(keyMap, "time", 0); - var value = getValue(keyMap, "value", defaultValue) * scale; - var bezier = 0; - for (var frame = 0;; frame++) { - timeline.setFrame(frame, time, value); - var nextMap = keys[frame + 1]; - if (!nextMap) { - timeline.shrink(bezier); - return timeline; - } - var time2 = getValue(nextMap, "time", 0); - var value2 = getValue(nextMap, "value", defaultValue) * scale; - if (keyMap.curve) - bezier = readCurve(keyMap.curve, timeline, bezier, frame, 0, time, time2, value, value2, scale); - time = time2; - value = value2; - keyMap = nextMap; - } - } - function readTimeline2(keys, timeline, name1, name2, defaultValue, scale) { - var keyMap = keys[0]; - var time = getValue(keyMap, "time", 0); - var value1 = getValue(keyMap, name1, defaultValue) * scale; - var value2 = getValue(keyMap, name2, defaultValue) * scale; - var bezier = 0; - for (var frame = 0;; frame++) { - timeline.setFrame(frame, time, value1, value2); - var nextMap = keys[frame + 1]; - if (!nextMap) { - timeline.shrink(bezier); - return timeline; - } - var time2 = getValue(nextMap, "time", 0); - var nvalue1 = getValue(nextMap, name1, defaultValue) * scale; - var nvalue2 = getValue(nextMap, name2, defaultValue) * scale; - var curve = keyMap.curve; - if (curve) { - bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value1, nvalue1, scale); - bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, value2, nvalue2, scale); - } - time = time2; - value1 = nvalue1; - value2 = nvalue2; - keyMap = nextMap; - } - } - function readCurve(curve, timeline, bezier, frame, value, time1, time2, value1, value2, scale) { - if (curve == "stepped") { - timeline.setStepped(frame); - return bezier; - } - var i = value << 2; - var cx1 = curve[i]; - var cy1 = curve[i + 1] * scale; - var cx2 = curve[i + 2]; - var cy2 = curve[i + 3] * scale; - timeline.setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2); - return bezier + 1; - } - function getValue(map, property, defaultValue) { - return map[property] !== undefined ? map[property] : defaultValue; - } - - /** - * @public - */ - var Spine$1 = /** @class */ (function (_super) { - __extends$1(Spine, _super); - function Spine() { - return _super !== null && _super.apply(this, arguments) || this; - } - Spine.prototype.createSkeleton = function (spineData) { - this.skeleton = new Skeleton(spineData); - this.skeleton.updateWorldTransform(); - this.stateData = new AnimationStateData(spineData); - this.state = new AnimationState(this.stateData); - }; - return Spine; - }(SpineBase)); - - var spine41 = /*#__PURE__*/Object.freeze({ - __proto__: null, - AlphaTimeline: AlphaTimeline, - Animation: Animation, - AnimationState: AnimationState, - AnimationStateAdapter: AnimationStateAdapter, - AnimationStateData: AnimationStateData, - AtlasAttachmentLoader: AtlasAttachmentLoader, - Attachment: Attachment, - AttachmentTimeline: AttachmentTimeline, - Bone: Bone, - BoneData: BoneData, - BoundingBoxAttachment: BoundingBoxAttachment, - ClippingAttachment: ClippingAttachment, - ConstraintData: ConstraintData, - CurveTimeline: CurveTimeline, - CurveTimeline1: CurveTimeline1, - CurveTimeline2: CurveTimeline2, - DeformTimeline: DeformTimeline, - DrawOrderTimeline: DrawOrderTimeline, - Event: Event, - EventData: EventData, - EventQueue: EventQueue, - EventTimeline: EventTimeline, - get EventType () { return EventType; }, - IkConstraint: IkConstraint, - IkConstraintData: IkConstraintData, - IkConstraintTimeline: IkConstraintTimeline, - MeshAttachment: MeshAttachment, - PathAttachment: PathAttachment, - PathConstraint: PathConstraint, - PathConstraintData: PathConstraintData, - PathConstraintMixTimeline: PathConstraintMixTimeline, - PathConstraintPositionTimeline: PathConstraintPositionTimeline, - PathConstraintSpacingTimeline: PathConstraintSpacingTimeline, - PointAttachment: PointAttachment, - RGB2Timeline: RGB2Timeline, - RGBA2Timeline: RGBA2Timeline, - RGBATimeline: RGBATimeline, - RGBTimeline: RGBTimeline, - RegionAttachment: RegionAttachment, - RotateTimeline: RotateTimeline, - ScaleTimeline: ScaleTimeline, - ScaleXTimeline: ScaleXTimeline, - ScaleYTimeline: ScaleYTimeline, - Sequence: Sequence, - get SequenceMode () { return SequenceMode; }, - SequenceModeValues: SequenceModeValues, - SequenceTimeline: SequenceTimeline, - ShearTimeline: ShearTimeline, - ShearXTimeline: ShearXTimeline, - ShearYTimeline: ShearYTimeline, - Skeleton: Skeleton, - SkeletonBinary: SkeletonBinary, - SkeletonBounds: SkeletonBounds, - SkeletonData: SkeletonData, - SkeletonJson: SkeletonJson, - Skin: Skin, - SkinEntry: SkinEntry, - Slot: Slot, - SlotData: SlotData, - get SpacingMode () { return SpacingMode; }, - Spine: Spine$1, - Timeline: Timeline, - TrackEntry: TrackEntry, - TransformConstraint: TransformConstraint, - TransformConstraintData: TransformConstraintData, - TransformConstraintTimeline: TransformConstraintTimeline, - TranslateTimeline: TranslateTimeline, - TranslateXTimeline: TranslateXTimeline, - TranslateYTimeline: TranslateYTimeline, - VertexAttachment: VertexAttachment - }); - - /* eslint-disable */ - - /*! ***************************************************************************** - Copyright (c) Microsoft Corporation. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. - ***************************************************************************** */ - /* global Reflect, Promise */ - - var extendStatics = function(d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - - function __extends(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - } - - /** - * @public - */ - var SPINE_VERSION; - (function (SPINE_VERSION) { - SPINE_VERSION[SPINE_VERSION["UNKNOWN"] = 0] = "UNKNOWN"; - SPINE_VERSION[SPINE_VERSION["VER37"] = 37] = "VER37"; - SPINE_VERSION[SPINE_VERSION["VER38"] = 38] = "VER38"; - SPINE_VERSION[SPINE_VERSION["VER40"] = 40] = "VER40"; - SPINE_VERSION[SPINE_VERSION["VER41"] = 41] = "VER41"; - })(SPINE_VERSION || (SPINE_VERSION = {})); - /** - * @public - */ - function detectSpineVersion(version) { - var ver3 = version.substr(0, 3); - var verNum = Math.floor(+ver3 * 10 + 1e-3); - if (ver3 === '3.7') { - return SPINE_VERSION.VER37; - } - if (ver3 === '3.8') { - return SPINE_VERSION.VER38; - } - if (ver3 === '4.0') { - return SPINE_VERSION.VER40; - } - if (ver3 === '4.1') { - return SPINE_VERSION.VER41; - } - // try parse old versions with 3.7 - if (verNum < SPINE_VERSION.VER37) { - return SPINE_VERSION.VER37; - } - return SPINE_VERSION.UNKNOWN; - } - - var UniBinaryParser = /** @class */ (function () { - function UniBinaryParser() { - this.scale = 1; - } - UniBinaryParser.prototype.readSkeletonData = function (atlas, dataToParse) { - var parser = null; - var version = this.readVersionOldFormat(dataToParse); - var ver = detectSpineVersion(version); - if (ver === SPINE_VERSION.VER38) { - parser = new SkeletonBinary$1(new AtlasAttachmentLoader$2(atlas)); - } - version = this.readVersionNewFormat(dataToParse); - ver = detectSpineVersion(version); - if (ver === SPINE_VERSION.VER40 || ver === SPINE_VERSION.VER41) { - parser = new SkeletonBinary(new AtlasAttachmentLoader(atlas)); - } - if (!parser) { - var error = "Unsupported version of spine model " + version + ", please update pixi-spine"; - console.error(error); - } - parser.scale = this.scale; - return parser.readSkeletonData(dataToParse); - }; - UniBinaryParser.prototype.readVersionOldFormat = function (dataToParse) { - var input = new BinaryInput(dataToParse); - var version; - try { - input.readString(); - version = input.readString(); - } - catch (e) { - version = ""; - } - return version || ""; - }; - UniBinaryParser.prototype.readVersionNewFormat = function (dataToParse) { - var input = new BinaryInput(dataToParse); - input.readInt32(); - input.readInt32(); - var version; - try { - version = input.readString(); - } - catch (e) { - version = ""; - } - return version || ""; - }; - return UniBinaryParser; - }()); - var UniJsonParser = /** @class */ (function () { - function UniJsonParser() { - this.scale = 1; - } - UniJsonParser.prototype.readSkeletonData = function (atlas, dataToParse) { - var version = dataToParse.skeleton.spine; - var ver = detectSpineVersion(version); - var parser = null; - if (ver === SPINE_VERSION.VER37) { - parser = new SkeletonJson$1(new AtlasAttachmentLoader$1(atlas)); - } - if (ver === SPINE_VERSION.VER38) { - parser = new SkeletonJson$2(new AtlasAttachmentLoader$2(atlas)); - } - if (ver === SPINE_VERSION.VER40 || ver === SPINE_VERSION.VER41) { - parser = new SkeletonJson(new AtlasAttachmentLoader(atlas)); - } - if (!parser) { - var error = "Unsupported version of spine model " + version + ", please update pixi-spine"; - console.error(error); - } - parser.scale = this.scale; - return parser.readSkeletonData(dataToParse); - }; - return UniJsonParser; - }()); - /** - * @public - */ - var SpineParser = /** @class */ (function (_super) { - __extends(SpineParser, _super); - function SpineParser() { - return _super !== null && _super.apply(this, arguments) || this; - } - SpineParser.prototype.createBinaryParser = function () { - return new UniBinaryParser(); - }; - SpineParser.prototype.createJsonParser = function () { - return new UniJsonParser(); - }; - SpineParser.prototype.parseData = function (resource, parser, atlas, dataToParse) { - var parserCast = parser; - resource.spineData = parserCast.readSkeletonData(atlas, dataToParse); - resource.spineAtlas = atlas; - }; - SpineParser.registerLoaderPlugin = function () { - loaders.Loader.registerPlugin(SpineParser); - }; - SpineParser.use = new SpineParser().genMiddleware().use; - return SpineParser; - }(AbstractSpineParser)); - - /** - * @public - */ - var Spine = /** @class */ (function (_super) { - __extends(Spine, _super); - function Spine() { - return _super !== null && _super.apply(this, arguments) || this; - } - Spine.prototype.createSkeleton = function (spineData) { - var ver = detectSpineVersion(spineData.version); - var spine = null; - if (ver === SPINE_VERSION.VER37) { - spine = spine37; - } - if (ver === SPINE_VERSION.VER38) { - spine = spine38; - } - if (ver === SPINE_VERSION.VER40 || ver === SPINE_VERSION.VER41) { - spine = spine41; - } - if (!spine) { - var error = "Cant detect version of spine model " + spineData.version; - console.error(error); - } - this.skeleton = new spine.Skeleton(spineData); - this.skeleton.updateWorldTransform(); - this.stateData = new spine.AnimationStateData(spineData); - this.state = new spine.AnimationState(this.stateData); - }; - return Spine; - }(SpineBase)); - - SpineParser.registerLoaderPlugin(); - - exports.BinaryInput = BinaryInput; - exports.Color = Color; - exports.DebugUtils = DebugUtils; - exports.IntSet = IntSet; - exports.Interpolation = Interpolation; - exports.MathUtils = MathUtils; - exports.Pool = Pool; - exports.Pow = Pow; - exports.PowOut = PowOut; - exports.SkeletonBounds = SkeletonBounds; - exports.SkeletonBoundsBase = SkeletonBoundsBase; - exports.Spine = Spine; - exports.SpineBase = SpineBase; - exports.SpineDebugRenderer = SpineDebugRenderer; - exports.SpineMesh = SpineMesh; - exports.SpineParser = SpineParser; - exports.SpineSprite = SpineSprite; - exports.StringSet = StringSet; - exports.TextureAtlas = TextureAtlas; - exports.TextureAtlasPage = TextureAtlasPage; - exports.TextureAtlasRegion = TextureAtlasRegion; - exports.TextureRegion = TextureRegion; - exports.TimeKeeper = TimeKeeper; - exports.Utils = Utils; - exports.Vector2 = Vector2; - exports.WindowedMean = WindowedMean; - exports.filterFromString = filterFromString; - exports.settings = settings; - exports.wrapFromString = wrapFromString; - - Object.defineProperty(exports, '__esModule', { value: true }); - -})); -if (typeof pixi_spine !== 'undefined') { Object.assign(this.PIXI.spine, pixi_spine); } -var GlobalPIXIModule = Object.assign(GlobalPIXIModule || {}, { PIXI_SPINE: this.PIXI.spine }); -//# sourceMappingURL=pixi-spine.umd.js.map +/*! + * pixi-spine - v4.0.4 + * Compiled Thu, 25 May 2023 20:30:28 UTC + * + * pixi-spine is licensed under the MIT License. + * http://www.opensource.org/licenses/mit-license + * + * Copyright 2023, Ivan Igorevich Popelyshev , All Rights Reserved +*/this.PIXI=this.PIXI||{},this.PIXI.spine=function(tt,H,dn,wr,br,oe,qe){"use strict";var Z=(c=>(c[c.Region=0]="Region",c[c.BoundingBox=1]="BoundingBox",c[c.Mesh=2]="Mesh",c[c.LinkedMesh=3]="LinkedMesh",c[c.Path=4]="Path",c[c.Point=5]="Point",c[c.Clipping=6]="Clipping",c))(Z||{});class Mn{constructor(t,n=new Array,e=0,i=new DataView(t.buffer)){this.strings=n,this.index=e,this.buffer=i}readByte(){return this.buffer.getInt8(this.index++)}readUnsignedByte(){return this.buffer.getUint8(this.index++)}readShort(){const t=this.buffer.getInt16(this.index);return this.index+=2,t}readInt32(){const t=this.buffer.getInt32(this.index);return this.index+=4,t}readInt(t){let n=this.readByte(),e=n&127;return n&128&&(n=this.readByte(),e|=(n&127)<<7,n&128&&(n=this.readByte(),e|=(n&127)<<14,n&128&&(n=this.readByte(),e|=(n&127)<<21,n&128&&(n=this.readByte(),e|=(n&127)<<28)))),t?e:e>>>1^-(e&1)}readStringRef(){const t=this.readInt(!0);return t==0?null:this.strings[t-1]}readString(){let t=this.readInt(!0);switch(t){case 0:return null;case 1:return""}t--;let n="";for(let e=0;e>4){case 12:case 13:n+=String.fromCharCode((i&31)<<6|this.readByte()&63),e+=2;break;case 14:n+=String.fromCharCode((i&15)<<12|(this.readByte()&63)<<6|this.readByte()&63),e+=3;break;default:n+=String.fromCharCode(i),e++}}return n}readFloat(){const t=this.buffer.getFloat32(this.index);return this.index+=4,t}readBoolean(){return this.readByte()!=0}}var A=(c=>(c[c.setup=0]="setup",c[c.first=1]="first",c[c.replace=2]="replace",c[c.add=3]="add",c))(A||{}),J=(c=>(c[c.mixIn=0]="mixIn",c[c.mixOut=1]="mixOut",c))(J||{}),dt=(c=>(c[c.Fixed=0]="Fixed",c[c.Percent=1]="Percent",c))(dt||{}),pt=(c=>(c[c.Tangent=0]="Tangent",c[c.Chain=1]="Chain",c[c.ChainScale=2]="ChainScale",c))(pt||{}),j=(c=>(c[c.Normal=0]="Normal",c[c.OnlyTranslation=1]="OnlyTranslation",c[c.NoRotationOrReflection=2]="NoRotationOrReflection",c[c.NoScale=3]="NoScale",c[c.NoScaleOrReflection=4]="NoScaleOrReflection",c))(j||{});function Jn(c){switch(c.toLowerCase()){case"nearest":return Bt.Nearest;case"linear":return Bt.Linear;case"mipmap":return Bt.MipMap;case"mipmapnearestnearest":return Bt.MipMapNearestNearest;case"mipmaplinearnearest":return Bt.MipMapLinearNearest;case"mipmapnearestlinear":return Bt.MipMapNearestLinear;case"mipmaplinearlinear":return Bt.MipMapLinearLinear;default:throw new Error(`Unknown texture filter ${c}`)}}function Er(c){switch(c.toLowerCase()){case"mirroredtepeat":return fe.MirroredRepeat;case"clamptoedge":return fe.ClampToEdge;case"repeat":return fe.Repeat;default:throw new Error(`Unknown texture wrap ${c}`)}}var Bt=(c=>(c[c.Nearest=9728]="Nearest",c[c.Linear=9729]="Linear",c[c.MipMap=9987]="MipMap",c[c.MipMapNearestNearest=9984]="MipMapNearestNearest",c[c.MipMapLinearNearest=9985]="MipMapLinearNearest",c[c.MipMapNearestLinear=9986]="MipMapNearestLinear",c[c.MipMapLinearLinear=9987]="MipMapLinearLinear",c))(Bt||{}),fe=(c=>(c[c.MirroredRepeat=33648]="MirroredRepeat",c[c.ClampToEdge=33071]="ClampToEdge",c[c.Repeat=10497]="Repeat",c))(fe||{});class Vn{constructor(){this.size=null,this.names=null,this.values=null,this.renderObject=null}get width(){const t=this.texture;return t.trim?t.trim.width:t.orig.width}get height(){const t=this.texture;return t.trim?t.trim.height:t.orig.height}get u(){return this.texture._uvs.x0}get v(){return this.texture._uvs.y0}get u2(){return this.texture._uvs.x2}get v2(){return this.texture._uvs.y2}get offsetX(){const t=this.texture;return t.trim?t.trim.x:0}get offsetY(){return this.spineOffsetY}get pixiOffsetY(){const t=this.texture;return t.trim?t.trim.y:0}get spineOffsetY(){const t=this.texture;return this.originalHeight-this.height-(t.trim?t.trim.y:0)}get originalWidth(){return this.texture.orig.width}get originalHeight(){return this.texture.orig.height}get x(){return this.texture.frame.x}get y(){return this.texture.frame.y}get rotate(){return this.texture.rotate!==0}get degrees(){return(360-this.texture.rotate*45)%360}}class Sr{constructor(){this.x=0,this.y=0,this.width=0,this.height=0,this.offsetX=0,this.offsetY=0,this.originalWidth=0,this.originalHeight=0,this.rotate=0,this.index=0}}class Fn{constructor(t,n,e){this.pages=new Array,this.regions=new Array,t&&this.addSpineAtlas(t,n,e)}addTexture(t,n){const e=this.pages;let i=null;for(let h=0;h{h.width=parseInt(r[1]),h.height=parseInt(r[2])},l.format=()=>{},l.filter=()=>{h.minFilter=Jn(r[1]),h.magFilter=Jn(r[2])},l.repeat=()=>{r[1].indexOf("x")!=-1&&(h.uWrap=fe.Repeat),r[1].indexOf("y")!=-1&&(h.vWrap=fe.Repeat)},l.pma=()=>{h.pma=r[1]=="true"};const a={};a.xy=()=>{s.x=parseInt(r[1]),s.y=parseInt(r[2])},a.size=()=>{s.width=parseInt(r[1]),s.height=parseInt(r[2])},a.bounds=()=>{s.x=parseInt(r[1]),s.y=parseInt(r[2]),s.width=parseInt(r[3]),s.height=parseInt(r[4])},a.offset=()=>{s.offsetX=parseInt(r[1]),s.offsetY=parseInt(r[2])},a.orig=()=>{s.originalWidth=parseInt(r[1]),s.originalHeight=parseInt(r[2])},a.offsets=()=>{s.offsetX=parseInt(r[1]),s.offsetY=parseInt(r[2]),s.originalWidth=parseInt(r[3]),s.originalHeight=parseInt(r[4])},a.rotate=()=>{const f=r[1];let u=0;f.toLocaleLowerCase()=="true"?u=6:f.toLocaleLowerCase()=="false"?u=0:u=(720-parseFloat(f))%360/45,s.rotate=u},a.index=()=>{s.index=parseInt(r[1])};let o=i.readLine();for(;o!=null&&o.trim().length==0;)o=i.readLine();for(;!(o==null||o.trim().length==0||i.readEntry(r,o)==0);)o=i.readLine();const d=()=>{for(;;){if(o==null)return e&&e(this);if(o.trim().length==0)h=null,o=i.readLine();else if(h===null){for(h=new ts,h.name=o.trim();i.readEntry(r,o=i.readLine())!=0;){const f=l[r[0]];f&&f()}this.pages.push(h),n(h.name,f=>{if(f===null)return this.pages.splice(this.pages.indexOf(h),1),e&&e(null);h.baseTexture=f,h.pma&&(f.alphaMode=H.ALPHA_MODES.PMA),f.valid||f.setSize(h.width,h.height),h.setFilters(),(!h.width||!h.height)&&(h.width=f.realWidth,h.height=f.realHeight,(!h.width||!h.height)&&console.log(`ERROR spine atlas page ${h.name}: meshes wont work if you dont specify size in atlas (http://www.html5gamedevs.com/topic/18888-pixi-spines-and-meshes/?p=107121)`)),d()});break}else{s=new Sr;const f=new es;f.name=o,f.page=h;let u=null,m=null;for(;;){const p=i.readEntry(r,o=i.readLine());if(p==0)break;const S=a[r[0]];if(S)S();else{u==null&&(u=[],m=[]),u.push(r[0]);const y=[];for(let M=0;M=this.lines.length?null:this.lines[this.index++]}readEntry(t,n){if(n==null||(n=n.trim(),n.length==0))return 0;const e=n.indexOf(":");if(e==-1)return 0;t[0]=n.substr(0,e).trim();for(let i=1,r=e+1;;i++){const h=n.indexOf(",",r);if(h==-1)return t[i]=n.substr(r).trim(),i;if(t[i]=n.substr(r,h-r).trim(),r=h+1,i==4)return 4}}}class ts{constructor(){this.minFilter=Bt.Nearest,this.magFilter=Bt.Nearest,this.uWrap=fe.ClampToEdge,this.vWrap=fe.ClampToEdge}setFilters(){const t=this.baseTexture,n=this.minFilter;n==Bt.Linear?t.scaleMode=H.SCALE_MODES.LINEAR:this.minFilter==Bt.Nearest?t.scaleMode=H.SCALE_MODES.NEAREST:(t.mipmap=H.MIPMAP_MODES.POW2,n==Bt.MipMapNearestNearest?t.scaleMode=H.SCALE_MODES.NEAREST:t.scaleMode=H.SCALE_MODES.LINEAR)}}class es extends Vn{}class ns{constructor(){this.array=new Array}add(t){const n=this.contains(t);return this.array[t|0]=t|0,!n}contains(t){return this.array[t|0]!=null}remove(t){this.array[t|0]=void 0}clear(){this.array.length=0}}class ss{constructor(){this.entries={},this.size=0}add(t){const n=this.entries[t];return this.entries[t]=!0,n?!1:(this.size++,!0)}addAll(t){const n=this.size;for(let e=0,i=t.length;e1&&(this.r=1),this.g<0?this.g=0:this.g>1&&(this.g=1),this.b<0?this.b=0:this.b>1&&(this.b=1),this.a<0?this.a=0:this.a>1&&(this.a=1),this}static rgba8888ToColor(c,t){c.r=((t&4278190080)>>>24)/255,c.g=((t&16711680)>>>16)/255,c.b=((t&65280)>>>8)/255,c.a=(t&255)/255}static rgb888ToColor(c,t){c.r=((t&16711680)>>>16)/255,c.g=((t&65280)>>>8)/255,c.b=(t&255)/255}static fromString(c){return new Je().setFromString(c)}};let _=Je;_.WHITE=new Je(1,1,1,1),_.RED=new Je(1,0,0,1),_.GREEN=new Je(0,1,0,1),_.BLUE=new Je(0,0,1,1),_.MAGENTA=new Je(1,0,1,1);const Fe=class{static clamp(c,t,n){return cn?n:c}static cosDeg(c){return Math.cos(c*Fe.degRad)}static sinDeg(c){return Math.sin(c*Fe.degRad)}static signum(c){return Math.sign(c)}static toInt(c){return c>0?Math.floor(c):Math.ceil(c)}static cbrt(c){const t=Math.pow(Math.abs(c),.3333333333333333);return c<0?-t:t}static randomTriangular(c,t){return Fe.randomTriangularWith(c,t,(c+t)*.5)}static randomTriangularWith(c,t,n){const e=Math.random(),i=t-c;return e<=(n-c)/i?c+Math.sqrt(e*i*(n-c)):t-Math.sqrt((1-e)*i*(t-n))}static isPowerOfTwo(c){return c&&(c&c-1)===0}};let C=Fe;C.PI=3.1415927,C.PI2=Fe.PI*2,C.radiansToDegrees=180/Fe.PI,C.radDeg=Fe.radiansToDegrees,C.degreesToRadians=Fe.PI/180,C.degRad=Fe.degreesToRadians;class Si{apply(t,n,e){return t+(n-t)*this.applyInternal(e)}}class yi extends Si{constructor(t){super(),this.power=2,this.power=t}applyInternal(t){return t<=.5?Math.pow(t*2,this.power)/2:Math.pow((t-1)*2,this.power)/(this.power%2==0?-2:2)+1}}class is extends yi{applyInternal(t){return Math.pow(t-1,this.power)*(this.power%2==0?-1:1)+1}}const fn=class{static arrayCopy(c,t,n,e,i){for(let r=t,h=e;r=t?c:fn.setArraySize(c,t,n)}static newArray(c,t){const n=new Array(c);for(let e=0;e0?this.items.pop():this.instantiator()}free(t){t.reset&&t.reset(),this.items.push(t)}freeAll(t){for(let n=0;nthis.maxDelta&&(this.delta=this.maxDelta),this.lastTime=t,this.frameCount++,this.frameTime>1&&(this.framesPerSecond=this.frameCount/this.frameTime,this.frameTime=0,this.frameCount=0)}}class Cr{constructor(t=32){this.addedValues=0,this.lastValue=0,this.mean=0,this.dirty=!0,this.values=new Array(t)}hasEnoughData(){return this.addedValues>=this.values.length}addValue(t){this.addedValuesthis.values.length-1&&(this.lastValue=0),this.dirty=!0}getMean(){if(this.hasEnoughData()){if(this.dirty){let t=0;for(let n=0;nv.newFloatArray(16))}update(t,n){if(!t)throw new Error("skeleton cannot be null.");const e=this.boundingBoxes,i=this.polygons,r=this.polygonPool,h=t.slots,l=h.length;e.length=0,r.freeAll(i),i.length=0;for(let s=0;s=this.minX&&t<=this.maxX&&n>=this.minY&&n<=this.maxY}aabbIntersectsSegment(t,n,e,i){const r=this.minX,h=this.minY,l=this.maxX,s=this.maxY;if(t<=r&&e<=r||n<=h&&i<=h||t>=l&&e>=l||n>=s&&i>=s)return!1;const a=(i-n)/(e-t);let o=a*(r-t)+n;if(o>h&&oh&&or&&dr&&dt.minX&&this.minYt.minY}containsPoint(t,n){const e=this.polygons;for(let i=0,r=e.length;i=e||o=e){const d=i[s];d+(e-a)/(o-a)*(i[h]-d)=d&&p<=m||p>=m&&p<=d)&&(p>=n&&p<=i||p>=i&&p<=n)){const S=(o*w-a*x)/b;if((S>=f&&S<=g||S>=g&&S<=f)&&(S>=e&&S<=r||S>=r&&S<=e))return!0}d=m,f=g}return!1}getPolygon(t){if(!t)throw new Error("boundingBox cannot be null.");const n=this.boundingBoxes.indexOf(t);return n==-1?null:this.polygons[n]}getWidth(){return this.maxX-this.minX}getHeight(){return this.maxY-this.minY}}const zt={yDown:!0,FAIL_ON_NON_EXISTING_SKIN:!1,GLOBAL_AUTO_UPDATE:!0,GLOBAL_DELAY_LIMIT:0},Ue=[0,0,0];class Mi extends wr.Sprite{constructor(){super(...arguments),this.region=null,this.attachment=null}}class Ai extends br.SimpleMesh{constructor(t,n,e,i,r){super(t,n,e,i,r),this.region=null,this.attachment=null}}const Ci=class extends dn.Container{constructor(c){if(super(),!c)throw new Error("The spineData param is required.");if(typeof c=="string")throw new Error('spineData param cant be string. Please use spine.Spine.fromAtlas("YOUR_RESOURCE_NAME") from now on.');this.spineData=c,this.createSkeleton(c),this.slotContainers=[],this.tempClipContainers=[];for(let t=0,n=this.skeleton.slots.length;tt&&(c=t),this.state.update(c),this.state.apply(this.skeleton),!this.skeleton)return;this.skeleton.updateWorldTransform();const n=this.skeleton.slots,e=this.color;let i=null,r=null;e?(i=e.light,r=e.dark):i=this.tintRgb;for(let o=0,d=n.length;o0;r--)n.bones.children[r-1].destroy({children:!0,texture:!0,baseTexture:!0});const e=t.scale.x||t.scale.y||1,i=this.lineWidth/e;this.drawBones&&this.drawBonesFunc(t,n,i,e),this.drawPaths&&this.drawPathsFunc(t,n,i),this.drawBoundingBoxes&&this.drawBoundingBoxesFunc(t,n,i),this.drawClipping&&this.drawClippingFunc(t,n,i),(this.drawMeshHull||this.drawMeshTriangles)&&this.drawMeshHullAndMeshTriangles(t,n,i),this.drawRegionAttachments&&this.drawRegionAttachmentsFunc(t,n,i)}drawBonesFunc(t,n,e,i){const r=t.skeleton,h=r.x,l=r.y,s=r.bones;n.skeletonXY.lineStyle(e,this.skeletonXYColor,1);for(let o=0,d=s.length;ox&&gx&&g>E?F=-I:mE?F=I:g===E&&mx?F=-90*k:m===x&&gE&&(F=0),R.rotation=F,R.lineStyle(e+V/2.4,this.bonesColor,1),R.beginFill(0,.6),R.drawCircle(0,M,V*1.2),R.endFill()}const a=e*3;n.skeletonXY.moveTo(h-a,l-a),n.skeletonXY.lineTo(h+a,l+a),n.skeletonXY.moveTo(h+a,l-a),n.skeletonXY.lineTo(h-a,l+a)}drawRegionAttachmentsFunc(t,n,e){const r=t.skeleton.slots;n.regionAttachmentsShape.lineStyle(e,this.regionAttachmentsColor,1);for(let h=0,l=r.length;h0){u=(u>>1)*2;let m=d[u-2],g=d[u-1];for(let x=0,E=u;x{if(n.boundingBoxesPolygon.lineStyle(e,this.boundingBoxesPolygonColor,1),n.boundingBoxesPolygon.beginFill(this.boundingBoxesPolygonColor,.1),a<3)throw new Error("Polygon must contain at least 3 vertices");const o=[],d=e*2;for(let f=0,u=l.length;f{r=o,h=d});let s;const a=o=>{o||h(`Something went terribly wrong loading a spine .atlas file +Most likely your texture failed to load.`),r(s)};if(e.image||e.images){const o=Object.assign(e.image?{default:e.image}:{},e.images);s=new Fn(c,(d,f)=>{const u=o[d]||o.default;u&&u.baseTexture?f(u.baseTexture):f(u)},a)}else s=new Fn(c,Ti(n,i,e.imageMetadata),a);return await l},unload(c){c.dispose()}}},Ti=(c,t,n)=>async(e,i)=>{const r=H.utils.path.normalize([...t.split(H.utils.path.sep),e].join(H.utils.path.sep)),h=await c.load({src:r,data:n});i(h.baseTexture)};H.extensions.add(kr);function ki(c){return c.hasOwnProperty("bones")}function Ir(c){return c instanceof ArrayBuffer}class Rr{constructor(){}installLoader(){const t=this,n={extension:H.ExtensionType.Asset,loader:{extension:{type:H.ExtensionType.LoadParser,priority:qe.LoaderParserPriority.Normal},test(e){return qe.checkExtension(e,".skel")},async load(e){return await(await H.settings.ADAPTER.fetch(e)).arrayBuffer()},testParse(e,i){var s;const r=qe.checkExtension(i.src,".json")&&ki(e),h=qe.checkExtension(i.src,".skel")&&Ir(e),l=((s=i.data)==null?void 0:s.spineAtlas)===!1;return Promise.resolve(r&&!l||h)},async parse(e,i,r){var w;const h=H.utils.path.extname(i.src).toLowerCase(),l=H.utils.path.basename(i.src,h);let s=H.utils.path.dirname(i.src);s&&s.lastIndexOf("/")!==s.length-1&&(s+="/");const a=qe.checkExtension(i.src,".json")&&ki(e);let o=null,d=e;a?o=t.createJsonParser():(o=t.createBinaryParser(),d=new Uint8Array(e));const f=i.data||{},u=(w=f==null?void 0:f.spineSkeletonScale)!=null?w:null;u&&(o.scale=u);const m=f.spineAtlas;if(m&&m.pages)return t.parseData(o,m,d);const g=f.atlasRawData;if(g){let b=null,p=null;const S=new Promise((T,k)=>{b=T,p=k}),y=new Fn(g,Ti(r,s,f.imageMetadata),T=>{T||p(`Something went terribly wrong loading a spine .atlas file +Most likely your texture failed to load.`),b(y)}),M=await S;return t.parseData(o,M,d)}let x=f.spineAtlasFile;x||(x=`${s+l}.atlas`);const E=await r.load({src:x,data:f,alias:f.spineAtlasAlias});return t.parseData(o,E,d)}}};return H.extensions.add(n),n}}let rs=class{constructor(t){if(t==null)throw new Error("name cannot be null.");this.name=t}};const Ii=class extends rs{constructor(t){super(t),this.id=(Ii.nextID++&65535)<<11,this.worldVerticesLength=0,this.deformAttachment=this}computeWorldVerticesOld(t,n){this.computeWorldVertices(t,0,this.worldVerticesLength,n,0,2)}computeWorldVertices(t,n,e,i,r,h){e=r+(e>>1)*h;const l=t.bone.skeleton,s=t.deform;let a=this.vertices;const o=this.bones;if(o==null){s.length>0&&(a=s);const m=t.bone.matrix,g=m.tx,x=m.ty,E=m.a,w=m.c,b=m.b,p=m.d;for(let S=n,y=r;y0&&(n%=this.duration));const a=this.timelines;for(let o=0,d=a.length;o>>1;for(;;){if(t[(h+1)*e]<=n?i=h+1:r=h,i==r)return(i+1)*e;h=i+r>>>1}}static linearSearch(t,n,e){for(let i=0,r=t.length-e;i<=r;i+=e)if(t[i]>n)return i;return-1}};var Pi=(c=>(c[c.rotate=0]="rotate",c[c.translate=1]="translate",c[c.scale=2]="scale",c[c.shear=3]="shear",c[c.attachment=4]="attachment",c[c.color=5]="color",c[c.deform=6]="deform",c[c.event=7]="event",c[c.drawOrder=8]="drawOrder",c[c.ikConstraint=9]="ikConstraint",c[c.transformConstraint=10]="transformConstraint",c[c.pathConstraintPosition=11]="pathConstraintPosition",c[c.pathConstraintSpacing=12]="pathConstraintSpacing",c[c.pathConstraintMix=13]="pathConstraintMix",c[c.twoColor=14]="twoColor",c))(Pi||{});const St=class{constructor(t){if(t<=0)throw new Error(`frameCount must be > 0: ${t}`);this.curves=v.newFloatArray((t-1)*St.BEZIER_SIZE)}getFrameCount(){return this.curves.length/St.BEZIER_SIZE+1}setLinear(t){this.curves[t*St.BEZIER_SIZE]=St.LINEAR}setStepped(t){this.curves[t*St.BEZIER_SIZE]=St.STEPPED}getCurveType(t){const n=t*St.BEZIER_SIZE;if(n==this.curves.length)return St.LINEAR;const e=this.curves[n];return e==St.LINEAR?St.LINEAR:e==St.STEPPED?St.STEPPED:St.BEZIER}setCurve(t,n,e,i,r){const h=(-n*2+i)*.03,l=(-e*2+r)*.03,s=((n-i)*3+1)*.006,a=((e-r)*3+1)*.006;let o=h*2+s,d=l*2+a,f=n*.3+h+s*.16666667,u=e*.3+l+a*.16666667,m=t*St.BEZIER_SIZE;const g=this.curves;g[m++]=St.BEZIER;let x=f,E=u;for(let w=m+St.BEZIER_SIZE-1;m=n){let o,d;return i==s?(o=0,d=0):(o=e[i-2],d=e[i-1]),d+(e[i+1]-d)*(n-o)/(h-o)}const l=e[i-1];return l+(1-l)*(n-h)/(1-h)}};let Ht=St;Ht.LINEAR=0,Ht.STEPPED=1,Ht.BEZIER=2,Ht.BEZIER_SIZE=10*2-1;const He=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t<<1)}getPropertyId(){return(0<<24)+this.boneIndex}setFrame(t,n,e){t<<=1,this.frames[t]=n,this.frames[t+He.ROTATION]=e}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-He.ENTRIES]){let g=s[s.length+He.PREV_ROTATION];switch(h){case A.setup:a.rotation=a.data.rotation+g*r;break;case A.first:case A.replace:g+=a.data.rotation-a.rotation,g-=(16384-(16384.499999999996-g/360|0))*360;case A.add:a.rotation+=g*r}return}const o=Et.binarySearch(s,e,He.ENTRIES),d=s[o+He.PREV_ROTATION],f=s[o],u=this.getCurvePercent((o>>1)-1,1-(e-f)/(s[o+He.PREV_TIME]-f));let m=s[o+He.ROTATION]-d;switch(m=d+(m-(16384-(16384.499999999996-m/360|0))*360)*u,h){case A.setup:a.rotation=a.data.rotation+(m-(16384-(16384.499999999996-m/360|0))*360)*r;break;case A.first:case A.replace:m+=a.data.rotation-a.rotation;case A.add:a.rotation+=(m-(16384-(16384.499999999996-m/360|0))*360)*r}}};let Vt=He;Vt.ENTRIES=2,Vt.PREV_TIME=-2,Vt.PREV_ROTATION=-1,Vt.ROTATION=1;const Dt=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*Dt.ENTRIES)}getPropertyId(){return(1<<24)+this.boneIndex}setFrame(t,n,e,i){t*=Dt.ENTRIES,this.frames[t]=n,this.frames[t+Dt.X]=e,this.frames[t+Dt.Y]=i}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-Dt.ENTRIES])o=s[s.length+Dt.PREV_X],d=s[s.length+Dt.PREV_Y];else{const f=Et.binarySearch(s,e,Dt.ENTRIES);o=s[f+Dt.PREV_X],d=s[f+Dt.PREV_Y];const u=s[f],m=this.getCurvePercent(f/Dt.ENTRIES-1,1-(e-u)/(s[f+Dt.PREV_TIME]-u));o+=(s[f+Dt.X]-o)*m,d+=(s[f+Dt.Y]-d)*m}switch(h){case A.setup:a.x=a.data.x+o*r,a.y=a.data.y+d*r;break;case A.first:case A.replace:a.x+=(a.data.x+o-a.x)*r,a.y+=(a.data.y+d-a.y)*r;break;case A.add:a.x+=o*r,a.y+=d*r}}};let Jt=Dt;Jt.ENTRIES=3,Jt.PREV_TIME=-3,Jt.PREV_X=-2,Jt.PREV_Y=-1,Jt.X=1,Jt.Y=2;let te=class extends Jt{constructor(t){super(t)}getPropertyId(){return(2<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-te.ENTRIES])o=s[s.length+te.PREV_X]*a.data.scaleX,d=s[s.length+te.PREV_Y]*a.data.scaleY;else{const f=Et.binarySearch(s,e,te.ENTRIES);o=s[f+te.PREV_X],d=s[f+te.PREV_Y];const u=s[f],m=this.getCurvePercent(f/te.ENTRIES-1,1-(e-u)/(s[f+te.PREV_TIME]-u));o=(o+(s[f+te.X]-o)*m)*a.data.scaleX,d=(d+(s[f+te.Y]-d)*m)*a.data.scaleY}if(r==1)h==A.add?(a.scaleX+=o-a.data.scaleX,a.scaleY+=d-a.data.scaleY):(a.scaleX=o,a.scaleY=d);else{let f=0,u=0;if(l==J.mixOut)switch(h){case A.setup:f=a.data.scaleX,u=a.data.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.first:case A.replace:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.add:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-a.data.scaleX)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-a.data.scaleY)*r}else switch(h){case A.setup:f=Math.abs(a.data.scaleX)*C.signum(o),u=Math.abs(a.data.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.first:case A.replace:f=Math.abs(a.scaleX)*C.signum(o),u=Math.abs(a.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.add:f=C.signum(o),u=C.signum(d),a.scaleX=Math.abs(a.scaleX)*f+(o-Math.abs(a.data.scaleX)*f)*r,a.scaleY=Math.abs(a.scaleY)*u+(d-Math.abs(a.data.scaleY)*u)*r}}}},ee=class extends Jt{constructor(t){super(t)}getPropertyId(){return(3<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-ee.ENTRIES])o=s[s.length+ee.PREV_X],d=s[s.length+ee.PREV_Y];else{const f=Et.binarySearch(s,e,ee.ENTRIES);o=s[f+ee.PREV_X],d=s[f+ee.PREV_Y];const u=s[f],m=this.getCurvePercent(f/ee.ENTRIES-1,1-(e-u)/(s[f+ee.PREV_TIME]-u));o=o+(s[f+ee.X]-o)*m,d=d+(s[f+ee.Y]-d)*m}switch(h){case A.setup:a.shearX=a.data.shearX+o*r,a.shearY=a.data.shearY+d*r;break;case A.first:case A.replace:a.shearX+=(a.data.shearX+o-a.shearX)*r,a.shearY+=(a.data.shearY+d-a.shearY)*r;break;case A.add:a.shearX+=o*r,a.shearY+=d*r}}};const ft=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*ft.ENTRIES)}getPropertyId(){return(5<<24)+this.slotIndex}setFrame(t,n,e,i,r,h){t*=ft.ENTRIES,this.frames[t]=n,this.frames[t+ft.R]=e,this.frames[t+ft.G]=i,this.frames[t+ft.B]=r,this.frames[t+ft.A]=h}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=this.frames;if(e=a[a.length-ft.ENTRIES]){const m=a.length;o=a[m+ft.PREV_R],d=a[m+ft.PREV_G],f=a[m+ft.PREV_B],u=a[m+ft.PREV_A]}else{const m=Et.binarySearch(a,e,ft.ENTRIES);o=a[m+ft.PREV_R],d=a[m+ft.PREV_G],f=a[m+ft.PREV_B],u=a[m+ft.PREV_A];const g=a[m],x=this.getCurvePercent(m/ft.ENTRIES-1,1-(e-g)/(a[m+ft.PREV_TIME]-g));o+=(a[m+ft.R]-o)*x,d+=(a[m+ft.G]-d)*x,f+=(a[m+ft.B]-f)*x,u+=(a[m+ft.A]-u)*x}if(r==1)s.color.set(o,d,f,u);else{const m=s.color;h==A.setup&&m.setFromColor(s.data.color),m.add((o-m.r)*r,(d-m.g)*r,(f-m.b)*r,(u-m.a)*r)}}};let Lt=ft;Lt.ENTRIES=5,Lt.PREV_TIME=-5,Lt.PREV_R=-4,Lt.PREV_G=-3,Lt.PREV_B=-2,Lt.PREV_A=-1,Lt.R=1,Lt.G=2,Lt.B=3,Lt.A=4;const nt=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*nt.ENTRIES)}getPropertyId(){return(14<<24)+this.slotIndex}setFrame(t,n,e,i,r,h,l,s,a){t*=nt.ENTRIES,this.frames[t]=n,this.frames[t+nt.R]=e,this.frames[t+nt.G]=i,this.frames[t+nt.B]=r,this.frames[t+nt.A]=h,this.frames[t+nt.R2]=l,this.frames[t+nt.G2]=s,this.frames[t+nt.B2]=a}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=this.frames;if(e=a[a.length-nt.ENTRIES]){const E=a.length;o=a[E+nt.PREV_R],d=a[E+nt.PREV_G],f=a[E+nt.PREV_B],u=a[E+nt.PREV_A],m=a[E+nt.PREV_R2],g=a[E+nt.PREV_G2],x=a[E+nt.PREV_B2]}else{const E=Et.binarySearch(a,e,nt.ENTRIES);o=a[E+nt.PREV_R],d=a[E+nt.PREV_G],f=a[E+nt.PREV_B],u=a[E+nt.PREV_A],m=a[E+nt.PREV_R2],g=a[E+nt.PREV_G2],x=a[E+nt.PREV_B2];const w=a[E],b=this.getCurvePercent(E/nt.ENTRIES-1,1-(e-w)/(a[E+nt.PREV_TIME]-w));o+=(a[E+nt.R]-o)*b,d+=(a[E+nt.G]-d)*b,f+=(a[E+nt.B]-f)*b,u+=(a[E+nt.A]-u)*b,m+=(a[E+nt.R2]-m)*b,g+=(a[E+nt.G2]-g)*b,x+=(a[E+nt.B2]-x)*b}if(r==1)s.color.set(o,d,f,u),s.darkColor.set(m,g,x,1);else{const E=s.color,w=s.darkColor;h==A.setup&&(E.setFromColor(s.data.color),w.setFromColor(s.data.darkColor)),E.add((o-E.r)*r,(d-E.g)*r,(f-E.b)*r,(u-E.a)*r),w.add((m-w.r)*r,(g-w.g)*r,(x-w.b)*r,0)}}};let yt=nt;yt.ENTRIES=8,yt.PREV_TIME=-8,yt.PREV_R=-7,yt.PREV_G=-6,yt.PREV_B=-5,yt.PREV_A=-4,yt.PREV_R2=-3,yt.PREV_G2=-2,yt.PREV_B2=-1,yt.R=1,yt.G=2,yt.B=3,yt.A=4,yt.R2=5,yt.G2=6,yt.B2=7;let en=class{constructor(t){this.frames=v.newFloatArray(t),this.attachmentNames=new Array(t)}getPropertyId(){return(4<<24)+this.slotIndex}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.attachmentNames[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;if(l==J.mixOut){h==A.setup&&this.setAttachment(t,s,s.data.attachmentName);return}const a=this.frames;if(e=a[a.length-1]?o=a.length-1:o=Et.binarySearch(a,e,1)-1;const d=this.attachmentNames[o];t.slots[this.slotIndex].setAttachment(d==null?null:t.getAttachment(this.slotIndex,d))}setAttachment(t,n,e){n.setAttachment(e==null?null:t.getAttachment(this.slotIndex,e))}},Vi=null,hs=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t),this.frameVertices=new Array(t),Vi==null&&(Vi=v.newFloatArray(64))}getPropertyId(){return(6<<27)+Number(this.attachment.id)+this.slotIndex}setFrame(t,n,e){this.frames[t]=n,this.frameVertices[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=s.getAttachment();if(!(a instanceof ze)||a.deformAttachment!=this.attachment)return;const o=s.deform;o.length==0&&(h=A.setup);const d=this.frameVertices,f=d[0].length,u=this.frames;if(e=u[u.length-1]){const p=d[u.length-1];if(r==1)if(h==A.add){const S=a;if(S.bones==null){const y=S.vertices;for(let M=0;Me)this.apply(t,n,Number.MAX_VALUE,i,r,h,l),n=-1;else if(n>=s[a-1])return;if(e0&&s[o-1]==d;)o--}for(;o=s[o];o++)i.push(this.events[o])}},xn=class{constructor(t){this.frames=v.newFloatArray(t),this.drawOrders=new Array(t)}getPropertyId(){return 8<<24}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.drawOrders[t]=e}apply(t,n,e,i,r,h,l){const s=t.drawOrder,a=t.slots;if(l==J.mixOut&&h==A.setup){v.arrayCopy(t.slots,0,t.drawOrder,0,t.slots.length);return}const o=this.frames;if(e=o[o.length-1]?d=o.length-1:d=Et.binarySearch(o,e)-1;const f=this.drawOrders[d];if(f==null)v.arrayCopy(a,0,s,0,a.length);else for(let u=0,m=f.length;u=s[s.length-at.ENTRIES]){h==A.setup?(a.mix=a.data.mix+(s[s.length+at.PREV_MIX]-a.data.mix)*r,a.softness=a.data.softness+(s[s.length+at.PREV_SOFTNESS]-a.data.softness)*r,l==J.mixOut?(a.bendDirection=a.data.bendDirection,a.compress=a.data.compress,a.stretch=a.data.stretch):(a.bendDirection=s[s.length+at.PREV_BEND_DIRECTION],a.compress=s[s.length+at.PREV_COMPRESS]!=0,a.stretch=s[s.length+at.PREV_STRETCH]!=0)):(a.mix+=(s[s.length+at.PREV_MIX]-a.mix)*r,a.softness+=(s[s.length+at.PREV_SOFTNESS]-a.softness)*r,l==J.mixIn&&(a.bendDirection=s[s.length+at.PREV_BEND_DIRECTION],a.compress=s[s.length+at.PREV_COMPRESS]!=0,a.stretch=s[s.length+at.PREV_STRETCH]!=0));return}const o=Et.binarySearch(s,e,at.ENTRIES),d=s[o+at.PREV_MIX],f=s[o+at.PREV_SOFTNESS],u=s[o],m=this.getCurvePercent(o/at.ENTRIES-1,1-(e-u)/(s[o+at.PREV_TIME]-u));h==A.setup?(a.mix=a.data.mix+(d+(s[o+at.MIX]-d)*m-a.data.mix)*r,a.softness=a.data.softness+(f+(s[o+at.SOFTNESS]-f)*m-a.data.softness)*r,l==J.mixOut?(a.bendDirection=a.data.bendDirection,a.compress=a.data.compress,a.stretch=a.data.stretch):(a.bendDirection=s[o+at.PREV_BEND_DIRECTION],a.compress=s[o+at.PREV_COMPRESS]!=0,a.stretch=s[o+at.PREV_STRETCH]!=0)):(a.mix+=(d+(s[o+at.MIX]-d)*m-a.mix)*r,a.softness+=(f+(s[o+at.SOFTNESS]-f)*m-a.softness)*r,l==J.mixIn&&(a.bendDirection=s[o+at.PREV_BEND_DIRECTION],a.compress=s[o+at.PREV_COMPRESS]!=0,a.stretch=s[o+at.PREV_STRETCH]!=0))}};let Ft=at;Ft.ENTRIES=6,Ft.PREV_TIME=-6,Ft.PREV_MIX=-5,Ft.PREV_SOFTNESS=-4,Ft.PREV_BEND_DIRECTION=-3,Ft.PREV_COMPRESS=-2,Ft.PREV_STRETCH=-1,Ft.MIX=1,Ft.SOFTNESS=2,Ft.BEND_DIRECTION=3,Ft.COMPRESS=4,Ft.STRETCH=5;const ut=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*ut.ENTRIES)}getPropertyId(){return(10<<24)+this.transformConstraintIndex}setFrame(t,n,e,i,r,h){t*=ut.ENTRIES,this.frames[t]=n,this.frames[t+ut.ROTATE]=e,this.frames[t+ut.TRANSLATE]=i,this.frames[t+ut.SCALE]=r,this.frames[t+ut.SHEAR]=h}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.transformConstraints[this.transformConstraintIndex];if(!a.active)return;if(e=s[s.length-ut.ENTRIES]){const m=s.length;o=s[m+ut.PREV_ROTATE],d=s[m+ut.PREV_TRANSLATE],f=s[m+ut.PREV_SCALE],u=s[m+ut.PREV_SHEAR]}else{const m=Et.binarySearch(s,e,ut.ENTRIES);o=s[m+ut.PREV_ROTATE],d=s[m+ut.PREV_TRANSLATE],f=s[m+ut.PREV_SCALE],u=s[m+ut.PREV_SHEAR];const g=s[m],x=this.getCurvePercent(m/ut.ENTRIES-1,1-(e-g)/(s[m+ut.PREV_TIME]-g));o+=(s[m+ut.ROTATE]-o)*x,d+=(s[m+ut.TRANSLATE]-d)*x,f+=(s[m+ut.SCALE]-f)*x,u+=(s[m+ut.SHEAR]-u)*x}if(h==A.setup){const m=a.data;a.rotateMix=m.rotateMix+(o-m.rotateMix)*r,a.translateMix=m.translateMix+(d-m.translateMix)*r,a.scaleMix=m.scaleMix+(f-m.scaleMix)*r,a.shearMix=m.shearMix+(u-m.shearMix)*r}else a.rotateMix+=(o-a.rotateMix)*r,a.translateMix+=(d-a.translateMix)*r,a.scaleMix+=(f-a.scaleMix)*r,a.shearMix+=(u-a.shearMix)*r}};let _t=ut;_t.ENTRIES=5,_t.PREV_TIME=-5,_t.PREV_ROTATE=-4,_t.PREV_TRANSLATE=-3,_t.PREV_SCALE=-2,_t.PREV_SHEAR=-1,_t.ROTATE=1,_t.TRANSLATE=2,_t.SCALE=3,_t.SHEAR=4;const ue=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*ue.ENTRIES)}getPropertyId(){return(11<<24)+this.pathConstraintIndex}setFrame(t,n,e){t*=ue.ENTRIES,this.frames[t]=n,this.frames[t+ue.VALUE]=e}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(!a.active)return;if(e=s[s.length-ue.ENTRIES])o=s[s.length+ue.PREV_VALUE];else{const d=Et.binarySearch(s,e,ue.ENTRIES);o=s[d+ue.PREV_VALUE];const f=s[d],u=this.getCurvePercent(d/ue.ENTRIES-1,1-(e-f)/(s[d+ue.PREV_TIME]-f));o+=(s[d+ue.VALUE]-o)*u}h==A.setup?a.position=a.data.position+(o-a.data.position)*r:a.position+=(o-a.position)*r}};let Te=ue;Te.ENTRIES=2,Te.PREV_TIME=-2,Te.PREV_VALUE=-1,Te.VALUE=1;let ke=class extends Te{constructor(t){super(t)}getPropertyId(){return(12<<24)+this.pathConstraintIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(!a.active)return;if(e=s[s.length-ke.ENTRIES])o=s[s.length+ke.PREV_VALUE];else{const d=Et.binarySearch(s,e,ke.ENTRIES);o=s[d+ke.PREV_VALUE];const f=s[d],u=this.getCurvePercent(d/ke.ENTRIES-1,1-(e-f)/(s[d+ke.PREV_TIME]-f));o+=(s[d+ke.VALUE]-o)*u}h==A.setup?a.spacing=a.data.spacing+(o-a.data.spacing)*r:a.spacing+=(o-a.spacing)*r}};const Ot=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*Ot.ENTRIES)}getPropertyId(){return(13<<24)+this.pathConstraintIndex}setFrame(t,n,e,i){t*=Ot.ENTRIES,this.frames[t]=n,this.frames[t+Ot.ROTATE]=e,this.frames[t+Ot.TRANSLATE]=i}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(!a.active)return;if(e=s[s.length-Ot.ENTRIES])o=s[s.length+Ot.PREV_ROTATE],d=s[s.length+Ot.PREV_TRANSLATE];else{const f=Et.binarySearch(s,e,Ot.ENTRIES);o=s[f+Ot.PREV_ROTATE],d=s[f+Ot.PREV_TRANSLATE];const u=s[f],m=this.getCurvePercent(f/Ot.ENTRIES-1,1-(e-u)/(s[f+Ot.PREV_TIME]-u));o+=(s[f+Ot.ROTATE]-o)*m,d+=(s[f+Ot.TRANSLATE]-d)*m}h==A.setup?(a.rotateMix=a.data.rotateMix+(o-a.data.rotateMix)*r,a.translateMix=a.data.translateMix+(d-a.data.translateMix)*r):(a.rotateMix+=(o-a.rotateMix)*r,a.translateMix+=(d-a.translateMix)*r)}};let me=Ot;me.ENTRIES=3,me.PREV_TIME=-3,me.PREV_ROTATE=-2,me.PREV_TRANSLATE=-1,me.ROTATE=1,me.TRANSLATE=2;const mt=class{constructor(t){this.tracks=new Array,this.timeScale=1,this.unkeyedState=0,this.events=new Array,this.listeners=new Array,this.queue=new fs(this),this.propertyIDs=new ns,this.animationsChanged=!1,this.trackEntryPool=new An(()=>new Xn),this.data=t}update(t){t*=this.timeScale;const n=this.tracks;for(let e=0,i=n.length;e0){if(r.delay-=h,r.delay>0)continue;h=-r.delay,r.delay=0}let l=r.next;if(l!=null){const s=r.trackLast-l.delay;if(s>=0){for(l.delay=0,l.trackTime+=r.timeScale==0?0:(s/r.timeScale+t)*l.timeScale,r.trackTime+=h,this.setCurrent(e,l,!0);l.mixingFrom!=null;)l.mixTime+=t,l=l.mixingFrom;continue}}else if(r.trackLast>=r.trackEnd&&r.mixingFrom==null){n[e]=null,this.queue.end(r),this.disposeNext(r);continue}if(r.mixingFrom!=null&&this.updateMixingFrom(r,t)){let s=r.mixingFrom;for(r.mixingFrom=null,s!=null&&(s.mixingTo=null);s!=null;)this.queue.end(s),s=s.mixingFrom}r.trackTime+=h}this.queue.drain()}updateMixingFrom(t,n){const e=t.mixingFrom;if(e==null)return!0;const i=this.updateMixingFrom(e,n);return e.animationLast=e.nextAnimationLast,e.trackLast=e.nextTrackLast,t.mixTime>0&&t.mixTime>=t.mixDuration?((e.totalAlpha==0||t.mixDuration==0)&&(t.mixingFrom=e.mixingFrom,e.mixingFrom!=null&&(e.mixingFrom.mixingTo=t),t.interruptAlpha=e.interruptAlpha,this.queue.end(e)),i):(e.trackTime+=n*e.timeScale,t.mixTime+=n,!1)}apply(t){if(t==null)throw new Error("skeleton cannot be null.");this.animationsChanged&&this._animationsChanged();const n=this.events,e=this.tracks;let i=!1;for(let l=0,s=e.length;l0)continue;i=!0;const o=l==0?A.first:a.mixBlend;let d=a.alpha;a.mixingFrom!=null?d*=this.applyMixingFrom(a,t,o):a.trackTime>=a.trackEnd&&a.next==null&&(d=0);const f=a.animationLast,u=a.getAnimationTime(),m=a.animation.timelines.length,g=a.animation.timelines;if(l==0&&d==1||o==A.add)for(let x=0;x1&&(r=1),e!=A.first&&(e=i.mixBlend));const h=r0&&this.queueEvents(i,o),this.events.length=0,i.nextAnimationLast=o,i.nextTrackLast=i.trackTime,r}applyAttachmentTimeline(t,n,e,i,r){const h=n.slots[t.slotIndex];if(!h.bone.active)return;const l=t.frames;if(e=l[l.length-1]?s=l.length-1:s=Et.binarySearch(l,e)-1,this.setAttachment(n,h,t.attachmentNames[s],r)}h.attachmentState<=this.unkeyedState&&(h.attachmentState=this.unkeyedState+mt.SETUP)}setAttachment(t,n,e,i){n.setAttachment(e==null?null:t.getAttachment(n.data.index,e)),i&&(n.attachmentState=this.unkeyedState+mt.CURRENT)}applyRotateTimeline(t,n,e,i,r,h,l,s){if(s&&(h[l]=0),i==1){t.apply(n,0,e,null,1,r,J.mixIn);return}const a=t,o=a.frames,d=n.bones[a.boneIndex];if(!d.active)return;let f=0,u=0;if(e=o[o.length-Vt.ENTRIES])u=d.data.rotation+o[o.length+Vt.PREV_ROTATION];else{const x=Et.binarySearch(o,e,Vt.ENTRIES),E=o[x+Vt.PREV_ROTATION],w=o[x],b=a.getCurvePercent((x>>1)-1,1-(e-w)/(o[x+Vt.PREV_TIME]-w));u=o[x+Vt.ROTATION]-E,u-=(16384-(16384.499999999996-u/360|0))*360,u=E+u*b+d.data.rotation,u-=(16384-(16384.499999999996-u/360|0))*360}let m=0,g=u-f;if(g-=(16384-(16384.499999999996-g/360|0))*360,g==0)m=h[l];else{let x=0,E=0;s?(x=0,E=g):(x=h[l],E=h[l+1]);const w=g>0;let b=x>=0;C.signum(E)!=C.signum(g)&&Math.abs(E)<=90&&(Math.abs(x)>180&&(x+=360*C.signum(x)),b=w),m=g+x-x%360,b!=w&&(m+=360*C.signum(x)),h[l]=m}h[l+1]=g,f+=m*i,d.rotation=f-(16384-(16384.499999999996-f/360|0))*360}queueEvents(t,n){const e=t.animationStart,i=t.animationEnd,r=i-e,h=t.trackLast%r,l=this.events;let s=0;const a=l.length;for(;si||this.queue.event(t,d)}let o=!1;for(t.loop?o=r==0||h>t.trackTime%r:o=n>=i&&t.animationLast=this.tracks.length)return;const n=this.tracks[t];if(n==null)return;this.queue.end(n),this.disposeNext(n);let e=n;for(;;){const i=e.mixingFrom;if(i==null)break;this.queue.end(i),e.mixingFrom=null,e.mixingTo=null,e=i}this.tracks[n.trackIndex]=null,this.queue.drain()}setCurrent(t,n,e){const i=this.expandToIndex(t);this.tracks[t]=n,i!=null&&(e&&this.queue.interrupt(i),n.mixingFrom=i,i.mixingTo=n,n.mixTime=0,i.mixingFrom!=null&&i.mixDuration>0&&(n.interruptAlpha*=Math.min(1,i.mixTime/i.mixDuration)),i.timelinesRotation.length=0),this.queue.start(n)}setAnimation(t,n,e){const i=this.data.skeletonData.findAnimation(n);if(i==null)throw new Error(`Animation not found: ${n}`);return this.setAnimationWith(t,i,e)}setAnimationWith(t,n,e){if(n==null)throw new Error("animation cannot be null.");let i=!0,r=this.expandToIndex(t);r!=null&&(r.nextTrackLast==-1?(this.tracks[t]=r.mixingFrom,this.queue.interrupt(r),this.queue.end(r),this.disposeNext(r),r=r.mixingFrom,i=!1):this.disposeNext(r));const h=this.trackEntry(t,n,e,r);return this.setCurrent(t,h,i),this.queue.drain(),h}addAnimation(t,n,e,i){const r=this.data.skeletonData.findAnimation(n);if(r==null)throw new Error(`Animation not found: ${n}`);return this.addAnimationWith(t,r,e,i)}addAnimationWith(t,n,e,i){if(n==null)throw new Error("animation cannot be null.");let r=this.expandToIndex(t);if(r!=null)for(;r.next!=null;)r=r.next;const h=this.trackEntry(t,n,e,r);if(r==null)this.setCurrent(t,h,!0),this.queue.drain();else if(r.next=h,i<=0){const l=r.animationEnd-r.animationStart;l!=0?(r.loop?i+=l*(1+(r.trackTime/l|0)):i+=Math.max(l,r.trackTime),i-=this.data.getMix(r.animation,n)):i=r.trackTime}return h.delay=i,h}setEmptyAnimation(t,n){const e=this.setAnimationWith(t,mt.emptyAnimation,!1);return e.mixDuration=n,e.trackEnd=n,e}addEmptyAnimation(t,n,e){e<=0&&(e-=n);const i=this.addAnimationWith(t,mt.emptyAnimation,!1,e);return i.mixDuration=n,i.trackEnd=n,i}setEmptyAnimations(t){const n=this.queue.drainDisabled;this.queue.drainDisabled=!0;for(let e=0,i=this.tracks.length;e0){r[s]=mt.HOLD_MIX,h[s]=d;continue t}break}r[s]=mt.HOLD_FIRST}}}getCurrent(t){return t>=this.tracks.length?null:this.tracks[t]}addListener(t){if(t==null)throw new Error("listener cannot be null.");this.listeners.push(t)}removeListener(t){const n=this.listeners.indexOf(t);n>=0&&this.listeners.splice(n,1)}clearListeners(){this.listeners.length=0}clearListenerNotifications(){this.queue.clear()}setAnimationByName(t,n,e){mt.deprecatedWarning1||(mt.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on.")),this.setAnimation(t,n,e)}addAnimationByName(t,n,e,i){mt.deprecatedWarning2||(mt.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on.")),this.addAnimation(t,n,e,i)}hasAnimation(t){return this.data.skeletonData.findAnimation(t)!==null}hasAnimationByName(t){return mt.deprecatedWarning3||(mt.deprecatedWarning3=!0,console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on.")),this.hasAnimation(t)}};let ne=mt;ne.emptyAnimation=new Et("",[],0),ne.SUBSEQUENT=0,ne.FIRST=1,ne.HOLD_SUBSEQUENT=2,ne.HOLD_FIRST=3,ne.HOLD_MIX=4,ne.SETUP=1,ne.CURRENT=2,ne.deprecatedWarning1=!1,ne.deprecatedWarning2=!1,ne.deprecatedWarning3=!1;const Ye=class{constructor(){this.mixBlend=A.replace,this.timelineMode=new Array,this.timelineHoldMix=new Array,this.timelinesRotation=new Array}reset(){this.next=null,this.mixingFrom=null,this.mixingTo=null,this.animation=null,this.listener=null,this.timelineMode.length=0,this.timelineHoldMix.length=0,this.timelinesRotation.length=0}getAnimationTime(){if(this.loop){const t=this.animationEnd-this.animationStart;return t==0?this.animationStart:this.trackTime%t+this.animationStart}return Math.min(this.trackTime+this.animationStart,this.animationEnd)}setAnimationLast(t){this.animationLast=t,this.nextAnimationLast=t}isComplete(){return this.trackTime>=this.animationEnd-this.animationStart}resetRotationDirections(){this.timelinesRotation.length=0}get time(){return Ye.deprecatedWarning1||(Ye.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime}set time(t){Ye.deprecatedWarning1||(Ye.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime=t}get endTime(){return Ye.deprecatedWarning2||(Ye.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime}set endTime(t){Ye.deprecatedWarning2||(Ye.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime=t}loopsCount(){return Math.floor(this.trackTime/this.trackEnd)}};let Xn=Ye;Xn.deprecatedWarning1=!1,Xn.deprecatedWarning2=!1;const ds=class{constructor(t){this.objects=[],this.drainDisabled=!1,this.animState=t}start(t){this.objects.push(Gt.start),this.objects.push(t),this.animState.animationsChanged=!0}interrupt(t){this.objects.push(Gt.interrupt),this.objects.push(t)}end(t){this.objects.push(Gt.end),this.objects.push(t),this.animState.animationsChanged=!0}dispose(t){this.objects.push(Gt.dispose),this.objects.push(t)}complete(t){this.objects.push(Gt.complete),this.objects.push(t)}event(t,n){this.objects.push(Gt.event),this.objects.push(t),this.objects.push(n)}deprecateStuff(){return ds.deprecatedWarning1||(ds.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: onComplete, onStart, onEnd, onEvent art deprecated, please use listeners from now on. 'state.addListener({ complete: function(track, event) { } })'")),!0}drain(){if(this.drainDisabled)return;this.drainDisabled=!0;const t=this.objects,n=this.animState.listeners;for(let e=0;e(c[c.start=0]="start",c[c.interrupt=1]="interrupt",c[c.end=2]="end",c[c.dispose=3]="dispose",c[c.complete=4]="complete",c[c.event=5]="event",c))(Gt||{});let Pr=class{start(t){}interrupt(t){}end(t){}dispose(t){}complete(t){}event(t,n){}};const us=class{constructor(t){if(this.animationToMixTime={},this.defaultMix=0,t==null)throw new Error("skeletonData cannot be null.");this.skeletonData=t}setMix(t,n,e){const i=this.skeletonData.findAnimation(t);if(i==null)throw new Error(`Animation not found: ${t}`);const r=this.skeletonData.findAnimation(n);if(r==null)throw new Error(`Animation not found: ${n}`);this.setMixWith(i,r,e)}setMixByName(t,n,e){us.deprecatedWarning1||(us.deprecatedWarning1=!0,console.warn("Deprecation Warning: AnimationStateData.setMixByName is deprecated, please use setMix from now on.")),this.setMix(t,n,e)}setMixWith(t,n,e){if(t==null)throw new Error("from cannot be null.");if(n==null)throw new Error("to cannot be null.");const i=`${t.name}.${n.name}`;this.animationToMixTime[i]=e}getMix(t,n){const e=`${t.name}.${n.name}`,i=this.animationToMixTime[e];return i===void 0?this.defaultMix:i}};let ms=us;ms.deprecatedWarning1=!1;let gs=class{constructor(t){this.atlas=t}newRegionAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (region attachment: ${n})`);const r=new Q(n);return r.region=i,r}newMeshAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (mesh attachment: ${n})`);const r=new mn(n);return r.region=i,r}newBoundingBoxAttachment(t,n){return new as(n)}newPathAttachment(t,n){return new gn(n)}newPointAttachment(t,n){return new ls(n)}newClippingAttachment(t,n){return new os(n)}},xs=class{constructor(t,n,e){if(this.matrix=new H.Matrix,this.children=new Array,this.x=0,this.y=0,this.rotation=0,this.scaleX=0,this.scaleY=0,this.shearX=0,this.shearY=0,this.ax=0,this.ay=0,this.arotation=0,this.ascaleX=0,this.ascaleY=0,this.ashearX=0,this.ashearY=0,this.appliedValid=!1,this.sorted=!1,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.skeleton=n,this.parent=e,this.setToSetupPose()}get worldX(){return this.matrix.tx}get worldY(){return this.matrix.ty}isActive(){return this.active}update(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransform(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransformWith(t,n,e,i,r,h,l){this.ax=t,this.ay=n,this.arotation=e,this.ascaleX=i,this.ascaleY=r,this.ashearX=h,this.ashearY=l,this.appliedValid=!0;const s=this.parent,a=this.matrix,o=this.skeleton.scaleX,d=zt.yDown?-this.skeleton.scaleY:this.skeleton.scaleY;if(s==null){const x=this.skeleton,E=e+90+l;a.a=C.cosDeg(e+h)*i*o,a.c=C.cosDeg(E)*r*o,a.b=C.sinDeg(e+h)*i*d,a.d=C.sinDeg(E)*r*d,a.tx=t*o+x.x,a.ty=n*d+x.y;return}let f=s.matrix.a,u=s.matrix.c,m=s.matrix.b,g=s.matrix.d;switch(a.tx=f*t+u*n+s.matrix.tx,a.ty=m*t+g*n+s.matrix.ty,this.data.transformMode){case j.Normal:{const x=e+90+l,E=C.cosDeg(e+h)*i,w=C.cosDeg(x)*r,b=C.sinDeg(e+h)*i,p=C.sinDeg(x)*r;a.a=f*E+u*b,a.c=f*w+u*p,a.b=m*E+g*b,a.d=m*w+g*p;return}case j.OnlyTranslation:{const x=e+90+l;a.a=C.cosDeg(e+h)*i,a.c=C.cosDeg(x)*r,a.b=C.sinDeg(e+h)*i,a.d=C.sinDeg(x)*r;break}case j.NoRotationOrReflection:{let x=f*f+m*m,E=0;x>1e-4?(x=Math.abs(f*g-u*m)/x,f/=this.skeleton.scaleX,m/=this.skeleton.scaleY,u=m*x,g=f*x,E=Math.atan2(m,f)*C.radDeg):(f=0,m=0,E=90-Math.atan2(g,u)*C.radDeg);const w=e+h-E,b=e+l-E+90,p=C.cosDeg(w)*i,S=C.cosDeg(b)*r,y=C.sinDeg(w)*i,M=C.sinDeg(b)*r;a.a=f*p-u*y,a.c=f*S-u*M,a.b=m*p+g*y,a.d=m*S+g*M;break}case j.NoScale:case j.NoScaleOrReflection:{const x=C.cosDeg(e),E=C.sinDeg(e);let w=(f*x+u*E)/o,b=(m*x+g*E)/d,p=Math.sqrt(w*w+b*b);p>1e-5&&(p=1/p),w*=p,b*=p,p=Math.sqrt(w*w+b*b),this.data.transformMode==j.NoScale&&f*g-u*m<0!=(zt.yDown?this.skeleton.scaleX<0!=this.skeleton.scaleY>0:this.skeleton.scaleX<0!=this.skeleton.scaleY<0)&&(p=-p);const S=Math.PI/2+Math.atan2(b,w),y=Math.cos(S)*p,M=Math.sin(S)*p,T=C.cosDeg(h)*i,k=C.cosDeg(90+l)*r,I=C.sinDeg(h)*i,R=C.sinDeg(90+l)*r;a.a=w*T+y*I,a.c=w*k+y*R,a.b=b*T+M*I,a.d=b*k+M*R;break}}a.a*=o,a.c*=o,a.b*=d,a.d*=d}setToSetupPose(){const t=this.data;this.x=t.x,this.y=t.y,this.rotation=t.rotation,this.scaleX=t.scaleX,this.scaleY=t.scaleY,this.shearX=t.shearX,this.shearY=t.shearY}getWorldRotationX(){return Math.atan2(this.matrix.b,this.matrix.a)*C.radDeg}getWorldRotationY(){return Math.atan2(this.matrix.d,this.matrix.c)*C.radDeg}getWorldScaleX(){const t=this.matrix;return Math.sqrt(t.a*t.a+t.c*t.c)}getWorldScaleY(){const t=this.matrix;return Math.sqrt(t.b*t.b+t.d*t.d)}updateAppliedTransform(){this.appliedValid=!0;const t=this.parent,n=this.matrix;if(t==null){this.ax=n.tx,this.ay=n.ty,this.arotation=Math.atan2(n.b,n.a)*C.radDeg,this.ascaleX=Math.sqrt(n.a*n.a+n.b*n.b),this.ascaleY=Math.sqrt(n.c*n.c+n.d*n.d),this.ashearX=0,this.ashearY=Math.atan2(n.a*n.c+n.b*n.d,n.a*n.d-n.b*n.c)*C.radDeg;return}const e=t.matrix,i=1/(e.a*e.d-e.b*e.c),r=n.tx-e.tx,h=n.ty-e.ty;this.ax=r*e.d*i-h*e.c*i,this.ay=h*e.a*i-r*e.b*i;const l=i*e.d,s=i*e.a,a=i*e.c,o=i*e.b,d=l*n.a-a*n.b,f=l*n.c-a*n.d,u=s*n.b-o*n.a,m=s*n.d-o*n.c;if(this.ashearX=0,this.ascaleX=Math.sqrt(d*d+u*u),this.ascaleX>1e-4){const g=d*m-f*u;this.ascaleY=g/this.ascaleX,this.ashearY=Math.atan2(d*f+u*m,g)*C.radDeg,this.arotation=Math.atan2(u,d)*C.radDeg}else this.ascaleX=0,this.ascaleY=Math.sqrt(f*f+m*m),this.ashearY=0,this.arotation=90-Math.atan2(m,f)*C.radDeg}worldToLocal(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=1/(e*h-i*r),s=t.x-n.tx,a=t.y-n.ty;return t.x=s*h*l-a*i*l,t.y=a*e*l-s*r*l,t}localToWorld(t){const n=this.matrix,e=t.x,i=t.y;return t.x=e*n.a+i*n.c+n.tx,t.y=e*n.b+i*n.d+n.ty,t}worldToLocalRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(i.a*n-i.b*e,i.d*e-i.c*n)*C.radDeg}localToWorldRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(e*i.b+n*i.d,e*i.a+n*i.c)*C.radDeg}rotateWorld(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=C.cosDeg(t),s=C.sinDeg(t);n.a=l*e-s*r,n.c=l*i-s*h,n.b=s*e+l*r,n.d=s*i+l*h,this.appliedValid=!1}},ps=class{constructor(t,n,e){if(this.x=0,this.y=0,this.rotation=0,this.scaleX=1,this.scaleY=1,this.shearX=0,this.shearY=0,this.transformMode=j.Normal,this.skinRequired=!1,this.color=new _,t<0)throw new Error("index must be >= 0.");if(n==null)throw new Error("name cannot be null.");this.index=t,this.name=n,this.parent=e}},Nn=class{constructor(t,n,e){this.name=t,this.order=n,this.skinRequired=e}},ws=class{constructor(t,n){if(n==null)throw new Error("data cannot be null.");this.time=t,this.data=n}},bs=class{constructor(t){this.name=t}},Fi=class{constructor(t,n){if(this.bendDirection=0,this.compress=!1,this.stretch=!1,this.mix=1,this.softness=0,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.mix=t.mix,this.softness=t.softness,this.bendDirection=t.bendDirection,this.compress=t.compress,this.stretch=t.stretch,this.bones=new Array;for(let e=0;e180?u-=360:u<-180&&(u+=360);let x=t.ascaleX,E=t.ascaleY;if(i||r){switch(t.data.transformMode){case j.NoScale:case j.NoScaleOrReflection:m=n-t.worldX,g=e-t.worldY}const w=t.data.length*x,b=Math.sqrt(m*m+g*g);if(i&&bw&&w>1e-4){const p=(b/w-1)*l+1;x*=p,h&&(E*=p)}}t.updateWorldTransformWith(t.ax,t.ay,t.arotation+u*l,x,E,t.ashearX,t.ashearY)}apply2(t,n,e,i,r,h,l,s){if(s==0){n.updateWorldTransform();return}t.appliedValid||t.updateAppliedTransform(),n.appliedValid||n.updateAppliedTransform();const a=t.ax,o=t.ay;let d=t.ascaleX,f=d,u=t.ascaleY,m=n.ascaleX;const g=t.matrix;let x=0,E=0,w=0;d<0?(d=-d,x=180,w=-1):(x=0,w=1),u<0&&(u=-u,w=-w),m<0?(m=-m,E=180):E=0;const b=n.ax;let p=0,S=0,y=0,M=g.a,T=g.c,k=g.b,I=g.d;const R=Math.abs(d-u)<=1e-4;R?(p=n.ay,S=M*b+T*p+g.tx,y=k*b+I*p+g.ty):(p=0,S=M*b+g.tx,y=k*b+g.ty);const V=t.parent.matrix;M=V.a,T=V.c,k=V.b,I=V.d;const F=1/(M*I-T*k);let B=S-V.tx,Y=y-V.ty;const N=(B*I-Y*T)*F-a,q=(Y*M-B*k)*F-o,z=Math.sqrt(N*N+q*q);let D=n.data.length*m,X,L;if(z<1e-4){this.apply1(t,e,i,!1,h,!1,s),n.updateWorldTransformWith(b,p,0,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY);return}B=e-V.tx,Y=i-V.ty;let O=(B*I-Y*T)*F-a,W=(Y*M-B*k)*F-o,U=O*O+W*W;if(l!=0){l*=d*(m+1)/2;const lt=Math.sqrt(U),It=lt-z-D*d+l;if(It>0){let ct=Math.min(1,It/(l*2))-1;ct=(It-l*(1-ct*ct))/lt,O-=ct*O,W-=ct*W,U=O*O+W*W}}t:if(R){D*=d;let lt=(U-z*z-D*D)/(2*z*D);lt<-1?lt=-1:lt>1&&(lt=1,h&&(f*=(Math.sqrt(U)/(z+D)-1)*s+1)),L=Math.acos(lt)*r,M=z+D*lt,T=D*Math.sin(L),X=Math.atan2(W*M-O*T,O*M+W*T)}else{M=d*D,T=u*D;const lt=M*M,It=T*T,ct=Math.atan2(W,O);k=It*z*z+lt*U-lt*It;const Xt=-2*It*z,Ut=It-lt;if(I=Xt*Xt-4*Ut*k,I>=0){let ae=Math.sqrt(I);Xt<0&&(ae=-ae),ae=-(Xt+ae)/2;const Ke=ae/Ut,Nt=k/ae,We=Math.abs(Ke)=-1&&k<=1&&(k=Math.acos(k),B=M*Math.cos(k)+z,Y=T*Math.sin(k),I=B*B+Y*Y,I$e&&(Ae=k,$e=I,Ce=B,Kt=Y)),U<=(Oe+$e)/2?(X=ct-Math.atan2(Ve*r,Me),L=de*r):(X=ct-Math.atan2(Kt*r,Ce),L=Ae*r)}const $=Math.atan2(p,b)*w;let G=t.arotation;X=(X-$)*C.radDeg+x-G,X>180?X-=360:X<-180&&(X+=360),t.updateWorldTransformWith(a,o,G+X*s,f,t.ascaleY,0,0),G=n.arotation,L=((L+$)*C.radDeg-n.ashearX)*w+E-G,L>180?L-=360:L<-180&&(L+=360),n.updateWorldTransformWith(b,p,G+L*s,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY)}},Es=class extends Nn{constructor(t){super(t,0,!1),this.bones=new Array,this.bendDirection=1,this.compress=!1,this.stretch=!1,this.uniform=!1,this.mix=1,this.softness=0}},Ss=class extends Nn{constructor(t){super(t,0,!1),this.bones=new Array}};var vt=(c=>(c[c.Length=0]="Length",c[c.Fixed=1]="Fixed",c[c.Percent=2]="Percent",c))(vt||{});const nn=class{constructor(t,n){if(this.position=0,this.spacing=0,this.rotateMix=0,this.translateMix=0,this.spaces=new Array,this.positions=new Array,this.world=new Array,this.curves=new Array,this.lengths=new Array,this.segments=new Array,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.bones=new Array;for(let e=0,i=t.bones.length;e0,r=n>0;if(!i&&!r)return;const h=this.data,l=h.spacingMode,s=l==vt.Length,a=h.rotateMode,o=a==pt.Tangent,d=a==pt.ChainScale,f=this.bones.length,u=o?f:f+1,m=this.bones,g=v.setArraySize(this.spaces,u);let x=null;const E=this.spacing;if(d||s){d&&(x=v.setArraySize(this.lengths,f));for(let M=0,T=u-1;M0?C.degRad:-C.degRad}for(let M=0,T=3;MC.PI?D-=C.PI2:D<-C.PI&&(D+=C.PI2),D*=n,X=Math.cos(D),L=Math.sin(D),I.a=X*Y-L*q,I.c=X*N-L*z,I.b=L*Y+X*q,I.d=L*N+X*z}k.appliedValid=!1}}computeWorldPositions(t,n,e,i,r){const h=this.target;let l=this.position;const s=this.spaces,a=v.setArraySize(this.positions,n*3+2);let o=null;const d=t.closed;let f=t.worldVerticesLength,u=f/6,m=nn.NONE;if(!t.constantSpeed){const D=t.lengths;u-=d?1:2;const X=D[u];if(i&&(l*=X),r)for(let L=0;LX){m!=nn.AFTER&&(m=nn.AFTER,t.computeWorldVertices(h,f-6,4,o,0,2)),this.addAfterPosition($-X,o,0,a,O);continue}for(;;W++){const G=D[W];if(!($>G)){if(W==0)$/=G;else{const lt=D[W-1];$=($-lt)/(G-lt)}break}}W!=m&&(m=W,d&&W==u?(t.computeWorldVertices(h,f-4,4,o,0,2),t.computeWorldVertices(h,0,4,o,4,2)):t.computeWorldVertices(h,W*6+2,8,o,0,2)),this.addCurvePosition($,o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7],a,O,e||L>0&&U==0)}return a}d?(f+=2,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f-4,o,0,2),t.computeWorldVertices(h,0,2,o,f-4,2),o[f-2]=o[0],o[f-1]=o[1]):(u--,f-=4,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f,o,0,2));const g=v.setArraySize(this.curves,u);let x=0,E=o[0],w=o[1],b=0,p=0,S=0,y=0,M=0,T=0,k=0,I=0,R=0,V=0,F=0,B=0,Y=0,N=0;for(let D=0,X=2;Dx){this.addAfterPosition(U-x,o,f-4,a,X);continue}for(;;L++){const $=g[L];if(!(U>$)){if(L==0)U/=$;else{const G=g[L-1];U=(U-G)/($-G)}break}}if(L!=m){m=L;let $=L*6;for(E=o[$],w=o[$+1],b=o[$+2],p=o[$+3],S=o[$+4],y=o[$+5],M=o[$+6],T=o[$+7],k=(E-b*2+S)*.03,I=(w-p*2+y)*.03,R=((b-S)*3-E+M)*.006,V=((p-y)*3-w+T)*.006,F=k*2+R,B=I*2+V,Y=(b-E)*.3+k+R*.16666667,N=(p-w)*.3+I+V*.16666667,z=Math.sqrt(Y*Y+N*N),q[0]=z,$=1;$<8;$++)Y+=F,N+=B,F+=R,B+=V,z+=Math.sqrt(Y*Y+N*N),q[$]=z;Y+=F,N+=B,z+=Math.sqrt(Y*Y+N*N),q[8]=z,Y+=F+R,N+=B+V,z+=Math.sqrt(Y*Y+N*N),q[9]=z,O=0}for(U*=z;;O++){const $=q[O];if(!(U>$)){if(O==0)U/=$;else{const G=q[O-1];U=O+(U-G)/($-G)}break}}this.addCurvePosition(U*.1,E,w,b,p,S,y,M,T,a,X,e||D>0&&W==0)}return a}addBeforePosition(t,n,e,i,r){const h=n[e],l=n[e+1],s=n[e+2]-h,a=n[e+3]-l,o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addAfterPosition(t,n,e,i,r){const h=n[e+2],l=n[e+3],s=h-n[e],a=l-n[e+1],o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addCurvePosition(t,n,e,i,r,h,l,s,a,o,d,f){(t==0||isNaN(t))&&(t=1e-4);const u=t*t,m=u*t,g=1-t,x=g*g,E=x*g,w=g*t,b=w*3,p=g*b,S=b*t,y=n*E+i*p+h*S+s*m,M=e*E+r*p+l*S+a*m;o[d]=y,o[d+1]=M,f&&(o[d+2]=Math.atan2(M-(e*x+r*w*2+l*u),y-(n*x+i*w*2+h*u)))}};let pn=nn;pn.NONE=-1,pn.BEFORE=-2,pn.AFTER=-3,pn.epsilon=1e-5;let Yi=class{constructor(t,n){if(this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.temp=new un,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.rotateMix=t.rotateMix,this.translateMix=t.translateMix,this.scaleMix=t.scaleMix,this.shearMix=t.shearMix,this.bones=new Array;for(let e=0;e0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=(p.x-b.tx)*n,b.ty+=(p.y-b.ty)*n,w=!0}if(e>0){let p=Math.sqrt(b.a*b.a+b.b*b.b),S=Math.sqrt(l*l+a*a);p>1e-5&&(p=(p+(S-p+this.data.offsetScaleX)*e)/p),b.a*=p,b.b*=p,p=Math.sqrt(b.c*b.c+b.d*b.d),S=Math.sqrt(s*s+o*o),p>1e-5&&(p=(p+(S-p+this.data.offsetScaleY)*e)/p),b.c*=p,b.d*=p,w=!0}if(i>0){const p=b.c,S=b.d,y=Math.atan2(S,p);let M=Math.atan2(o,s)-Math.atan2(a,l)-(y-Math.atan2(b.b,b.a));M>C.PI?M-=C.PI2:M<-C.PI&&(M+=C.PI2),M=y+(M+u)*i;const T=Math.sqrt(p*p+S*S);b.c=Math.cos(M)*T,b.d=Math.sin(M)*T,w=!0}w&&(E.appliedValid=!1)}}applyRelativeWorld(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target,h=r.matrix,l=h.a,s=h.c,a=h.b,o=h.d,d=l*o-s*a>0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=p.x*n,b.ty+=p.y*n,w=!0}if(e>0){let p=(Math.sqrt(l*l+a*a)-1+this.data.offsetScaleX)*e+1;b.a*=p,b.b*=p,p=(Math.sqrt(s*s+o*o)-1+this.data.offsetScaleY)*e+1,b.c*=p,b.d*=p,w=!0}if(i>0){let p=Math.atan2(o,s)-Math.atan2(a,l);p>C.PI?p-=C.PI2:p<-C.PI&&(p+=C.PI2);const S=b.c,y=b.d;p=Math.atan2(y,S)+(p-C.PI/2+u)*i;const M=Math.sqrt(S*S+y*y);b.c=Math.cos(p)*M,b.d=Math.sin(p)*M,w=!0}w&&(E.appliedValid=!1)}}applyAbsoluteLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u=(u+(r.ascaleX-u+this.data.offsetScaleX)*e)/u),m>1e-5&&(m=(m+(r.ascaleY-m+this.data.offsetScaleY)*e)/m));const g=a.ashearY;if(i>0){let x=r.ashearY-g+this.data.offsetShearY;x-=(16384-(16384.499999999996-x/360|0))*360,a.shearY+=x*i}a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}applyRelativeLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u*=(r.ascaleX-1+this.data.offsetScaleX)*e+1),m>1e-5&&(m*=(r.ascaleY-1+this.data.offsetScaleY)*e+1));let g=a.ashearY;i>0&&(g+=(r.ashearY+this.data.offsetShearY)*i),a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}};const Tn=class{constructor(t){if(this._updateCache=new Array,this.updateCacheReset=new Array,this.time=0,this.scaleX=1,this.scaleY=1,this.x=0,this.y=0,t==null)throw new Error("data cannot be null.");this.data=t,this.bones=new Array;for(let n=0;n1){const r=e[e.length-1];this._updateCache.indexOf(r)>-1||this.updateCacheReset.push(r)}this._updateCache.push(t),this.sortReset(i.children),e[e.length-1].sorted=!0}sortPathConstraint(t){if(t.active=t.target.bone.isActive()&&(!t.data.skinRequired||this.skin!=null&&v.contains(this.skin.constraints,t.data,!0)),!t.active)return;const n=t.target,e=n.data.index,i=n.bone;this.skin!=null&&this.sortPathConstraintAttachment(this.skin,e,i),this.data.defaultSkin!=null&&this.data.defaultSkin!=this.skin&&this.sortPathConstraintAttachment(this.data.defaultSkin,e,i);for(let s=0,a=this.data.skins.length;s-1||this.updateCacheReset.push(r)}else for(let i=0;i= 0.");if(n==null)throw new Error("name cannot be null.");if(e==null)throw new Error("boneData cannot be null.");this.index=t,this.name=n,this.boneData=e}},Cs=class extends Nn{constructor(t){super(t,0,!1),this.bones=new Array,this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.offsetRotation=0,this.offsetX=0,this.offsetY=0,this.offsetScaleX=0,this.offsetScaleY=0,this.offsetShearY=0,this.relative=!1,this.local=!1}},Ts=class{constructor(t,n,e){this.slotIndex=t,this.name=n,this.attachment=e}},Bn=class{constructor(t){if(this.attachments=new Array,this.bones=Array(),this.constraints=new Array,t==null)throw new Error("name cannot be null.");this.name=t}setAttachment(t,n,e){if(e==null)throw new Error("attachment cannot be null.");const i=this.attachments;t>=i.length&&(i.length=t+1),i[t]||(i[t]={}),i[t][n]=e}addSkin(t){for(let e=0;e0){const o=new xn(s),d=n.slots.length;for(let f=0;f=0;b--)g[b]=-1;const x=v.newArray(d-m,0);let E=0,w=0;for(let b=0;b=0;b--)g[b]==-1&&(g[b]=x[--w]);o.setFrame(f,u,g)}e.push(o),r=Math.max(r,o.frames[s-1])}const a=c.readInt(!0);if(a>0){const o=new Yn(a);for(let d=0;d=0;w--)u[w]==-1&&(u[w]=g[--E])}s.setFrame(o++,this.getValue(f,"time",0),u)}r.push(s),h=Math.max(h,s.frames[s.getFrameCount()-1])}if(t.events){const s=new Yn(t.events.length);let a=0;for(let o=0;o>1)*h;const l=t.bone.skeleton,s=t.attachmentVertices;let a=this.vertices;const o=this.bones;if(o==null){s.length>0&&(a=s);const m=t.bone.matrix,g=m.tx,x=m.ty,E=m.a,w=m.c,b=m.b,p=m.d;for(let S=n,y=r;y0&&(n%=this.duration));const a=this.timelines;for(let o=0,d=a.length;o>>1;for(;;){if(t[(h+1)*e]<=n?i=h+1:r=h,i==r)return(i+1)*e;h=i+r>>>1}}static linearSearch(t,n,e){for(let i=0,r=t.length-e;i<=r;i+=e)if(t[i]>n)return i;return-1}};var Oi=(c=>(c[c.rotate=0]="rotate",c[c.translate=1]="translate",c[c.scale=2]="scale",c[c.shear=3]="shear",c[c.attachment=4]="attachment",c[c.color=5]="color",c[c.deform=6]="deform",c[c.event=7]="event",c[c.drawOrder=8]="drawOrder",c[c.ikConstraint=9]="ikConstraint",c[c.transformConstraint=10]="transformConstraint",c[c.pathConstraintPosition=11]="pathConstraintPosition",c[c.pathConstraintSpacing=12]="pathConstraintSpacing",c[c.pathConstraintMix=13]="pathConstraintMix",c[c.twoColor=14]="twoColor",c))(Oi||{});const At=class{constructor(c){if(c<=0)throw new Error(`frameCount must be > 0: ${c}`);this.curves=v.newFloatArray((c-1)*At.BEZIER_SIZE)}getFrameCount(){return this.curves.length/At.BEZIER_SIZE+1}setLinear(c){this.curves[c*At.BEZIER_SIZE]=At.LINEAR}setStepped(c){this.curves[c*At.BEZIER_SIZE]=At.STEPPED}getCurveType(c){const t=c*At.BEZIER_SIZE;if(t==this.curves.length)return At.LINEAR;const n=this.curves[t];return n==At.LINEAR?At.LINEAR:n==At.STEPPED?At.STEPPED:At.BEZIER}setCurve(c,t,n,e,i){const r=(-t*2+e)*.03,h=(-n*2+i)*.03,l=((t-e)*3+1)*.006,s=((n-i)*3+1)*.006;let a=r*2+l,o=h*2+s,d=t*.3+r+l*.16666667,f=n*.3+h+s*.16666667,u=c*At.BEZIER_SIZE;const m=this.curves;m[u++]=At.BEZIER;let g=d,x=f;for(let E=u+At.BEZIER_SIZE-1;u=t){let a,o;return e==l?(a=0,o=0):(a=n[e-2],o=n[e-1]),o+(n[e+1]-o)*(t-a)/(r-a)}const h=n[e-1];return h+(1-h)*(t-r)/(1-r)}};let jt=At;jt.LINEAR=0,jt.STEPPED=1,jt.BEZIER=2,jt.BEZIER_SIZE=10*2-1;const je=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c<<1)}getPropertyId(){return(0<<24)+this.boneIndex}setFrame(c,t,n){c<<=1,this.frames[c]=t,this.frames[c+je.ROTATION]=n}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.bones[this.boneIndex];if(n=l[l.length-je.ENTRIES]){let m=l[l.length+je.PREV_ROTATION];switch(r){case A.setup:s.rotation=s.data.rotation+m*i;break;case A.first:case A.replace:m+=s.data.rotation-s.rotation,m-=(16384-(16384.499999999996-m/360|0))*360;case A.add:s.rotation+=m*i}return}const a=Ct.binarySearch(l,n,je.ENTRIES),o=l[a+je.PREV_ROTATION],d=l[a],f=this.getCurvePercent((a>>1)-1,1-(n-d)/(l[a+je.PREV_TIME]-d));let u=l[a+je.ROTATION]-o;switch(u=o+(u-(16384-(16384.499999999996-u/360|0))*360)*f,r){case A.setup:s.rotation=s.data.rotation+(u-(16384-(16384.499999999996-u/360|0))*360)*i;break;case A.first:case A.replace:u+=s.data.rotation-s.rotation;case A.add:s.rotation+=(u-(16384-(16384.499999999996-u/360|0))*360)*i}}};let $t=je;$t.ENTRIES=2,$t.PREV_TIME=-2,$t.PREV_ROTATION=-1,$t.ROTATION=1;const Wt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*Wt.ENTRIES)}getPropertyId(){return(1<<24)+this.boneIndex}setFrame(c,t,n,e){c*=Wt.ENTRIES,this.frames[c]=t,this.frames[c+Wt.X]=n,this.frames[c+Wt.Y]=e}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.bones[this.boneIndex];if(n=l[l.length-Wt.ENTRIES])a=l[l.length+Wt.PREV_X],o=l[l.length+Wt.PREV_Y];else{const d=Ct.binarySearch(l,n,Wt.ENTRIES);a=l[d+Wt.PREV_X],o=l[d+Wt.PREV_Y];const f=l[d],u=this.getCurvePercent(d/Wt.ENTRIES-1,1-(n-f)/(l[d+Wt.PREV_TIME]-f));a+=(l[d+Wt.X]-a)*u,o+=(l[d+Wt.Y]-o)*u}switch(r){case A.setup:s.x=s.data.x+a*i,s.y=s.data.y+o*i;break;case A.first:case A.replace:s.x+=(s.data.x+a-s.x)*i,s.y+=(s.data.y+o-s.y)*i;break;case A.add:s.x+=a*i,s.y+=o*i}}};let ge=Wt;ge.ENTRIES=3,ge.PREV_TIME=-3,ge.PREV_X=-2,ge.PREV_Y=-1,ge.X=1,ge.Y=2;let le=class extends ge{constructor(t){super(t)}getPropertyId(){return(2<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(e=s[s.length-le.ENTRIES])o=s[s.length+le.PREV_X]*a.data.scaleX,d=s[s.length+le.PREV_Y]*a.data.scaleY;else{const f=Ct.binarySearch(s,e,le.ENTRIES);o=s[f+le.PREV_X],d=s[f+le.PREV_Y];const u=s[f],m=this.getCurvePercent(f/le.ENTRIES-1,1-(e-u)/(s[f+le.PREV_TIME]-u));o=(o+(s[f+le.X]-o)*m)*a.data.scaleX,d=(d+(s[f+le.Y]-d)*m)*a.data.scaleY}if(r==1)h==A.add?(a.scaleX+=o-a.data.scaleX,a.scaleY+=d-a.data.scaleY):(a.scaleX=o,a.scaleY=d);else{let f=0,u=0;if(l==J.mixOut)switch(h){case A.setup:f=a.data.scaleX,u=a.data.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.first:case A.replace:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.add:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-a.data.scaleX)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-a.data.scaleY)*r}else switch(h){case A.setup:f=Math.abs(a.data.scaleX)*C.signum(o),u=Math.abs(a.data.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.first:case A.replace:f=Math.abs(a.scaleX)*C.signum(o),u=Math.abs(a.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.add:f=C.signum(o),u=C.signum(d),a.scaleX=Math.abs(a.scaleX)*f+(o-Math.abs(a.data.scaleX)*f)*r,a.scaleY=Math.abs(a.scaleY)*u+(d-Math.abs(a.data.scaleY)*u)*r}}}},ce=class extends ge{constructor(t){super(t)}getPropertyId(){return(3<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(e=s[s.length-ce.ENTRIES])o=s[s.length+ce.PREV_X],d=s[s.length+ce.PREV_Y];else{const f=Ct.binarySearch(s,e,ce.ENTRIES);o=s[f+ce.PREV_X],d=s[f+ce.PREV_Y];const u=s[f],m=this.getCurvePercent(f/ce.ENTRIES-1,1-(e-u)/(s[f+ce.PREV_TIME]-u));o=o+(s[f+ce.X]-o)*m,d=d+(s[f+ce.Y]-d)*m}switch(h){case A.setup:a.shearX=a.data.shearX+o*r,a.shearY=a.data.shearY+d*r;break;case A.first:case A.replace:a.shearX+=(a.data.shearX+o-a.shearX)*r,a.shearY+=(a.data.shearY+d-a.shearY)*r;break;case A.add:a.shearX+=o*r,a.shearY+=d*r}}};const gt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*gt.ENTRIES)}getPropertyId(){return(5<<24)+this.slotIndex}setFrame(c,t,n,e,i,r){c*=gt.ENTRIES,this.frames[c]=t,this.frames[c+gt.R]=n,this.frames[c+gt.G]=e,this.frames[c+gt.B]=i,this.frames[c+gt.A]=r}apply(c,t,n,e,i,r,h){const l=c.slots[this.slotIndex],s=this.frames;if(n=s[s.length-gt.ENTRIES]){const u=s.length;a=s[u+gt.PREV_R],o=s[u+gt.PREV_G],d=s[u+gt.PREV_B],f=s[u+gt.PREV_A]}else{const u=Ct.binarySearch(s,n,gt.ENTRIES);a=s[u+gt.PREV_R],o=s[u+gt.PREV_G],d=s[u+gt.PREV_B],f=s[u+gt.PREV_A];const m=s[u],g=this.getCurvePercent(u/gt.ENTRIES-1,1-(n-m)/(s[u+gt.PREV_TIME]-m));a+=(s[u+gt.R]-a)*g,o+=(s[u+gt.G]-o)*g,d+=(s[u+gt.B]-d)*g,f+=(s[u+gt.A]-f)*g}if(i==1)l.color.set(a,o,d,f);else{const u=l.color;r==A.setup&&u.setFromColor(l.data.color),u.add((a-u.r)*i,(o-u.g)*i,(d-u.b)*i,(f-u.a)*i)}}};let se=gt;se.ENTRIES=5,se.PREV_TIME=-5,se.PREV_R=-4,se.PREV_G=-3,se.PREV_B=-2,se.PREV_A=-1,se.R=1,se.G=2,se.B=3,se.A=4;const st=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*st.ENTRIES)}getPropertyId(){return(14<<24)+this.slotIndex}setFrame(c,t,n,e,i,r,h,l,s){c*=st.ENTRIES,this.frames[c]=t,this.frames[c+st.R]=n,this.frames[c+st.G]=e,this.frames[c+st.B]=i,this.frames[c+st.A]=r,this.frames[c+st.R2]=h,this.frames[c+st.G2]=l,this.frames[c+st.B2]=s}apply(c,t,n,e,i,r,h){const l=c.slots[this.slotIndex],s=this.frames;if(n=s[s.length-st.ENTRIES]){const x=s.length;a=s[x+st.PREV_R],o=s[x+st.PREV_G],d=s[x+st.PREV_B],f=s[x+st.PREV_A],u=s[x+st.PREV_R2],m=s[x+st.PREV_G2],g=s[x+st.PREV_B2]}else{const x=Ct.binarySearch(s,n,st.ENTRIES);a=s[x+st.PREV_R],o=s[x+st.PREV_G],d=s[x+st.PREV_B],f=s[x+st.PREV_A],u=s[x+st.PREV_R2],m=s[x+st.PREV_G2],g=s[x+st.PREV_B2];const E=s[x],w=this.getCurvePercent(x/st.ENTRIES-1,1-(n-E)/(s[x+st.PREV_TIME]-E));a+=(s[x+st.R]-a)*w,o+=(s[x+st.G]-o)*w,d+=(s[x+st.B]-d)*w,f+=(s[x+st.A]-f)*w,u+=(s[x+st.R2]-u)*w,m+=(s[x+st.G2]-m)*w,g+=(s[x+st.B2]-g)*w}if(i==1)l.color.set(a,o,d,f),l.darkColor.set(u,m,g,1);else{const x=l.color,E=l.darkColor;r==A.setup&&(x.setFromColor(l.data.color),E.setFromColor(l.data.darkColor)),x.add((a-x.r)*i,(o-x.g)*i,(d-x.b)*i,(f-x.a)*i),E.add((u-E.r)*i,(m-E.g)*i,(g-E.b)*i,0)}}};let Tt=st;Tt.ENTRIES=8,Tt.PREV_TIME=-8,Tt.PREV_R=-7,Tt.PREV_G=-6,Tt.PREV_B=-5,Tt.PREV_A=-4,Tt.PREV_R2=-3,Tt.PREV_G2=-2,Tt.PREV_B2=-1,Tt.R=1,Tt.G=2,Tt.B=3,Tt.A=4,Tt.R2=5,Tt.G2=6,Tt.B2=7;let Dn=class{constructor(t){this.frames=v.newFloatArray(t),this.attachmentNames=new Array(t)}getPropertyId(){return(4<<24)+this.slotIndex}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.attachmentNames[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(l==J.mixOut&&h==A.setup){const f=s.data.attachmentName;s.setAttachment(f==null?null:t.getAttachment(this.slotIndex,f));return}const a=this.frames;if(e=a[a.length-1]?o=a.length-1:o=Ct.binarySearch(a,e,1)-1;const d=this.attachmentNames[o];t.slots[this.slotIndex].setAttachment(d==null?null:t.getAttachment(this.slotIndex,d))}},$i=null,Wi=class extends jt{constructor(t){super(t),this.frames=v.newFloatArray(t),this.frameVertices=new Array(t),$i==null&&($i=v.newFloatArray(64))}getPropertyId(){return(6<<27)+Number(this.attachment.id)+this.slotIndex}setFrame(t,n,e){this.frames[t]=n,this.frameVertices[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex],a=s.getAttachment();if(!(a instanceof Ge)||!a.applyDeform(this.attachment))return;const o=s.attachmentVertices;o.length==0&&(h=A.setup);const d=this.frameVertices,f=d[0].length,u=this.frames;if(e=u[u.length-1]){const p=d[u.length-1];if(r==1)if(h==A.add){const S=a;if(S.bones==null){const y=S.vertices;for(let M=0;Me)this.apply(t,n,Number.MAX_VALUE,i,r,h,l),n=-1;else if(n>=s[a-1])return;if(e0&&s[o-1]==d;)o--}for(;o=s[o];o++)i.push(this.events[o])}},Ln=class{constructor(t){this.frames=v.newFloatArray(t),this.drawOrders=new Array(t)}getPropertyId(){return 8<<24}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.drawOrders[t]=e}apply(t,n,e,i,r,h,l){const s=t.drawOrder,a=t.slots;if(l==J.mixOut&&h==A.setup){v.arrayCopy(t.slots,0,t.drawOrder,0,t.slots.length);return}const o=this.frames;if(e=o[o.length-1]?d=o.length-1:d=Ct.binarySearch(o,e)-1;const f=this.drawOrders[d];if(f==null)v.arrayCopy(a,0,s,0,a.length);else for(let u=0,m=f.length;u=l[l.length-ht.ENTRIES]){r==A.setup?(s.mix=s.data.mix+(l[l.length+ht.PREV_MIX]-s.data.mix)*i,h==J.mixOut?(s.bendDirection=s.data.bendDirection,s.compress=s.data.compress,s.stretch=s.data.stretch):(s.bendDirection=l[l.length+ht.PREV_BEND_DIRECTION],s.compress=l[l.length+ht.PREV_COMPRESS]!=0,s.stretch=l[l.length+ht.PREV_STRETCH]!=0)):(s.mix+=(l[l.length+ht.PREV_MIX]-s.mix)*i,h==J.mixIn&&(s.bendDirection=l[l.length+ht.PREV_BEND_DIRECTION],s.compress=l[l.length+ht.PREV_COMPRESS]!=0,s.stretch=l[l.length+ht.PREV_STRETCH]!=0));return}const a=Ct.binarySearch(l,n,ht.ENTRIES),o=l[a+ht.PREV_MIX],d=l[a],f=this.getCurvePercent(a/ht.ENTRIES-1,1-(n-d)/(l[a+ht.PREV_TIME]-d));r==A.setup?(s.mix=s.data.mix+(o+(l[a+ht.MIX]-o)*f-s.data.mix)*i,h==J.mixOut?(s.bendDirection=s.data.bendDirection,s.compress=s.data.compress,s.stretch=s.data.stretch):(s.bendDirection=l[a+ht.PREV_BEND_DIRECTION],s.compress=l[a+ht.PREV_COMPRESS]!=0,s.stretch=l[a+ht.PREV_STRETCH]!=0)):(s.mix+=(o+(l[a+ht.MIX]-o)*f-s.mix)*i,h==J.mixIn&&(s.bendDirection=l[a+ht.PREV_BEND_DIRECTION],s.compress=l[a+ht.PREV_COMPRESS]!=0,s.stretch=l[a+ht.PREV_STRETCH]!=0))}};let ie=ht;ie.ENTRIES=5,ie.PREV_TIME=-5,ie.PREV_MIX=-4,ie.PREV_BEND_DIRECTION=-3,ie.PREV_COMPRESS=-2,ie.PREV_STRETCH=-1,ie.MIX=1,ie.BEND_DIRECTION=2,ie.COMPRESS=3,ie.STRETCH=4;const xt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*xt.ENTRIES)}getPropertyId(){return(10<<24)+this.transformConstraintIndex}setFrame(c,t,n,e,i,r){c*=xt.ENTRIES,this.frames[c]=t,this.frames[c+xt.ROTATE]=n,this.frames[c+xt.TRANSLATE]=e,this.frames[c+xt.SCALE]=i,this.frames[c+xt.SHEAR]=r}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.transformConstraints[this.transformConstraintIndex];if(n=l[l.length-xt.ENTRIES]){const u=l.length;a=l[u+xt.PREV_ROTATE],o=l[u+xt.PREV_TRANSLATE],d=l[u+xt.PREV_SCALE],f=l[u+xt.PREV_SHEAR]}else{const u=Ct.binarySearch(l,n,xt.ENTRIES);a=l[u+xt.PREV_ROTATE],o=l[u+xt.PREV_TRANSLATE],d=l[u+xt.PREV_SCALE],f=l[u+xt.PREV_SHEAR];const m=l[u],g=this.getCurvePercent(u/xt.ENTRIES-1,1-(n-m)/(l[u+xt.PREV_TIME]-m));a+=(l[u+xt.ROTATE]-a)*g,o+=(l[u+xt.TRANSLATE]-o)*g,d+=(l[u+xt.SCALE]-d)*g,f+=(l[u+xt.SHEAR]-f)*g}if(r==A.setup){const u=s.data;s.rotateMix=u.rotateMix+(a-u.rotateMix)*i,s.translateMix=u.translateMix+(o-u.translateMix)*i,s.scaleMix=u.scaleMix+(d-u.scaleMix)*i,s.shearMix=u.shearMix+(f-u.shearMix)*i}else s.rotateMix+=(a-s.rotateMix)*i,s.translateMix+=(o-s.translateMix)*i,s.scaleMix+=(d-s.scaleMix)*i,s.shearMix+=(f-s.shearMix)*i}};let re=xt;re.ENTRIES=5,re.PREV_TIME=-5,re.PREV_ROTATE=-4,re.PREV_TRANSLATE=-3,re.PREV_SCALE=-2,re.PREV_SHEAR=-1,re.ROTATE=1,re.TRANSLATE=2,re.SCALE=3,re.SHEAR=4;const xe=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*xe.ENTRIES)}getPropertyId(){return(11<<24)+this.pathConstraintIndex}setFrame(c,t,n){c*=xe.ENTRIES,this.frames[c]=t,this.frames[c+xe.VALUE]=n}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.pathConstraints[this.pathConstraintIndex];if(n=l[l.length-xe.ENTRIES])a=l[l.length+xe.PREV_VALUE];else{const o=Ct.binarySearch(l,n,xe.ENTRIES);a=l[o+xe.PREV_VALUE];const d=l[o],f=this.getCurvePercent(o/xe.ENTRIES-1,1-(n-d)/(l[o+xe.PREV_TIME]-d));a+=(l[o+xe.VALUE]-a)*f}r==A.setup?s.position=s.data.position+(a-s.data.position)*i:s.position+=(a-s.position)*i}};let Ze=xe;Ze.ENTRIES=2,Ze.PREV_TIME=-2,Ze.PREV_VALUE=-1,Ze.VALUE=1;let Xe=class extends Ze{constructor(t){super(t)}getPropertyId(){return(12<<24)+this.pathConstraintIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(e=s[s.length-Xe.ENTRIES])o=s[s.length+Xe.PREV_VALUE];else{const d=Ct.binarySearch(s,e,Xe.ENTRIES);o=s[d+Xe.PREV_VALUE];const f=s[d],u=this.getCurvePercent(d/Xe.ENTRIES-1,1-(e-f)/(s[d+Xe.PREV_TIME]-f));o+=(s[d+Xe.VALUE]-o)*u}h==A.setup?a.spacing=a.data.spacing+(o-a.data.spacing)*r:a.spacing+=(o-a.spacing)*r}};const qt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*qt.ENTRIES)}getPropertyId(){return(13<<24)+this.pathConstraintIndex}setFrame(c,t,n,e){c*=qt.ENTRIES,this.frames[c]=t,this.frames[c+qt.ROTATE]=n,this.frames[c+qt.TRANSLATE]=e}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.pathConstraints[this.pathConstraintIndex];if(n=l[l.length-qt.ENTRIES])a=l[l.length+qt.PREV_ROTATE],o=l[l.length+qt.PREV_TRANSLATE];else{const d=Ct.binarySearch(l,n,qt.ENTRIES);a=l[d+qt.PREV_ROTATE],o=l[d+qt.PREV_TRANSLATE];const f=l[d],u=this.getCurvePercent(d/qt.ENTRIES-1,1-(n-f)/(l[d+qt.PREV_TIME]-f));a+=(l[d+qt.ROTATE]-a)*u,o+=(l[d+qt.TRANSLATE]-o)*u}r==A.setup?(s.rotateMix=s.data.rotateMix+(a-s.data.rotateMix)*i,s.translateMix=s.data.translateMix+(o-s.data.translateMix)*i):(s.rotateMix+=(a-s.rotateMix)*i,s.translateMix+=(o-s.translateMix)*i)}};let Ne=qt;Ne.ENTRIES=3,Ne.PREV_TIME=-3,Ne.PREV_ROTATE=-2,Ne.PREV_TRANSLATE=-1,Ne.ROTATE=1,Ne.TRANSLATE=2;const Pt=class{constructor(t){this.tracks=new Array,this.events=new Array,this.listeners=new Array,this.queue=new Ps(this),this.propertyIDs=new ns,this.animationsChanged=!1,this.timeScale=1,this.trackEntryPool=new An(()=>new _n),this.data=t}update(t){t*=this.timeScale;const n=this.tracks;for(let e=0,i=n.length;e0){if(r.delay-=h,r.delay>0)continue;h=-r.delay,r.delay=0}let l=r.next;if(l!=null){const s=r.trackLast-l.delay;if(s>=0){for(l.delay=0,l.trackTime=r.timeScale==0?0:(s/r.timeScale+t)*l.timeScale,r.trackTime+=h,this.setCurrent(e,l,!0);l.mixingFrom!=null;)l.mixTime+=t,l=l.mixingFrom;continue}}else if(r.trackLast>=r.trackEnd&&r.mixingFrom==null){n[e]=null,this.queue.end(r),this.disposeNext(r);continue}if(r.mixingFrom!=null&&this.updateMixingFrom(r,t)){let s=r.mixingFrom;for(r.mixingFrom=null,s!=null&&(s.mixingTo=null);s!=null;)this.queue.end(s),s=s.mixingFrom}r.trackTime+=h}this.queue.drain()}updateMixingFrom(t,n){const e=t.mixingFrom;if(e==null)return!0;const i=this.updateMixingFrom(e,n);return e.animationLast=e.nextAnimationLast,e.trackLast=e.nextTrackLast,t.mixTime>0&&t.mixTime>=t.mixDuration?((e.totalAlpha==0||t.mixDuration==0)&&(t.mixingFrom=e.mixingFrom,e.mixingFrom!=null&&(e.mixingFrom.mixingTo=t),t.interruptAlpha=e.interruptAlpha,this.queue.end(e)),i):(e.trackTime+=n*e.timeScale,t.mixTime+=n,!1)}apply(t){if(t==null)throw new Error("skeleton cannot be null.");this.animationsChanged&&this._animationsChanged();const n=this.events,e=this.tracks;let i=!1;for(let r=0,h=e.length;r0)continue;i=!0;const s=r==0?A.first:l.mixBlend;let a=l.alpha;l.mixingFrom!=null?a*=this.applyMixingFrom(l,t,s):l.trackTime>=l.trackEnd&&l.next==null&&(a=0);const o=l.animationLast,d=l.getAnimationTime(),f=l.animation.timelines.length,u=l.animation.timelines;if(r==0&&a==1||s==A.add)for(let m=0;m1&&(r=1),e!=A.first&&(e=i.mixBlend));const h=r0&&this.queueEvents(i,o),this.events.length=0,i.nextAnimationLast=o,i.nextTrackLast=i.trackTime,r}applyRotateTimeline(t,n,e,i,r,h,l,s){if(s&&(h[l]=0),i==1){t.apply(n,0,e,null,1,r,J.mixIn);return}const a=t,o=a.frames,d=n.bones[a.boneIndex];let f=0,u=0;if(e=o[o.length-$t.ENTRIES])u=d.data.rotation+o[o.length+$t.PREV_ROTATION];else{const x=Ct.binarySearch(o,e,$t.ENTRIES),E=o[x+$t.PREV_ROTATION],w=o[x],b=a.getCurvePercent((x>>1)-1,1-(e-w)/(o[x+$t.PREV_TIME]-w));u=o[x+$t.ROTATION]-E,u-=(16384-(16384.499999999996-u/360|0))*360,u=E+u*b+d.data.rotation,u-=(16384-(16384.499999999996-u/360|0))*360}let m=0,g=u-f;if(g-=(16384-(16384.499999999996-g/360|0))*360,g==0)m=h[l];else{let x=0,E=0;s?(x=0,E=g):(x=h[l],E=h[l+1]);const w=g>0;let b=x>=0;C.signum(E)!=C.signum(g)&&Math.abs(E)<=90&&(Math.abs(x)>180&&(x+=360*C.signum(x)),b=w),m=g+x-x%360,b!=w&&(m+=360*C.signum(x)),h[l]=m}h[l+1]=g,f+=m*i,d.rotation=f-(16384-(16384.499999999996-f/360|0))*360}queueEvents(t,n){const e=t.animationStart,i=t.animationEnd,r=i-e,h=t.trackLast%r,l=this.events;let s=0;const a=l.length;for(;si||this.queue.event(t,d)}let o=!1;for(t.loop?o=r==0||h>t.trackTime%r:o=n>=i&&t.animationLast=this.tracks.length)return;const n=this.tracks[t];if(n==null)return;this.queue.end(n),this.disposeNext(n);let e=n;for(;;){const i=e.mixingFrom;if(i==null)break;this.queue.end(i),e.mixingFrom=null,e.mixingTo=null,e=i}this.tracks[n.trackIndex]=null,this.queue.drain()}setCurrent(t,n,e){const i=this.expandToIndex(t);this.tracks[t]=n,i!=null&&(e&&this.queue.interrupt(i),n.mixingFrom=i,i.mixingTo=n,n.mixTime=0,i.mixingFrom!=null&&i.mixDuration>0&&(n.interruptAlpha*=Math.min(1,i.mixTime/i.mixDuration)),i.timelinesRotation.length=0),this.queue.start(n)}setAnimation(t,n,e){const i=this.data.skeletonData.findAnimation(n);if(i==null)throw new Error(`Animation not found: ${n}`);return this.setAnimationWith(t,i,e)}setAnimationWith(t,n,e){if(n==null)throw new Error("animation cannot be null.");let i=!0,r=this.expandToIndex(t);r!=null&&(r.nextTrackLast==-1?(this.tracks[t]=r.mixingFrom,this.queue.interrupt(r),this.queue.end(r),this.disposeNext(r),r=r.mixingFrom,i=!1):this.disposeNext(r));const h=this.trackEntry(t,n,e,r);return this.setCurrent(t,h,i),this.queue.drain(),h}addAnimation(t,n,e,i){const r=this.data.skeletonData.findAnimation(n);if(r==null)throw new Error(`Animation not found: ${n}`);return this.addAnimationWith(t,r,e,i)}addAnimationWith(t,n,e,i){if(n==null)throw new Error("animation cannot be null.");let r=this.expandToIndex(t);if(r!=null)for(;r.next!=null;)r=r.next;const h=this.trackEntry(t,n,e,r);if(r==null)this.setCurrent(t,h,!0),this.queue.drain();else if(r.next=h,i<=0){const l=r.animationEnd-r.animationStart;l!=0?(r.loop?i+=l*(1+(r.trackTime/l|0)):i+=Math.max(l,r.trackTime),i-=this.data.getMix(r.animation,n)):i=r.trackTime}return h.delay=i,h}setEmptyAnimation(t,n){const e=this.setAnimationWith(t,Pt.emptyAnimation,!1);return e.mixDuration=n,e.trackEnd=n,e}addEmptyAnimation(t,n,e){e<=0&&(e-=n);const i=this.addAnimationWith(t,Pt.emptyAnimation,!1,e);return i.mixDuration=n,i.trackEnd=n,i}setEmptyAnimations(t){const n=this.queue.drainDisabled;this.queue.drainDisabled=!0;for(let e=0,i=this.tracks.length;e0){r[s]=Pt.HOLD_MIX,h[s]=o;continue t}break}r[s]=Pt.HOLD}}}hasTimeline(t,n){const e=t.animation.timelines;for(let i=0,r=e.length;i=this.tracks.length?null:this.tracks[t]}addListener(t){if(t==null)throw new Error("listener cannot be null.");this.listeners.push(t)}removeListener(t){const n=this.listeners.indexOf(t);n>=0&&this.listeners.splice(n,1)}clearListeners(){this.listeners.length=0}clearListenerNotifications(){this.queue.clear()}setAnimationByName(t,n,e){Pt.deprecatedWarning1||(Pt.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on.")),this.setAnimation(t,n,e)}addAnimationByName(t,n,e,i){Pt.deprecatedWarning2||(Pt.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on.")),this.addAnimation(t,n,e,i)}hasAnimation(t){return this.data.skeletonData.findAnimation(t)!==null}hasAnimationByName(t){return Pt.deprecatedWarning3||(Pt.deprecatedWarning3=!0,console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on.")),this.hasAnimation(t)}};let Ie=Pt;Ie.emptyAnimation=new Ct("",[],0),Ie.SUBSEQUENT=0,Ie.FIRST=1,Ie.HOLD=2,Ie.HOLD_MIX=3,Ie.deprecatedWarning1=!1,Ie.deprecatedWarning2=!1,Ie.deprecatedWarning3=!1;const Be=class{constructor(){this.mixBlend=A.replace,this.timelineMode=new Array,this.timelineHoldMix=new Array,this.timelinesRotation=new Array}reset(){this.next=null,this.mixingFrom=null,this.mixingTo=null,this.animation=null,this.listener=null,this.timelineMode.length=0,this.timelineHoldMix.length=0,this.timelinesRotation.length=0}getAnimationTime(){if(this.loop){const t=this.animationEnd-this.animationStart;return t==0?this.animationStart:this.trackTime%t+this.animationStart}return Math.min(this.trackTime+this.animationStart,this.animationEnd)}setAnimationLast(t){this.animationLast=t,this.nextAnimationLast=t}isComplete(){return this.trackTime>=this.animationEnd-this.animationStart}resetRotationDirections(){this.timelinesRotation.length=0}get time(){return Be.deprecatedWarning1||(Be.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime}set time(t){Be.deprecatedWarning1||(Be.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime=t}get endTime(){return Be.deprecatedWarning2||(Be.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime}set endTime(t){Be.deprecatedWarning2||(Be.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime=t}loopsCount(){return Math.floor(this.trackTime/this.trackEnd)}};let _n=Be;_n.deprecatedWarning1=!1,_n.deprecatedWarning2=!1;const vs=class{constructor(c){this.objects=[],this.drainDisabled=!1,this.animState=c}start(c){this.objects.push(Zt.start),this.objects.push(c),this.animState.animationsChanged=!0}interrupt(c){this.objects.push(Zt.interrupt),this.objects.push(c)}end(c){this.objects.push(Zt.end),this.objects.push(c),this.animState.animationsChanged=!0}dispose(c){this.objects.push(Zt.dispose),this.objects.push(c)}complete(c){this.objects.push(Zt.complete),this.objects.push(c)}event(c,t){this.objects.push(Zt.event),this.objects.push(c),this.objects.push(t)}deprecateStuff(){return vs.deprecatedWarning1||(vs.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: onComplete, onStart, onEnd, onEvent art deprecated, please use listeners from now on. 'state.addListener({ complete: function(track, event) { } })'")),!0}drain(){if(this.drainDisabled)return;this.drainDisabled=!0;const c=this.objects,t=this.animState.listeners;for(let n=0;n(c[c.start=0]="start",c[c.interrupt=1]="interrupt",c[c.end=2]="end",c[c.dispose=3]="dispose",c[c.complete=4]="complete",c[c.event=5]="event",c))(Zt||{});class Dr{start(t){}interrupt(t){}end(t){}dispose(t){}complete(t){}event(t,n){}}const Vs=class{constructor(c){if(this.animationToMixTime={},this.defaultMix=0,c==null)throw new Error("skeletonData cannot be null.");this.skeletonData=c}setMix(c,t,n){const e=this.skeletonData.findAnimation(c);if(e==null)throw new Error(`Animation not found: ${c}`);const i=this.skeletonData.findAnimation(t);if(i==null)throw new Error(`Animation not found: ${t}`);this.setMixWith(e,i,n)}setMixByName(c,t,n){Vs.deprecatedWarning1||(Vs.deprecatedWarning1=!0,console.warn("Deprecation Warning: AnimationStateData.setMixByName is deprecated, please use setMix from now on.")),this.setMix(c,t,n)}setMixWith(c,t,n){if(c==null)throw new Error("from cannot be null.");if(t==null)throw new Error("to cannot be null.");const e=`${c.name}.${t.name}`;this.animationToMixTime[e]=n}getMix(c,t){const n=`${c.name}.${t.name}`,e=this.animationToMixTime[n];return e===void 0?this.defaultMix:e}};let Fs=Vs;Fs.deprecatedWarning1=!1;let Ui=class{constructor(t){this.atlas=t}newRegionAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (region attachment: ${n})`);const r=new K(n);return r.region=i,r}newMeshAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (mesh attachment: ${n})`);const r=new Is(n);return r.region=i,r}newBoundingBoxAttachment(t,n){return new Ni(n)}newPathAttachment(t,n){return new kn(n)}newPointAttachment(t,n){return new Di(n)}newClippingAttachment(t,n){return new Bi(n)}},Ys=class{constructor(t,n,e){if(this.matrix=new H.Matrix,this.children=new Array,this.x=0,this.y=0,this.rotation=0,this.scaleX=0,this.scaleY=0,this.shearX=0,this.shearY=0,this.ax=0,this.ay=0,this.arotation=0,this.ascaleX=0,this.ascaleY=0,this.ashearX=0,this.ashearY=0,this.appliedValid=!1,this.sorted=!1,this.active=!0,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.skeleton=n,this.parent=e,this.setToSetupPose()}get worldX(){return this.matrix.tx}get worldY(){return this.matrix.ty}update(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransform(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransformWith(t,n,e,i,r,h,l){this.ax=t,this.ay=n,this.arotation=e,this.ascaleX=i,this.ascaleY=r,this.ashearX=h,this.ashearY=l,this.appliedValid=!0;const s=this.parent,a=this.matrix,o=this.skeleton.scaleX,d=zt.yDown?-this.skeleton.scaleY:this.skeleton.scaleY;if(s==null){const x=this.skeleton,E=e+90+l;a.a=C.cosDeg(e+h)*i*o,a.c=C.cosDeg(E)*r*o,a.b=C.sinDeg(e+h)*i*d,a.d=C.sinDeg(E)*r*d,a.tx=t*o+x.x,a.ty=n*d+x.y;return}let f=s.matrix.a,u=s.matrix.c,m=s.matrix.b,g=s.matrix.d;switch(a.tx=f*t+u*n+s.matrix.tx,a.ty=m*t+g*n+s.matrix.ty,this.data.transformMode){case j.Normal:{const x=e+90+l,E=C.cosDeg(e+h)*i,w=C.cosDeg(x)*r,b=C.sinDeg(e+h)*i,p=C.sinDeg(x)*r;a.a=f*E+u*b,a.c=f*w+u*p,a.b=m*E+g*b,a.d=m*w+g*p;return}case j.OnlyTranslation:{const x=e+90+l;a.a=C.cosDeg(e+h)*i,a.c=C.cosDeg(x)*r,a.b=C.sinDeg(e+h)*i,a.d=C.sinDeg(x)*r;break}case j.NoRotationOrReflection:{let x=f*f+m*m,E=0;x>1e-4?(x=Math.abs(f*g-u*m)/x,u=m*x,g=f*x,E=Math.atan2(m,f)*C.radDeg):(f=0,m=0,E=90-Math.atan2(g,u)*C.radDeg);const w=e+h-E,b=e+l-E+90,p=C.cosDeg(w)*i,S=C.cosDeg(b)*r,y=C.sinDeg(w)*i,M=C.sinDeg(b)*r;a.a=f*p-u*y,a.c=f*S-u*M,a.b=m*p+g*y,a.d=m*S+g*M;break}case j.NoScale:case j.NoScaleOrReflection:{const x=C.cosDeg(e),E=C.sinDeg(e);let w=(f*x+u*E)/o,b=(m*x+g*E)/d,p=Math.sqrt(w*w+b*b);p>1e-5&&(p=1/p),w*=p,b*=p,p=Math.sqrt(w*w+b*b),this.data.transformMode==j.NoScale&&f*g-u*m<0!=(zt.yDown?this.skeleton.scaleX<0!=this.skeleton.scaleY>0:this.skeleton.scaleX<0!=this.skeleton.scaleY<0)&&(p=-p);const S=Math.PI/2+Math.atan2(b,w),y=Math.cos(S)*p,M=Math.sin(S)*p,T=C.cosDeg(h)*i,k=C.cosDeg(90+l)*r,I=C.sinDeg(h)*i,R=C.sinDeg(90+l)*r;a.a=w*T+y*I,a.c=w*k+y*R,a.b=b*T+M*I,a.d=b*k+M*R;break}}a.a*=o,a.c*=o,a.b*=d,a.d*=d}setToSetupPose(){const t=this.data;this.x=t.x,this.y=t.y,this.rotation=t.rotation,this.scaleX=t.scaleX,this.scaleY=t.scaleY,this.shearX=t.shearX,this.shearY=t.shearY}getWorldRotationX(){return Math.atan2(this.matrix.b,this.matrix.a)*C.radDeg}getWorldRotationY(){return Math.atan2(this.matrix.d,this.matrix.c)*C.radDeg}getWorldScaleX(){const t=this.matrix;return Math.sqrt(t.a*t.a+t.c*t.c)}getWorldScaleY(){const t=this.matrix;return Math.sqrt(t.b*t.b+t.d*t.d)}updateAppliedTransform(){this.appliedValid=!0;const t=this.parent,n=this.matrix;if(t==null){this.ax=n.tx,this.ay=n.ty,this.arotation=Math.atan2(n.b,n.a)*C.radDeg,this.ascaleX=Math.sqrt(n.a*n.a+n.b*n.b),this.ascaleY=Math.sqrt(n.c*n.c+n.d*n.d),this.ashearX=0,this.ashearY=Math.atan2(n.a*n.c+n.b*n.d,n.a*n.d-n.b*n.c)*C.radDeg;return}const e=t.matrix,i=1/(e.a*e.d-e.b*e.c),r=n.tx-e.tx,h=n.ty-e.ty;this.ax=r*e.d*i-h*e.c*i,this.ay=h*e.a*i-r*e.b*i;const l=i*e.d,s=i*e.a,a=i*e.c,o=i*e.b,d=l*n.a-a*n.b,f=l*n.c-a*n.d,u=s*n.b-o*n.a,m=s*n.d-o*n.c;if(this.ashearX=0,this.ascaleX=Math.sqrt(d*d+u*u),this.ascaleX>1e-4){const g=d*m-f*u;this.ascaleY=g/this.ascaleX,this.ashearY=Math.atan2(d*f+u*m,g)*C.radDeg,this.arotation=Math.atan2(u,d)*C.radDeg}else this.ascaleX=0,this.ascaleY=Math.sqrt(f*f+m*m),this.ashearY=0,this.arotation=90-Math.atan2(m,f)*C.radDeg}worldToLocal(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=1/(e*h-i*r),s=t.x-n.tx,a=t.y-n.ty;return t.x=s*h*l-a*i*l,t.y=a*e*l-s*r*l,t}localToWorld(t){const n=this.matrix,e=t.x,i=t.y;return t.x=e*n.a+i*n.c+n.tx,t.y=e*n.b+i*n.d+n.ty,t}worldToLocalRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(i.a*n-i.b*e,i.d*e-i.c*n)*C.radDeg}localToWorldRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(e*i.b+n*i.d,e*i.a+n*i.c)*C.radDeg}rotateWorld(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=C.cosDeg(t),s=C.sinDeg(t);n.a=l*e-s*r,n.c=l*i-s*h,n.b=s*e+l*r,n.d=s*i+l*h,this.appliedValid=!1}},zi=class{constructor(t,n,e){if(this.x=0,this.y=0,this.rotation=0,this.scaleX=1,this.scaleY=1,this.shearX=0,this.shearY=0,this.transformMode=j.Normal,t<0)throw new Error("index must be >= 0.");if(n==null)throw new Error("name cannot be null.");this.index=t,this.name=n,this.parent=e}},Hi=class{constructor(t,n){if(n==null)throw new Error("data cannot be null.");this.time=t,this.data=n}},Gi=class{constructor(t){this.name=t}},ji=class{constructor(t,n){if(this.bendDirection=0,this.compress=!1,this.stretch=!1,this.mix=1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.mix=t.mix,this.bendDirection=t.bendDirection,this.compress=t.compress,this.stretch=t.stretch,this.bones=new Array;for(let e=0;e180?m-=360:m<-180&&(m+=360);let g=t.ascaleX,x=t.ascaleY;if(i||r){const E=t.data.length*g,w=Math.sqrt(f*f+u*u);if(i&&wE&&E>1e-4){const b=(w/E-1)*l+1;g*=b,h&&(x*=b)}}t.updateWorldTransformWith(t.ax,t.ay,t.arotation+m*l,g,x,t.ashearX,t.ashearY)}apply2(t,n,e,i,r,h,l){if(l==0){n.updateWorldTransform();return}t.appliedValid||t.updateAppliedTransform(),n.appliedValid||n.updateAppliedTransform();const s=t.ax,a=t.ay;let o=t.ascaleX,d=o,f=t.ascaleY,u=n.ascaleX;const m=t.matrix;let g=0,x=0,E=0;o<0?(o=-o,g=180,E=-1):(g=0,E=1),f<0&&(f=-f,E=-E),u<0?(u=-u,x=180):x=0;const w=n.ax;let b=0,p=0,S=0,y=m.a,M=m.c,T=m.b,k=m.d;const I=Math.abs(o-f)<=1e-4;I?(b=n.ay,p=y*w+M*b+m.tx,S=T*w+k*b+m.ty):(b=0,p=y*w+m.tx,S=T*w+m.ty);const R=t.parent.matrix;y=R.a,M=R.c,T=R.b,k=R.d;const V=1/(y*k-M*T);let F=e-R.tx,B=i-R.ty;const Y=(F*k-B*M)*V-s,N=(B*y-F*T)*V-a,q=Y*Y+N*N;F=p-R.tx,B=S-R.ty;const z=(F*k-B*M)*V-s,D=(B*y-F*T)*V-a,X=Math.sqrt(z*z+D*D);let L=n.data.length*u,O=0,W=0;t:if(I){L*=o;let G=(q-X*X-L*L)/(2*X*L);G<-1?G=-1:G>1&&(G=1,h&&X+L>1e-4&&(d*=(Math.sqrt(q)/(X+L)-1)*l+1)),W=Math.acos(G)*r,y=X+L*G,M=L*Math.sin(W),O=Math.atan2(N*y-Y*M,Y*y+N*M)}else{y=o*L,M=f*L;const G=y*y,lt=M*M,It=Math.atan2(N,Y);T=lt*X*X+G*q-G*lt;const ct=-2*lt*X,Xt=lt-G;if(k=ct*ct-4*Xt*T,k>=0){let Kt=Math.sqrt(k);ct<0&&(Kt=-Kt),Kt=-(ct+Kt)/2;const ae=Kt/Xt,Ke=T/Kt,Nt=Math.abs(ae)=-1&&T<=1&&(T=Math.acos(T),F=y*Math.cos(T)+X,B=M*Math.sin(T),k=F*F+B*B,kCe&&(Ve=T,Ce=k,Ae=F,$e=B)),q<=(Me+Ce)/2?(O=It-Math.atan2(Oe*r,de),W=Ut*r):(O=It-Math.atan2($e*r,Ae),W=Ve*r)}const U=Math.atan2(b,w)*E;let $=t.arotation;O=(O-U)*C.radDeg+g-$,O>180?O-=360:O<-180&&(O+=360),t.updateWorldTransformWith(s,a,$+O*l,d,t.ascaleY,0,0),$=n.arotation,W=((W+U)*C.radDeg-n.ashearX)*E+x-$,W>180?W-=360:W<-180&&(W+=360),n.updateWorldTransformWith(w,b,$+W*l,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY)}},Zi=class{constructor(t){this.order=0,this.bones=new Array,this.bendDirection=1,this.compress=!1,this.stretch=!1,this.uniform=!1,this.mix=1,this.name=t}},Qi=class{constructor(t){this.order=0,this.bones=new Array,this.name=t}};var pe=(c=>(c[c.Length=0]="Length",c[c.Fixed=1]="Fixed",c[c.Percent=2]="Percent",c))(pe||{});const rn=class{constructor(t,n){if(this.position=0,this.spacing=0,this.rotateMix=0,this.translateMix=0,this.spaces=new Array,this.positions=new Array,this.world=new Array,this.curves=new Array,this.lengths=new Array,this.segments=new Array,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.bones=new Array;for(let e=0,i=t.bones.length;e0,r=n>0;if(!i&&!r)return;const h=this.data,l=h.spacingMode,s=l==pe.Length,a=h.rotateMode,o=a==pt.Tangent,d=a==pt.ChainScale,f=this.bones.length,u=o?f:f+1,m=this.bones,g=v.setArraySize(this.spaces,u);let x=null;const E=this.spacing;if(d||s){d&&(x=v.setArraySize(this.lengths,f));for(let M=0,T=u-1;M0?C.degRad:-C.degRad}for(let M=0,T=3;MC.PI?D-=C.PI2:D<-C.PI&&(D+=C.PI2),D*=n,X=Math.cos(D),L=Math.sin(D),I.a=X*Y-L*q,I.c=X*N-L*z,I.b=L*Y+X*q,I.d=L*N+X*z}k.appliedValid=!1}}computeWorldPositions(t,n,e,i,r){const h=this.target;let l=this.position;const s=this.spaces,a=v.setArraySize(this.positions,n*3+2);let o=null;const d=t.closed;let f=t.worldVerticesLength,u=f/6,m=rn.NONE;if(!t.constantSpeed){const D=t.lengths;u-=d?1:2;const X=D[u];if(i&&(l*=X),r)for(let L=0;LX){m!=rn.AFTER&&(m=rn.AFTER,t.computeWorldVertices(h,f-6,4,o,0,2)),this.addAfterPosition($-X,o,0,a,O);continue}for(;;W++){const G=D[W];if(!($>G)){if(W==0)$/=G;else{const lt=D[W-1];$=($-lt)/(G-lt)}break}}W!=m&&(m=W,d&&W==u?(t.computeWorldVertices(h,f-4,4,o,0,2),t.computeWorldVertices(h,0,4,o,4,2)):t.computeWorldVertices(h,W*6+2,8,o,0,2)),this.addCurvePosition($,o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7],a,O,e||L>0&&U==0)}return a}d?(f+=2,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f-4,o,0,2),t.computeWorldVertices(h,0,2,o,f-4,2),o[f-2]=o[0],o[f-1]=o[1]):(u--,f-=4,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f,o,0,2));const g=v.setArraySize(this.curves,u);let x=0,E=o[0],w=o[1],b=0,p=0,S=0,y=0,M=0,T=0,k=0,I=0,R=0,V=0,F=0,B=0,Y=0,N=0;for(let D=0,X=2;Dx){this.addAfterPosition(U-x,o,f-4,a,X);continue}for(;;L++){const $=g[L];if(!(U>$)){if(L==0)U/=$;else{const G=g[L-1];U=(U-G)/($-G)}break}}if(L!=m){m=L;let $=L*6;for(E=o[$],w=o[$+1],b=o[$+2],p=o[$+3],S=o[$+4],y=o[$+5],M=o[$+6],T=o[$+7],k=(E-b*2+S)*.03,I=(w-p*2+y)*.03,R=((b-S)*3-E+M)*.006,V=((p-y)*3-w+T)*.006,F=k*2+R,B=I*2+V,Y=(b-E)*.3+k+R*.16666667,N=(p-w)*.3+I+V*.16666667,z=Math.sqrt(Y*Y+N*N),q[0]=z,$=1;$<8;$++)Y+=F,N+=B,F+=R,B+=V,z+=Math.sqrt(Y*Y+N*N),q[$]=z;Y+=F,N+=B,z+=Math.sqrt(Y*Y+N*N),q[8]=z,Y+=F+R,N+=B+V,z+=Math.sqrt(Y*Y+N*N),q[9]=z,O=0}for(U*=z;;O++){const $=q[O];if(!(U>$)){if(O==0)U/=$;else{const G=q[O-1];U=O+(U-G)/($-G)}break}}this.addCurvePosition(U*.1,E,w,b,p,S,y,M,T,a,X,e||D>0&&W==0)}return a}addBeforePosition(t,n,e,i,r){const h=n[e],l=n[e+1],s=n[e+2]-h,a=n[e+3]-l,o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addAfterPosition(t,n,e,i,r){const h=n[e+2],l=n[e+3],s=h-n[e],a=l-n[e+1],o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addCurvePosition(t,n,e,i,r,h,l,s,a,o,d,f){(t==0||isNaN(t))&&(t=1e-4);const u=t*t,m=u*t,g=1-t,x=g*g,E=x*g,w=g*t,b=w*3,p=g*b,S=b*t,y=n*E+i*p+h*S+s*m,M=e*E+r*p+l*S+a*m;o[d]=y,o[d+1]=M,f&&(o[d+2]=Math.atan2(M-(e*x+r*w*2+l*u),y-(n*x+i*w*2+h*u)))}getOrder(){return this.data.order}};let wn=rn;wn.NONE=-1,wn.BEFORE=-2,wn.AFTER=-3,wn.epsilon=1e-5;let Ki=class{constructor(t,n){if(this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.temp=new un,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.rotateMix=t.rotateMix,this.translateMix=t.translateMix,this.scaleMix=t.scaleMix,this.shearMix=t.shearMix,this.bones=new Array;for(let e=0;e0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=(p.x-b.tx)*n,b.ty+=(p.y-b.ty)*n,w=!0}if(e>0){let p=Math.sqrt(b.a*b.a+b.b*b.b),S=Math.sqrt(l*l+a*a);p>1e-5&&(p=(p+(S-p+this.data.offsetScaleX)*e)/p),b.a*=p,b.b*=p,p=Math.sqrt(b.c*b.c+b.d*b.d),S=Math.sqrt(s*s+o*o),p>1e-5&&(p=(p+(S-p+this.data.offsetScaleY)*e)/p),b.c*=p,b.d*=p,w=!0}if(i>0){const p=b.c,S=b.d,y=Math.atan2(S,p);let M=Math.atan2(o,s)-Math.atan2(a,l)-(y-Math.atan2(b.b,b.a));M>C.PI?M-=C.PI2:M<-C.PI&&(M+=C.PI2),M=y+(M+u)*i;const T=Math.sqrt(p*p+S*S);b.c=Math.cos(M)*T,b.d=Math.sin(M)*T,w=!0}w&&(E.appliedValid=!1)}}applyRelativeWorld(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target,h=r.matrix,l=h.a,s=h.c,a=h.b,o=h.d,d=l*o-s*a>0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=p.x*n,b.ty+=p.y*n,w=!0}if(e>0){let p=(Math.sqrt(l*l+a*a)-1+this.data.offsetScaleX)*e+1;b.a*=p,b.b*=p,p=(Math.sqrt(s*s+o*o)-1+this.data.offsetScaleY)*e+1,b.c*=p,b.d*=p,w=!0}if(i>0){let p=Math.atan2(o,s)-Math.atan2(a,l);p>C.PI?p-=C.PI2:p<-C.PI&&(p+=C.PI2);const S=b.c,y=b.d;p=Math.atan2(y,S)+(p-C.PI/2+u)*i;const M=Math.sqrt(S*S+y*y);b.c=Math.cos(p)*M,b.d=Math.sin(p)*M,w=!0}w&&(E.appliedValid=!1)}}applyAbsoluteLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u=(u+(r.ascaleX-u+this.data.offsetScaleX)*e)/u),m>1e-5&&(m=(m+(r.ascaleY-m+this.data.offsetScaleY)*e)/m));const g=a.ashearY;if(i>0){let x=r.ashearY-g+this.data.offsetShearY;x-=(16384-(16384.499999999996-x/360|0))*360,a.shearY+=x*i}a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}applyRelativeLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u*=(r.ascaleX-1+this.data.offsetScaleX)*e+1),m>1e-5&&(m*=(r.ascaleY-1+this.data.offsetScaleY)*e+1));let g=a.ashearY;i>0&&(g+=(r.ashearY+this.data.offsetShearY)*i),a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}getOrder(){return this.data.order}};const In=class{constructor(t){if(this._updateCache=new Array,this.updateCacheReset=new Array,this.time=0,this.scaleX=1,this.scaleY=1,this.x=0,this.y=0,t==null)throw new Error("data cannot be null.");this.data=t,this.bones=new Array;for(let n=0;n1){const r=e[e.length-1];this._updateCache.indexOf(r)>-1||this.updateCacheReset.push(r)}this._updateCache.push(t),this.sortReset(i.children),e[e.length-1].sorted=!0}sortPathConstraint(t){const n=t.target,e=n.data.index,i=n.bone;this.skin!=null&&this.sortPathConstraintAttachment(this.skin,e,i),this.data.defaultSkin!=null&&this.data.defaultSkin!=this.skin&&this.sortPathConstraintAttachment(this.data.defaultSkin,e,i);for(let s=0,a=this.data.skins.length;s-1||this.updateCacheReset.push(r)}else for(let i=0;i= 0.");if(n==null)throw new Error("name cannot be null.");if(e==null)throw new Error("boneData cannot be null.");this.index=t,this.name=n,this.boneData=e}},er=class{constructor(t){if(this.order=0,this.bones=new Array,this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.offsetRotation=0,this.offsetX=0,this.offsetY=0,this.offsetScaleX=0,this.offsetScaleY=0,this.offsetShearY=0,this.relative=!1,this.local=!1,t==null)throw new Error("name cannot be null.");this.name=t}},nr=class{constructor(t){if(this.attachments=new Array,t==null)throw new Error("name cannot be null.");this.name=t}addAttachment(t,n,e){if(e==null)throw new Error("attachment cannot be null.");const i=this.attachments;t>=i.length&&(i.length=t+1),i[t]||(i[t]={}),i[t][n]=e}getAttachment(t,n){const e=this.attachments[t];return e?e[n]:null}attachAll(t,n){let e=0;for(let i=0;i=0;w--)u[w]==-1&&(u[w]=g[--E])}s.setFrame(o++,f.time,u)}r.push(s),h=Math.max(h,s.frames[s.getFrameCount()-1])}if(t.events){const s=new qi(t.events.length);let a=0;for(let o=0;o>1)*r;const h=c.bone.skeleton,l=c.deform;let s=this.vertices;const a=this.bones;if(!a){l.length>0&&(s=l);const u=c.bone.matrix,m=u.tx,g=u.ty,x=u.a,E=u.c,w=u.b,b=u.d;for(let p=t,S=i;S=this.regions.length&&(n=this.regions.length-1);const e=this.regions[n];t.region!=e&&(t.region=e)}getPath(c,t){let n=c;const e=(this.start+t).toString();for(let i=this.digits-e.length;i>0;i--)n+="0";return n+=e,n}static nextID(){return qn._nextID++}};let Un=qn;Un._nextID=0;var Re=(c=>(c[c.hold=0]="hold",c[c.once=1]="once",c[c.loop=2]="loop",c[c.pingpong=3]="pingpong",c[c.onceReverse=4]="onceReverse",c[c.loopReverse=5]="loopReverse",c[c.pingpongReverse=6]="pingpongReverse",c))(Re||{});const Bs=[0,1,2,3,4,5,6];class zn{constructor(t,n,e){if(this.timelines=[],this.timelineIds=new ss,!t)throw new Error("name cannot be null.");this.name=t,this.setTimelines(n),this.duration=e}setTimelines(t){if(!t)throw new Error("timelines cannot be null.");this.timelines=t,this.timelineIds.clear();for(let n=0;n0&&(n%=this.duration));const a=this.timelines;for(let o=0,d=a.length;on)return i-1;return e-1}static search(t,n,e){const i=t.length;for(let r=e;rn)return r-e;return i-e}}class be extends bt{constructor(t,n,e){super(t,e),this.curves=v.newFloatArray(t+n*18),this.curves[t-1]=1}setLinear(t){this.curves[t]=0}setStepped(t){this.curves[t]=1}shrink(t){const n=this.getFrameCount()+t*18;if(this.curves.length>n){const e=v.newFloatArray(n);v.arrayCopy(this.curves,0,e,0,n),this.curves=e}}setBezier(t,n,e,i,r,h,l,s,a,o,d){const f=this.curves;let u=this.getFrameCount()+t*18;e==0&&(f[n]=2+u);const m=(i-h*2+s)*.03,g=(r-l*2+a)*.03,x=((h-s)*3-i+o)*.006,E=((l-a)*3-r+d)*.006;let w=m*2+x,b=g*2+E,p=(h-i)*.3+m+x*.16666667,S=(l-r)*.3+g+E*.16666667,y=i+p,M=r+S;for(let T=u+18;ut){const a=this.frames[n],o=this.frames[n+e];return o+(t-a)/(r[i]-a)*(r[i+1]-o)}const h=i+18;for(i+=2;i=t){const a=r[i-2],o=r[i-1];return o+(t-a)/(r[i]-a)*(r[i+1]-o)}n+=this.getFrameEntries();const l=r[h-2],s=r[h-1];return s+(t-l)/(this.frames[n]-l)*(this.frames[n+e]-s)}}class Ee extends be{constructor(t,n,e){super(t,n,[e])}getFrameEntries(){return 2}setFrame(t,n,e){t<<=1,this.frames[t]=n,this.frames[t+1]=e}getCurveValue(t){const n=this.frames;let e=n.length-2;for(let r=2;r<=e;r+=2)if(n[r]>t){e=r-2;break}const i=this.curves[e>>1];switch(i){case 0:const r=n[e],h=n[e+1];return h+(t-r)/(n[e+2]-r)*(n[e+2+1]-h);case 1:return n[e+1]}return this.getBezierValue(t,e,1,i-2)}}class Hn extends be{constructor(t,n,e,i){super(t,n,[e,i])}getFrameEntries(){return 3}setFrame(t,n,e,i){t*=3,this.frames[t]=n,this.frames[t+1]=e,this.frames[t+2]=i}}class Rn extends Ee{constructor(t,n,e){super(t,n,`${ot.rotate}|${e}`),this.boneIndex=0,this.boneIndex=e}apply(t,n,e,i,r,h,l){const s=t.bones[this.boneIndex];if(!s.active)return;const a=this.frames;if(e>2];switch(g){case 0:const x=a[m];d=a[m+1],f=a[m+2],u=a[m+3];const E=(e-x)/(a[m+4]-x);d+=(a[m+4+1]-d)*E,f+=(a[m+4+2]-f)*E,u+=(a[m+4+3]-u)*E;break;case 1:d=a[m+1],f=a[m+2],u=a[m+3];break;default:d=this.getBezierValue(e,m,1,g-2),f=this.getBezierValue(e,m,2,g+18-2),u=this.getBezierValue(e,m,3,g+18*2-2)}if(r==1)o.r=d,o.g=f,o.b=u;else{if(h==A.setup){const x=s.data.color;o.r=x.r,o.g=x.g,o.b=x.b}o.r+=(d-o.r)*r,o.g+=(f-o.g)*r,o.b+=(u-o.b)*r}}}class js extends Ee{constructor(t,n,e){super(t,n,`${ot.alpha}|${e}`),this.slotIndex=0,this.slotIndex=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=s.color;if(e>3];switch(p){case 0:const S=a[b];f=a[b+1],u=a[b+2],m=a[b+3],g=a[b+4],x=a[b+5],E=a[b+6],w=a[b+7];const y=(e-S)/(a[b+8]-S);f+=(a[b+8+1]-f)*y,u+=(a[b+8+2]-u)*y,m+=(a[b+8+3]-m)*y,g+=(a[b+8+4]-g)*y,x+=(a[b+8+5]-x)*y,E+=(a[b+8+6]-E)*y,w+=(a[b+8+7]-w)*y;break;case 1:f=a[b+1],u=a[b+2],m=a[b+3],g=a[b+4],x=a[b+5],E=a[b+6],w=a[b+7];break;default:f=this.getBezierValue(e,b,1,p-2),u=this.getBezierValue(e,b,2,p+18-2),m=this.getBezierValue(e,b,3,p+18*2-2),g=this.getBezierValue(e,b,4,p+18*3-2),x=this.getBezierValue(e,b,5,p+18*4-2),E=this.getBezierValue(e,b,6,p+18*5-2),w=this.getBezierValue(e,b,7,p+18*6-2)}if(r==1)o.set(f,u,m,g),d.r=x,d.g=E,d.b=w;else{if(h==A.setup){o.setFromColor(s.data.color);const S=s.data.darkColor;d.r=S.r,d.g=S.g,d.b=S.b}o.add((f-o.r)*r,(u-o.g)*r,(m-o.b)*r,(g-o.a)*r),d.r+=(x-d.r)*r,d.g+=(E-d.g)*r,d.b+=(w-d.b)*r}}}class Qs extends be{constructor(t,n,e){super(t,n,[`${ot.rgb}|${e}`,`${ot.rgb2}|${e}`]),this.slotIndex=0,this.slotIndex=e}getFrameEntries(){return 7}setFrame(t,n,e,i,r,h,l,s){t*=7,this.frames[t]=n,this.frames[t+1]=e,this.frames[t+2]=i,this.frames[t+3]=r,this.frames[t+4]=h,this.frames[t+5]=l,this.frames[t+6]=s}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=this.frames,o=s.color,d=s.darkColor;if(et){const s=this.frames[n];return e[i+1]*(t-s)/(e[i]-s)}const r=i+18;for(i+=2;i=t){const s=e[i-2],a=e[i-1];return a+(t-s)/(e[i]-s)*(e[i+1]-a)}const h=e[r-2],l=e[r-1];return l+(1-l)*(t-h)/(this.frames[n+this.getFrameEntries()]-h)}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=s.getAttachment();if(!a||!(a instanceof we)||a.timelineAttachment!=this.attachment)return;const o=s.deform;o.length==0&&(h=A.setup);const d=this.vertices,f=d[0].length,u=this.frames;if(e=u[u.length-1]){const w=d[u.length-1];if(r==1)if(h==A.add){const b=a;if(b.bones)for(let p=0;pn)this.apply(c,t,Number.MAX_VALUE,e,i,r,h),t=-1;else if(t>=l[s-1])return;if(n0&&l[a-1]==o;)a--}for(;a=l[a];a++)e.push(this.events[a])}};let vn=rr;vn.propertyIds=[`${ot.event}`];const ar=class extends bt{constructor(c){super(c,ar.propertyIds),this.drawOrders=new Array(c)}getFrameCount(){return this.frames.length}setFrame(c,t,n){this.frames[c]=t,this.drawOrders[c]=n}apply(c,t,n,e,i,r,h){if(h==J.mixOut){r==A.setup&&v.arrayCopy(c.slots,0,c.drawOrder,0,c.slots.length);return}if(n>2];switch(m){case 0:const g=a[u];o=a[u+1],d=a[u+2],f=a[u+3];const x=(e-g)/(a[u+4]-g);o+=(a[u+4+1]-o)*x,d+=(a[u+4+2]-d)*x,f+=(a[u+4+3]-f)*x;break;case 1:o=a[u+1],d=a[u+2],f=a[u+3];break;default:o=this.getBezierValue(e,u,1,m-2),d=this.getBezierValue(e,u,2,m+18-2),f=this.getBezierValue(e,u,3,m+18*2-2)}if(h==A.setup){const g=s.data;s.mixRotate=g.mixRotate+(o-g.mixRotate)*r,s.mixX=g.mixX+(d-g.mixX)*r,s.mixY=g.mixY+(f-g.mixY)*r}else s.mixRotate+=(o-s.mixRotate)*r,s.mixX+=(d-s.mixX)*r,s.mixY+=(f-s.mixY)*r}}const Qe=class extends bt{constructor(c,t,n){super(c,[`${ot.sequence}|${t}|${n.sequence.id}`]),this.slotIndex=t,this.attachment=n}getFrameEntries(){return Qe.ENTRIES}getSlotIndex(){return this.slotIndex}getAttachment(){return this.attachment}setFrame(c,t,n,e,i){const r=this.frames;c*=Qe.ENTRIES,r[c]=t,r[c+Qe.MODE]=n|e<<4,r[c+Qe.DELAY]=i}apply(c,t,n,e,i,r,h){const l=c.slots[this.slotIndex];if(!l.bone.active)return;const s=l.attachment,a=this.attachment;if(s!=a&&(!(s instanceof we)||s.timelineAttachment!=a))return;const o=this.frames;if(n>4;const x=this.attachment.sequence.regions.length,E=Bs[u&15];if(E!=Re.hold)switch(g+=(n-f)/m+1e-5|0,E){case Re.once:g=Math.min(x-1,g);break;case Re.loop:g%=x;break;case Re.pingpong:{const w=(x<<1)-2;g=w==0?0:g%w,g>=x&&(g=w-g);break}case Re.onceReverse:g=Math.max(x-1-g,0);break;case Re.loopReverse:g=x-1-g%x;break;case Re.pingpongReverse:{const w=(x<<1)-2;g=w==0?0:(g+x-1)%w,g>=x&&(g=w-g)}}l.sequenceIndex=g}};let bn=Qe;bn.ENTRIES=3,bn.MODE=1,bn.DELAY=2;const ve=class{constructor(c){this.tracks=new Array,this.timeScale=1,this.unkeyedState=0,this.events=new Array,this.listeners=new Array,this.queue=new or(this),this.propertyIDs=new ss,this.animationsChanged=!1,this.trackEntryPool=new An(()=>new Gn),this.data=c}static emptyAnimation(){return ve._emptyAnimation}update(c){c*=this.timeScale;const t=this.tracks;for(let n=0,e=t.length;n0){if(i.delay-=r,i.delay>0)continue;r=-i.delay,i.delay=0}let h=i.next;if(h){const l=i.trackLast-h.delay;if(l>=0){for(h.delay=0,h.trackTime+=i.timeScale==0?0:(l/i.timeScale+c)*h.timeScale,i.trackTime+=r,this.setCurrent(n,h,!0);h.mixingFrom;)h.mixTime+=c,h=h.mixingFrom;continue}}else if(i.trackLast>=i.trackEnd&&!i.mixingFrom){t[n]=null,this.queue.end(i),this.clearNext(i);continue}if(i.mixingFrom&&this.updateMixingFrom(i,c)){let l=i.mixingFrom;for(i.mixingFrom=null,l&&(l.mixingTo=null);l;)this.queue.end(l),l=l.mixingFrom}i.trackTime+=r}this.queue.drain()}updateMixingFrom(c,t){const n=c.mixingFrom;if(!n)return!0;const e=this.updateMixingFrom(n,t);return n.animationLast=n.nextAnimationLast,n.trackLast=n.nextTrackLast,c.mixTime>0&&c.mixTime>=c.mixDuration?((n.totalAlpha==0||c.mixDuration==0)&&(c.mixingFrom=n.mixingFrom,n.mixingFrom&&(n.mixingFrom.mixingTo=c),c.interruptAlpha=n.interruptAlpha,this.queue.end(n)),e):(n.trackTime+=t*n.timeScale,c.mixTime+=t,!1)}apply(c){if(!c)throw new Error("skeleton cannot be null.");this.animationsChanged&&this._animationsChanged();const t=this.events,n=this.tracks;let e=!1;for(let h=0,l=n.length;h0)continue;e=!0;const a=h==0?A.first:s.mixBlend;let o=s.alpha;s.mixingFrom?o*=this.applyMixingFrom(s,c,a):s.trackTime>=s.trackEnd&&!s.next&&(o=0);const d=s.animationLast,f=s.getAnimationTime();let u=f,m=t;s.reverse&&(u=s.animation.duration-u,m=null);const g=s.animation.timelines,x=g.length;if(h==0&&o==1||a==A.add)for(let E=0;E1&&(i=1),n!=A.first&&(n=e.mixBlend));const r=i0&&this.queueEvents(e,f),this.events.length=0,e.nextAnimationLast=f,e.nextTrackLast=e.trackTime,i}applyAttachmentTimeline(c,t,n,e,i){const r=t.slots[c.slotIndex];r.bone.active&&(n0;let E=m>=0;C.signum(g)!=C.signum(u)&&Math.abs(g)<=90&&(Math.abs(m)>180&&(m+=360*C.signum(m)),E=x),f=u+m-m%360,E!=x&&(f+=360*C.signum(m)),r[h]=f}r[h+1]=u,s.rotation=o+f*e}queueEvents(c,t){const n=c.animationStart,e=c.animationEnd,i=e-n,r=c.trackLast%i,h=this.events;let l=0;const s=h.length;for(;le||this.queue.event(c,o)}let a=!1;for(c.loop?a=i==0||r>c.trackTime%i:a=t>=e&&c.animationLast=this.tracks.length)return;const t=this.tracks[c];if(!t)return;this.queue.end(t),this.clearNext(t);let n=t;for(;;){const e=n.mixingFrom;if(!e)break;this.queue.end(e),n.mixingFrom=null,n.mixingTo=null,n=e}this.tracks[t.trackIndex]=null,this.queue.drain()}setCurrent(c,t,n){const e=this.expandToIndex(c);this.tracks[c]=t,t.previous=null,e&&(n&&this.queue.interrupt(e),t.mixingFrom=e,e.mixingTo=t,t.mixTime=0,e.mixingFrom&&e.mixDuration>0&&(t.interruptAlpha*=Math.min(1,e.mixTime/e.mixDuration)),e.timelinesRotation.length=0),this.queue.start(t)}setAnimation(c,t,n=!1){const e=this.data.skeletonData.findAnimation(t);if(!e)throw new Error(`Animation not found: ${t}`);return this.setAnimationWith(c,e,n)}setAnimationWith(c,t,n=!1){if(!t)throw new Error("animation cannot be null.");let e=!0,i=this.expandToIndex(c);i&&(i.nextTrackLast==-1?(this.tracks[c]=i.mixingFrom,this.queue.interrupt(i),this.queue.end(i),this.clearNext(i),i=i.mixingFrom,e=!1):this.clearNext(i));const r=this.trackEntry(c,t,n,i);return this.setCurrent(c,r,e),this.queue.drain(),r}addAnimation(c,t,n=!1,e=0){const i=this.data.skeletonData.findAnimation(t);if(!i)throw new Error(`Animation not found: ${t}`);return this.addAnimationWith(c,i,n,e)}addAnimationWith(c,t,n=!1,e=0){if(!t)throw new Error("animation cannot be null.");let i=this.expandToIndex(c);if(i)for(;i.next;)i=i.next;const r=this.trackEntry(c,t,n,i);return i?(i.next=r,r.previous=i,e<=0&&(e+=i.getTrackComplete()-r.mixDuration)):(this.setCurrent(c,r,!0),this.queue.drain()),r.delay=e,r}setEmptyAnimation(c,t=0){const n=this.setAnimationWith(c,ve.emptyAnimation(),!1);return n.mixDuration=t,n.trackEnd=t,n}addEmptyAnimation(c,t=0,n=0){const e=this.addAnimationWith(c,ve.emptyAnimation(),!1,n);return n<=0&&(e.delay+=e.mixDuration-t),e.mixDuration=t,e.trackEnd=t,e}setEmptyAnimations(c=0){const t=this.queue.drainDisabled;this.queue.drainDisabled=!0;for(let n=0,e=this.tracks.length;n0){i[l]=Wr,r[l]=o;continue t}break}i[l]=ri}}}getCurrent(c){return c>=this.tracks.length?null:this.tracks[c]}addListener(c){if(!c)throw new Error("listener cannot be null.");this.listeners.push(c)}removeListener(c){const t=this.listeners.indexOf(c);t>=0&&this.listeners.splice(t,1)}clearListeners(){this.listeners.length=0}clearListenerNotifications(){this.queue.clear()}setAnimationByName(c,t,n){ve.deprecatedWarning1||(ve.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on.")),this.setAnimation(c,t,n)}addAnimationByName(c,t,n,e){ve.deprecatedWarning2||(ve.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on.")),this.addAnimation(c,t,n,e)}hasAnimation(c){return this.data.skeletonData.findAnimation(c)!==null}hasAnimationByName(c){return ve.deprecatedWarning3||(ve.deprecatedWarning3=!0,console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on.")),this.hasAnimation(c)}};let En=ve;En._emptyAnimation=new zn("",[],0),En.deprecatedWarning1=!1,En.deprecatedWarning2=!1,En.deprecatedWarning3=!1;const De=class{constructor(){this.animation=null,this.previous=null,this.next=null,this.mixingFrom=null,this.mixingTo=null,this.listener=null,this.trackIndex=0,this.loop=!1,this.holdPrevious=!1,this.reverse=!1,this.shortestRotation=!1,this.eventThreshold=0,this.attachmentThreshold=0,this.drawOrderThreshold=0,this.animationStart=0,this.animationEnd=0,this.animationLast=0,this.nextAnimationLast=0,this.delay=0,this.trackTime=0,this.trackLast=0,this.nextTrackLast=0,this.trackEnd=0,this.timeScale=0,this.alpha=0,this.mixTime=0,this.mixDuration=0,this.interruptAlpha=0,this.totalAlpha=0,this.mixBlend=A.replace,this.timelineMode=new Array,this.timelineHoldMix=new Array,this.timelinesRotation=new Array}reset(){this.next=null,this.previous=null,this.mixingFrom=null,this.mixingTo=null,this.animation=null,this.listener=null,this.timelineMode.length=0,this.timelineHoldMix.length=0,this.timelinesRotation.length=0}getAnimationTime(){if(this.loop){const c=this.animationEnd-this.animationStart;return c==0?this.animationStart:this.trackTime%c+this.animationStart}return Math.min(this.trackTime+this.animationStart,this.animationEnd)}setAnimationLast(c){this.animationLast=c,this.nextAnimationLast=c}isComplete(){return this.trackTime>=this.animationEnd-this.animationStart}resetRotationDirections(){this.timelinesRotation.length=0}getTrackComplete(){const c=this.animationEnd-this.animationStart;if(c!=0){if(this.loop)return c*(1+(this.trackTime/c|0));if(this.trackTime(c[c.start=0]="start",c[c.interrupt=1]="interrupt",c[c.end=2]="end",c[c.dispose=3]="dispose",c[c.complete=4]="complete",c[c.event=5]="event",c))(Qt||{});class $r{start(t){}interrupt(t){}end(t){}dispose(t){}complete(t){}event(t,n){}}const ii=0,lr=1,cr=2,ri=3,Wr=4,hr=1,qr=2;class dr{constructor(t){if(this.animationToMixTime={},this.defaultMix=0,!t)throw new Error("skeletonData cannot be null.");this.skeletonData=t}setMix(t,n,e){const i=this.skeletonData.findAnimation(t);if(!i)throw new Error(`Animation not found: ${t}`);const r=this.skeletonData.findAnimation(n);if(!r)throw new Error(`Animation not found: ${n}`);this.setMixWith(i,r,e)}setMixWith(t,n,e){if(!t)throw new Error("from cannot be null.");if(!n)throw new Error("to cannot be null.");const i=`${t.name}.${n.name}`;this.animationToMixTime[i]=e}getMix(t,n){const e=`${t.name}.${n.name}`,i=this.animationToMixTime[e];return i===void 0?this.defaultMix:i}}class ai{constructor(t){this.atlas=t}loadSequence(t,n,e){const i=e.regions;for(let r=0,h=i.length;r1e-4?(x=Math.abs(f*g-u*m)/x,f/=o,m/=d,u=m*x,g=f*x,E=Math.atan2(m,f)*C.radDeg):(f=0,m=0,E=90-Math.atan2(g,u)*C.radDeg);const w=e+h-E,b=e+l-E+90,p=C.cosDeg(w)*i,S=C.cosDeg(b)*r,y=C.sinDeg(w)*i,M=C.sinDeg(b)*r;a.a=f*p-u*y,a.c=f*S-u*M,a.b=m*p+g*y,a.d=m*S+g*M;break}case j.NoScale:case j.NoScaleOrReflection:{const x=C.cosDeg(e),E=C.sinDeg(e);let w=(f*x+u*E)/o,b=(m*x+g*E)/d,p=Math.sqrt(w*w+b*b);p>1e-5&&(p=1/p),w*=p,b*=p,p=Math.sqrt(w*w+b*b),this.data.transformMode==j.NoScale&&f*g-u*m<0!=(o<0!=d<0)&&(p=-p);const S=Math.PI/2+Math.atan2(b,w),y=Math.cos(S)*p,M=Math.sin(S)*p,T=C.cosDeg(h)*i,k=C.cosDeg(90+l)*r,I=C.sinDeg(h)*i,R=C.sinDeg(90+l)*r;a.a=w*T+y*I,a.c=w*k+y*R,a.b=b*T+M*I,a.d=b*k+M*R;break}}a.a*=o,a.c*=o,a.b*=d,a.d*=d}setToSetupPose(){const t=this.data;this.x=t.x,this.y=t.y,this.rotation=t.rotation,this.scaleX=t.scaleX,this.scaleY=t.scaleY,this.shearX=t.shearX,this.shearY=t.shearY}getWorldRotationX(){return Math.atan2(this.matrix.b,this.matrix.a)*C.radDeg}getWorldRotationY(){return Math.atan2(this.matrix.d,this.matrix.c)*C.radDeg}getWorldScaleX(){const t=this.matrix;return Math.sqrt(t.a*t.a+t.b*t.b)}getWorldScaleY(){const t=this.matrix;return Math.sqrt(t.c*t.c+t.d*t.d)}updateAppliedTransform(){const t=this.parent,n=this.matrix;if(!t){this.ax=n.tx-this.skeleton.x,this.ay=n.ty-this.skeleton.y,this.arotation=Math.atan2(n.b,n.a)*C.radDeg,this.ascaleX=Math.sqrt(n.a*n.a+n.b*n.b),this.ascaleY=Math.sqrt(n.c*n.c+n.d*n.d),this.ashearX=0,this.ashearY=Math.atan2(n.a*n.c+n.b*n.d,n.a*n.d-n.b*n.c)*C.radDeg;return}const e=t.matrix,i=1/(e.a*e.d-e.b*e.c),r=n.tx-e.tx,h=n.ty-e.ty;this.ax=r*e.d*i-h*e.c*i,this.ay=h*e.a*i-r*e.b*i;const l=i*e.d,s=i*e.a,a=i*e.c,o=i*e.b,d=l*n.a-a*n.b,f=l*n.c-a*n.d,u=s*n.b-o*n.a,m=s*n.d-o*n.c;if(this.ashearX=0,this.ascaleX=Math.sqrt(d*d+u*u),this.ascaleX>1e-4){const g=d*m-f*u;this.ascaleY=g/this.ascaleX,this.ashearY=Math.atan2(d*f+u*m,g)*C.radDeg,this.arotation=Math.atan2(u,d)*C.radDeg}else this.ascaleX=0,this.ascaleY=Math.sqrt(f*f+m*m),this.ashearY=0,this.arotation=90-Math.atan2(m,f)*C.radDeg}worldToLocal(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=1/(e*h-i*r),s=t.x-n.tx,a=t.y-n.ty;return t.x=s*h*l-a*i*l,t.y=a*e*l-s*r*l,t}localToWorld(t){const n=this.matrix,e=t.x,i=t.y;return t.x=e*n.a+i*n.c+n.tx,t.y=e*n.b+i*n.d+n.ty,t}worldToLocalRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(i.a*n-i.b*e,i.d*e-i.c*n)*C.radDeg}localToWorldRotation(t){t-=this.rotation-this.shearX;const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(e*i.b+n*i.d,e*i.a+n*i.c)*C.radDeg}rotateWorld(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=C.cosDeg(t),s=C.sinDeg(t);n.a=l*e-s*r,n.c=l*i-s*h,n.b=s*e+l*r,n.d=s*i+l*h}}class li{constructor(t,n,e){if(this.index=0,this.parent=null,this.length=0,this.x=0,this.y=0,this.rotation=0,this.scaleX=1,this.scaleY=1,this.shearX=0,this.shearY=0,this.transformMode=j.Normal,this.skinRequired=!1,this.color=new _,t<0)throw new Error("index must be >= 0.");if(!n)throw new Error("name cannot be null.");this.index=t,this.name=n,this.parent=e}}class jn{constructor(t,n,e){this.name=t,this.order=n,this.skinRequired=e}}class ci{constructor(t,n){if(this.intValue=0,this.floatValue=0,this.stringValue=null,this.time=0,this.volume=0,this.balance=0,!n)throw new Error("data cannot be null.");this.time=t,this.data=n}}class hi{constructor(t){this.intValue=0,this.floatValue=0,this.stringValue=null,this.audioPath=null,this.volume=0,this.balance=0,this.name=t}}class fr{constructor(t,n){if(this.bendDirection=0,this.compress=!1,this.stretch=!1,this.mix=1,this.softness=0,this.active=!1,!t)throw new Error("data cannot be null.");if(!n)throw new Error("skeleton cannot be null.");this.data=t,this.mix=t.mix,this.softness=t.softness,this.bendDirection=t.bendDirection,this.compress=t.compress,this.stretch=t.stretch,this.bones=new Array;for(let i=0;i180?u-=360:u<-180&&(u+=360);let w=t.ascaleX,b=t.ascaleY;if(i||r){switch(t.data.transformMode){case j.NoScale:case j.NoScaleOrReflection:m=n-t.worldX,g=e-t.worldY}const p=t.data.length*w,S=Math.sqrt(m*m+g*g);if(i&&Sp&&p>1e-4){const y=(S/p-1)*l+1;w*=y,h&&(b*=y)}}t.updateWorldTransformWith(t.ax,t.ay,t.arotation+u*l,w,b,t.ashearX,t.ashearY)}apply2(t,n,e,i,r,h,l,s,a){const o=t.ax,d=t.ay;let f=t.ascaleX,u=t.ascaleY,m=f,g=u,x=n.ascaleX;const E=t.matrix;let w=0,b=0,p=0;f<0?(f=-f,w=180,p=-1):(w=0,p=1),u<0&&(u=-u,p=-p),x<0?(x=-x,b=180):b=0;const S=n.ax;let y=0,M=0,T=0,k=E.a,I=E.c,R=E.b,V=E.d;const F=Math.abs(f-u)<=1e-4;!F||h?(y=0,M=k*S+E.tx,T=R*S+E.ty):(y=n.ay,M=k*S+I*y+E.tx,T=R*S+V*y+E.ty);const B=t.parent.matrix;if(!B)throw new Error("IK parent must itself have a parent.");k=B.a,I=B.c,R=B.b,V=B.d;const Y=1/(k*V-I*R);let N=M-B.tx,q=T-B.ty;const z=(N*V-q*I)*Y-o,D=(q*k-N*R)*Y-d,X=Math.sqrt(z*z+D*D);let L=n.data.length*x,O,W;if(X<1e-4){this.apply1(t,e,i,!1,h,!1,a),n.updateWorldTransformWith(S,y,0,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY);return}N=e-B.tx,q=i-B.ty;let U=(N*V-q*I)*Y-o,$=(q*k-N*R)*Y-d,G=U*U+$*$;if(s!=0){s*=f*(x+1)*.5;const ct=Math.sqrt(G),Xt=ct-X-L*f+s;if(Xt>0){let Ut=Math.min(1,Xt/(s*2))-1;Ut=(Xt-s*(1-Ut*Ut))/ct,U-=Ut*U,$-=Ut*$,G=U*U+$*$}}t:if(F){L*=f;let ct=(G-X*X-L*L)/(2*X*L);ct<-1?(ct=-1,W=Math.PI*r):ct>1?(ct=1,W=0,h&&(k=(Math.sqrt(G)/(X+L)-1)*a+1,m*=k,l&&(g*=k))):W=Math.acos(ct)*r,k=X+L*ct,I=L*Math.sin(W),O=Math.atan2($*k-U*I,U*k+$*I)}else{k=f*L,I=u*L;const ct=k*k,Xt=I*I,Ut=Math.atan2($,U);R=Xt*X*X+ct*G-ct*Xt;const de=-2*Xt*X,Me=Xt-ct;if(V=de*de-4*Me*R,V>=0){let Nt=Math.sqrt(V);de<0&&(Nt=-Nt),Nt=-(de+Nt)*.5;const We=Nt/Me,pr=R/Nt,yn=Math.abs(We)=-1&&R<=1&&(R=Math.acos(R),N=k*Math.cos(R)+X,q=I*Math.sin(R),V=N*N+q*q,Vae&&($e=R,ae=V,Kt=N,Ke=q)),G<=(Ae+ae)*.5?(O=Ut-Math.atan2(Ce*r,Ve),W=Oe*r):(O=Ut-Math.atan2(Ke*r,Kt),W=$e*r)}const lt=Math.atan2(y,S)*p;let It=t.arotation;O=(O-lt)*C.radDeg+w-It,O>180?O-=360:O<-180&&(O+=360),t.updateWorldTransformWith(o,d,It+O*a,m,g,0,0),It=n.arotation,W=((W+lt)*C.radDeg-n.ashearX)*p+b-It,W>180?W-=360:W<-180&&(W+=360),n.updateWorldTransformWith(S,y,It+W*a,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY)}}class di extends jn{constructor(t){super(t,0,!1),this.bones=new Array,this._target=null,this.bendDirection=1,this.compress=!1,this.stretch=!1,this.uniform=!1,this.mix=1,this.softness=0}set target(t){this._target=t}get target(){if(this._target)return this._target;throw new Error("BoneData not set.")}}class fi extends jn{constructor(t){super(t,0,!1),this.bones=new Array,this._target=null,this.positionMode=dt.Fixed,this.spacingMode=kt.Fixed,this.rotateMode=pt.Chain,this.offsetRotation=0,this.position=0,this.spacing=0,this.mixRotate=0,this.mixX=0,this.mixY=0}set target(t){this._target=t}get target(){if(this._target)return this._target;throw new Error("SlotData not set.")}}var kt=(c=>(c[c.Length=0]="Length",c[c.Fixed=1]="Fixed",c[c.Percent=2]="Percent",c[c.Proportional=3]="Proportional",c))(kt||{});const Le=class{constructor(c,t){if(this.position=0,this.spacing=0,this.mixRotate=0,this.mixX=0,this.mixY=0,this.spaces=new Array,this.positions=new Array,this.world=new Array,this.curves=new Array,this.lengths=new Array,this.segments=new Array,this.active=!1,!c)throw new Error("data cannot be null.");if(!t)throw new Error("skeleton cannot be null.");this.data=c,this.bones=new Array;for(let e=0,i=c.bones.length;e0){w=a/w*f;for(let p=1;p0?C.degRad:-C.degRad}for(let w=0,b=3;w0){const I=S.a,R=S.c,V=S.b,F=S.d;let B=0,Y=0,N=0;if(r?B=u[b-1]:o[w+1]==0?B=u[b+2]:B=Math.atan2(k,T),B-=Math.atan2(V,I),E){Y=Math.cos(B),N=Math.sin(B);const q=p.data.length;m+=(q*(Y*I-N*V)-T)*t,g+=(q*(N*I+Y*V)-k)*t}else B+=x;B>C.PI?B-=C.PI2:B<-C.PI&&(B+=C.PI2),B*=t,Y=Math.cos(B),N=Math.sin(B),S.a=Y*I-N*V,S.c=Y*R-N*F,S.b=N*I+Y*V,S.d=N*R+Y*F}p.updateAppliedTransform()}}computeWorldPositions(c,t,n){const e=this.target;let i=this.position;const r=this.spaces,h=v.setArraySize(this.positions,t*3+2);let l=this.world;const s=c.closed;let a=c.worldVerticesLength,o=a/6,d=Le.NONE;if(!c.constantSpeed){const q=c.lengths;o-=s?1:2;const z=q[o];this.data.positionMode==dt.Percent&&(i*=z);let D;switch(this.data.spacingMode){case kt.Percent:D=z;break;case kt.Proportional:D=z/t;break;default:D=1}l=v.setArraySize(this.world,8);for(let X=0,L=0,O=0;Xz){d!=Le.AFTER&&(d=Le.AFTER,c.computeWorldVertices(e,a-6,4,l,0,2)),this.addAfterPosition(U-z,l,0,h,L);continue}for(;;O++){const $=q[O];if(!(U>$)){if(O==0)U/=$;else{const G=q[O-1];U=(U-G)/($-G)}break}}O!=d&&(d=O,s&&O==o?(c.computeWorldVertices(e,a-4,4,l,0,2),c.computeWorldVertices(e,0,4,l,4,2)):c.computeWorldVertices(e,O*6+2,8,l,0,2)),this.addCurvePosition(U,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],h,L,n||X>0&&W==0)}return h}s?(a+=2,l=v.setArraySize(this.world,a),c.computeWorldVertices(e,2,a-4,l,0,2),c.computeWorldVertices(e,0,2,l,a-4,2),l[a-2]=l[0],l[a-1]=l[1]):(o--,a-=4,l=v.setArraySize(this.world,a),c.computeWorldVertices(e,2,a,l,0,2));const f=v.setArraySize(this.curves,o);let u=0,m=l[0],g=l[1],x=0,E=0,w=0,b=0,p=0,S=0,y=0,M=0,T=0,k=0,I=0,R=0,V=0,F=0;for(let q=0,z=2;qu){this.addAfterPosition(O-u,l,a-4,h,z);continue}for(;;D++){const W=f[D];if(!(O>W)){if(D==0)O/=W;else{const U=f[D-1];O=(O-U)/(W-U)}break}}if(D!=d){d=D;let W=D*6;for(m=l[W],g=l[W+1],x=l[W+2],E=l[W+3],w=l[W+4],b=l[W+5],p=l[W+6],S=l[W+7],y=(m-x*2+w)*.03,M=(g-E*2+b)*.03,T=((x-w)*3-m+p)*.006,k=((E-b)*3-g+S)*.006,I=y*2+T,R=M*2+k,V=(x-m)*.3+y+T*.16666667,F=(E-g)*.3+M+k*.16666667,N=Math.sqrt(V*V+F*F),Y[0]=N,W=1;W<8;W++)V+=I,F+=R,I+=T,R+=k,N+=Math.sqrt(V*V+F*F),Y[W]=N;V+=I,F+=R,N+=Math.sqrt(V*V+F*F),Y[8]=N,V+=I+T,F+=R+k,N+=Math.sqrt(V*V+F*F),Y[9]=N,X=0}for(O*=N;;X++){const W=Y[X];if(!(O>W)){if(X==0)O/=W;else{const U=Y[X-1];O=X+(O-U)/(W-U)}break}}this.addCurvePosition(O*.1,m,g,x,E,w,b,p,S,h,z,n||q>0&&L==0)}return h}addBeforePosition(c,t,n,e,i){const r=t[n],h=t[n+1],l=t[n+2]-r,s=t[n+3]-h,a=Math.atan2(s,l);e[i]=r+c*Math.cos(a),e[i+1]=h+c*Math.sin(a),e[i+2]=a}addAfterPosition(c,t,n,e,i){const r=t[n+2],h=t[n+3],l=r-t[n],s=h-t[n+1],a=Math.atan2(s,l);e[i]=r+c*Math.cos(a),e[i+1]=h+c*Math.sin(a),e[i+2]=a}addCurvePosition(c,t,n,e,i,r,h,l,s,a,o,d){if(c==0||isNaN(c)){a[o]=t,a[o+1]=n,a[o+2]=Math.atan2(i-n,e-t);return}const f=c*c,u=f*c,m=1-c,g=m*m,x=g*m,E=m*c,w=E*3,b=m*w,p=w*c,S=t*x+e*b+r*p+l*u,y=n*x+i*b+h*p+s*u;a[o]=S,a[o+1]=y,d&&(c<.001?a[o+2]=Math.atan2(i-n,e-t):a[o+2]=Math.atan2(y-(n*g+i*E*2+h*f),S-(t*g+e*E*2+r*f)))}};let Sn=Le;Sn.NONE=-1,Sn.BEFORE=-2,Sn.AFTER=-3,Sn.epsilon=1e-5;class ur{constructor(t,n){if(this.darkColor=null,this.attachment=null,this.attachmentState=0,this.sequenceIndex=-1,this.deform=new Array,!t)throw new Error("data cannot be null.");if(!n)throw new Error("bone cannot be null.");this.data=t,this.bone=n,this.color=new _,this.darkColor=t.darkColor?new _:null,this.setToSetupPose(),this.blendMode=this.data.blendMode}getSkeleton(){return this.bone.skeleton}getAttachment(){return this.attachment}setAttachment(t){this.attachment!=t&&((!(t instanceof we)||!(this.attachment instanceof we)||t.timelineAttachment!=this.attachment.timelineAttachment)&&(this.deform.length=0),this.attachment=t,this.sequenceIndex=-1)}setToSetupPose(){this.color.setFromColor(this.data.color),this.darkColor&&this.darkColor.setFromColor(this.data.darkColor),this.data.attachmentName?(this.attachment=null,this.setAttachment(this.bone.skeleton.getAttachment(this.data.index,this.data.attachmentName))):this.attachment=null}}class mr{constructor(t,n){if(this.mixRotate=0,this.mixX=0,this.mixY=0,this.mixScaleX=0,this.mixScaleY=0,this.mixShearY=0,this.temp=new un,this.active=!1,!t)throw new Error("data cannot be null.");if(!n)throw new Error("skeleton cannot be null.");this.data=t,this.mixRotate=t.mixRotate,this.mixX=t.mixX,this.mixY=t.mixY,this.mixScaleX=t.mixScaleX,this.mixScaleY=t.mixScaleY,this.mixShearY=t.mixShearY,this.bones=new Array;for(let i=0;i0?C.degRad:-C.degRad,g=this.data.offsetRotation*m,x=this.data.offsetShearY*m,E=this.bones;for(let w=0,b=E.length;wC.PI?I-=C.PI2:I<-C.PI&&(I+=C.PI2),I*=t;const R=Math.cos(I),V=Math.sin(I);S.a=R*y-V*T,S.c=R*M-V*k,S.b=V*y+R*T,S.d=V*M+R*k}if(l){const y=this.temp;s.localToWorld(y.set(this.data.offsetX,this.data.offsetY)),S.tx+=(y.x-S.tx)*n,S.ty+=(y.y-S.ty)*e}if(i!=0){let y=Math.sqrt(S.a*S.a+S.b*S.b);y!=0&&(y=(y+(Math.sqrt(o*o+f*f)-y+this.data.offsetScaleX)*i)/y),S.a*=y,S.b*=y}if(r!=0){let y=Math.sqrt(S.c*S.c+S.d*S.d);y!=0&&(y=(y+(Math.sqrt(d*d+u*u)-y+this.data.offsetScaleY)*r)/y),S.c*=y,S.d*=y}if(h>0){const y=S.c,M=S.d,T=Math.atan2(M,y);let k=Math.atan2(u,d)-Math.atan2(f,o)-(T-Math.atan2(S.b,S.a));k>C.PI?k-=C.PI2:k<-C.PI&&(k+=C.PI2),k=T+(k+x)*h;const I=Math.sqrt(y*y+M*M);S.c=Math.cos(k)*I,S.d=Math.sin(k)*I}p.updateAppliedTransform()}}applyRelativeWorld(){const t=this.mixRotate,n=this.mixX,e=this.mixY,i=this.mixScaleX,r=this.mixScaleY,h=this.mixShearY,l=n!=0||e!=0,s=this.target,a=s.matrix,o=a.a,d=a.c,f=a.b,u=a.d,m=o*u-d*f>0?C.degRad:-C.degRad,g=this.data.offsetRotation*m,x=this.data.offsetShearY*m,E=this.bones;for(let w=0,b=E.length;wC.PI?I-=C.PI2:I<-C.PI&&(I+=C.PI2),I*=t;const R=Math.cos(I),V=Math.sin(I);S.a=R*y-V*T,S.c=R*M-V*k,S.b=V*y+R*T,S.d=V*M+R*k}if(l){const y=this.temp;s.localToWorld(y.set(this.data.offsetX,this.data.offsetY)),S.tx+=y.x*n,S.ty+=y.y*e}if(i!=0){const y=(Math.sqrt(o*o+f*f)-1+this.data.offsetScaleX)*i+1;S.a*=y,S.b*=y}if(r!=0){const y=(Math.sqrt(d*d+u*u)-1+this.data.offsetScaleY)*r+1;S.c*=y,S.d*=y}if(h>0){let y=Math.atan2(u,d)-Math.atan2(f,o);y>C.PI?y-=C.PI2:y<-C.PI&&(y+=C.PI2);const M=S.c,T=S.d;y=Math.atan2(T,M)+(y-C.PI/2+x)*h;const k=Math.sqrt(M*M+T*T);S.c=Math.cos(y)*k,S.d=Math.sin(y)*k}p.updateAppliedTransform()}}applyAbsoluteLocal(){const t=this.mixRotate,n=this.mixX,e=this.mixY,i=this.mixScaleX,r=this.mixScaleY,h=this.mixShearY,l=this.target,s=this.bones;for(let a=0,o=s.length;a= 0.");if(!n)throw new Error("name cannot be null.");if(!e)throw new Error("boneData cannot be null.");this.index=t,this.name=n,this.boneData=e}}class xi extends jn{constructor(t){super(t,0,!1),this.bones=new Array,this._target=null,this.mixRotate=0,this.mixX=0,this.mixY=0,this.mixScaleX=0,this.mixScaleY=0,this.mixShearY=0,this.offsetRotation=0,this.offsetX=0,this.offsetY=0,this.offsetScaleX=0,this.offsetScaleY=0,this.offsetShearY=0,this.relative=!1,this.local=!1}set target(t){this._target=t}get target(){if(this._target)return this._target;throw new Error("BoneData not set.")}}class pi{constructor(t,n,e){this.slotIndex=t,this.name=n,this.attachment=e}}class Zn{constructor(t){if(this.attachments=new Array,this.bones=Array(),this.constraints=new Array,!t)throw new Error("name cannot be null.");this.name=t}setAttachment(t,n,e){if(!e)throw new Error("attachment cannot be null.");const i=this.attachments;t>=i.length&&(i.length=t+1),i[t]||(i[t]={}),i[t][n]=e}addSkin(t){for(let e=0;e>4,t.readFloat())}i.push(y);break}}}}}const h=t.readInt(!0);if(h>0){const a=new hn(h),o=e.slots.length;for(let d=0;d=0;w--)m[w]=-1;const g=v.newArray(o-u,0);let x=0,E=0;for(let w=0;w=0;w--)m[w]==-1&&(m[w]=g[--E]);a.setFrame(d,f,m)}i.push(a)}const l=t.readInt(!0);if(l>0){const a=new vn(l);for(let o=0;o=0;E--)f[E]==-1&&(f[E]=m[--x])}l.setFrame(a,P(d,"time",0),f)}r.push(l)}if(t.events){const l=new vn(t.events.length);let s=0;for(let a=0;a(c[c.UNKNOWN=0]="UNKNOWN",c[c.VER37=37]="VER37",c[c.VER38=38]="VER38",c[c.VER40=40]="VER40",c[c.VER41=41]="VER41",c))(he||{});function Kn(c){const t=c.substr(0,3),n=Math.floor(Number(t)*10+.001);return t==="3.7"?37:t==="3.8"?38:t==="4.0"?40:t==="4.1"?41:n<37?37:0}class ga{constructor(){this.scale=1}readSkeletonData(t,n){let e=null,i=this.readVersionOldFormat(n),r=Kn(i);if(r===he.VER38&&(e=new Mt(new gs(t))),i=this.readVersionNewFormat(n),r=Kn(i),(r===he.VER40||r===he.VER41)&&(e=new wi(new ai(t))),!e){const h=`Unsupported version of spine model ${i}, please update pixi-spine`;console.error(h)}return e.scale=this.scale,e.readSkeletonData(n)}readVersionOldFormat(t){const n=new Mn(t);let e;try{n.readString(),e=n.readString()}catch(i){e=""}return e||""}readVersionNewFormat(t){const n=new Mn(t);n.readInt32(),n.readInt32();let e;try{e=n.readString()}catch(i){e=""}return e||""}}class xa{constructor(){this.scale=1}readSkeletonData(t,n){const e=n.skeleton.spine,i=Kn(e);let r=null;if(i===he.VER37&&(r=new an(new Ui(t))),i===he.VER38&&(r=new sn(new gs(t))),(i===he.VER40||i===he.VER41)&&(r=new Qn(new ai(t))),!r){const h=`Unsupported version of spine model ${e}, please update pixi-spine`;console.error(h)}return r.scale=this.scale,r.readSkeletonData(n)}}class pa extends Rr{createBinaryParser(){return new ga}createJsonParser(){return new xa}parseData(t,n,e){return{spineData:t.readSkeletonData(n,e),spineAtlas:n}}}class wa extends tn{createSkeleton(t){const n=Kn(t.version);let e=null;if(n===he.VER37&&(e=Or),n===he.VER38&&(e=Nr),(n===he.VER40||n===he.VER41)&&(e=ma),!e){const i=`Cant detect version of spine model ${t.version}`;console.error(i)}this.skeleton=new e.Skeleton(t),this.skeleton.updateWorldTransform(),this.stateData=new e.AnimationStateData(t),this.state=new e.AnimationState(this.stateData)}}return new pa().installLoader(),tt.AttachmentType=Z,tt.BinaryInput=Mn,tt.Color=_,tt.DebugUtils=Mr,tt.IntSet=ns,tt.Interpolation=Si,tt.MathUtils=C,tt.MixBlend=A,tt.MixDirection=J,tt.Pool=An,tt.PositionMode=dt,tt.Pow=yi,tt.PowOut=is,tt.RotateMode=pt,tt.SkeletonBounds=xr,tt.SkeletonBoundsBase=Cn,tt.Spine=wa,tt.SpineBase=tn,tt.SpineDebugRenderer=Tr,tt.SpineMesh=Ai,tt.SpineSprite=Mi,tt.StringSet=ss,tt.TextureAtlas=Fn,tt.TextureAtlasPage=ts,tt.TextureAtlasRegion=es,tt.TextureFilter=Bt,tt.TextureRegion=Vn,tt.TextureWrap=fe,tt.TimeKeeper=Ar,tt.TransformMode=j,tt.Utils=v,tt.Vector2=un,tt.WindowedMean=Cr,tt.filterFromString=Jn,tt.settings=zt,tt.wrapFromString=Er,tt}({},PIXI,PIXI,PIXI,PIXI,PIXI,PIXI); +var pixi_spine = this.PIXI.spine; +//# sourceMappingURL=pixi-spine.js.map diff --git a/GDJS/Runtime/pixi-renderers/pixi.js b/GDJS/Runtime/pixi-renderers/pixi.js index 5f885b19830e..46bf49637041 100644 --- a/GDJS/Runtime/pixi-renderers/pixi.js +++ b/GDJS/Runtime/pixi-renderers/pixi.js @@ -1160,4 +1160,4 @@ void main(void)\r font-display: ${e.display}; }`,this._stylesheet)}get stylesheet(){return this._stylesheet}set stylesheet(t){this._stylesheet!==t&&(this._stylesheet=t,this.styleID++)}normalizeColor(t){return Array.isArray(t)&&(t=To(t)),typeof t=="number"?bo(t):t}dropShadowToCSS(){let t=this.normalizeColor(this.dropShadowColor);const e=this.dropShadowAlpha,s=Math.round(Math.cos(this.dropShadowAngle)*this.dropShadowDistance),r=Math.round(Math.sin(this.dropShadowAngle)*this.dropShadowDistance);t.startsWith("#")&&e<1&&(t+=(e*255|0).toString(16).padStart(2,"0"));const n=`${s}px ${r}px`;return this.dropShadowBlur>0?`text-shadow: ${n} ${this.dropShadowBlur}px ${t}`:`text-shadow: ${n} ${t}`}reset(){Object.assign(this,os.defaultOptions)}onBeforeDraw(){const{fontsDirty:t}=this;return this.fontsDirty=!1,this.isSafari&&this._fonts.length>0&&t?new Promise(e=>setTimeout(e,100)):Promise.resolve()}get isSafari(){const{userAgent:t}=N.ADAPTER.getNavigator();return/^((?!chrome|android).)*safari/i.test(t)}set fillGradientStops(t){console.warn("[HTMLTextStyle] fillGradientStops is not supported by HTMLText")}get fillGradientStops(){return super.fillGradientStops}set fillGradientType(t){console.warn("[HTMLTextStyle] fillGradientType is not supported by HTMLText")}get fillGradientType(){return super.fillGradientType}set miterLimit(t){console.warn("[HTMLTextStyle] miterLimit is not supported by HTMLText")}get miterLimit(){return super.miterLimit}set trim(t){console.warn("[HTMLTextStyle] trim is not supported by HTMLText")}get trim(){return super.trim}set textBaseline(t){console.warn("[HTMLTextStyle] textBaseline is not supported by HTMLText")}get textBaseline(){return super.textBaseline}set leading(t){console.warn("[HTMLTextStyle] leading is not supported by HTMLText")}get leading(){return super.leading}set lineJoin(t){console.warn("[HTMLTextStyle] lineJoin is not supported by HTMLText")}get lineJoin(){return super.lineJoin}};ma.availableFonts={},ma.defaultOptions={align:"left",breakWords:!1,dropShadow:!1,dropShadowAlpha:1,dropShadowAngle:Math.PI/6,dropShadowBlur:0,dropShadowColor:"black",dropShadowDistance:5,fill:"black",fontFamily:"Arial",fontSize:26,fontStyle:"normal",fontVariant:"normal",fontWeight:"normal",letterSpacing:0,lineHeight:0,padding:0,stroke:"black",strokeThickness:0,whiteSpace:"normal",wordWrap:!1,wordWrapWidth:100};let _r=ma;const ti=class hs extends Ut{constructor(t="",e={}){var s;super(L.EMPTY),this._text=null,this._style=null,this._autoResolution=!0,this.localStyleID=-1,this.dirty=!1,this._updateID=0,this.ownsStyle=!1;const r=new Image,n=L.from(r,{scaleMode:N.SCALE_MODE,resourceOptions:{autoLoad:!1}});n.orig=new z,n.trim=new z,this.texture=n;const a="http://www.w3.org/2000/svg",o="http://www.w3.org/1999/xhtml",h=document.createElementNS(a,"svg"),l=document.createElementNS(a,"foreignObject"),u=document.createElementNS(o,"div"),c=document.createElementNS(o,"style");l.setAttribute("width","10000"),l.setAttribute("height","10000"),l.style.overflow="hidden",h.appendChild(l),this.maxWidth=hs.defaultMaxWidth,this.maxHeight=hs.defaultMaxHeight,this._domElement=u,this._styleElement=c,this._svgRoot=h,this._foreignObject=l,this._foreignObject.appendChild(c),this._foreignObject.appendChild(u),this._image=r,this._loadImage=new Image,this._autoResolution=hs.defaultAutoResolution,this._resolution=(s=hs.defaultResolution)!=null?s:N.RESOLUTION,this.text=t,this.style=e}measureText(t){var e,s;const{text:r,style:n,resolution:a}=Object.assign({text:this._text,style:this._style,resolution:this._resolution},t);Object.assign(this._domElement,{innerHTML:r,style:n.toCSS(a)}),this._styleElement.textContent=n.toGlobalCSS(),document.body.appendChild(this._svgRoot);const o=this._domElement.getBoundingClientRect();this._svgRoot.remove();const{width:h,height:l}=o,u=Math.min(this.maxWidth,Math.ceil(h)),c=Math.min(this.maxHeight,Math.ceil(l));return this._svgRoot.setAttribute("width",u.toString()),this._svgRoot.setAttribute("height",c.toString()),r!==this._text&&(this._domElement.innerHTML=this._text),n!==this._style&&(Object.assign(this._domElement,{style:(e=this._style)==null?void 0:e.toCSS(a)}),this._styleElement.textContent=(s=this._style)==null?void 0:s.toGlobalCSS()),{width:u+n.padding*2,height:c+n.padding*2}}async updateText(t=!0){const{style:e,_image:s,_loadImage:r}=this;if(this.localStyleID!==e.styleID&&(this.dirty=!0,this.localStyleID=e.styleID),!this.dirty&&t)return;const{width:n,height:a}=this.measureText();s.width=r.width=Math.ceil(Math.max(1,n)),s.height=r.height=Math.ceil(Math.max(1,a)),this._updateID++;const o=this._updateID;await new Promise(h=>{r.onload=async()=>{if(o/gi,"
").replace(/


/gi,"
").replace(/ /gi," ")}};ti.defaultDestroyOptions={texture:!0,children:!1,baseTexture:!0},ti.defaultMaxWidth=2024,ti.defaultMaxHeight=2024,ti.defaultAutoResolution=!0;let hg=ti;const Pe=new z;class ga{constructor(t){this.renderer=t}async image(t,e,s,r){const n=new Image;return n.src=await this.base64(t,e,s,r),n}async base64(t,e,s,r){const n=this.canvas(t,r);if(n.toBlob!==void 0)return new Promise((a,o)=>{n.toBlob(h=>{if(!h){o(new Error("ICanvas.toBlob failed!"));return}const l=new FileReader;l.onload=()=>a(l.result),l.onerror=o,l.readAsDataURL(h)},e,s)});if(n.toDataURL!==void 0)return n.toDataURL(e,s);if(n.convertToBlob!==void 0){const a=await n.convertToBlob({type:e,quality:s});return new Promise((o,h)=>{const l=new FileReader;l.onload=()=>o(l.result),l.onerror=h,l.readAsDataURL(a)})}throw new Error("CanvasExtract.base64() requires ICanvas.toDataURL, ICanvas.toBlob, or ICanvas.convertToBlob to be implemented")}canvas(t,e){const s=this.renderer;if(!s)throw new Error("The CanvasExtract has already been destroyed");let r,n,a;t&&(t instanceof Yt?a=t:(a=s.generateTexture(t,{region:e,resolution:s.resolution}),e&&(Pe.width=e.width,Pe.height=e.height,e=Pe))),a?(r=a.baseTexture._canvasRenderTarget.context,n=a.baseTexture._canvasRenderTarget.resolution,e=e!=null?e:a.frame):(r=s.canvasContext.rootContext,n=s._view.resolution,e||(e=Pe,e.width=s.width/n,e.height=s.height/n));const o=Math.round(e.x*n),h=Math.round(e.y*n),l=Math.max(Math.round(e.width*n),1),u=Math.max(Math.round(e.height*n),1),c=new ys(l,u,1),d=r.getImageData(o,h,l,u);return c.context.putImageData(d,0,0),c.canvas}pixels(t,e){const s=this.renderer;if(!s)throw new Error("The CanvasExtract has already been destroyed");let r,n,a;t&&(t instanceof Yt?a=t:(a=s.generateTexture(t,{region:e,resolution:s.resolution}),e&&(Pe.width=e.width,Pe.height=e.height,e=Pe))),a?(r=a.baseTexture._canvasRenderTarget.context,n=a.baseTexture._canvasRenderTarget.resolution,e=e!=null?e:a.frame):(r=s.canvasContext.rootContext,n=s.resolution,e||(e=Pe,e.width=s.width/n,e.height=s.height/n));const o=Math.round(e.x*n),h=Math.round(e.y*n),l=Math.max(Math.round(e.width*n),1),u=Math.max(Math.round(e.height*n),1);return r.getImageData(o,h,l,u).data}destroy(){this.renderer=null}}ga.extension={name:"extract",type:D.CanvasRendererSystem},U.add(ga);let _a;const ei=new tt;rs.prototype.generateCanvasTexture=function(i,t=1){const e=this.getLocalBounds(new z);e.width=Math.max(e.width,1/t),e.height=Math.max(e.height,1/t);const s=Yt.create({width:e.width,height:e.height,scaleMode:i,resolution:t});_a||(_a=new Bs),this.transform.updateLocalTransform(),this.transform.localTransform.copyTo(ei),ei.invert(),ei.tx-=e.x,ei.ty-=e.y,_a.render(this,{renderTexture:s,clear:!0,transform:ei});const r=L.from(s.baseTexture._canvasRenderTarget.canvas,{scaleMode:i});return r.baseTexture.setResolution(t),r},rs.prototype.cachedGraphicsData=[],rs.prototype._renderCanvas=function(i){this.isMask!==!0&&(this.finishPoly(),i.plugins.graphics.render(this))};class si{static offsetPolygon(t,e){const s=[],r=t.length;e=si.isPolygonClockwise(t)?e:-1*e;for(let n=0;n0}}class va{constructor(t){this._svgMatrix=null,this._tempMatrix=new tt,this.renderer=t}_calcCanvasStyle(t,e){let s;return t.texture&&t.texture.baseTexture!==L.WHITE.baseTexture?t.texture.valid?(s=gt.getTintedPattern(t.texture,e),this.setPatternTransform(s,t.matrix||tt.IDENTITY)):s="#808080":s=`#${`00000${(e|0).toString(16)}`.slice(-6)}`,s}render(t){const e=this.renderer,s=e.canvasContext.activeContext,r=t.worldAlpha,n=t.transform.worldTransform;e.canvasContext.setContextTransform(n),e.canvasContext.setBlendMode(t.blendMode);const a=t.geometry.graphicsData;let o,h;const l=Y.shared.setValue(t.tint).toArray();for(let u=0;u0){A=[],b=0,R=x[0],w=x[1];for(let S=2;S+2=0;I-=2)s.lineTo(x[I],x[I+1])}v[S].shape.closeStroke&&s.closePath(),A[S]=T*b<0}}f.visible&&(s.globalAlpha=f.alpha*r,s.fillStyle=o,s.fill()),p.visible&&this.paintPolygonStroke(_,p,h,v,A,r,s)}else if(c.type===it.RECT){const _=d;if(f.visible&&(s.globalAlpha=f.alpha*r,s.fillStyle=o,s.fillRect(_.x,_.y,_.width,_.height)),p.visible){const x=p.width*(.5-(1-p.alignment)),v=_.width+2*x,b=_.height+2*x;s.globalAlpha=p.alpha*r,s.strokeStyle=h,s.strokeRect(_.x-x,_.y-x,v,b)}}else if(c.type===it.CIRC){const _=d;if(s.beginPath(),s.arc(_.x,_.y,_.radius,0,2*Math.PI),s.closePath(),f.visible&&(s.globalAlpha=f.alpha*r,s.fillStyle=o,s.fill()),p.visible){if(p.alignment!==.5){const x=p.width*(.5-(1-p.alignment));s.beginPath(),s.arc(_.x,_.y,_.radius+x,0,2*Math.PI),s.closePath()}s.globalAlpha=p.alpha*r,s.strokeStyle=h,s.stroke()}}else if(c.type===it.ELIP){const _=d,x=p.alignment===1;if(x||this.paintEllipse(_,f,p,o,r,s),p.visible){if(p.alignment!==.5){const v=.5522848,b=p.width*(.5-(1-p.alignment)),T=(_.width+b)*2,R=(_.height+b)*2,w=_.x-T/2,A=_.y-R/2,S=T/2*v,I=R/2*v,H=w+T,B=A+R,E=w+T/2,P=A+R/2;s.beginPath(),s.moveTo(w,P),s.bezierCurveTo(w,P-I,E-S,A,E,A),s.bezierCurveTo(E+S,A,H,P-I,H,P),s.bezierCurveTo(H,P+I,E+S,B,E,B),s.bezierCurveTo(E-S,B,w,P+I,w,P),s.closePath()}s.globalAlpha=p.alpha*r,s.strokeStyle=h,s.stroke()}x&&this.paintEllipse(_,f,p,o,r,s)}else if(c.type===it.RREC){const _=d,x=p.alignment===1;if(x||this.paintRoundedRectangle(_,f,p,o,r,s),p.visible){if(p.alignment!==.5){const v=_.width,b=_.height,T=p.width*(.5-(1-p.alignment)),R=_.x-T,w=_.y-T,A=_.width+2*T,S=_.height+2*T,I=T*(p.alignment>=1?Math.min(A/v,S/b):Math.min(v/A,b/S));let H=_.radius+I;const B=Math.min(A,S)/2;H=H>B?B:H,s.beginPath(),s.moveTo(R,w+H),s.lineTo(R,w+S-H),s.quadraticCurveTo(R,w+S,R+H,w+S),s.lineTo(R+A-H,w+S),s.quadraticCurveTo(R+A,w+S,R+A,w+S-H),s.lineTo(R+A,w+H),s.quadraticCurveTo(R+A,w,R+A-H,w),s.lineTo(R+H,w),s.quadraticCurveTo(R,w,R,w+H),s.closePath()}s.globalAlpha=p.alpha*r,s.strokeStyle=h,s.stroke()}x&&this.paintRoundedRectangle(_,f,p,o,r,s)}}}paintPolygonStroke(t,e,s,r,n,a,o){if(e.alignment!==.5){const h=e.width*(.5-(1-e.alignment));let l=si.offsetPolygon(t.points,h),u;o.beginPath(),o.moveTo(l[0],l[1]);for(let c=2;c=0;d-=2)o.lineTo(l[d],l[d+1])}r[c].shape.closeStroke&&o.closePath()}}o.globalAlpha=e.alpha*a,o.strokeStyle=s,o.stroke()}paintEllipse(t,e,s,r,n,a){const o=t.width*2,h=t.height*2,l=t.x-o/2,u=t.y-h/2,c=.5522848,d=o/2*c,f=h/2*c,p=l+o,m=u+h,g=l+o/2,_=u+h/2;s.alignment===0&&a.save(),a.beginPath(),a.moveTo(l,_),a.bezierCurveTo(l,_-f,g-d,u,g,u),a.bezierCurveTo(g+d,u,p,_-f,p,_),a.bezierCurveTo(p,_+f,g+d,m,g,m),a.bezierCurveTo(g-d,m,l,_+f,l,_),a.closePath(),s.alignment===0&&a.clip(),e.visible&&(a.globalAlpha=e.alpha*n,a.fillStyle=r,a.fill()),s.alignment===0&&a.restore()}paintRoundedRectangle(t,e,s,r,n,a){const o=t.x,h=t.y,l=t.width,u=t.height;let c=t.radius;const d=Math.min(l,u)/2;c=c>d?d:c,s.alignment===0&&a.save(),a.beginPath(),a.moveTo(o,h+c),a.lineTo(o,h+u-c),a.quadraticCurveTo(o,h+u,o+c,h+u),a.lineTo(o+l-c,h+u),a.quadraticCurveTo(o+l,h+u,o+l,h+u-c),a.lineTo(o+l,h+c),a.quadraticCurveTo(o+l,h,o+l-c,h),a.lineTo(o+c,h),a.quadraticCurveTo(o,h,o,h+c),a.closePath(),s.alignment===0&&a.clip(),e.visible&&(a.globalAlpha=e.alpha*n,a.fillStyle=r,a.fill()),s.alignment===0&&a.restore()}setPatternTransform(t,e){if(this._svgMatrix!==!1){if(!this._svgMatrix){const s=document.createElementNS("http://www.w3.org/2000/svg","svg");if(s!=null&&s.createSVGMatrix&&(this._svgMatrix=s.createSVGMatrix()),!this._svgMatrix||!t.setTransform){this._svgMatrix=!1;return}}this._svgMatrix.a=e.a,this._svgMatrix.b=e.b,this._svgMatrix.c=e.c,this._svgMatrix.d=e.d,this._svgMatrix.e=e.tx,this._svgMatrix.f=e.ty,t.setTransform(this._svgMatrix.inverse())}}destroy(){this.renderer=null,this._svgMatrix=null,this._tempMatrix=null}}va.extension={name:"graphics",type:D.CanvasRendererPlugin},U.add(va),Object.defineProperties(N,{MESH_CANVAS_PADDING:{get(){return Et.defaultCanvasPadding},set(i){Et.defaultCanvasPadding=i}}}),Xe.prototype._renderCanvas=function(i,t){i.plugins.mesh.render(t)},Ks.prototype._cachedTint=16777215,Ks.prototype._tintedCanvas=null,Ks.prototype._canvasUvs=null,Ks.prototype._renderCanvas=function(i){const t=i.canvasContext.activeContext,e=this.worldTransform,s=this.tintValue!==16777215,r=this.texture;if(!r.valid)return;s&&this._cachedTint!==this.tintValue&&(this._cachedTint=this.tintValue,this._tintedCanvas=gt.getTintedCanvas(this,this.tintValue));const n=s?this._tintedCanvas:r.baseTexture.getDrawableSource();this._canvasUvs||(this._canvasUvs=[0,0,0,0,0,0,0,0]);const a=this.vertices,o=this._canvasUvs,h=s?0:r.frame.x,l=s?0:r.frame.y,u=h+r.frame.width,c=l+r.frame.height;o[0]=h,o[1]=h+this._leftWidth,o[2]=u-this._rightWidth,o[3]=u,o[4]=l,o[5]=l+this._topHeight,o[6]=c-this._bottomHeight,o[7]=c;for(let d=0;d<8;d++)o[d]*=r.baseTexture.resolution;t.globalAlpha=this.worldAlpha,i.canvasContext.setBlendMode(this.blendMode),i.canvasContext.setContextTransform(e,this.roundPixels);for(let d=0;d<3;d++)for(let f=0;f<3;f++){const p=f*2+d*8,m=Math.max(1,o[f+1]-o[f]),g=Math.max(1,o[d+5]-o[d+4]),_=Math.max(1,a[p+10]-a[p]),x=Math.max(1,a[p+11]-a[p+1]);t.drawImage(n,o[f],o[d+4],m,g,a[p],a[p+1],_,x)}};let Fu=!1;Et.prototype._cachedTint=16777215,Et.prototype._tintedCanvas=null,Et.prototype._cachedTexture=null,Et.prototype._renderCanvas=function(i){this.shader.uvMatrix&&(this.shader.uvMatrix.update(),this.calculateUvs()),this.material._renderCanvas?this.material._renderCanvas(i,this):Fu||(Fu=!0,globalThis.console.warn("Mesh with custom shaders are not supported in CanvasRenderer."))},Et.prototype._canvasPadding=null,Et.defaultCanvasPadding=0,Object.defineProperty(Et.prototype,"canvasPadding",{get(){var i;return(i=this._canvasPadding)!=null?i:Et.defaultCanvasPadding},set(i){this._canvasPadding=i}}),mu.prototype._renderCanvas=function(i){this.autoUpdate&&this.geometry.getBuffer("aVertexPosition").update(),this.shader.update&&this.shader.update(),this.calculateUvs(),this.material._renderCanvas(i,this)},gu.prototype._renderCanvas=function(i){(this.autoUpdate||this.geometry._width!==this.shader.texture.height)&&(this.geometry._width=this.shader.texture.height,this.geometry.update()),this.shader.update&&this.shader.update(),this.calculateUvs(),this.material._renderCanvas(i,this)};class ya{constructor(t){this.renderer=t}render(t){const e=this.renderer,s=t.worldTransform;e.canvasContext.activeContext.globalAlpha=t.worldAlpha,e.canvasContext.setBlendMode(t.blendMode),e.canvasContext.setContextTransform(s,t.roundPixels),t.drawMode!==Ot.TRIANGLES?this._renderTriangleMesh(t):this._renderTriangles(t)}_renderTriangleMesh(t){const e=t.geometry.buffers[0].data.length;for(let s=0;s0){const{a:ht,b:F,c:O,d:Z}=t.worldTransform,Q=(T+R+w)/3,J=(A+S+I)/3;let st=T-Q,et=A-J,rt=ht*st+O*et,lt=F*st+Z*et,_t=Math.sqrt(rt*rt+lt*lt),nt=1+H/_t;T=Q+st*nt,A=J+et*nt,st=R-Q,et=S-J,rt=ht*st+O*et,lt=F*st+Z*et,_t=Math.sqrt(rt*rt+lt*lt),nt=1+H/_t,R=Q+st*nt,S=J+et*nt,st=w-Q,et=I-J,rt=ht*st+O*et,lt=F*st+Z*et,_t=Math.sqrt(rt*rt+lt*lt),nt=1+H/_t,w=Q+st*nt,I=J+et*nt}a.save(),a.beginPath(),a.moveTo(T,A),a.lineTo(R,S),a.lineTo(w,I),a.closePath(),a.clip();const B=m*v+x*_+g*b-v*_-x*g-m*b,E=T*v+x*w+R*b-v*w-x*R-T*b,P=m*R+T*_+g*w-R*_-T*g-m*w,V=m*v*w+x*R*_+T*g*b-T*v*_-x*g*w-m*R*b,q=A*v+x*I+S*b-v*I-x*S-A*b,j=m*S+A*_+g*I-S*_-A*g-m*I,W=m*v*I+x*S*_+A*g*b-A*v*_-x*g*I-m*S*b;a.transform(E/B,q/B,P/B,j/B,V/B,W/B),a.drawImage(p,0,0,d*c.resolution,f*c.resolution,0,0,d,f),a.restore(),this.renderer.canvasContext.invalidateBlendMode()}renderMeshFlat(t){const e=this.renderer.canvasContext.activeContext,s=t.geometry.getBuffer("aVertexPosition").data,r=s.length/2;e.beginPath();for(let n=1;n=14" + "node_modules/@pixi/graphics": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-7.3.0.tgz", + "integrity": "sha512-+5yyv8z4sZDxvdyYbGn/DeR1EdSD+ieXf9N3BS2puoxmrM5blMUzZCoY4vFCeF+r59VpB0ildYl3APzwMdRCLw==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/display": "7.3.0", + "@pixi/sprite": "7.3.0" } }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.10", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-html-community": "^0.0.8", + "node_modules/@pixi/math": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/math/-/math-7.3.0.tgz", + "integrity": "sha512-3gM1MffXlDM8bFNl+D1ndq4W1Gn7quRvxbAZ9RUp7Zvoqcud/0c/VcxngM2st+IXeFf8htlKxytkotMKk5gQxA==" + }, + "node_modules/@pixi/mesh": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-7.3.0.tgz", + "integrity": "sha512-TZqYmWiONuIIFzt+XL1+lnUFMHhiyJUyT5pNcW/mB1Kfg9vGIebgNbml+Ut6Rghe6B1ntereRyCyEpr+hLbbWg==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/display": "7.3.0" + } + }, + "node_modules/@pixi/mesh-extras": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-7.3.0.tgz", + "integrity": "sha512-SxTrfQ8gzFru2DPv2dlEelignSBf6gN1taSVweAKs9HKfGi6hXYDbtQYQ9b21dsecXZYnrpL04kcY+QukOUVqQ==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/mesh": "7.3.0" + } + }, + "node_modules/@pixi/mixin-cache-as-bitmap": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-7.3.0.tgz", + "integrity": "sha512-Wck2Ro+832pZ4Wu6N3vptF2J0XveQ9W3dBfGGSPHCLypSZgZ9T2hvbF6WyzZShQFKBo+oeKhnX+Nf+fb8v81Rg==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/display": "7.3.0", + "@pixi/sprite": "7.3.0" + } + }, + "node_modules/@pixi/mixin-get-child-by-name": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-7.3.0.tgz", + "integrity": "sha512-CQ+cy59Oy5nVFCC3c/hYa73bmY0qlsbpax3sMrwaF4q/33o0ymPS50dBQvfu26l5OcK3UoE5XzR3fdB3H8lcHg==", + "peerDependencies": { + "@pixi/display": "7.3.0" + } + }, + "node_modules/@pixi/mixin-get-global-position": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/mixin-get-global-position/-/mixin-get-global-position-7.3.0.tgz", + "integrity": "sha512-mM3UzWy9zFEz7o4LHlVUt3WJBAk57ZrPHwE8S5VgUrppiwHAdsLryoRwbTJkSAtW2gz+D2sLYbE6YkMdO76eVg==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/display": "7.3.0" + } + }, + "node_modules/@pixi/particle-container": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-7.3.0.tgz", + "integrity": "sha512-7pHVmn4FlHBRlHUuLM+L/+viv1AbZBfHH6Q7tJu1dWHBenlqd81VZINW7YdzMLdkQpcT5eRm+xLyjBxGqCZNFw==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/display": "7.3.0", + "@pixi/sprite": "7.3.0" + } + }, + "node_modules/@pixi/prepare": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-7.3.0.tgz", + "integrity": "sha512-WI/sWB+OHomJrLo9ATknmOagBLDGn5TccVRBSltW1lLre6i0X+eYTDLovQyTQq3JNmR2VsTEuwMYapDUIAVE5g==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/display": "7.3.0", + "@pixi/graphics": "7.3.0", + "@pixi/text": "7.3.0" + } + }, + "node_modules/@pixi/runner": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-7.3.0.tgz", + "integrity": "sha512-U0qQk5yhZcCYQVm444IO604aoe1TivQjKeaAYaEpxNyEbSJ2/rEIQEttrnw6JXnm6a0ycI8iBtweDthnpyatqA==" + }, + "node_modules/@pixi/settings": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-7.3.0.tgz", + "integrity": "sha512-x8Tms/DBnedbJBjkP4VHqyBckqXqJnoAfoayqEcFrqNDQa+1qkr1UnyPj3l4eiEPhY8cEUBz1wSZnhM7R4XcDw==", + "dependencies": { + "@pixi/constants": "7.3.0", + "@types/css-font-loading-module": "^0.0.7", + "ismobilejs": "^1.1.0" + } + }, + "node_modules/@pixi/sprite": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-7.3.0.tgz", + "integrity": "sha512-3hJveyaxJ9jmZiyOo/Wfmh0Lje7eElF0FoqPl9mfNCXz1TKHSmWqHste+1LimqnThTiUhruJqwUq8h5o1DKLuw==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/display": "7.3.0" + } + }, + "node_modules/@pixi/sprite-animated": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/sprite-animated/-/sprite-animated-7.3.0.tgz", + "integrity": "sha512-K8KCViX0BeYwZyN0IVcvCYtTSoKoAKtNPH5/EYhSPwRsFDq/3kqW/pVx7Mgh/+MM4fyIuweVd9IHxMCjYh7LKw==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/sprite": "7.3.0" + } + }, + "node_modules/@pixi/sprite-tiling": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-7.3.0.tgz", + "integrity": "sha512-9ktdL5LU2xq5ZORq8iRpyb5qz7josU6rmwCPggAAuuIS0HHt5HvmWRnklTjCL634FvkzbwlD3+DZnJ842qFRFA==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/display": "7.3.0", + "@pixi/sprite": "7.3.0" + } + }, + "node_modules/@pixi/spritesheet": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/spritesheet/-/spritesheet-7.3.0.tgz", + "integrity": "sha512-BloKplTxlM0cX1O60wW7upKPdzrVarYcRg/8+VTwlOpl2inHj/sVloyqOsNoG2eGVHgW3dl0yaeYiJQH/HzQQA==", + "peerDependencies": { + "@pixi/assets": "7.3.0", + "@pixi/core": "7.3.0" + } + }, + "node_modules/@pixi/text": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/text/-/text-7.3.0.tgz", + "integrity": "sha512-oShmP5CvATLJecK54i2YqwzKAkx8VRgpPqXk3m/gWvF+cs9i9AqCMV3sO5J6xdcCnc+Zb61hjX07J39+QxDqWg==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/sprite": "7.3.0" + } + }, + "node_modules/@pixi/text-bitmap": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/text-bitmap/-/text-bitmap-7.3.0.tgz", + "integrity": "sha512-o0EnbnR4zhSceLjl2i33yjz2R5Xm/r35ieuGE6CPDUiiTKG8J5fGhccieRpZ1ucr/dJ3B1JkYQq9QTbBFr5dMg==", + "peerDependencies": { + "@pixi/assets": "7.3.0", + "@pixi/core": "7.3.0", + "@pixi/display": "7.3.0", + "@pixi/mesh": "7.3.0", + "@pixi/text": "7.3.0" + } + }, + "node_modules/@pixi/text-html": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/text-html/-/text-html-7.3.0.tgz", + "integrity": "sha512-0RAsNz0ps/Q3yy4Tp7RZaJ9GxQJcVUox4N+I809AI0zwLhlBQClJdzSbjBfCEAzK24K8SQ+MJcDlsH3P+O8RGQ==", + "peerDependencies": { + "@pixi/core": "7.3.0", + "@pixi/display": "7.3.0", + "@pixi/sprite": "7.3.0", + "@pixi/text": "7.3.0" + } + }, + "node_modules/@pixi/ticker": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-7.3.0.tgz", + "integrity": "sha512-F77FpONHOn5JkZRMHUM8bXLLIG+Czve7zxOqb1Mk57QHLADhcHP88Kj2eYu9E7zJu4Flx51nyTdmVWQgQXW96g==", + "dependencies": { + "@pixi/extensions": "7.3.0", + "@pixi/settings": "7.3.0", + "@pixi/utils": "7.3.0" + } + }, + "node_modules/@pixi/utils": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-7.3.0.tgz", + "integrity": "sha512-syUi0UuJslUAs3PkZKycliND1Fs0cX3c+s2YyVTiRRRvuM81LvjrG/1AqKFhNaav7oYapBOQBWjgzBGv3wmM/A==", + "dependencies": { + "@pixi/color": "7.3.0", + "@pixi/constants": "7.3.0", + "@pixi/settings": "7.3.0", + "@types/earcut": "^2.1.0", + "earcut": "^2.2.4", + "eventemitter3": "^4.0.0", + "url": "^0.11.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-html-community": "^0.0.8", "common-path-prefix": "^3.0.0", "core-js-pure": "^3.23.3", "error-stack-parser": "^2.0.6", @@ -10457,8 +10737,9 @@ "license": "MIT" }, "node_modules/@types/earcut": { - "version": "2.1.1", - "license": "MIT" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.3.tgz", + "integrity": "sha512-pskpibEbm73+7nA9RqxGEnAiALRO92DdoSVxasyjGrqzEndaSDjFG73GCtstMzhdOowZMItVw2fhTdxVrY221w==" }, "node_modules/@types/ejs": { "version": "3.1.3", @@ -10691,9 +10972,9 @@ "dev": true }, "node_modules/@types/offscreencanvas": { - "version": "2019.7.1", - "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.1.tgz", - "integrity": "sha512-+HSrJgjBW77ALieQdMJvXhRZUIRN1597L+BKvsyeiIlHHERnqjcuOLyodK3auJ3Y3zRezNKtKAhuQWYJfEgFHQ==" + "version": "2019.7.2", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.2.tgz", + "integrity": "sha512-ujCjOxeA07IbEBQYAkoOI+XFw5sT3nhWJ/xZfPR6reJppDG7iPQPZacQiLTtWH1b3a2NYXWlxvYqa40y/LAixQ==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -15177,7 +15458,8 @@ }, "node_modules/earcut": { "version": "2.2.4", - "license": "ISC" + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" }, "node_modules/eastasianwidth": { "version": "0.1.1", @@ -25957,640 +26239,6 @@ "url": "https://opencollective.com/pixijs" } }, - "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-display": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/canvas-display/-/canvas-display-7.3.0.tgz", - "integrity": "sha512-Xy2PN1H9sCJpMOsLNoyRcC9F2iZos9uqkBpZsFnDLauwGn2XFXTJkNTbYX5cZ5X99rvUF7vQsULQMuonyMOxrA==", - "peerDependencies": { - "@pixi/display": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-extract": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/canvas-extract/-/canvas-extract-7.3.0.tgz", - "integrity": "sha512-SkXlGQn2b+rfaeS6N0wBpEoHB35QuHzKbnoMdQdHh/p6t02LKI21QiGMgqr56emaQl/elLUhKBQSZx1wfYZfJw==", - "peerDependencies": { - "@pixi/canvas-renderer": "7.3.0", - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/extract": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-graphics": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/canvas-graphics/-/canvas-graphics-7.3.0.tgz", - "integrity": "sha512-H9gt7bOgqqKgikaPfXE4YsK2EYS9YnhxkiTMqxbu7cUjjT541TlWpSkOi8OKMVbVn8hqwI5OgvPAsFbnxs40tg==", - "peerDependencies": { - "@pixi/canvas-display": "7.3.0", - "@pixi/canvas-renderer": "7.3.0", - "@pixi/core": "7.3.0", - "@pixi/graphics": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-mesh": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/canvas-mesh/-/canvas-mesh-7.3.0.tgz", - "integrity": "sha512-XjIuMUbJHtnOYOSo/oGopEtFOdQYAjkDViELTVs5oq1Qow80dUuPm8TbVyVvAUeC981lIuaGs3SlxbAz28qpIw==", - "peerDependencies": { - "@pixi/canvas-display": "7.3.0", - "@pixi/canvas-renderer": "7.3.0", - "@pixi/core": "7.3.0", - "@pixi/mesh": "7.3.0", - "@pixi/mesh-extras": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-particle-container": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/canvas-particle-container/-/canvas-particle-container-7.3.0.tgz", - "integrity": "sha512-0lKI6/l/SSIyVyR2PT0LODZJVK8I8z8QYG4SJzvPabH/g8dHc7rxzW2yCz63H6PlTiZF1d6aCjxzLb36gi8Niw==", - "peerDependencies": { - "@pixi/particle-container": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-prepare": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/canvas-prepare/-/canvas-prepare-7.3.0.tgz", - "integrity": "sha512-6HBkWDjZzgkECwEb2R+V3CZGPaegaRP+bcyKcBv4mssRbl0cslxt2DPxCoL9OL5ZjCRaHjIIdoE4KTXCH5c2QA==", - "peerDependencies": { - "@pixi/canvas-renderer": "7.3.0", - "@pixi/core": "7.3.0", - "@pixi/prepare": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-renderer": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/canvas-renderer/-/canvas-renderer-7.3.0.tgz", - "integrity": "sha512-xp8psuucRWmJGY1piQWxOLxQZ+7hJ4xWCTc2f+S2ekxsgYTumBCD7XBggPLAEY8YcyWWpqjyCAERBTroX6B+9A==", - "peerDependencies": { - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-sprite": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/canvas-sprite/-/canvas-sprite-7.3.0.tgz", - "integrity": "sha512-DpfTOaNq4pVd4DcE+IW7gggXnGvbGvNcbTSR46fl94KE7engCmbAAfEsG+VYZL6gYYdAgdUCIuRrbZzpM+Pw3g==", - "peerDependencies": { - "@pixi/canvas-display": "7.3.0", - "@pixi/canvas-renderer": "7.3.0", - "@pixi/core": "7.3.0", - "@pixi/sprite": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-sprite-tiling": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/canvas-sprite-tiling/-/canvas-sprite-tiling-7.3.0.tgz", - "integrity": "sha512-rPl/SwvQHdYLtksZpwq2z58z2vSOaUAO7Ex5boYWgiY5/upoUJcy/hsWqQXxF7Q4wdZujL90GS3p833z5LzGEg==", - "peerDependencies": { - "@pixi/canvas-renderer": "7.3.0", - "@pixi/canvas-sprite": "7.3.0", - "@pixi/core": "7.3.0", - "@pixi/sprite-tiling": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/canvas-text": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/canvas-text/-/canvas-text-7.3.0.tgz", - "integrity": "sha512-MhFYXdw53ErLtxKwrW3hpAU2v9ZNEeX7kRZ5AR8QGQUABsfSgTvhlCoxKtI2F2ibP3eCXWjVJwusd/yw/hMgdQ==", - "peerDependencies": { - "@pixi/canvas-sprite": "7.3.0", - "@pixi/sprite": "7.3.0", - "@pixi/text": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/color": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/color/-/color-7.3.0.tgz", - "integrity": "sha512-qwgsP+cQhw0QjvouvAslpJ3g7DUMwKLUrXF6Nv+G4GhgVC2Z03CsCfWgUxLxKPD3WadB6FacdRIGx6o2TywB+A==", - "peer": true, - "dependencies": { - "colord": "^2.9.3" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/constants": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-7.3.0.tgz", - "integrity": "sha512-zRBX5RAxm14zs7/sse/eXSrFzbv2XPEJwj2fQga+4hI7tAsXazYgGFl3CMlDET5mW9rXUSxROE0dvnLe9DcYRQ==", - "peer": true - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-7.3.0.tgz", - "integrity": "sha512-ZgFdlqOZfijfgvWMi6ZuQey2m3U+ik8GUD7MsLn96Gtg7UQGwmcEsEB2MZ7f7TUoLkMAOlxb0aXEHzdV/+v1zg==", - "peer": true, - "dependencies": { - "@pixi/color": "7.3.0", - "@pixi/constants": "7.3.0", - "@pixi/extensions": "7.3.0", - "@pixi/math": "7.3.0", - "@pixi/runner": "7.3.0", - "@pixi/settings": "7.3.0", - "@pixi/ticker": "7.3.0", - "@pixi/utils": "7.3.0", - "@types/offscreencanvas": "^2019.6.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/pixijs" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/display": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-7.3.0.tgz", - "integrity": "sha512-YQJZEcQo/0BIhvAaKrG68w01HYhPMwyPLj0Rvw30J4sW4uer/vf50IEAkM80rdQIUowqjUvatUYRW/r+owomXg==", - "peer": true, - "peerDependencies": { - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/extensions": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/extensions/-/extensions-7.3.0.tgz", - "integrity": "sha512-kr0nia7yvPLIXqBeOKLUXcOoxRG5yCxIPUtXvsFSrrmJvqsXsyg4l9cH0CS/I9yTb67/ks5wjzieUdwNf8pfTg==", - "peer": true - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/extract": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-7.3.0.tgz", - "integrity": "sha512-3CpGgu7I+4EVbEp/HU91nyTHKVUql5o/nik0hM+z402tlBbrbLejNAhoJ/Foq3L49n6SkpM2G8KN6d+G4Rn+jg==", - "peer": true, - "peerDependencies": { - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/graphics": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-7.3.0.tgz", - "integrity": "sha512-+5yyv8z4sZDxvdyYbGn/DeR1EdSD+ieXf9N3BS2puoxmrM5blMUzZCoY4vFCeF+r59VpB0ildYl3APzwMdRCLw==", - "peer": true, - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/sprite": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/math": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/math/-/math-7.3.0.tgz", - "integrity": "sha512-3gM1MffXlDM8bFNl+D1ndq4W1Gn7quRvxbAZ9RUp7Zvoqcud/0c/VcxngM2st+IXeFf8htlKxytkotMKk5gQxA==", - "peer": true - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/mesh": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-7.3.0.tgz", - "integrity": "sha512-TZqYmWiONuIIFzt+XL1+lnUFMHhiyJUyT5pNcW/mB1Kfg9vGIebgNbml+Ut6Rghe6B1ntereRyCyEpr+hLbbWg==", - "peer": true, - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/mesh-extras": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-7.3.0.tgz", - "integrity": "sha512-SxTrfQ8gzFru2DPv2dlEelignSBf6gN1taSVweAKs9HKfGi6hXYDbtQYQ9b21dsecXZYnrpL04kcY+QukOUVqQ==", - "peer": true, - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/mesh": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/particle-container": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-7.3.0.tgz", - "integrity": "sha512-7pHVmn4FlHBRlHUuLM+L/+viv1AbZBfHH6Q7tJu1dWHBenlqd81VZINW7YdzMLdkQpcT5eRm+xLyjBxGqCZNFw==", - "peer": true, - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/sprite": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/prepare": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-7.3.0.tgz", - "integrity": "sha512-WI/sWB+OHomJrLo9ATknmOagBLDGn5TccVRBSltW1lLre6i0X+eYTDLovQyTQq3JNmR2VsTEuwMYapDUIAVE5g==", - "peer": true, - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/graphics": "7.3.0", - "@pixi/text": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/runner": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-7.3.0.tgz", - "integrity": "sha512-U0qQk5yhZcCYQVm444IO604aoe1TivQjKeaAYaEpxNyEbSJ2/rEIQEttrnw6JXnm6a0ycI8iBtweDthnpyatqA==", - "peer": true - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/settings": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-7.3.0.tgz", - "integrity": "sha512-x8Tms/DBnedbJBjkP4VHqyBckqXqJnoAfoayqEcFrqNDQa+1qkr1UnyPj3l4eiEPhY8cEUBz1wSZnhM7R4XcDw==", - "peer": true, - "dependencies": { - "@pixi/constants": "7.3.0", - "@types/css-font-loading-module": "^0.0.7", - "ismobilejs": "^1.1.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/sprite": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-7.3.0.tgz", - "integrity": "sha512-3hJveyaxJ9jmZiyOo/Wfmh0Lje7eElF0FoqPl9mfNCXz1TKHSmWqHste+1LimqnThTiUhruJqwUq8h5o1DKLuw==", - "peer": true, - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/sprite-tiling": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-7.3.0.tgz", - "integrity": "sha512-9ktdL5LU2xq5ZORq8iRpyb5qz7josU6rmwCPggAAuuIS0HHt5HvmWRnklTjCL634FvkzbwlD3+DZnJ842qFRFA==", - "peer": true, - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/sprite": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/text": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/text/-/text-7.3.0.tgz", - "integrity": "sha512-oShmP5CvATLJecK54i2YqwzKAkx8VRgpPqXk3m/gWvF+cs9i9AqCMV3sO5J6xdcCnc+Zb61hjX07J39+QxDqWg==", - "peer": true, - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/sprite": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/ticker": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-7.3.0.tgz", - "integrity": "sha512-F77FpONHOn5JkZRMHUM8bXLLIG+Czve7zxOqb1Mk57QHLADhcHP88Kj2eYu9E7zJu4Flx51nyTdmVWQgQXW96g==", - "peer": true, - "dependencies": { - "@pixi/extensions": "7.3.0", - "@pixi/settings": "7.3.0", - "@pixi/utils": "7.3.0" - } - }, - "node_modules/pixi.js-legacy/node_modules/@pixi/utils": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-7.3.0.tgz", - "integrity": "sha512-syUi0UuJslUAs3PkZKycliND1Fs0cX3c+s2YyVTiRRRvuM81LvjrG/1AqKFhNaav7oYapBOQBWjgzBGv3wmM/A==", - "peer": true, - "dependencies": { - "@pixi/color": "7.3.0", - "@pixi/constants": "7.3.0", - "@pixi/settings": "7.3.0", - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^4.0.0", - "url": "^0.11.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/accessibility": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-7.3.0.tgz", - "integrity": "sha512-NgKl84HLkUsWK0Bd06okhsERsHteVzuTANi3Jd01QDqfNCz0qAfpjn4dPviUmqwbqu4zMuc3FRwWKDHszoa9aw==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/events": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/app": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/app/-/app-7.3.0.tgz", - "integrity": "sha512-dBXI4o36vgjoXVYkuiDPQcIsSuI3LUHQ6ycfqnX7jXlbGX5x1310O1WZfYENN18S3njm6WCtOdNTxDoHAo9NHw==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/assets": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/assets/-/assets-7.3.0.tgz", - "integrity": "sha512-eIbvOMFwWKRUuOrFwTy9UDVrAY95o5OlwOHnxAmeYhn6VTchua/oAeeaAYJyJqjyw+ONFsLWE1cFX6uEKHM2Sw==", - "dependencies": { - "@types/css-font-loading-module": "^0.0.7" - }, - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/utils": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/color": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/color/-/color-7.3.0.tgz", - "integrity": "sha512-qwgsP+cQhw0QjvouvAslpJ3g7DUMwKLUrXF6Nv+G4GhgVC2Z03CsCfWgUxLxKPD3WadB6FacdRIGx6o2TywB+A==", - "dependencies": { - "colord": "^2.9.3" - } - }, - "node_modules/pixi.js/node_modules/@pixi/compressed-textures": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/compressed-textures/-/compressed-textures-7.3.0.tgz", - "integrity": "sha512-bxs8Fh/tPkC2jD+GZhnQvpW/qpuFq4PspApCFTClmwGhGfYlIRUExexwn+y0akKCIgBikNniLt0hATxBqw4ABQ==", - "peerDependencies": { - "@pixi/assets": "7.3.0", - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/constants": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-7.3.0.tgz", - "integrity": "sha512-zRBX5RAxm14zs7/sse/eXSrFzbv2XPEJwj2fQga+4hI7tAsXazYgGFl3CMlDET5mW9rXUSxROE0dvnLe9DcYRQ==" - }, - "node_modules/pixi.js/node_modules/@pixi/core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-7.3.0.tgz", - "integrity": "sha512-ZgFdlqOZfijfgvWMi6ZuQey2m3U+ik8GUD7MsLn96Gtg7UQGwmcEsEB2MZ7f7TUoLkMAOlxb0aXEHzdV/+v1zg==", - "dependencies": { - "@pixi/color": "7.3.0", - "@pixi/constants": "7.3.0", - "@pixi/extensions": "7.3.0", - "@pixi/math": "7.3.0", - "@pixi/runner": "7.3.0", - "@pixi/settings": "7.3.0", - "@pixi/ticker": "7.3.0", - "@pixi/utils": "7.3.0", - "@types/offscreencanvas": "^2019.6.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/pixijs" - } - }, - "node_modules/pixi.js/node_modules/@pixi/display": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-7.3.0.tgz", - "integrity": "sha512-YQJZEcQo/0BIhvAaKrG68w01HYhPMwyPLj0Rvw30J4sW4uer/vf50IEAkM80rdQIUowqjUvatUYRW/r+owomXg==", - "peerDependencies": { - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/events": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/events/-/events-7.3.0.tgz", - "integrity": "sha512-8nBmX1I6CQovn63uf2Q/6m1lg1Jw9ygdVGgCQCxF7uF7+PDu6vNhLl2uTv+tLs9v9fooRe9ddtTsIvK0P2v4fQ==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/extensions": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/extensions/-/extensions-7.3.0.tgz", - "integrity": "sha512-kr0nia7yvPLIXqBeOKLUXcOoxRG5yCxIPUtXvsFSrrmJvqsXsyg4l9cH0CS/I9yTb67/ks5wjzieUdwNf8pfTg==" - }, - "node_modules/pixi.js/node_modules/@pixi/extract": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-7.3.0.tgz", - "integrity": "sha512-3CpGgu7I+4EVbEp/HU91nyTHKVUql5o/nik0hM+z402tlBbrbLejNAhoJ/Foq3L49n6SkpM2G8KN6d+G4Rn+jg==", - "peerDependencies": { - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/filter-alpha": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/filter-alpha/-/filter-alpha-7.3.0.tgz", - "integrity": "sha512-J/Zzs8ajqGc94St1WMJV03f8IHNSDrPi3s0D6vTNfm64YqBxXMpmeuPzArP/AG47ObDGrKJFRUhkv9VFNix62w==", - "peerDependencies": { - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/filter-blur": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/filter-blur/-/filter-blur-7.3.0.tgz", - "integrity": "sha512-21YUauI05m6yqvW1bugVAzCfc1q4OSfkv353G3/s+cXGjkk/hTcA+ShSENcJnSJouZpjs0XHavXDtvvHBg30fA==", - "peerDependencies": { - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/filter-color-matrix": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/filter-color-matrix/-/filter-color-matrix-7.3.0.tgz", - "integrity": "sha512-vUcn+l5w21J57Z4tGaWW9DTys9gSqiPdj8gpcl5APnjNVyYUuD1n+NRl+OAk/6v4BTU7I2iLnr6zIgWCucDz9Q==", - "peerDependencies": { - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/filter-displacement": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/filter-displacement/-/filter-displacement-7.3.0.tgz", - "integrity": "sha512-7YQtsB/YSHmhAPlK9oFMsEzWPm6TyQ9nr539osVIfrKq/xHuPRLxHYpJafL6MvAGQWocUUPiqCy4zkad9qsjWA==", - "peerDependencies": { - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/filter-fxaa": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/filter-fxaa/-/filter-fxaa-7.3.0.tgz", - "integrity": "sha512-IHomJnQ4VZ8ihZ+P7E86g2FcfxzEfBGq956gQ3UPYb0DW6fTMnvxzIuI9z+ElfuihdyAl7dR69xmwuwF3mqm0Q==", - "peerDependencies": { - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/filter-noise": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/filter-noise/-/filter-noise-7.3.0.tgz", - "integrity": "sha512-en6LUe0tNyzidcK7ByHbHm98Hh5/LlycBiFVrTjnk++ANZSrbAg3Wd+KRGITSy2BggrOcnpcJ1Ixd8sGejZEUA==", - "peerDependencies": { - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/graphics": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-7.3.0.tgz", - "integrity": "sha512-+5yyv8z4sZDxvdyYbGn/DeR1EdSD+ieXf9N3BS2puoxmrM5blMUzZCoY4vFCeF+r59VpB0ildYl3APzwMdRCLw==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/sprite": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/math": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/math/-/math-7.3.0.tgz", - "integrity": "sha512-3gM1MffXlDM8bFNl+D1ndq4W1Gn7quRvxbAZ9RUp7Zvoqcud/0c/VcxngM2st+IXeFf8htlKxytkotMKk5gQxA==" - }, - "node_modules/pixi.js/node_modules/@pixi/mesh": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-7.3.0.tgz", - "integrity": "sha512-TZqYmWiONuIIFzt+XL1+lnUFMHhiyJUyT5pNcW/mB1Kfg9vGIebgNbml+Ut6Rghe6B1ntereRyCyEpr+hLbbWg==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/mesh-extras": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-7.3.0.tgz", - "integrity": "sha512-SxTrfQ8gzFru2DPv2dlEelignSBf6gN1taSVweAKs9HKfGi6hXYDbtQYQ9b21dsecXZYnrpL04kcY+QukOUVqQ==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/mesh": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/mixin-cache-as-bitmap": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-7.3.0.tgz", - "integrity": "sha512-Wck2Ro+832pZ4Wu6N3vptF2J0XveQ9W3dBfGGSPHCLypSZgZ9T2hvbF6WyzZShQFKBo+oeKhnX+Nf+fb8v81Rg==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/sprite": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/mixin-get-child-by-name": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-7.3.0.tgz", - "integrity": "sha512-CQ+cy59Oy5nVFCC3c/hYa73bmY0qlsbpax3sMrwaF4q/33o0ymPS50dBQvfu26l5OcK3UoE5XzR3fdB3H8lcHg==", - "peerDependencies": { - "@pixi/display": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/mixin-get-global-position": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/mixin-get-global-position/-/mixin-get-global-position-7.3.0.tgz", - "integrity": "sha512-mM3UzWy9zFEz7o4LHlVUt3WJBAk57ZrPHwE8S5VgUrppiwHAdsLryoRwbTJkSAtW2gz+D2sLYbE6YkMdO76eVg==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/particle-container": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-7.3.0.tgz", - "integrity": "sha512-7pHVmn4FlHBRlHUuLM+L/+viv1AbZBfHH6Q7tJu1dWHBenlqd81VZINW7YdzMLdkQpcT5eRm+xLyjBxGqCZNFw==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/sprite": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/prepare": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-7.3.0.tgz", - "integrity": "sha512-WI/sWB+OHomJrLo9ATknmOagBLDGn5TccVRBSltW1lLre6i0X+eYTDLovQyTQq3JNmR2VsTEuwMYapDUIAVE5g==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/graphics": "7.3.0", - "@pixi/text": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/runner": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-7.3.0.tgz", - "integrity": "sha512-U0qQk5yhZcCYQVm444IO604aoe1TivQjKeaAYaEpxNyEbSJ2/rEIQEttrnw6JXnm6a0ycI8iBtweDthnpyatqA==" - }, - "node_modules/pixi.js/node_modules/@pixi/settings": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-7.3.0.tgz", - "integrity": "sha512-x8Tms/DBnedbJBjkP4VHqyBckqXqJnoAfoayqEcFrqNDQa+1qkr1UnyPj3l4eiEPhY8cEUBz1wSZnhM7R4XcDw==", - "dependencies": { - "@pixi/constants": "7.3.0", - "@types/css-font-loading-module": "^0.0.7", - "ismobilejs": "^1.1.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/sprite": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-7.3.0.tgz", - "integrity": "sha512-3hJveyaxJ9jmZiyOo/Wfmh0Lje7eElF0FoqPl9mfNCXz1TKHSmWqHste+1LimqnThTiUhruJqwUq8h5o1DKLuw==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/sprite-animated": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/sprite-animated/-/sprite-animated-7.3.0.tgz", - "integrity": "sha512-K8KCViX0BeYwZyN0IVcvCYtTSoKoAKtNPH5/EYhSPwRsFDq/3kqW/pVx7Mgh/+MM4fyIuweVd9IHxMCjYh7LKw==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/sprite": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/sprite-tiling": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-7.3.0.tgz", - "integrity": "sha512-9ktdL5LU2xq5ZORq8iRpyb5qz7josU6rmwCPggAAuuIS0HHt5HvmWRnklTjCL634FvkzbwlD3+DZnJ842qFRFA==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/sprite": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/spritesheet": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/spritesheet/-/spritesheet-7.3.0.tgz", - "integrity": "sha512-BloKplTxlM0cX1O60wW7upKPdzrVarYcRg/8+VTwlOpl2inHj/sVloyqOsNoG2eGVHgW3dl0yaeYiJQH/HzQQA==", - "peerDependencies": { - "@pixi/assets": "7.3.0", - "@pixi/core": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/text": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/text/-/text-7.3.0.tgz", - "integrity": "sha512-oShmP5CvATLJecK54i2YqwzKAkx8VRgpPqXk3m/gWvF+cs9i9AqCMV3sO5J6xdcCnc+Zb61hjX07J39+QxDqWg==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/sprite": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/text-bitmap": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/text-bitmap/-/text-bitmap-7.3.0.tgz", - "integrity": "sha512-o0EnbnR4zhSceLjl2i33yjz2R5Xm/r35ieuGE6CPDUiiTKG8J5fGhccieRpZ1ucr/dJ3B1JkYQq9QTbBFr5dMg==", - "peerDependencies": { - "@pixi/assets": "7.3.0", - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/mesh": "7.3.0", - "@pixi/text": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/text-html": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/text-html/-/text-html-7.3.0.tgz", - "integrity": "sha512-0RAsNz0ps/Q3yy4Tp7RZaJ9GxQJcVUox4N+I809AI0zwLhlBQClJdzSbjBfCEAzK24K8SQ+MJcDlsH3P+O8RGQ==", - "peerDependencies": { - "@pixi/core": "7.3.0", - "@pixi/display": "7.3.0", - "@pixi/sprite": "7.3.0", - "@pixi/text": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/ticker": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-7.3.0.tgz", - "integrity": "sha512-F77FpONHOn5JkZRMHUM8bXLLIG+Czve7zxOqb1Mk57QHLADhcHP88Kj2eYu9E7zJu4Flx51nyTdmVWQgQXW96g==", - "dependencies": { - "@pixi/extensions": "7.3.0", - "@pixi/settings": "7.3.0", - "@pixi/utils": "7.3.0" - } - }, - "node_modules/pixi.js/node_modules/@pixi/utils": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-7.3.0.tgz", - "integrity": "sha512-syUi0UuJslUAs3PkZKycliND1Fs0cX3c+s2YyVTiRRRvuM81LvjrG/1AqKFhNaav7oYapBOQBWjgzBGv3wmM/A==", - "dependencies": { - "@pixi/color": "7.3.0", - "@pixi/constants": "7.3.0", - "@pixi/settings": "7.3.0", - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^4.0.0", - "url": "^0.11.0" - } - }, "node_modules/pkg-conf": { "version": "3.1.0", "dev": true, diff --git a/newIDE/app/package.json b/newIDE/app/package.json index 65ce3fd6b3ad..827e2e9be435 100644 --- a/newIDE/app/package.json +++ b/newIDE/app/package.json @@ -62,8 +62,8 @@ "node-require-function": "^1.2.0", "path-browserify": "^1.0.1", "pixi-simple-gesture": "github:4ian/pixi-simple-gesture#v0.3.3", - "pixi-spine": "^4.0.0", - "pixi.js-legacy": "7.3.0", + "pixi-spine": "^4.0.4", + "pixi.js-legacy": "^7.3.0", "posthog-js": "^1.57.2", "prop-types": "^15.5.10", "qr-creator": "^1.0.0", @@ -96,6 +96,17 @@ "url-search-params": "^1.0.2", "xxhashjs": "^0.2.2" }, + "overrides": { + "pixi-spine": { + "@pixi/assets": "7.3.0", + "@pixi/core": "7.3.0", + "@pixi/display": "7.3.0", + "@pixi/graphics": "7.3.0", + "@pixi/mesh": "7.3.0", + "@pixi/mesh-extras": "7.3.0", + "@pixi/sprite": "7.3.0" + } + }, "scripts": { "postinstall": "patch-package && cd ../../GDJS && npm install && cd ../newIDE/app && npm run import-resources && npm run make-version-metadata", "import-resources": "npm run import-zipped-external-editors && npm run build-theme-resources && cd scripts && node import-libGD.js && node import-GDJS-Runtime.js && node import-monaco-editor.js && node import-zipped-external-libs.js", diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 1f7cd21ed1ff..b7410e3b02ad 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -50,6 +50,24 @@ const SpineEditor = ({ }: EditorProps) => { const scrollView = React.useRef(null); + const getResource = (name) => { + const resourcesManager = project.getResourcesManager(); + + return resourcesManager.hasResource(name) ? + resourcesManager.getResource(name) : + null; + }; + const getMetadata = (resource) => { + const metadataString = resource.getMetadata(); + + return !!metadataString ? JSON.parse(metadataString) : { }; + }; + const setMetadata = (resource, metadata) => resource?.setMetadata(JSON.stringify(metadata)); + const extendMetadata = (resourceName, metadata) => { + const resource = getResource(resourceName); + + setMetadata(resource, Object.assign(getMetadata(resource), metadata)); + } const [ justAddedAnimationName, setJustAddedAnimationName, @@ -118,29 +136,51 @@ const SpineEditor = ({ const onChangeJsonResourceName = React.useCallback( (jsonResourceName: string) => { + const atlasResourceName = properties.get('atlasResourceName').getValue(); + + if (atlasResourceName) { + extendMetadata(jsonResourceName, { atlas: atlasResourceName }); + } + getSkeleton( jsonResourceName, properties.get('imageResourceName').getValue(), - properties.get('atlasResourceName').getValue() + atlasResourceName ); }, [getSkeleton] ); - const onChangeImageResourceName = React.useCallback( - (imageResourceName: string) => { + const onChangeAtlasResourceName = React.useCallback( + (atlasResourceName: string) => { + const jsonResourceName = properties.get('jsonResourceName').getValue(); + const imageResourceName = properties.get('imageResourceName').getValue(); + + if (jsonResourceName) { + extendMetadata(jsonResourceName, { atlas: atlasResourceName }); + } + if (imageResourceName) { + extendMetadata(atlasResourceName, { image: imageResourceName }); + } + getSkeleton( properties.get('jsonResourceName').getValue(), imageResourceName, - properties.get('atlasResourceName').getValue() + atlasResourceName ); }, [getSkeleton] ); - const onChangeAtlasResourceName = React.useCallback( - (atlasResourceName: string) => { + const onChangeImageResourceName = React.useCallback( + (imageResourceName: string) => { + const atlasResourceName = properties.get('atlasResourceName').getValue(); + + if (atlasResourceName) { + extendMetadata(atlasResourceName, { image: imageResourceName }); + } + getSkeleton( properties.get('jsonResourceName').getValue(), - properties.get('imageResourceName').getValue(), + imageResourceName, atlasResourceName ); }, @@ -334,17 +374,17 @@ const SpineEditor = ({ /> Appearance diff --git a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js index b80e14e5cfd8..f49c9ec609bb 100644 --- a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js +++ b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js @@ -1,4 +1,5 @@ // @flow +import 'pixi-spine' import RenderedUnknownInstance from './Renderers/RenderedUnknownInstance'; import RenderedSpriteInstance from './Renderers/RenderedSpriteInstance'; import RenderedTiledSpriteInstance from './Renderers/RenderedTiledSpriteInstance'; @@ -21,8 +22,11 @@ import { rgbOrHexToHexNumber } from '../Utils/ColorTransformer'; const path = optionalRequire('path'); const electron = optionalRequire('electron'); const gd: libGDevelop = global.gd; +// const PIXI = PIXI_LEGACY; const PIXI = { ...PIXI_LEGACY, ...PIXI_SPINE }; +console.log(PIXI_LEGACY, PIXI_SPINE, PIXI); + // Some PixiJS plugins like pixi-tilemap are not distributed as UMD modules, // or still require a global PIXI object to be accessible, so we expose PIXI here. // This can be removed if no more extension PixiJS plugin requires this. diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 41450b3b7d63..9fe85a36ca4b 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -1,19 +1,18 @@ // @flow +import 'pixi-spine'; import slugs from 'slugs'; import axios from 'axios'; import * as PIXI from 'pixi.js-legacy'; import * as PIXI_SPINE from 'pixi-spine'; +import { ISkeleton } from 'pixi-spine'; import * as THREE from 'three'; import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; import ResourcesLoader from '../ResourcesLoader'; import { loadFontFace } from '../Utils/FontFaceLoader'; import { checkIfCredentialsRequired } from '../Utils/CrossOrigin'; -import { ISkeleton } from 'pixi-spine'; const gd: libGDevelop = global.gd; -PIXI.Loader.registerPlugin(PIXI_SPINE.SpineParser); - type ResourcePromise = { [resourceName: string]: Promise }; const loadedBitmapFonts = {}; @@ -355,7 +354,7 @@ export default class PixiResourcesLoader { atlasImageName: string, atlasTextName: string ): Promise { - const loader = PIXI.Loader.shared; + const loader = PIXI.Assets.loader; const resourceManager = project.getResourcesManager(); const resourcesData = [ [spineName, 'json'], @@ -376,36 +375,39 @@ export default class PixiResourcesLoader { // https://github.com/pixijs/spine/blob/master/examples/preload_atlas_text.md if (!atlasPromises[atlasTextName]) { - atlasPromises[atlasTextName] = new Promise(resolve => - loader - .add( - atlasTextName, - ResourcesLoader.getResourceFullUrl(project, atlasTextName, { - isResourceForPixi: true, - }), - { xhrType: 'text' } - ) - .load((_, atlasData) => resolve(atlasData[atlasTextName].data)) - ); + atlasPromises[atlasTextName] = new Promise(resolve => { + const atlasUrl = ResourcesLoader.getResourceFullUrl(project, atlasTextName, { + isResourceForPixi: true, + }); + PIXI.Assets.setPreferences({ + preferWorkers: false, + crossOrigin: checkIfCredentialsRequired(atlasUrl) + ? 'use-credentials' + : 'anonymous', + }); + PIXI.Assets.add(atlasTextName, atlasUrl, { image: this.getPIXITexture(project, atlasImageName) }); + PIXI.Assets.load(atlasTextName).then((atlas) => { + resolve(atlas); + }); + }); } if (!spineDataPromises[spineName]) { spineDataPromises[spineName] = new Promise(resolve => { - atlasPromises[atlasTextName].then(atlasRawData => { - const metadata = { - image: this.getPIXITexture(project, atlasImageName), - atlasRawData, - }; - - loader - .add( - spineName, - ResourcesLoader.getResourceFullUrl(project, spineName, { - isResourceForPixi: true, - }), - { metadata } - ) - .load((_, jsonData) => resolve(jsonData[spineName].spineData)); + atlasPromises[atlasTextName].then(spineAtlas => { + const jsonUrl = ResourcesLoader.getResourceFullUrl(project, spineName, { + isResourceForPixi: true, + }); + PIXI.Assets.setPreferences({ + preferWorkers: false, + crossOrigin: checkIfCredentialsRequired(jsonUrl) + ? 'use-credentials' + : 'anonymous', + }); + PIXI.Assets.add(spineName, jsonUrl, { spineAtlas }) + PIXI.Assets.load(jsonUrl).then((jsonData) => { + resolve(jsonData.spineData) + }); }); }); } From bd6095633c86d6d317ed9590e6f524cb7ea32118 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 14 Nov 2023 13:42:37 +0200 Subject: [PATCH 16/80] copy pixi-spine.js from node_modules on postinstall --- GDJS/.gitignore | 1 + GDJS/Runtime/pixi-renderers/pixi-spine.js | 12 ------------ GDJS/Runtime/pixi-renderers/pixi-spine.umd.js | 13 ------------- GDJS/package.json | 2 +- GDJS/scripts/install-spine.js | 10 ++++++++++ 5 files changed, 12 insertions(+), 26 deletions(-) delete mode 100644 GDJS/Runtime/pixi-renderers/pixi-spine.js delete mode 100644 GDJS/Runtime/pixi-renderers/pixi-spine.umd.js create mode 100644 GDJS/scripts/install-spine.js diff --git a/GDJS/.gitignore b/GDJS/.gitignore index 07e6e472cc75..b238e714d3d4 100644 --- a/GDJS/.gitignore +++ b/GDJS/.gitignore @@ -1 +1,2 @@ /node_modules +Runtime/pixi-renderers/pixi-spine.js \ No newline at end of file diff --git a/GDJS/Runtime/pixi-renderers/pixi-spine.js b/GDJS/Runtime/pixi-renderers/pixi-spine.js deleted file mode 100644 index 8e71827138db..000000000000 --- a/GDJS/Runtime/pixi-renderers/pixi-spine.js +++ /dev/null @@ -1,12 +0,0 @@ -/*! - * pixi-spine - v4.0.4 - * Compiled Thu, 25 May 2023 20:30:28 UTC - * - * pixi-spine is licensed under the MIT License. - * http://www.opensource.org/licenses/mit-license - * - * Copyright 2023, Ivan Igorevich Popelyshev , All Rights Reserved - */this.PIXI=this.PIXI||{},this.PIXI.spine=function(tt,H,dn,wr,br,oe,qe){"use strict";var Z=(c=>(c[c.Region=0]="Region",c[c.BoundingBox=1]="BoundingBox",c[c.Mesh=2]="Mesh",c[c.LinkedMesh=3]="LinkedMesh",c[c.Path=4]="Path",c[c.Point=5]="Point",c[c.Clipping=6]="Clipping",c))(Z||{});class Mn{constructor(t,n=new Array,e=0,i=new DataView(t.buffer)){this.strings=n,this.index=e,this.buffer=i}readByte(){return this.buffer.getInt8(this.index++)}readUnsignedByte(){return this.buffer.getUint8(this.index++)}readShort(){const t=this.buffer.getInt16(this.index);return this.index+=2,t}readInt32(){const t=this.buffer.getInt32(this.index);return this.index+=4,t}readInt(t){let n=this.readByte(),e=n&127;return n&128&&(n=this.readByte(),e|=(n&127)<<7,n&128&&(n=this.readByte(),e|=(n&127)<<14,n&128&&(n=this.readByte(),e|=(n&127)<<21,n&128&&(n=this.readByte(),e|=(n&127)<<28)))),t?e:e>>>1^-(e&1)}readStringRef(){const t=this.readInt(!0);return t==0?null:this.strings[t-1]}readString(){let t=this.readInt(!0);switch(t){case 0:return null;case 1:return""}t--;let n="";for(let e=0;e>4){case 12:case 13:n+=String.fromCharCode((i&31)<<6|this.readByte()&63),e+=2;break;case 14:n+=String.fromCharCode((i&15)<<12|(this.readByte()&63)<<6|this.readByte()&63),e+=3;break;default:n+=String.fromCharCode(i),e++}}return n}readFloat(){const t=this.buffer.getFloat32(this.index);return this.index+=4,t}readBoolean(){return this.readByte()!=0}}var A=(c=>(c[c.setup=0]="setup",c[c.first=1]="first",c[c.replace=2]="replace",c[c.add=3]="add",c))(A||{}),J=(c=>(c[c.mixIn=0]="mixIn",c[c.mixOut=1]="mixOut",c))(J||{}),dt=(c=>(c[c.Fixed=0]="Fixed",c[c.Percent=1]="Percent",c))(dt||{}),pt=(c=>(c[c.Tangent=0]="Tangent",c[c.Chain=1]="Chain",c[c.ChainScale=2]="ChainScale",c))(pt||{}),j=(c=>(c[c.Normal=0]="Normal",c[c.OnlyTranslation=1]="OnlyTranslation",c[c.NoRotationOrReflection=2]="NoRotationOrReflection",c[c.NoScale=3]="NoScale",c[c.NoScaleOrReflection=4]="NoScaleOrReflection",c))(j||{});function Jn(c){switch(c.toLowerCase()){case"nearest":return Bt.Nearest;case"linear":return Bt.Linear;case"mipmap":return Bt.MipMap;case"mipmapnearestnearest":return Bt.MipMapNearestNearest;case"mipmaplinearnearest":return Bt.MipMapLinearNearest;case"mipmapnearestlinear":return Bt.MipMapNearestLinear;case"mipmaplinearlinear":return Bt.MipMapLinearLinear;default:throw new Error(`Unknown texture filter ${c}`)}}function Er(c){switch(c.toLowerCase()){case"mirroredtepeat":return fe.MirroredRepeat;case"clamptoedge":return fe.ClampToEdge;case"repeat":return fe.Repeat;default:throw new Error(`Unknown texture wrap ${c}`)}}var Bt=(c=>(c[c.Nearest=9728]="Nearest",c[c.Linear=9729]="Linear",c[c.MipMap=9987]="MipMap",c[c.MipMapNearestNearest=9984]="MipMapNearestNearest",c[c.MipMapLinearNearest=9985]="MipMapLinearNearest",c[c.MipMapNearestLinear=9986]="MipMapNearestLinear",c[c.MipMapLinearLinear=9987]="MipMapLinearLinear",c))(Bt||{}),fe=(c=>(c[c.MirroredRepeat=33648]="MirroredRepeat",c[c.ClampToEdge=33071]="ClampToEdge",c[c.Repeat=10497]="Repeat",c))(fe||{});class Vn{constructor(){this.size=null,this.names=null,this.values=null,this.renderObject=null}get width(){const t=this.texture;return t.trim?t.trim.width:t.orig.width}get height(){const t=this.texture;return t.trim?t.trim.height:t.orig.height}get u(){return this.texture._uvs.x0}get v(){return this.texture._uvs.y0}get u2(){return this.texture._uvs.x2}get v2(){return this.texture._uvs.y2}get offsetX(){const t=this.texture;return t.trim?t.trim.x:0}get offsetY(){return this.spineOffsetY}get pixiOffsetY(){const t=this.texture;return t.trim?t.trim.y:0}get spineOffsetY(){const t=this.texture;return this.originalHeight-this.height-(t.trim?t.trim.y:0)}get originalWidth(){return this.texture.orig.width}get originalHeight(){return this.texture.orig.height}get x(){return this.texture.frame.x}get y(){return this.texture.frame.y}get rotate(){return this.texture.rotate!==0}get degrees(){return(360-this.texture.rotate*45)%360}}class Sr{constructor(){this.x=0,this.y=0,this.width=0,this.height=0,this.offsetX=0,this.offsetY=0,this.originalWidth=0,this.originalHeight=0,this.rotate=0,this.index=0}}class Fn{constructor(t,n,e){this.pages=new Array,this.regions=new Array,t&&this.addSpineAtlas(t,n,e)}addTexture(t,n){const e=this.pages;let i=null;for(let h=0;h{h.width=parseInt(r[1]),h.height=parseInt(r[2])},l.format=()=>{},l.filter=()=>{h.minFilter=Jn(r[1]),h.magFilter=Jn(r[2])},l.repeat=()=>{r[1].indexOf("x")!=-1&&(h.uWrap=fe.Repeat),r[1].indexOf("y")!=-1&&(h.vWrap=fe.Repeat)},l.pma=()=>{h.pma=r[1]=="true"};const a={};a.xy=()=>{s.x=parseInt(r[1]),s.y=parseInt(r[2])},a.size=()=>{s.width=parseInt(r[1]),s.height=parseInt(r[2])},a.bounds=()=>{s.x=parseInt(r[1]),s.y=parseInt(r[2]),s.width=parseInt(r[3]),s.height=parseInt(r[4])},a.offset=()=>{s.offsetX=parseInt(r[1]),s.offsetY=parseInt(r[2])},a.orig=()=>{s.originalWidth=parseInt(r[1]),s.originalHeight=parseInt(r[2])},a.offsets=()=>{s.offsetX=parseInt(r[1]),s.offsetY=parseInt(r[2]),s.originalWidth=parseInt(r[3]),s.originalHeight=parseInt(r[4])},a.rotate=()=>{const f=r[1];let u=0;f.toLocaleLowerCase()=="true"?u=6:f.toLocaleLowerCase()=="false"?u=0:u=(720-parseFloat(f))%360/45,s.rotate=u},a.index=()=>{s.index=parseInt(r[1])};let o=i.readLine();for(;o!=null&&o.trim().length==0;)o=i.readLine();for(;!(o==null||o.trim().length==0||i.readEntry(r,o)==0);)o=i.readLine();const d=()=>{for(;;){if(o==null)return e&&e(this);if(o.trim().length==0)h=null,o=i.readLine();else if(h===null){for(h=new ts,h.name=o.trim();i.readEntry(r,o=i.readLine())!=0;){const f=l[r[0]];f&&f()}this.pages.push(h),n(h.name,f=>{if(f===null)return this.pages.splice(this.pages.indexOf(h),1),e&&e(null);h.baseTexture=f,h.pma&&(f.alphaMode=H.ALPHA_MODES.PMA),f.valid||f.setSize(h.width,h.height),h.setFilters(),(!h.width||!h.height)&&(h.width=f.realWidth,h.height=f.realHeight,(!h.width||!h.height)&&console.log(`ERROR spine atlas page ${h.name}: meshes wont work if you dont specify size in atlas (http://www.html5gamedevs.com/topic/18888-pixi-spines-and-meshes/?p=107121)`)),d()});break}else{s=new Sr;const f=new es;f.name=o,f.page=h;let u=null,m=null;for(;;){const p=i.readEntry(r,o=i.readLine());if(p==0)break;const S=a[r[0]];if(S)S();else{u==null&&(u=[],m=[]),u.push(r[0]);const y=[];for(let M=0;M=this.lines.length?null:this.lines[this.index++]}readEntry(t,n){if(n==null||(n=n.trim(),n.length==0))return 0;const e=n.indexOf(":");if(e==-1)return 0;t[0]=n.substr(0,e).trim();for(let i=1,r=e+1;;i++){const h=n.indexOf(",",r);if(h==-1)return t[i]=n.substr(r).trim(),i;if(t[i]=n.substr(r,h-r).trim(),r=h+1,i==4)return 4}}}class ts{constructor(){this.minFilter=Bt.Nearest,this.magFilter=Bt.Nearest,this.uWrap=fe.ClampToEdge,this.vWrap=fe.ClampToEdge}setFilters(){const t=this.baseTexture,n=this.minFilter;n==Bt.Linear?t.scaleMode=H.SCALE_MODES.LINEAR:this.minFilter==Bt.Nearest?t.scaleMode=H.SCALE_MODES.NEAREST:(t.mipmap=H.MIPMAP_MODES.POW2,n==Bt.MipMapNearestNearest?t.scaleMode=H.SCALE_MODES.NEAREST:t.scaleMode=H.SCALE_MODES.LINEAR)}}class es extends Vn{}class ns{constructor(){this.array=new Array}add(t){const n=this.contains(t);return this.array[t|0]=t|0,!n}contains(t){return this.array[t|0]!=null}remove(t){this.array[t|0]=void 0}clear(){this.array.length=0}}class ss{constructor(){this.entries={},this.size=0}add(t){const n=this.entries[t];return this.entries[t]=!0,n?!1:(this.size++,!0)}addAll(t){const n=this.size;for(let e=0,i=t.length;e1&&(this.r=1),this.g<0?this.g=0:this.g>1&&(this.g=1),this.b<0?this.b=0:this.b>1&&(this.b=1),this.a<0?this.a=0:this.a>1&&(this.a=1),this}static rgba8888ToColor(c,t){c.r=((t&4278190080)>>>24)/255,c.g=((t&16711680)>>>16)/255,c.b=((t&65280)>>>8)/255,c.a=(t&255)/255}static rgb888ToColor(c,t){c.r=((t&16711680)>>>16)/255,c.g=((t&65280)>>>8)/255,c.b=(t&255)/255}static fromString(c){return new Je().setFromString(c)}};let _=Je;_.WHITE=new Je(1,1,1,1),_.RED=new Je(1,0,0,1),_.GREEN=new Je(0,1,0,1),_.BLUE=new Je(0,0,1,1),_.MAGENTA=new Je(1,0,1,1);const Fe=class{static clamp(c,t,n){return cn?n:c}static cosDeg(c){return Math.cos(c*Fe.degRad)}static sinDeg(c){return Math.sin(c*Fe.degRad)}static signum(c){return Math.sign(c)}static toInt(c){return c>0?Math.floor(c):Math.ceil(c)}static cbrt(c){const t=Math.pow(Math.abs(c),.3333333333333333);return c<0?-t:t}static randomTriangular(c,t){return Fe.randomTriangularWith(c,t,(c+t)*.5)}static randomTriangularWith(c,t,n){const e=Math.random(),i=t-c;return e<=(n-c)/i?c+Math.sqrt(e*i*(n-c)):t-Math.sqrt((1-e)*i*(t-n))}static isPowerOfTwo(c){return c&&(c&c-1)===0}};let C=Fe;C.PI=3.1415927,C.PI2=Fe.PI*2,C.radiansToDegrees=180/Fe.PI,C.radDeg=Fe.radiansToDegrees,C.degreesToRadians=Fe.PI/180,C.degRad=Fe.degreesToRadians;class Si{apply(t,n,e){return t+(n-t)*this.applyInternal(e)}}class yi extends Si{constructor(t){super(),this.power=2,this.power=t}applyInternal(t){return t<=.5?Math.pow(t*2,this.power)/2:Math.pow((t-1)*2,this.power)/(this.power%2==0?-2:2)+1}}class is extends yi{applyInternal(t){return Math.pow(t-1,this.power)*(this.power%2==0?-1:1)+1}}const fn=class{static arrayCopy(c,t,n,e,i){for(let r=t,h=e;r=t?c:fn.setArraySize(c,t,n)}static newArray(c,t){const n=new Array(c);for(let e=0;e0?this.items.pop():this.instantiator()}free(t){t.reset&&t.reset(),this.items.push(t)}freeAll(t){for(let n=0;nthis.maxDelta&&(this.delta=this.maxDelta),this.lastTime=t,this.frameCount++,this.frameTime>1&&(this.framesPerSecond=this.frameCount/this.frameTime,this.frameTime=0,this.frameCount=0)}}class Cr{constructor(t=32){this.addedValues=0,this.lastValue=0,this.mean=0,this.dirty=!0,this.values=new Array(t)}hasEnoughData(){return this.addedValues>=this.values.length}addValue(t){this.addedValuesthis.values.length-1&&(this.lastValue=0),this.dirty=!0}getMean(){if(this.hasEnoughData()){if(this.dirty){let t=0;for(let n=0;nv.newFloatArray(16))}update(t,n){if(!t)throw new Error("skeleton cannot be null.");const e=this.boundingBoxes,i=this.polygons,r=this.polygonPool,h=t.slots,l=h.length;e.length=0,r.freeAll(i),i.length=0;for(let s=0;s=this.minX&&t<=this.maxX&&n>=this.minY&&n<=this.maxY}aabbIntersectsSegment(t,n,e,i){const r=this.minX,h=this.minY,l=this.maxX,s=this.maxY;if(t<=r&&e<=r||n<=h&&i<=h||t>=l&&e>=l||n>=s&&i>=s)return!1;const a=(i-n)/(e-t);let o=a*(r-t)+n;if(o>h&&oh&&or&&dr&&dt.minX&&this.minYt.minY}containsPoint(t,n){const e=this.polygons;for(let i=0,r=e.length;i=e||o=e){const d=i[s];d+(e-a)/(o-a)*(i[h]-d)=d&&p<=m||p>=m&&p<=d)&&(p>=n&&p<=i||p>=i&&p<=n)){const S=(o*w-a*x)/b;if((S>=f&&S<=g||S>=g&&S<=f)&&(S>=e&&S<=r||S>=r&&S<=e))return!0}d=m,f=g}return!1}getPolygon(t){if(!t)throw new Error("boundingBox cannot be null.");const n=this.boundingBoxes.indexOf(t);return n==-1?null:this.polygons[n]}getWidth(){return this.maxX-this.minX}getHeight(){return this.maxY-this.minY}}const zt={yDown:!0,FAIL_ON_NON_EXISTING_SKIN:!1,GLOBAL_AUTO_UPDATE:!0,GLOBAL_DELAY_LIMIT:0},Ue=[0,0,0];class Mi extends wr.Sprite{constructor(){super(...arguments),this.region=null,this.attachment=null}}class Ai extends br.SimpleMesh{constructor(t,n,e,i,r){super(t,n,e,i,r),this.region=null,this.attachment=null}}const Ci=class extends dn.Container{constructor(c){if(super(),!c)throw new Error("The spineData param is required.");if(typeof c=="string")throw new Error('spineData param cant be string. Please use spine.Spine.fromAtlas("YOUR_RESOURCE_NAME") from now on.');this.spineData=c,this.createSkeleton(c),this.slotContainers=[],this.tempClipContainers=[];for(let t=0,n=this.skeleton.slots.length;tt&&(c=t),this.state.update(c),this.state.apply(this.skeleton),!this.skeleton)return;this.skeleton.updateWorldTransform();const n=this.skeleton.slots,e=this.color;let i=null,r=null;e?(i=e.light,r=e.dark):i=this.tintRgb;for(let o=0,d=n.length;o0;r--)n.bones.children[r-1].destroy({children:!0,texture:!0,baseTexture:!0});const e=t.scale.x||t.scale.y||1,i=this.lineWidth/e;this.drawBones&&this.drawBonesFunc(t,n,i,e),this.drawPaths&&this.drawPathsFunc(t,n,i),this.drawBoundingBoxes&&this.drawBoundingBoxesFunc(t,n,i),this.drawClipping&&this.drawClippingFunc(t,n,i),(this.drawMeshHull||this.drawMeshTriangles)&&this.drawMeshHullAndMeshTriangles(t,n,i),this.drawRegionAttachments&&this.drawRegionAttachmentsFunc(t,n,i)}drawBonesFunc(t,n,e,i){const r=t.skeleton,h=r.x,l=r.y,s=r.bones;n.skeletonXY.lineStyle(e,this.skeletonXYColor,1);for(let o=0,d=s.length;ox&&gx&&g>E?F=-I:mE?F=I:g===E&&mx?F=-90*k:m===x&&gE&&(F=0),R.rotation=F,R.lineStyle(e+V/2.4,this.bonesColor,1),R.beginFill(0,.6),R.drawCircle(0,M,V*1.2),R.endFill()}const a=e*3;n.skeletonXY.moveTo(h-a,l-a),n.skeletonXY.lineTo(h+a,l+a),n.skeletonXY.moveTo(h+a,l-a),n.skeletonXY.lineTo(h-a,l+a)}drawRegionAttachmentsFunc(t,n,e){const r=t.skeleton.slots;n.regionAttachmentsShape.lineStyle(e,this.regionAttachmentsColor,1);for(let h=0,l=r.length;h0){u=(u>>1)*2;let m=d[u-2],g=d[u-1];for(let x=0,E=u;x{if(n.boundingBoxesPolygon.lineStyle(e,this.boundingBoxesPolygonColor,1),n.boundingBoxesPolygon.beginFill(this.boundingBoxesPolygonColor,.1),a<3)throw new Error("Polygon must contain at least 3 vertices");const o=[],d=e*2;for(let f=0,u=l.length;f{r=o,h=d});let s;const a=o=>{o||h(`Something went terribly wrong loading a spine .atlas file -Most likely your texture failed to load.`),r(s)};if(e.image||e.images){const o=Object.assign(e.image?{default:e.image}:{},e.images);s=new Fn(c,(d,f)=>{const u=o[d]||o.default;u&&u.baseTexture?f(u.baseTexture):f(u)},a)}else s=new Fn(c,Ti(n,i,e.imageMetadata),a);return await l},unload(c){c.dispose()}}},Ti=(c,t,n)=>async(e,i)=>{const r=H.utils.path.normalize([...t.split(H.utils.path.sep),e].join(H.utils.path.sep)),h=await c.load({src:r,data:n});i(h.baseTexture)};H.extensions.add(kr);function ki(c){return c.hasOwnProperty("bones")}function Ir(c){return c instanceof ArrayBuffer}class Rr{constructor(){}installLoader(){const t=this,n={extension:H.ExtensionType.Asset,loader:{extension:{type:H.ExtensionType.LoadParser,priority:qe.LoaderParserPriority.Normal},test(e){return qe.checkExtension(e,".skel")},async load(e){return await(await H.settings.ADAPTER.fetch(e)).arrayBuffer()},testParse(e,i){var s;const r=qe.checkExtension(i.src,".json")&&ki(e),h=qe.checkExtension(i.src,".skel")&&Ir(e),l=((s=i.data)==null?void 0:s.spineAtlas)===!1;return Promise.resolve(r&&!l||h)},async parse(e,i,r){var w;const h=H.utils.path.extname(i.src).toLowerCase(),l=H.utils.path.basename(i.src,h);let s=H.utils.path.dirname(i.src);s&&s.lastIndexOf("/")!==s.length-1&&(s+="/");const a=qe.checkExtension(i.src,".json")&&ki(e);let o=null,d=e;a?o=t.createJsonParser():(o=t.createBinaryParser(),d=new Uint8Array(e));const f=i.data||{},u=(w=f==null?void 0:f.spineSkeletonScale)!=null?w:null;u&&(o.scale=u);const m=f.spineAtlas;if(m&&m.pages)return t.parseData(o,m,d);const g=f.atlasRawData;if(g){let b=null,p=null;const S=new Promise((T,k)=>{b=T,p=k}),y=new Fn(g,Ti(r,s,f.imageMetadata),T=>{T||p(`Something went terribly wrong loading a spine .atlas file -Most likely your texture failed to load.`),b(y)}),M=await S;return t.parseData(o,M,d)}let x=f.spineAtlasFile;x||(x=`${s+l}.atlas`);const E=await r.load({src:x,data:f,alias:f.spineAtlasAlias});return t.parseData(o,E,d)}}};return H.extensions.add(n),n}}let rs=class{constructor(t){if(t==null)throw new Error("name cannot be null.");this.name=t}};const Ii=class extends rs{constructor(t){super(t),this.id=(Ii.nextID++&65535)<<11,this.worldVerticesLength=0,this.deformAttachment=this}computeWorldVerticesOld(t,n){this.computeWorldVertices(t,0,this.worldVerticesLength,n,0,2)}computeWorldVertices(t,n,e,i,r,h){e=r+(e>>1)*h;const l=t.bone.skeleton,s=t.deform;let a=this.vertices;const o=this.bones;if(o==null){s.length>0&&(a=s);const m=t.bone.matrix,g=m.tx,x=m.ty,E=m.a,w=m.c,b=m.b,p=m.d;for(let S=n,y=r;y0&&(n%=this.duration));const a=this.timelines;for(let o=0,d=a.length;o>>1;for(;;){if(t[(h+1)*e]<=n?i=h+1:r=h,i==r)return(i+1)*e;h=i+r>>>1}}static linearSearch(t,n,e){for(let i=0,r=t.length-e;i<=r;i+=e)if(t[i]>n)return i;return-1}};var Pi=(c=>(c[c.rotate=0]="rotate",c[c.translate=1]="translate",c[c.scale=2]="scale",c[c.shear=3]="shear",c[c.attachment=4]="attachment",c[c.color=5]="color",c[c.deform=6]="deform",c[c.event=7]="event",c[c.drawOrder=8]="drawOrder",c[c.ikConstraint=9]="ikConstraint",c[c.transformConstraint=10]="transformConstraint",c[c.pathConstraintPosition=11]="pathConstraintPosition",c[c.pathConstraintSpacing=12]="pathConstraintSpacing",c[c.pathConstraintMix=13]="pathConstraintMix",c[c.twoColor=14]="twoColor",c))(Pi||{});const St=class{constructor(t){if(t<=0)throw new Error(`frameCount must be > 0: ${t}`);this.curves=v.newFloatArray((t-1)*St.BEZIER_SIZE)}getFrameCount(){return this.curves.length/St.BEZIER_SIZE+1}setLinear(t){this.curves[t*St.BEZIER_SIZE]=St.LINEAR}setStepped(t){this.curves[t*St.BEZIER_SIZE]=St.STEPPED}getCurveType(t){const n=t*St.BEZIER_SIZE;if(n==this.curves.length)return St.LINEAR;const e=this.curves[n];return e==St.LINEAR?St.LINEAR:e==St.STEPPED?St.STEPPED:St.BEZIER}setCurve(t,n,e,i,r){const h=(-n*2+i)*.03,l=(-e*2+r)*.03,s=((n-i)*3+1)*.006,a=((e-r)*3+1)*.006;let o=h*2+s,d=l*2+a,f=n*.3+h+s*.16666667,u=e*.3+l+a*.16666667,m=t*St.BEZIER_SIZE;const g=this.curves;g[m++]=St.BEZIER;let x=f,E=u;for(let w=m+St.BEZIER_SIZE-1;m=n){let o,d;return i==s?(o=0,d=0):(o=e[i-2],d=e[i-1]),d+(e[i+1]-d)*(n-o)/(h-o)}const l=e[i-1];return l+(1-l)*(n-h)/(1-h)}};let Ht=St;Ht.LINEAR=0,Ht.STEPPED=1,Ht.BEZIER=2,Ht.BEZIER_SIZE=10*2-1;const He=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t<<1)}getPropertyId(){return(0<<24)+this.boneIndex}setFrame(t,n,e){t<<=1,this.frames[t]=n,this.frames[t+He.ROTATION]=e}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-He.ENTRIES]){let g=s[s.length+He.PREV_ROTATION];switch(h){case A.setup:a.rotation=a.data.rotation+g*r;break;case A.first:case A.replace:g+=a.data.rotation-a.rotation,g-=(16384-(16384.499999999996-g/360|0))*360;case A.add:a.rotation+=g*r}return}const o=Et.binarySearch(s,e,He.ENTRIES),d=s[o+He.PREV_ROTATION],f=s[o],u=this.getCurvePercent((o>>1)-1,1-(e-f)/(s[o+He.PREV_TIME]-f));let m=s[o+He.ROTATION]-d;switch(m=d+(m-(16384-(16384.499999999996-m/360|0))*360)*u,h){case A.setup:a.rotation=a.data.rotation+(m-(16384-(16384.499999999996-m/360|0))*360)*r;break;case A.first:case A.replace:m+=a.data.rotation-a.rotation;case A.add:a.rotation+=(m-(16384-(16384.499999999996-m/360|0))*360)*r}}};let Vt=He;Vt.ENTRIES=2,Vt.PREV_TIME=-2,Vt.PREV_ROTATION=-1,Vt.ROTATION=1;const Dt=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*Dt.ENTRIES)}getPropertyId(){return(1<<24)+this.boneIndex}setFrame(t,n,e,i){t*=Dt.ENTRIES,this.frames[t]=n,this.frames[t+Dt.X]=e,this.frames[t+Dt.Y]=i}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-Dt.ENTRIES])o=s[s.length+Dt.PREV_X],d=s[s.length+Dt.PREV_Y];else{const f=Et.binarySearch(s,e,Dt.ENTRIES);o=s[f+Dt.PREV_X],d=s[f+Dt.PREV_Y];const u=s[f],m=this.getCurvePercent(f/Dt.ENTRIES-1,1-(e-u)/(s[f+Dt.PREV_TIME]-u));o+=(s[f+Dt.X]-o)*m,d+=(s[f+Dt.Y]-d)*m}switch(h){case A.setup:a.x=a.data.x+o*r,a.y=a.data.y+d*r;break;case A.first:case A.replace:a.x+=(a.data.x+o-a.x)*r,a.y+=(a.data.y+d-a.y)*r;break;case A.add:a.x+=o*r,a.y+=d*r}}};let Jt=Dt;Jt.ENTRIES=3,Jt.PREV_TIME=-3,Jt.PREV_X=-2,Jt.PREV_Y=-1,Jt.X=1,Jt.Y=2;let te=class extends Jt{constructor(t){super(t)}getPropertyId(){return(2<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-te.ENTRIES])o=s[s.length+te.PREV_X]*a.data.scaleX,d=s[s.length+te.PREV_Y]*a.data.scaleY;else{const f=Et.binarySearch(s,e,te.ENTRIES);o=s[f+te.PREV_X],d=s[f+te.PREV_Y];const u=s[f],m=this.getCurvePercent(f/te.ENTRIES-1,1-(e-u)/(s[f+te.PREV_TIME]-u));o=(o+(s[f+te.X]-o)*m)*a.data.scaleX,d=(d+(s[f+te.Y]-d)*m)*a.data.scaleY}if(r==1)h==A.add?(a.scaleX+=o-a.data.scaleX,a.scaleY+=d-a.data.scaleY):(a.scaleX=o,a.scaleY=d);else{let f=0,u=0;if(l==J.mixOut)switch(h){case A.setup:f=a.data.scaleX,u=a.data.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.first:case A.replace:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.add:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-a.data.scaleX)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-a.data.scaleY)*r}else switch(h){case A.setup:f=Math.abs(a.data.scaleX)*C.signum(o),u=Math.abs(a.data.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.first:case A.replace:f=Math.abs(a.scaleX)*C.signum(o),u=Math.abs(a.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.add:f=C.signum(o),u=C.signum(d),a.scaleX=Math.abs(a.scaleX)*f+(o-Math.abs(a.data.scaleX)*f)*r,a.scaleY=Math.abs(a.scaleY)*u+(d-Math.abs(a.data.scaleY)*u)*r}}}},ee=class extends Jt{constructor(t){super(t)}getPropertyId(){return(3<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-ee.ENTRIES])o=s[s.length+ee.PREV_X],d=s[s.length+ee.PREV_Y];else{const f=Et.binarySearch(s,e,ee.ENTRIES);o=s[f+ee.PREV_X],d=s[f+ee.PREV_Y];const u=s[f],m=this.getCurvePercent(f/ee.ENTRIES-1,1-(e-u)/(s[f+ee.PREV_TIME]-u));o=o+(s[f+ee.X]-o)*m,d=d+(s[f+ee.Y]-d)*m}switch(h){case A.setup:a.shearX=a.data.shearX+o*r,a.shearY=a.data.shearY+d*r;break;case A.first:case A.replace:a.shearX+=(a.data.shearX+o-a.shearX)*r,a.shearY+=(a.data.shearY+d-a.shearY)*r;break;case A.add:a.shearX+=o*r,a.shearY+=d*r}}};const ft=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*ft.ENTRIES)}getPropertyId(){return(5<<24)+this.slotIndex}setFrame(t,n,e,i,r,h){t*=ft.ENTRIES,this.frames[t]=n,this.frames[t+ft.R]=e,this.frames[t+ft.G]=i,this.frames[t+ft.B]=r,this.frames[t+ft.A]=h}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=this.frames;if(e=a[a.length-ft.ENTRIES]){const m=a.length;o=a[m+ft.PREV_R],d=a[m+ft.PREV_G],f=a[m+ft.PREV_B],u=a[m+ft.PREV_A]}else{const m=Et.binarySearch(a,e,ft.ENTRIES);o=a[m+ft.PREV_R],d=a[m+ft.PREV_G],f=a[m+ft.PREV_B],u=a[m+ft.PREV_A];const g=a[m],x=this.getCurvePercent(m/ft.ENTRIES-1,1-(e-g)/(a[m+ft.PREV_TIME]-g));o+=(a[m+ft.R]-o)*x,d+=(a[m+ft.G]-d)*x,f+=(a[m+ft.B]-f)*x,u+=(a[m+ft.A]-u)*x}if(r==1)s.color.set(o,d,f,u);else{const m=s.color;h==A.setup&&m.setFromColor(s.data.color),m.add((o-m.r)*r,(d-m.g)*r,(f-m.b)*r,(u-m.a)*r)}}};let Lt=ft;Lt.ENTRIES=5,Lt.PREV_TIME=-5,Lt.PREV_R=-4,Lt.PREV_G=-3,Lt.PREV_B=-2,Lt.PREV_A=-1,Lt.R=1,Lt.G=2,Lt.B=3,Lt.A=4;const nt=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*nt.ENTRIES)}getPropertyId(){return(14<<24)+this.slotIndex}setFrame(t,n,e,i,r,h,l,s,a){t*=nt.ENTRIES,this.frames[t]=n,this.frames[t+nt.R]=e,this.frames[t+nt.G]=i,this.frames[t+nt.B]=r,this.frames[t+nt.A]=h,this.frames[t+nt.R2]=l,this.frames[t+nt.G2]=s,this.frames[t+nt.B2]=a}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=this.frames;if(e=a[a.length-nt.ENTRIES]){const E=a.length;o=a[E+nt.PREV_R],d=a[E+nt.PREV_G],f=a[E+nt.PREV_B],u=a[E+nt.PREV_A],m=a[E+nt.PREV_R2],g=a[E+nt.PREV_G2],x=a[E+nt.PREV_B2]}else{const E=Et.binarySearch(a,e,nt.ENTRIES);o=a[E+nt.PREV_R],d=a[E+nt.PREV_G],f=a[E+nt.PREV_B],u=a[E+nt.PREV_A],m=a[E+nt.PREV_R2],g=a[E+nt.PREV_G2],x=a[E+nt.PREV_B2];const w=a[E],b=this.getCurvePercent(E/nt.ENTRIES-1,1-(e-w)/(a[E+nt.PREV_TIME]-w));o+=(a[E+nt.R]-o)*b,d+=(a[E+nt.G]-d)*b,f+=(a[E+nt.B]-f)*b,u+=(a[E+nt.A]-u)*b,m+=(a[E+nt.R2]-m)*b,g+=(a[E+nt.G2]-g)*b,x+=(a[E+nt.B2]-x)*b}if(r==1)s.color.set(o,d,f,u),s.darkColor.set(m,g,x,1);else{const E=s.color,w=s.darkColor;h==A.setup&&(E.setFromColor(s.data.color),w.setFromColor(s.data.darkColor)),E.add((o-E.r)*r,(d-E.g)*r,(f-E.b)*r,(u-E.a)*r),w.add((m-w.r)*r,(g-w.g)*r,(x-w.b)*r,0)}}};let yt=nt;yt.ENTRIES=8,yt.PREV_TIME=-8,yt.PREV_R=-7,yt.PREV_G=-6,yt.PREV_B=-5,yt.PREV_A=-4,yt.PREV_R2=-3,yt.PREV_G2=-2,yt.PREV_B2=-1,yt.R=1,yt.G=2,yt.B=3,yt.A=4,yt.R2=5,yt.G2=6,yt.B2=7;let en=class{constructor(t){this.frames=v.newFloatArray(t),this.attachmentNames=new Array(t)}getPropertyId(){return(4<<24)+this.slotIndex}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.attachmentNames[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;if(l==J.mixOut){h==A.setup&&this.setAttachment(t,s,s.data.attachmentName);return}const a=this.frames;if(e=a[a.length-1]?o=a.length-1:o=Et.binarySearch(a,e,1)-1;const d=this.attachmentNames[o];t.slots[this.slotIndex].setAttachment(d==null?null:t.getAttachment(this.slotIndex,d))}setAttachment(t,n,e){n.setAttachment(e==null?null:t.getAttachment(this.slotIndex,e))}},Vi=null,hs=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t),this.frameVertices=new Array(t),Vi==null&&(Vi=v.newFloatArray(64))}getPropertyId(){return(6<<27)+Number(this.attachment.id)+this.slotIndex}setFrame(t,n,e){this.frames[t]=n,this.frameVertices[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=s.getAttachment();if(!(a instanceof ze)||a.deformAttachment!=this.attachment)return;const o=s.deform;o.length==0&&(h=A.setup);const d=this.frameVertices,f=d[0].length,u=this.frames;if(e=u[u.length-1]){const p=d[u.length-1];if(r==1)if(h==A.add){const S=a;if(S.bones==null){const y=S.vertices;for(let M=0;Me)this.apply(t,n,Number.MAX_VALUE,i,r,h,l),n=-1;else if(n>=s[a-1])return;if(e0&&s[o-1]==d;)o--}for(;o=s[o];o++)i.push(this.events[o])}},xn=class{constructor(t){this.frames=v.newFloatArray(t),this.drawOrders=new Array(t)}getPropertyId(){return 8<<24}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.drawOrders[t]=e}apply(t,n,e,i,r,h,l){const s=t.drawOrder,a=t.slots;if(l==J.mixOut&&h==A.setup){v.arrayCopy(t.slots,0,t.drawOrder,0,t.slots.length);return}const o=this.frames;if(e=o[o.length-1]?d=o.length-1:d=Et.binarySearch(o,e)-1;const f=this.drawOrders[d];if(f==null)v.arrayCopy(a,0,s,0,a.length);else for(let u=0,m=f.length;u=s[s.length-at.ENTRIES]){h==A.setup?(a.mix=a.data.mix+(s[s.length+at.PREV_MIX]-a.data.mix)*r,a.softness=a.data.softness+(s[s.length+at.PREV_SOFTNESS]-a.data.softness)*r,l==J.mixOut?(a.bendDirection=a.data.bendDirection,a.compress=a.data.compress,a.stretch=a.data.stretch):(a.bendDirection=s[s.length+at.PREV_BEND_DIRECTION],a.compress=s[s.length+at.PREV_COMPRESS]!=0,a.stretch=s[s.length+at.PREV_STRETCH]!=0)):(a.mix+=(s[s.length+at.PREV_MIX]-a.mix)*r,a.softness+=(s[s.length+at.PREV_SOFTNESS]-a.softness)*r,l==J.mixIn&&(a.bendDirection=s[s.length+at.PREV_BEND_DIRECTION],a.compress=s[s.length+at.PREV_COMPRESS]!=0,a.stretch=s[s.length+at.PREV_STRETCH]!=0));return}const o=Et.binarySearch(s,e,at.ENTRIES),d=s[o+at.PREV_MIX],f=s[o+at.PREV_SOFTNESS],u=s[o],m=this.getCurvePercent(o/at.ENTRIES-1,1-(e-u)/(s[o+at.PREV_TIME]-u));h==A.setup?(a.mix=a.data.mix+(d+(s[o+at.MIX]-d)*m-a.data.mix)*r,a.softness=a.data.softness+(f+(s[o+at.SOFTNESS]-f)*m-a.data.softness)*r,l==J.mixOut?(a.bendDirection=a.data.bendDirection,a.compress=a.data.compress,a.stretch=a.data.stretch):(a.bendDirection=s[o+at.PREV_BEND_DIRECTION],a.compress=s[o+at.PREV_COMPRESS]!=0,a.stretch=s[o+at.PREV_STRETCH]!=0)):(a.mix+=(d+(s[o+at.MIX]-d)*m-a.mix)*r,a.softness+=(f+(s[o+at.SOFTNESS]-f)*m-a.softness)*r,l==J.mixIn&&(a.bendDirection=s[o+at.PREV_BEND_DIRECTION],a.compress=s[o+at.PREV_COMPRESS]!=0,a.stretch=s[o+at.PREV_STRETCH]!=0))}};let Ft=at;Ft.ENTRIES=6,Ft.PREV_TIME=-6,Ft.PREV_MIX=-5,Ft.PREV_SOFTNESS=-4,Ft.PREV_BEND_DIRECTION=-3,Ft.PREV_COMPRESS=-2,Ft.PREV_STRETCH=-1,Ft.MIX=1,Ft.SOFTNESS=2,Ft.BEND_DIRECTION=3,Ft.COMPRESS=4,Ft.STRETCH=5;const ut=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*ut.ENTRIES)}getPropertyId(){return(10<<24)+this.transformConstraintIndex}setFrame(t,n,e,i,r,h){t*=ut.ENTRIES,this.frames[t]=n,this.frames[t+ut.ROTATE]=e,this.frames[t+ut.TRANSLATE]=i,this.frames[t+ut.SCALE]=r,this.frames[t+ut.SHEAR]=h}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.transformConstraints[this.transformConstraintIndex];if(!a.active)return;if(e=s[s.length-ut.ENTRIES]){const m=s.length;o=s[m+ut.PREV_ROTATE],d=s[m+ut.PREV_TRANSLATE],f=s[m+ut.PREV_SCALE],u=s[m+ut.PREV_SHEAR]}else{const m=Et.binarySearch(s,e,ut.ENTRIES);o=s[m+ut.PREV_ROTATE],d=s[m+ut.PREV_TRANSLATE],f=s[m+ut.PREV_SCALE],u=s[m+ut.PREV_SHEAR];const g=s[m],x=this.getCurvePercent(m/ut.ENTRIES-1,1-(e-g)/(s[m+ut.PREV_TIME]-g));o+=(s[m+ut.ROTATE]-o)*x,d+=(s[m+ut.TRANSLATE]-d)*x,f+=(s[m+ut.SCALE]-f)*x,u+=(s[m+ut.SHEAR]-u)*x}if(h==A.setup){const m=a.data;a.rotateMix=m.rotateMix+(o-m.rotateMix)*r,a.translateMix=m.translateMix+(d-m.translateMix)*r,a.scaleMix=m.scaleMix+(f-m.scaleMix)*r,a.shearMix=m.shearMix+(u-m.shearMix)*r}else a.rotateMix+=(o-a.rotateMix)*r,a.translateMix+=(d-a.translateMix)*r,a.scaleMix+=(f-a.scaleMix)*r,a.shearMix+=(u-a.shearMix)*r}};let _t=ut;_t.ENTRIES=5,_t.PREV_TIME=-5,_t.PREV_ROTATE=-4,_t.PREV_TRANSLATE=-3,_t.PREV_SCALE=-2,_t.PREV_SHEAR=-1,_t.ROTATE=1,_t.TRANSLATE=2,_t.SCALE=3,_t.SHEAR=4;const ue=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*ue.ENTRIES)}getPropertyId(){return(11<<24)+this.pathConstraintIndex}setFrame(t,n,e){t*=ue.ENTRIES,this.frames[t]=n,this.frames[t+ue.VALUE]=e}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(!a.active)return;if(e=s[s.length-ue.ENTRIES])o=s[s.length+ue.PREV_VALUE];else{const d=Et.binarySearch(s,e,ue.ENTRIES);o=s[d+ue.PREV_VALUE];const f=s[d],u=this.getCurvePercent(d/ue.ENTRIES-1,1-(e-f)/(s[d+ue.PREV_TIME]-f));o+=(s[d+ue.VALUE]-o)*u}h==A.setup?a.position=a.data.position+(o-a.data.position)*r:a.position+=(o-a.position)*r}};let Te=ue;Te.ENTRIES=2,Te.PREV_TIME=-2,Te.PREV_VALUE=-1,Te.VALUE=1;let ke=class extends Te{constructor(t){super(t)}getPropertyId(){return(12<<24)+this.pathConstraintIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(!a.active)return;if(e=s[s.length-ke.ENTRIES])o=s[s.length+ke.PREV_VALUE];else{const d=Et.binarySearch(s,e,ke.ENTRIES);o=s[d+ke.PREV_VALUE];const f=s[d],u=this.getCurvePercent(d/ke.ENTRIES-1,1-(e-f)/(s[d+ke.PREV_TIME]-f));o+=(s[d+ke.VALUE]-o)*u}h==A.setup?a.spacing=a.data.spacing+(o-a.data.spacing)*r:a.spacing+=(o-a.spacing)*r}};const Ot=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*Ot.ENTRIES)}getPropertyId(){return(13<<24)+this.pathConstraintIndex}setFrame(t,n,e,i){t*=Ot.ENTRIES,this.frames[t]=n,this.frames[t+Ot.ROTATE]=e,this.frames[t+Ot.TRANSLATE]=i}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(!a.active)return;if(e=s[s.length-Ot.ENTRIES])o=s[s.length+Ot.PREV_ROTATE],d=s[s.length+Ot.PREV_TRANSLATE];else{const f=Et.binarySearch(s,e,Ot.ENTRIES);o=s[f+Ot.PREV_ROTATE],d=s[f+Ot.PREV_TRANSLATE];const u=s[f],m=this.getCurvePercent(f/Ot.ENTRIES-1,1-(e-u)/(s[f+Ot.PREV_TIME]-u));o+=(s[f+Ot.ROTATE]-o)*m,d+=(s[f+Ot.TRANSLATE]-d)*m}h==A.setup?(a.rotateMix=a.data.rotateMix+(o-a.data.rotateMix)*r,a.translateMix=a.data.translateMix+(d-a.data.translateMix)*r):(a.rotateMix+=(o-a.rotateMix)*r,a.translateMix+=(d-a.translateMix)*r)}};let me=Ot;me.ENTRIES=3,me.PREV_TIME=-3,me.PREV_ROTATE=-2,me.PREV_TRANSLATE=-1,me.ROTATE=1,me.TRANSLATE=2;const mt=class{constructor(t){this.tracks=new Array,this.timeScale=1,this.unkeyedState=0,this.events=new Array,this.listeners=new Array,this.queue=new fs(this),this.propertyIDs=new ns,this.animationsChanged=!1,this.trackEntryPool=new An(()=>new Xn),this.data=t}update(t){t*=this.timeScale;const n=this.tracks;for(let e=0,i=n.length;e0){if(r.delay-=h,r.delay>0)continue;h=-r.delay,r.delay=0}let l=r.next;if(l!=null){const s=r.trackLast-l.delay;if(s>=0){for(l.delay=0,l.trackTime+=r.timeScale==0?0:(s/r.timeScale+t)*l.timeScale,r.trackTime+=h,this.setCurrent(e,l,!0);l.mixingFrom!=null;)l.mixTime+=t,l=l.mixingFrom;continue}}else if(r.trackLast>=r.trackEnd&&r.mixingFrom==null){n[e]=null,this.queue.end(r),this.disposeNext(r);continue}if(r.mixingFrom!=null&&this.updateMixingFrom(r,t)){let s=r.mixingFrom;for(r.mixingFrom=null,s!=null&&(s.mixingTo=null);s!=null;)this.queue.end(s),s=s.mixingFrom}r.trackTime+=h}this.queue.drain()}updateMixingFrom(t,n){const e=t.mixingFrom;if(e==null)return!0;const i=this.updateMixingFrom(e,n);return e.animationLast=e.nextAnimationLast,e.trackLast=e.nextTrackLast,t.mixTime>0&&t.mixTime>=t.mixDuration?((e.totalAlpha==0||t.mixDuration==0)&&(t.mixingFrom=e.mixingFrom,e.mixingFrom!=null&&(e.mixingFrom.mixingTo=t),t.interruptAlpha=e.interruptAlpha,this.queue.end(e)),i):(e.trackTime+=n*e.timeScale,t.mixTime+=n,!1)}apply(t){if(t==null)throw new Error("skeleton cannot be null.");this.animationsChanged&&this._animationsChanged();const n=this.events,e=this.tracks;let i=!1;for(let l=0,s=e.length;l0)continue;i=!0;const o=l==0?A.first:a.mixBlend;let d=a.alpha;a.mixingFrom!=null?d*=this.applyMixingFrom(a,t,o):a.trackTime>=a.trackEnd&&a.next==null&&(d=0);const f=a.animationLast,u=a.getAnimationTime(),m=a.animation.timelines.length,g=a.animation.timelines;if(l==0&&d==1||o==A.add)for(let x=0;x1&&(r=1),e!=A.first&&(e=i.mixBlend));const h=r0&&this.queueEvents(i,o),this.events.length=0,i.nextAnimationLast=o,i.nextTrackLast=i.trackTime,r}applyAttachmentTimeline(t,n,e,i,r){const h=n.slots[t.slotIndex];if(!h.bone.active)return;const l=t.frames;if(e=l[l.length-1]?s=l.length-1:s=Et.binarySearch(l,e)-1,this.setAttachment(n,h,t.attachmentNames[s],r)}h.attachmentState<=this.unkeyedState&&(h.attachmentState=this.unkeyedState+mt.SETUP)}setAttachment(t,n,e,i){n.setAttachment(e==null?null:t.getAttachment(n.data.index,e)),i&&(n.attachmentState=this.unkeyedState+mt.CURRENT)}applyRotateTimeline(t,n,e,i,r,h,l,s){if(s&&(h[l]=0),i==1){t.apply(n,0,e,null,1,r,J.mixIn);return}const a=t,o=a.frames,d=n.bones[a.boneIndex];if(!d.active)return;let f=0,u=0;if(e=o[o.length-Vt.ENTRIES])u=d.data.rotation+o[o.length+Vt.PREV_ROTATION];else{const x=Et.binarySearch(o,e,Vt.ENTRIES),E=o[x+Vt.PREV_ROTATION],w=o[x],b=a.getCurvePercent((x>>1)-1,1-(e-w)/(o[x+Vt.PREV_TIME]-w));u=o[x+Vt.ROTATION]-E,u-=(16384-(16384.499999999996-u/360|0))*360,u=E+u*b+d.data.rotation,u-=(16384-(16384.499999999996-u/360|0))*360}let m=0,g=u-f;if(g-=(16384-(16384.499999999996-g/360|0))*360,g==0)m=h[l];else{let x=0,E=0;s?(x=0,E=g):(x=h[l],E=h[l+1]);const w=g>0;let b=x>=0;C.signum(E)!=C.signum(g)&&Math.abs(E)<=90&&(Math.abs(x)>180&&(x+=360*C.signum(x)),b=w),m=g+x-x%360,b!=w&&(m+=360*C.signum(x)),h[l]=m}h[l+1]=g,f+=m*i,d.rotation=f-(16384-(16384.499999999996-f/360|0))*360}queueEvents(t,n){const e=t.animationStart,i=t.animationEnd,r=i-e,h=t.trackLast%r,l=this.events;let s=0;const a=l.length;for(;si||this.queue.event(t,d)}let o=!1;for(t.loop?o=r==0||h>t.trackTime%r:o=n>=i&&t.animationLast=this.tracks.length)return;const n=this.tracks[t];if(n==null)return;this.queue.end(n),this.disposeNext(n);let e=n;for(;;){const i=e.mixingFrom;if(i==null)break;this.queue.end(i),e.mixingFrom=null,e.mixingTo=null,e=i}this.tracks[n.trackIndex]=null,this.queue.drain()}setCurrent(t,n,e){const i=this.expandToIndex(t);this.tracks[t]=n,i!=null&&(e&&this.queue.interrupt(i),n.mixingFrom=i,i.mixingTo=n,n.mixTime=0,i.mixingFrom!=null&&i.mixDuration>0&&(n.interruptAlpha*=Math.min(1,i.mixTime/i.mixDuration)),i.timelinesRotation.length=0),this.queue.start(n)}setAnimation(t,n,e){const i=this.data.skeletonData.findAnimation(n);if(i==null)throw new Error(`Animation not found: ${n}`);return this.setAnimationWith(t,i,e)}setAnimationWith(t,n,e){if(n==null)throw new Error("animation cannot be null.");let i=!0,r=this.expandToIndex(t);r!=null&&(r.nextTrackLast==-1?(this.tracks[t]=r.mixingFrom,this.queue.interrupt(r),this.queue.end(r),this.disposeNext(r),r=r.mixingFrom,i=!1):this.disposeNext(r));const h=this.trackEntry(t,n,e,r);return this.setCurrent(t,h,i),this.queue.drain(),h}addAnimation(t,n,e,i){const r=this.data.skeletonData.findAnimation(n);if(r==null)throw new Error(`Animation not found: ${n}`);return this.addAnimationWith(t,r,e,i)}addAnimationWith(t,n,e,i){if(n==null)throw new Error("animation cannot be null.");let r=this.expandToIndex(t);if(r!=null)for(;r.next!=null;)r=r.next;const h=this.trackEntry(t,n,e,r);if(r==null)this.setCurrent(t,h,!0),this.queue.drain();else if(r.next=h,i<=0){const l=r.animationEnd-r.animationStart;l!=0?(r.loop?i+=l*(1+(r.trackTime/l|0)):i+=Math.max(l,r.trackTime),i-=this.data.getMix(r.animation,n)):i=r.trackTime}return h.delay=i,h}setEmptyAnimation(t,n){const e=this.setAnimationWith(t,mt.emptyAnimation,!1);return e.mixDuration=n,e.trackEnd=n,e}addEmptyAnimation(t,n,e){e<=0&&(e-=n);const i=this.addAnimationWith(t,mt.emptyAnimation,!1,e);return i.mixDuration=n,i.trackEnd=n,i}setEmptyAnimations(t){const n=this.queue.drainDisabled;this.queue.drainDisabled=!0;for(let e=0,i=this.tracks.length;e0){r[s]=mt.HOLD_MIX,h[s]=d;continue t}break}r[s]=mt.HOLD_FIRST}}}getCurrent(t){return t>=this.tracks.length?null:this.tracks[t]}addListener(t){if(t==null)throw new Error("listener cannot be null.");this.listeners.push(t)}removeListener(t){const n=this.listeners.indexOf(t);n>=0&&this.listeners.splice(n,1)}clearListeners(){this.listeners.length=0}clearListenerNotifications(){this.queue.clear()}setAnimationByName(t,n,e){mt.deprecatedWarning1||(mt.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on.")),this.setAnimation(t,n,e)}addAnimationByName(t,n,e,i){mt.deprecatedWarning2||(mt.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on.")),this.addAnimation(t,n,e,i)}hasAnimation(t){return this.data.skeletonData.findAnimation(t)!==null}hasAnimationByName(t){return mt.deprecatedWarning3||(mt.deprecatedWarning3=!0,console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on.")),this.hasAnimation(t)}};let ne=mt;ne.emptyAnimation=new Et("",[],0),ne.SUBSEQUENT=0,ne.FIRST=1,ne.HOLD_SUBSEQUENT=2,ne.HOLD_FIRST=3,ne.HOLD_MIX=4,ne.SETUP=1,ne.CURRENT=2,ne.deprecatedWarning1=!1,ne.deprecatedWarning2=!1,ne.deprecatedWarning3=!1;const Ye=class{constructor(){this.mixBlend=A.replace,this.timelineMode=new Array,this.timelineHoldMix=new Array,this.timelinesRotation=new Array}reset(){this.next=null,this.mixingFrom=null,this.mixingTo=null,this.animation=null,this.listener=null,this.timelineMode.length=0,this.timelineHoldMix.length=0,this.timelinesRotation.length=0}getAnimationTime(){if(this.loop){const t=this.animationEnd-this.animationStart;return t==0?this.animationStart:this.trackTime%t+this.animationStart}return Math.min(this.trackTime+this.animationStart,this.animationEnd)}setAnimationLast(t){this.animationLast=t,this.nextAnimationLast=t}isComplete(){return this.trackTime>=this.animationEnd-this.animationStart}resetRotationDirections(){this.timelinesRotation.length=0}get time(){return Ye.deprecatedWarning1||(Ye.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime}set time(t){Ye.deprecatedWarning1||(Ye.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime=t}get endTime(){return Ye.deprecatedWarning2||(Ye.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime}set endTime(t){Ye.deprecatedWarning2||(Ye.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime=t}loopsCount(){return Math.floor(this.trackTime/this.trackEnd)}};let Xn=Ye;Xn.deprecatedWarning1=!1,Xn.deprecatedWarning2=!1;const ds=class{constructor(t){this.objects=[],this.drainDisabled=!1,this.animState=t}start(t){this.objects.push(Gt.start),this.objects.push(t),this.animState.animationsChanged=!0}interrupt(t){this.objects.push(Gt.interrupt),this.objects.push(t)}end(t){this.objects.push(Gt.end),this.objects.push(t),this.animState.animationsChanged=!0}dispose(t){this.objects.push(Gt.dispose),this.objects.push(t)}complete(t){this.objects.push(Gt.complete),this.objects.push(t)}event(t,n){this.objects.push(Gt.event),this.objects.push(t),this.objects.push(n)}deprecateStuff(){return ds.deprecatedWarning1||(ds.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: onComplete, onStart, onEnd, onEvent art deprecated, please use listeners from now on. 'state.addListener({ complete: function(track, event) { } })'")),!0}drain(){if(this.drainDisabled)return;this.drainDisabled=!0;const t=this.objects,n=this.animState.listeners;for(let e=0;e(c[c.start=0]="start",c[c.interrupt=1]="interrupt",c[c.end=2]="end",c[c.dispose=3]="dispose",c[c.complete=4]="complete",c[c.event=5]="event",c))(Gt||{});let Pr=class{start(t){}interrupt(t){}end(t){}dispose(t){}complete(t){}event(t,n){}};const us=class{constructor(t){if(this.animationToMixTime={},this.defaultMix=0,t==null)throw new Error("skeletonData cannot be null.");this.skeletonData=t}setMix(t,n,e){const i=this.skeletonData.findAnimation(t);if(i==null)throw new Error(`Animation not found: ${t}`);const r=this.skeletonData.findAnimation(n);if(r==null)throw new Error(`Animation not found: ${n}`);this.setMixWith(i,r,e)}setMixByName(t,n,e){us.deprecatedWarning1||(us.deprecatedWarning1=!0,console.warn("Deprecation Warning: AnimationStateData.setMixByName is deprecated, please use setMix from now on.")),this.setMix(t,n,e)}setMixWith(t,n,e){if(t==null)throw new Error("from cannot be null.");if(n==null)throw new Error("to cannot be null.");const i=`${t.name}.${n.name}`;this.animationToMixTime[i]=e}getMix(t,n){const e=`${t.name}.${n.name}`,i=this.animationToMixTime[e];return i===void 0?this.defaultMix:i}};let ms=us;ms.deprecatedWarning1=!1;let gs=class{constructor(t){this.atlas=t}newRegionAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (region attachment: ${n})`);const r=new Q(n);return r.region=i,r}newMeshAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (mesh attachment: ${n})`);const r=new mn(n);return r.region=i,r}newBoundingBoxAttachment(t,n){return new as(n)}newPathAttachment(t,n){return new gn(n)}newPointAttachment(t,n){return new ls(n)}newClippingAttachment(t,n){return new os(n)}},xs=class{constructor(t,n,e){if(this.matrix=new H.Matrix,this.children=new Array,this.x=0,this.y=0,this.rotation=0,this.scaleX=0,this.scaleY=0,this.shearX=0,this.shearY=0,this.ax=0,this.ay=0,this.arotation=0,this.ascaleX=0,this.ascaleY=0,this.ashearX=0,this.ashearY=0,this.appliedValid=!1,this.sorted=!1,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.skeleton=n,this.parent=e,this.setToSetupPose()}get worldX(){return this.matrix.tx}get worldY(){return this.matrix.ty}isActive(){return this.active}update(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransform(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransformWith(t,n,e,i,r,h,l){this.ax=t,this.ay=n,this.arotation=e,this.ascaleX=i,this.ascaleY=r,this.ashearX=h,this.ashearY=l,this.appliedValid=!0;const s=this.parent,a=this.matrix,o=this.skeleton.scaleX,d=zt.yDown?-this.skeleton.scaleY:this.skeleton.scaleY;if(s==null){const x=this.skeleton,E=e+90+l;a.a=C.cosDeg(e+h)*i*o,a.c=C.cosDeg(E)*r*o,a.b=C.sinDeg(e+h)*i*d,a.d=C.sinDeg(E)*r*d,a.tx=t*o+x.x,a.ty=n*d+x.y;return}let f=s.matrix.a,u=s.matrix.c,m=s.matrix.b,g=s.matrix.d;switch(a.tx=f*t+u*n+s.matrix.tx,a.ty=m*t+g*n+s.matrix.ty,this.data.transformMode){case j.Normal:{const x=e+90+l,E=C.cosDeg(e+h)*i,w=C.cosDeg(x)*r,b=C.sinDeg(e+h)*i,p=C.sinDeg(x)*r;a.a=f*E+u*b,a.c=f*w+u*p,a.b=m*E+g*b,a.d=m*w+g*p;return}case j.OnlyTranslation:{const x=e+90+l;a.a=C.cosDeg(e+h)*i,a.c=C.cosDeg(x)*r,a.b=C.sinDeg(e+h)*i,a.d=C.sinDeg(x)*r;break}case j.NoRotationOrReflection:{let x=f*f+m*m,E=0;x>1e-4?(x=Math.abs(f*g-u*m)/x,f/=this.skeleton.scaleX,m/=this.skeleton.scaleY,u=m*x,g=f*x,E=Math.atan2(m,f)*C.radDeg):(f=0,m=0,E=90-Math.atan2(g,u)*C.radDeg);const w=e+h-E,b=e+l-E+90,p=C.cosDeg(w)*i,S=C.cosDeg(b)*r,y=C.sinDeg(w)*i,M=C.sinDeg(b)*r;a.a=f*p-u*y,a.c=f*S-u*M,a.b=m*p+g*y,a.d=m*S+g*M;break}case j.NoScale:case j.NoScaleOrReflection:{const x=C.cosDeg(e),E=C.sinDeg(e);let w=(f*x+u*E)/o,b=(m*x+g*E)/d,p=Math.sqrt(w*w+b*b);p>1e-5&&(p=1/p),w*=p,b*=p,p=Math.sqrt(w*w+b*b),this.data.transformMode==j.NoScale&&f*g-u*m<0!=(zt.yDown?this.skeleton.scaleX<0!=this.skeleton.scaleY>0:this.skeleton.scaleX<0!=this.skeleton.scaleY<0)&&(p=-p);const S=Math.PI/2+Math.atan2(b,w),y=Math.cos(S)*p,M=Math.sin(S)*p,T=C.cosDeg(h)*i,k=C.cosDeg(90+l)*r,I=C.sinDeg(h)*i,R=C.sinDeg(90+l)*r;a.a=w*T+y*I,a.c=w*k+y*R,a.b=b*T+M*I,a.d=b*k+M*R;break}}a.a*=o,a.c*=o,a.b*=d,a.d*=d}setToSetupPose(){const t=this.data;this.x=t.x,this.y=t.y,this.rotation=t.rotation,this.scaleX=t.scaleX,this.scaleY=t.scaleY,this.shearX=t.shearX,this.shearY=t.shearY}getWorldRotationX(){return Math.atan2(this.matrix.b,this.matrix.a)*C.radDeg}getWorldRotationY(){return Math.atan2(this.matrix.d,this.matrix.c)*C.radDeg}getWorldScaleX(){const t=this.matrix;return Math.sqrt(t.a*t.a+t.c*t.c)}getWorldScaleY(){const t=this.matrix;return Math.sqrt(t.b*t.b+t.d*t.d)}updateAppliedTransform(){this.appliedValid=!0;const t=this.parent,n=this.matrix;if(t==null){this.ax=n.tx,this.ay=n.ty,this.arotation=Math.atan2(n.b,n.a)*C.radDeg,this.ascaleX=Math.sqrt(n.a*n.a+n.b*n.b),this.ascaleY=Math.sqrt(n.c*n.c+n.d*n.d),this.ashearX=0,this.ashearY=Math.atan2(n.a*n.c+n.b*n.d,n.a*n.d-n.b*n.c)*C.radDeg;return}const e=t.matrix,i=1/(e.a*e.d-e.b*e.c),r=n.tx-e.tx,h=n.ty-e.ty;this.ax=r*e.d*i-h*e.c*i,this.ay=h*e.a*i-r*e.b*i;const l=i*e.d,s=i*e.a,a=i*e.c,o=i*e.b,d=l*n.a-a*n.b,f=l*n.c-a*n.d,u=s*n.b-o*n.a,m=s*n.d-o*n.c;if(this.ashearX=0,this.ascaleX=Math.sqrt(d*d+u*u),this.ascaleX>1e-4){const g=d*m-f*u;this.ascaleY=g/this.ascaleX,this.ashearY=Math.atan2(d*f+u*m,g)*C.radDeg,this.arotation=Math.atan2(u,d)*C.radDeg}else this.ascaleX=0,this.ascaleY=Math.sqrt(f*f+m*m),this.ashearY=0,this.arotation=90-Math.atan2(m,f)*C.radDeg}worldToLocal(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=1/(e*h-i*r),s=t.x-n.tx,a=t.y-n.ty;return t.x=s*h*l-a*i*l,t.y=a*e*l-s*r*l,t}localToWorld(t){const n=this.matrix,e=t.x,i=t.y;return t.x=e*n.a+i*n.c+n.tx,t.y=e*n.b+i*n.d+n.ty,t}worldToLocalRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(i.a*n-i.b*e,i.d*e-i.c*n)*C.radDeg}localToWorldRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(e*i.b+n*i.d,e*i.a+n*i.c)*C.radDeg}rotateWorld(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=C.cosDeg(t),s=C.sinDeg(t);n.a=l*e-s*r,n.c=l*i-s*h,n.b=s*e+l*r,n.d=s*i+l*h,this.appliedValid=!1}},ps=class{constructor(t,n,e){if(this.x=0,this.y=0,this.rotation=0,this.scaleX=1,this.scaleY=1,this.shearX=0,this.shearY=0,this.transformMode=j.Normal,this.skinRequired=!1,this.color=new _,t<0)throw new Error("index must be >= 0.");if(n==null)throw new Error("name cannot be null.");this.index=t,this.name=n,this.parent=e}},Nn=class{constructor(t,n,e){this.name=t,this.order=n,this.skinRequired=e}},ws=class{constructor(t,n){if(n==null)throw new Error("data cannot be null.");this.time=t,this.data=n}},bs=class{constructor(t){this.name=t}},Fi=class{constructor(t,n){if(this.bendDirection=0,this.compress=!1,this.stretch=!1,this.mix=1,this.softness=0,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.mix=t.mix,this.softness=t.softness,this.bendDirection=t.bendDirection,this.compress=t.compress,this.stretch=t.stretch,this.bones=new Array;for(let e=0;e180?u-=360:u<-180&&(u+=360);let x=t.ascaleX,E=t.ascaleY;if(i||r){switch(t.data.transformMode){case j.NoScale:case j.NoScaleOrReflection:m=n-t.worldX,g=e-t.worldY}const w=t.data.length*x,b=Math.sqrt(m*m+g*g);if(i&&bw&&w>1e-4){const p=(b/w-1)*l+1;x*=p,h&&(E*=p)}}t.updateWorldTransformWith(t.ax,t.ay,t.arotation+u*l,x,E,t.ashearX,t.ashearY)}apply2(t,n,e,i,r,h,l,s){if(s==0){n.updateWorldTransform();return}t.appliedValid||t.updateAppliedTransform(),n.appliedValid||n.updateAppliedTransform();const a=t.ax,o=t.ay;let d=t.ascaleX,f=d,u=t.ascaleY,m=n.ascaleX;const g=t.matrix;let x=0,E=0,w=0;d<0?(d=-d,x=180,w=-1):(x=0,w=1),u<0&&(u=-u,w=-w),m<0?(m=-m,E=180):E=0;const b=n.ax;let p=0,S=0,y=0,M=g.a,T=g.c,k=g.b,I=g.d;const R=Math.abs(d-u)<=1e-4;R?(p=n.ay,S=M*b+T*p+g.tx,y=k*b+I*p+g.ty):(p=0,S=M*b+g.tx,y=k*b+g.ty);const V=t.parent.matrix;M=V.a,T=V.c,k=V.b,I=V.d;const F=1/(M*I-T*k);let B=S-V.tx,Y=y-V.ty;const N=(B*I-Y*T)*F-a,q=(Y*M-B*k)*F-o,z=Math.sqrt(N*N+q*q);let D=n.data.length*m,X,L;if(z<1e-4){this.apply1(t,e,i,!1,h,!1,s),n.updateWorldTransformWith(b,p,0,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY);return}B=e-V.tx,Y=i-V.ty;let O=(B*I-Y*T)*F-a,W=(Y*M-B*k)*F-o,U=O*O+W*W;if(l!=0){l*=d*(m+1)/2;const lt=Math.sqrt(U),It=lt-z-D*d+l;if(It>0){let ct=Math.min(1,It/(l*2))-1;ct=(It-l*(1-ct*ct))/lt,O-=ct*O,W-=ct*W,U=O*O+W*W}}t:if(R){D*=d;let lt=(U-z*z-D*D)/(2*z*D);lt<-1?lt=-1:lt>1&&(lt=1,h&&(f*=(Math.sqrt(U)/(z+D)-1)*s+1)),L=Math.acos(lt)*r,M=z+D*lt,T=D*Math.sin(L),X=Math.atan2(W*M-O*T,O*M+W*T)}else{M=d*D,T=u*D;const lt=M*M,It=T*T,ct=Math.atan2(W,O);k=It*z*z+lt*U-lt*It;const Xt=-2*It*z,Ut=It-lt;if(I=Xt*Xt-4*Ut*k,I>=0){let ae=Math.sqrt(I);Xt<0&&(ae=-ae),ae=-(Xt+ae)/2;const Ke=ae/Ut,Nt=k/ae,We=Math.abs(Ke)=-1&&k<=1&&(k=Math.acos(k),B=M*Math.cos(k)+z,Y=T*Math.sin(k),I=B*B+Y*Y,I$e&&(Ae=k,$e=I,Ce=B,Kt=Y)),U<=(Oe+$e)/2?(X=ct-Math.atan2(Ve*r,Me),L=de*r):(X=ct-Math.atan2(Kt*r,Ce),L=Ae*r)}const $=Math.atan2(p,b)*w;let G=t.arotation;X=(X-$)*C.radDeg+x-G,X>180?X-=360:X<-180&&(X+=360),t.updateWorldTransformWith(a,o,G+X*s,f,t.ascaleY,0,0),G=n.arotation,L=((L+$)*C.radDeg-n.ashearX)*w+E-G,L>180?L-=360:L<-180&&(L+=360),n.updateWorldTransformWith(b,p,G+L*s,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY)}},Es=class extends Nn{constructor(t){super(t,0,!1),this.bones=new Array,this.bendDirection=1,this.compress=!1,this.stretch=!1,this.uniform=!1,this.mix=1,this.softness=0}},Ss=class extends Nn{constructor(t){super(t,0,!1),this.bones=new Array}};var vt=(c=>(c[c.Length=0]="Length",c[c.Fixed=1]="Fixed",c[c.Percent=2]="Percent",c))(vt||{});const nn=class{constructor(t,n){if(this.position=0,this.spacing=0,this.rotateMix=0,this.translateMix=0,this.spaces=new Array,this.positions=new Array,this.world=new Array,this.curves=new Array,this.lengths=new Array,this.segments=new Array,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.bones=new Array;for(let e=0,i=t.bones.length;e0,r=n>0;if(!i&&!r)return;const h=this.data,l=h.spacingMode,s=l==vt.Length,a=h.rotateMode,o=a==pt.Tangent,d=a==pt.ChainScale,f=this.bones.length,u=o?f:f+1,m=this.bones,g=v.setArraySize(this.spaces,u);let x=null;const E=this.spacing;if(d||s){d&&(x=v.setArraySize(this.lengths,f));for(let M=0,T=u-1;M0?C.degRad:-C.degRad}for(let M=0,T=3;MC.PI?D-=C.PI2:D<-C.PI&&(D+=C.PI2),D*=n,X=Math.cos(D),L=Math.sin(D),I.a=X*Y-L*q,I.c=X*N-L*z,I.b=L*Y+X*q,I.d=L*N+X*z}k.appliedValid=!1}}computeWorldPositions(t,n,e,i,r){const h=this.target;let l=this.position;const s=this.spaces,a=v.setArraySize(this.positions,n*3+2);let o=null;const d=t.closed;let f=t.worldVerticesLength,u=f/6,m=nn.NONE;if(!t.constantSpeed){const D=t.lengths;u-=d?1:2;const X=D[u];if(i&&(l*=X),r)for(let L=0;LX){m!=nn.AFTER&&(m=nn.AFTER,t.computeWorldVertices(h,f-6,4,o,0,2)),this.addAfterPosition($-X,o,0,a,O);continue}for(;;W++){const G=D[W];if(!($>G)){if(W==0)$/=G;else{const lt=D[W-1];$=($-lt)/(G-lt)}break}}W!=m&&(m=W,d&&W==u?(t.computeWorldVertices(h,f-4,4,o,0,2),t.computeWorldVertices(h,0,4,o,4,2)):t.computeWorldVertices(h,W*6+2,8,o,0,2)),this.addCurvePosition($,o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7],a,O,e||L>0&&U==0)}return a}d?(f+=2,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f-4,o,0,2),t.computeWorldVertices(h,0,2,o,f-4,2),o[f-2]=o[0],o[f-1]=o[1]):(u--,f-=4,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f,o,0,2));const g=v.setArraySize(this.curves,u);let x=0,E=o[0],w=o[1],b=0,p=0,S=0,y=0,M=0,T=0,k=0,I=0,R=0,V=0,F=0,B=0,Y=0,N=0;for(let D=0,X=2;Dx){this.addAfterPosition(U-x,o,f-4,a,X);continue}for(;;L++){const $=g[L];if(!(U>$)){if(L==0)U/=$;else{const G=g[L-1];U=(U-G)/($-G)}break}}if(L!=m){m=L;let $=L*6;for(E=o[$],w=o[$+1],b=o[$+2],p=o[$+3],S=o[$+4],y=o[$+5],M=o[$+6],T=o[$+7],k=(E-b*2+S)*.03,I=(w-p*2+y)*.03,R=((b-S)*3-E+M)*.006,V=((p-y)*3-w+T)*.006,F=k*2+R,B=I*2+V,Y=(b-E)*.3+k+R*.16666667,N=(p-w)*.3+I+V*.16666667,z=Math.sqrt(Y*Y+N*N),q[0]=z,$=1;$<8;$++)Y+=F,N+=B,F+=R,B+=V,z+=Math.sqrt(Y*Y+N*N),q[$]=z;Y+=F,N+=B,z+=Math.sqrt(Y*Y+N*N),q[8]=z,Y+=F+R,N+=B+V,z+=Math.sqrt(Y*Y+N*N),q[9]=z,O=0}for(U*=z;;O++){const $=q[O];if(!(U>$)){if(O==0)U/=$;else{const G=q[O-1];U=O+(U-G)/($-G)}break}}this.addCurvePosition(U*.1,E,w,b,p,S,y,M,T,a,X,e||D>0&&W==0)}return a}addBeforePosition(t,n,e,i,r){const h=n[e],l=n[e+1],s=n[e+2]-h,a=n[e+3]-l,o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addAfterPosition(t,n,e,i,r){const h=n[e+2],l=n[e+3],s=h-n[e],a=l-n[e+1],o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addCurvePosition(t,n,e,i,r,h,l,s,a,o,d,f){(t==0||isNaN(t))&&(t=1e-4);const u=t*t,m=u*t,g=1-t,x=g*g,E=x*g,w=g*t,b=w*3,p=g*b,S=b*t,y=n*E+i*p+h*S+s*m,M=e*E+r*p+l*S+a*m;o[d]=y,o[d+1]=M,f&&(o[d+2]=Math.atan2(M-(e*x+r*w*2+l*u),y-(n*x+i*w*2+h*u)))}};let pn=nn;pn.NONE=-1,pn.BEFORE=-2,pn.AFTER=-3,pn.epsilon=1e-5;let Yi=class{constructor(t,n){if(this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.temp=new un,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.rotateMix=t.rotateMix,this.translateMix=t.translateMix,this.scaleMix=t.scaleMix,this.shearMix=t.shearMix,this.bones=new Array;for(let e=0;e0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=(p.x-b.tx)*n,b.ty+=(p.y-b.ty)*n,w=!0}if(e>0){let p=Math.sqrt(b.a*b.a+b.b*b.b),S=Math.sqrt(l*l+a*a);p>1e-5&&(p=(p+(S-p+this.data.offsetScaleX)*e)/p),b.a*=p,b.b*=p,p=Math.sqrt(b.c*b.c+b.d*b.d),S=Math.sqrt(s*s+o*o),p>1e-5&&(p=(p+(S-p+this.data.offsetScaleY)*e)/p),b.c*=p,b.d*=p,w=!0}if(i>0){const p=b.c,S=b.d,y=Math.atan2(S,p);let M=Math.atan2(o,s)-Math.atan2(a,l)-(y-Math.atan2(b.b,b.a));M>C.PI?M-=C.PI2:M<-C.PI&&(M+=C.PI2),M=y+(M+u)*i;const T=Math.sqrt(p*p+S*S);b.c=Math.cos(M)*T,b.d=Math.sin(M)*T,w=!0}w&&(E.appliedValid=!1)}}applyRelativeWorld(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target,h=r.matrix,l=h.a,s=h.c,a=h.b,o=h.d,d=l*o-s*a>0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=p.x*n,b.ty+=p.y*n,w=!0}if(e>0){let p=(Math.sqrt(l*l+a*a)-1+this.data.offsetScaleX)*e+1;b.a*=p,b.b*=p,p=(Math.sqrt(s*s+o*o)-1+this.data.offsetScaleY)*e+1,b.c*=p,b.d*=p,w=!0}if(i>0){let p=Math.atan2(o,s)-Math.atan2(a,l);p>C.PI?p-=C.PI2:p<-C.PI&&(p+=C.PI2);const S=b.c,y=b.d;p=Math.atan2(y,S)+(p-C.PI/2+u)*i;const M=Math.sqrt(S*S+y*y);b.c=Math.cos(p)*M,b.d=Math.sin(p)*M,w=!0}w&&(E.appliedValid=!1)}}applyAbsoluteLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u=(u+(r.ascaleX-u+this.data.offsetScaleX)*e)/u),m>1e-5&&(m=(m+(r.ascaleY-m+this.data.offsetScaleY)*e)/m));const g=a.ashearY;if(i>0){let x=r.ashearY-g+this.data.offsetShearY;x-=(16384-(16384.499999999996-x/360|0))*360,a.shearY+=x*i}a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}applyRelativeLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u*=(r.ascaleX-1+this.data.offsetScaleX)*e+1),m>1e-5&&(m*=(r.ascaleY-1+this.data.offsetScaleY)*e+1));let g=a.ashearY;i>0&&(g+=(r.ashearY+this.data.offsetShearY)*i),a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}};const Tn=class{constructor(t){if(this._updateCache=new Array,this.updateCacheReset=new Array,this.time=0,this.scaleX=1,this.scaleY=1,this.x=0,this.y=0,t==null)throw new Error("data cannot be null.");this.data=t,this.bones=new Array;for(let n=0;n1){const r=e[e.length-1];this._updateCache.indexOf(r)>-1||this.updateCacheReset.push(r)}this._updateCache.push(t),this.sortReset(i.children),e[e.length-1].sorted=!0}sortPathConstraint(t){if(t.active=t.target.bone.isActive()&&(!t.data.skinRequired||this.skin!=null&&v.contains(this.skin.constraints,t.data,!0)),!t.active)return;const n=t.target,e=n.data.index,i=n.bone;this.skin!=null&&this.sortPathConstraintAttachment(this.skin,e,i),this.data.defaultSkin!=null&&this.data.defaultSkin!=this.skin&&this.sortPathConstraintAttachment(this.data.defaultSkin,e,i);for(let s=0,a=this.data.skins.length;s-1||this.updateCacheReset.push(r)}else for(let i=0;i= 0.");if(n==null)throw new Error("name cannot be null.");if(e==null)throw new Error("boneData cannot be null.");this.index=t,this.name=n,this.boneData=e}},Cs=class extends Nn{constructor(t){super(t,0,!1),this.bones=new Array,this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.offsetRotation=0,this.offsetX=0,this.offsetY=0,this.offsetScaleX=0,this.offsetScaleY=0,this.offsetShearY=0,this.relative=!1,this.local=!1}},Ts=class{constructor(t,n,e){this.slotIndex=t,this.name=n,this.attachment=e}},Bn=class{constructor(t){if(this.attachments=new Array,this.bones=Array(),this.constraints=new Array,t==null)throw new Error("name cannot be null.");this.name=t}setAttachment(t,n,e){if(e==null)throw new Error("attachment cannot be null.");const i=this.attachments;t>=i.length&&(i.length=t+1),i[t]||(i[t]={}),i[t][n]=e}addSkin(t){for(let e=0;e0){const o=new xn(s),d=n.slots.length;for(let f=0;f=0;b--)g[b]=-1;const x=v.newArray(d-m,0);let E=0,w=0;for(let b=0;b=0;b--)g[b]==-1&&(g[b]=x[--w]);o.setFrame(f,u,g)}e.push(o),r=Math.max(r,o.frames[s-1])}const a=c.readInt(!0);if(a>0){const o=new Yn(a);for(let d=0;d=0;w--)u[w]==-1&&(u[w]=g[--E])}s.setFrame(o++,this.getValue(f,"time",0),u)}r.push(s),h=Math.max(h,s.frames[s.getFrameCount()-1])}if(t.events){const s=new Yn(t.events.length);let a=0;for(let o=0;o>1)*h;const l=t.bone.skeleton,s=t.attachmentVertices;let a=this.vertices;const o=this.bones;if(o==null){s.length>0&&(a=s);const m=t.bone.matrix,g=m.tx,x=m.ty,E=m.a,w=m.c,b=m.b,p=m.d;for(let S=n,y=r;y0&&(n%=this.duration));const a=this.timelines;for(let o=0,d=a.length;o>>1;for(;;){if(t[(h+1)*e]<=n?i=h+1:r=h,i==r)return(i+1)*e;h=i+r>>>1}}static linearSearch(t,n,e){for(let i=0,r=t.length-e;i<=r;i+=e)if(t[i]>n)return i;return-1}};var Oi=(c=>(c[c.rotate=0]="rotate",c[c.translate=1]="translate",c[c.scale=2]="scale",c[c.shear=3]="shear",c[c.attachment=4]="attachment",c[c.color=5]="color",c[c.deform=6]="deform",c[c.event=7]="event",c[c.drawOrder=8]="drawOrder",c[c.ikConstraint=9]="ikConstraint",c[c.transformConstraint=10]="transformConstraint",c[c.pathConstraintPosition=11]="pathConstraintPosition",c[c.pathConstraintSpacing=12]="pathConstraintSpacing",c[c.pathConstraintMix=13]="pathConstraintMix",c[c.twoColor=14]="twoColor",c))(Oi||{});const At=class{constructor(c){if(c<=0)throw new Error(`frameCount must be > 0: ${c}`);this.curves=v.newFloatArray((c-1)*At.BEZIER_SIZE)}getFrameCount(){return this.curves.length/At.BEZIER_SIZE+1}setLinear(c){this.curves[c*At.BEZIER_SIZE]=At.LINEAR}setStepped(c){this.curves[c*At.BEZIER_SIZE]=At.STEPPED}getCurveType(c){const t=c*At.BEZIER_SIZE;if(t==this.curves.length)return At.LINEAR;const n=this.curves[t];return n==At.LINEAR?At.LINEAR:n==At.STEPPED?At.STEPPED:At.BEZIER}setCurve(c,t,n,e,i){const r=(-t*2+e)*.03,h=(-n*2+i)*.03,l=((t-e)*3+1)*.006,s=((n-i)*3+1)*.006;let a=r*2+l,o=h*2+s,d=t*.3+r+l*.16666667,f=n*.3+h+s*.16666667,u=c*At.BEZIER_SIZE;const m=this.curves;m[u++]=At.BEZIER;let g=d,x=f;for(let E=u+At.BEZIER_SIZE-1;u=t){let a,o;return e==l?(a=0,o=0):(a=n[e-2],o=n[e-1]),o+(n[e+1]-o)*(t-a)/(r-a)}const h=n[e-1];return h+(1-h)*(t-r)/(1-r)}};let jt=At;jt.LINEAR=0,jt.STEPPED=1,jt.BEZIER=2,jt.BEZIER_SIZE=10*2-1;const je=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c<<1)}getPropertyId(){return(0<<24)+this.boneIndex}setFrame(c,t,n){c<<=1,this.frames[c]=t,this.frames[c+je.ROTATION]=n}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.bones[this.boneIndex];if(n=l[l.length-je.ENTRIES]){let m=l[l.length+je.PREV_ROTATION];switch(r){case A.setup:s.rotation=s.data.rotation+m*i;break;case A.first:case A.replace:m+=s.data.rotation-s.rotation,m-=(16384-(16384.499999999996-m/360|0))*360;case A.add:s.rotation+=m*i}return}const a=Ct.binarySearch(l,n,je.ENTRIES),o=l[a+je.PREV_ROTATION],d=l[a],f=this.getCurvePercent((a>>1)-1,1-(n-d)/(l[a+je.PREV_TIME]-d));let u=l[a+je.ROTATION]-o;switch(u=o+(u-(16384-(16384.499999999996-u/360|0))*360)*f,r){case A.setup:s.rotation=s.data.rotation+(u-(16384-(16384.499999999996-u/360|0))*360)*i;break;case A.first:case A.replace:u+=s.data.rotation-s.rotation;case A.add:s.rotation+=(u-(16384-(16384.499999999996-u/360|0))*360)*i}}};let $t=je;$t.ENTRIES=2,$t.PREV_TIME=-2,$t.PREV_ROTATION=-1,$t.ROTATION=1;const Wt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*Wt.ENTRIES)}getPropertyId(){return(1<<24)+this.boneIndex}setFrame(c,t,n,e){c*=Wt.ENTRIES,this.frames[c]=t,this.frames[c+Wt.X]=n,this.frames[c+Wt.Y]=e}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.bones[this.boneIndex];if(n=l[l.length-Wt.ENTRIES])a=l[l.length+Wt.PREV_X],o=l[l.length+Wt.PREV_Y];else{const d=Ct.binarySearch(l,n,Wt.ENTRIES);a=l[d+Wt.PREV_X],o=l[d+Wt.PREV_Y];const f=l[d],u=this.getCurvePercent(d/Wt.ENTRIES-1,1-(n-f)/(l[d+Wt.PREV_TIME]-f));a+=(l[d+Wt.X]-a)*u,o+=(l[d+Wt.Y]-o)*u}switch(r){case A.setup:s.x=s.data.x+a*i,s.y=s.data.y+o*i;break;case A.first:case A.replace:s.x+=(s.data.x+a-s.x)*i,s.y+=(s.data.y+o-s.y)*i;break;case A.add:s.x+=a*i,s.y+=o*i}}};let ge=Wt;ge.ENTRIES=3,ge.PREV_TIME=-3,ge.PREV_X=-2,ge.PREV_Y=-1,ge.X=1,ge.Y=2;let le=class extends ge{constructor(t){super(t)}getPropertyId(){return(2<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(e=s[s.length-le.ENTRIES])o=s[s.length+le.PREV_X]*a.data.scaleX,d=s[s.length+le.PREV_Y]*a.data.scaleY;else{const f=Ct.binarySearch(s,e,le.ENTRIES);o=s[f+le.PREV_X],d=s[f+le.PREV_Y];const u=s[f],m=this.getCurvePercent(f/le.ENTRIES-1,1-(e-u)/(s[f+le.PREV_TIME]-u));o=(o+(s[f+le.X]-o)*m)*a.data.scaleX,d=(d+(s[f+le.Y]-d)*m)*a.data.scaleY}if(r==1)h==A.add?(a.scaleX+=o-a.data.scaleX,a.scaleY+=d-a.data.scaleY):(a.scaleX=o,a.scaleY=d);else{let f=0,u=0;if(l==J.mixOut)switch(h){case A.setup:f=a.data.scaleX,u=a.data.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.first:case A.replace:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.add:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-a.data.scaleX)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-a.data.scaleY)*r}else switch(h){case A.setup:f=Math.abs(a.data.scaleX)*C.signum(o),u=Math.abs(a.data.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.first:case A.replace:f=Math.abs(a.scaleX)*C.signum(o),u=Math.abs(a.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.add:f=C.signum(o),u=C.signum(d),a.scaleX=Math.abs(a.scaleX)*f+(o-Math.abs(a.data.scaleX)*f)*r,a.scaleY=Math.abs(a.scaleY)*u+(d-Math.abs(a.data.scaleY)*u)*r}}}},ce=class extends ge{constructor(t){super(t)}getPropertyId(){return(3<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(e=s[s.length-ce.ENTRIES])o=s[s.length+ce.PREV_X],d=s[s.length+ce.PREV_Y];else{const f=Ct.binarySearch(s,e,ce.ENTRIES);o=s[f+ce.PREV_X],d=s[f+ce.PREV_Y];const u=s[f],m=this.getCurvePercent(f/ce.ENTRIES-1,1-(e-u)/(s[f+ce.PREV_TIME]-u));o=o+(s[f+ce.X]-o)*m,d=d+(s[f+ce.Y]-d)*m}switch(h){case A.setup:a.shearX=a.data.shearX+o*r,a.shearY=a.data.shearY+d*r;break;case A.first:case A.replace:a.shearX+=(a.data.shearX+o-a.shearX)*r,a.shearY+=(a.data.shearY+d-a.shearY)*r;break;case A.add:a.shearX+=o*r,a.shearY+=d*r}}};const gt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*gt.ENTRIES)}getPropertyId(){return(5<<24)+this.slotIndex}setFrame(c,t,n,e,i,r){c*=gt.ENTRIES,this.frames[c]=t,this.frames[c+gt.R]=n,this.frames[c+gt.G]=e,this.frames[c+gt.B]=i,this.frames[c+gt.A]=r}apply(c,t,n,e,i,r,h){const l=c.slots[this.slotIndex],s=this.frames;if(n=s[s.length-gt.ENTRIES]){const u=s.length;a=s[u+gt.PREV_R],o=s[u+gt.PREV_G],d=s[u+gt.PREV_B],f=s[u+gt.PREV_A]}else{const u=Ct.binarySearch(s,n,gt.ENTRIES);a=s[u+gt.PREV_R],o=s[u+gt.PREV_G],d=s[u+gt.PREV_B],f=s[u+gt.PREV_A];const m=s[u],g=this.getCurvePercent(u/gt.ENTRIES-1,1-(n-m)/(s[u+gt.PREV_TIME]-m));a+=(s[u+gt.R]-a)*g,o+=(s[u+gt.G]-o)*g,d+=(s[u+gt.B]-d)*g,f+=(s[u+gt.A]-f)*g}if(i==1)l.color.set(a,o,d,f);else{const u=l.color;r==A.setup&&u.setFromColor(l.data.color),u.add((a-u.r)*i,(o-u.g)*i,(d-u.b)*i,(f-u.a)*i)}}};let se=gt;se.ENTRIES=5,se.PREV_TIME=-5,se.PREV_R=-4,se.PREV_G=-3,se.PREV_B=-2,se.PREV_A=-1,se.R=1,se.G=2,se.B=3,se.A=4;const st=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*st.ENTRIES)}getPropertyId(){return(14<<24)+this.slotIndex}setFrame(c,t,n,e,i,r,h,l,s){c*=st.ENTRIES,this.frames[c]=t,this.frames[c+st.R]=n,this.frames[c+st.G]=e,this.frames[c+st.B]=i,this.frames[c+st.A]=r,this.frames[c+st.R2]=h,this.frames[c+st.G2]=l,this.frames[c+st.B2]=s}apply(c,t,n,e,i,r,h){const l=c.slots[this.slotIndex],s=this.frames;if(n=s[s.length-st.ENTRIES]){const x=s.length;a=s[x+st.PREV_R],o=s[x+st.PREV_G],d=s[x+st.PREV_B],f=s[x+st.PREV_A],u=s[x+st.PREV_R2],m=s[x+st.PREV_G2],g=s[x+st.PREV_B2]}else{const x=Ct.binarySearch(s,n,st.ENTRIES);a=s[x+st.PREV_R],o=s[x+st.PREV_G],d=s[x+st.PREV_B],f=s[x+st.PREV_A],u=s[x+st.PREV_R2],m=s[x+st.PREV_G2],g=s[x+st.PREV_B2];const E=s[x],w=this.getCurvePercent(x/st.ENTRIES-1,1-(n-E)/(s[x+st.PREV_TIME]-E));a+=(s[x+st.R]-a)*w,o+=(s[x+st.G]-o)*w,d+=(s[x+st.B]-d)*w,f+=(s[x+st.A]-f)*w,u+=(s[x+st.R2]-u)*w,m+=(s[x+st.G2]-m)*w,g+=(s[x+st.B2]-g)*w}if(i==1)l.color.set(a,o,d,f),l.darkColor.set(u,m,g,1);else{const x=l.color,E=l.darkColor;r==A.setup&&(x.setFromColor(l.data.color),E.setFromColor(l.data.darkColor)),x.add((a-x.r)*i,(o-x.g)*i,(d-x.b)*i,(f-x.a)*i),E.add((u-E.r)*i,(m-E.g)*i,(g-E.b)*i,0)}}};let Tt=st;Tt.ENTRIES=8,Tt.PREV_TIME=-8,Tt.PREV_R=-7,Tt.PREV_G=-6,Tt.PREV_B=-5,Tt.PREV_A=-4,Tt.PREV_R2=-3,Tt.PREV_G2=-2,Tt.PREV_B2=-1,Tt.R=1,Tt.G=2,Tt.B=3,Tt.A=4,Tt.R2=5,Tt.G2=6,Tt.B2=7;let Dn=class{constructor(t){this.frames=v.newFloatArray(t),this.attachmentNames=new Array(t)}getPropertyId(){return(4<<24)+this.slotIndex}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.attachmentNames[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(l==J.mixOut&&h==A.setup){const f=s.data.attachmentName;s.setAttachment(f==null?null:t.getAttachment(this.slotIndex,f));return}const a=this.frames;if(e=a[a.length-1]?o=a.length-1:o=Ct.binarySearch(a,e,1)-1;const d=this.attachmentNames[o];t.slots[this.slotIndex].setAttachment(d==null?null:t.getAttachment(this.slotIndex,d))}},$i=null,Wi=class extends jt{constructor(t){super(t),this.frames=v.newFloatArray(t),this.frameVertices=new Array(t),$i==null&&($i=v.newFloatArray(64))}getPropertyId(){return(6<<27)+Number(this.attachment.id)+this.slotIndex}setFrame(t,n,e){this.frames[t]=n,this.frameVertices[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex],a=s.getAttachment();if(!(a instanceof Ge)||!a.applyDeform(this.attachment))return;const o=s.attachmentVertices;o.length==0&&(h=A.setup);const d=this.frameVertices,f=d[0].length,u=this.frames;if(e=u[u.length-1]){const p=d[u.length-1];if(r==1)if(h==A.add){const S=a;if(S.bones==null){const y=S.vertices;for(let M=0;Me)this.apply(t,n,Number.MAX_VALUE,i,r,h,l),n=-1;else if(n>=s[a-1])return;if(e0&&s[o-1]==d;)o--}for(;o=s[o];o++)i.push(this.events[o])}},Ln=class{constructor(t){this.frames=v.newFloatArray(t),this.drawOrders=new Array(t)}getPropertyId(){return 8<<24}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.drawOrders[t]=e}apply(t,n,e,i,r,h,l){const s=t.drawOrder,a=t.slots;if(l==J.mixOut&&h==A.setup){v.arrayCopy(t.slots,0,t.drawOrder,0,t.slots.length);return}const o=this.frames;if(e=o[o.length-1]?d=o.length-1:d=Ct.binarySearch(o,e)-1;const f=this.drawOrders[d];if(f==null)v.arrayCopy(a,0,s,0,a.length);else for(let u=0,m=f.length;u=l[l.length-ht.ENTRIES]){r==A.setup?(s.mix=s.data.mix+(l[l.length+ht.PREV_MIX]-s.data.mix)*i,h==J.mixOut?(s.bendDirection=s.data.bendDirection,s.compress=s.data.compress,s.stretch=s.data.stretch):(s.bendDirection=l[l.length+ht.PREV_BEND_DIRECTION],s.compress=l[l.length+ht.PREV_COMPRESS]!=0,s.stretch=l[l.length+ht.PREV_STRETCH]!=0)):(s.mix+=(l[l.length+ht.PREV_MIX]-s.mix)*i,h==J.mixIn&&(s.bendDirection=l[l.length+ht.PREV_BEND_DIRECTION],s.compress=l[l.length+ht.PREV_COMPRESS]!=0,s.stretch=l[l.length+ht.PREV_STRETCH]!=0));return}const a=Ct.binarySearch(l,n,ht.ENTRIES),o=l[a+ht.PREV_MIX],d=l[a],f=this.getCurvePercent(a/ht.ENTRIES-1,1-(n-d)/(l[a+ht.PREV_TIME]-d));r==A.setup?(s.mix=s.data.mix+(o+(l[a+ht.MIX]-o)*f-s.data.mix)*i,h==J.mixOut?(s.bendDirection=s.data.bendDirection,s.compress=s.data.compress,s.stretch=s.data.stretch):(s.bendDirection=l[a+ht.PREV_BEND_DIRECTION],s.compress=l[a+ht.PREV_COMPRESS]!=0,s.stretch=l[a+ht.PREV_STRETCH]!=0)):(s.mix+=(o+(l[a+ht.MIX]-o)*f-s.mix)*i,h==J.mixIn&&(s.bendDirection=l[a+ht.PREV_BEND_DIRECTION],s.compress=l[a+ht.PREV_COMPRESS]!=0,s.stretch=l[a+ht.PREV_STRETCH]!=0))}};let ie=ht;ie.ENTRIES=5,ie.PREV_TIME=-5,ie.PREV_MIX=-4,ie.PREV_BEND_DIRECTION=-3,ie.PREV_COMPRESS=-2,ie.PREV_STRETCH=-1,ie.MIX=1,ie.BEND_DIRECTION=2,ie.COMPRESS=3,ie.STRETCH=4;const xt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*xt.ENTRIES)}getPropertyId(){return(10<<24)+this.transformConstraintIndex}setFrame(c,t,n,e,i,r){c*=xt.ENTRIES,this.frames[c]=t,this.frames[c+xt.ROTATE]=n,this.frames[c+xt.TRANSLATE]=e,this.frames[c+xt.SCALE]=i,this.frames[c+xt.SHEAR]=r}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.transformConstraints[this.transformConstraintIndex];if(n=l[l.length-xt.ENTRIES]){const u=l.length;a=l[u+xt.PREV_ROTATE],o=l[u+xt.PREV_TRANSLATE],d=l[u+xt.PREV_SCALE],f=l[u+xt.PREV_SHEAR]}else{const u=Ct.binarySearch(l,n,xt.ENTRIES);a=l[u+xt.PREV_ROTATE],o=l[u+xt.PREV_TRANSLATE],d=l[u+xt.PREV_SCALE],f=l[u+xt.PREV_SHEAR];const m=l[u],g=this.getCurvePercent(u/xt.ENTRIES-1,1-(n-m)/(l[u+xt.PREV_TIME]-m));a+=(l[u+xt.ROTATE]-a)*g,o+=(l[u+xt.TRANSLATE]-o)*g,d+=(l[u+xt.SCALE]-d)*g,f+=(l[u+xt.SHEAR]-f)*g}if(r==A.setup){const u=s.data;s.rotateMix=u.rotateMix+(a-u.rotateMix)*i,s.translateMix=u.translateMix+(o-u.translateMix)*i,s.scaleMix=u.scaleMix+(d-u.scaleMix)*i,s.shearMix=u.shearMix+(f-u.shearMix)*i}else s.rotateMix+=(a-s.rotateMix)*i,s.translateMix+=(o-s.translateMix)*i,s.scaleMix+=(d-s.scaleMix)*i,s.shearMix+=(f-s.shearMix)*i}};let re=xt;re.ENTRIES=5,re.PREV_TIME=-5,re.PREV_ROTATE=-4,re.PREV_TRANSLATE=-3,re.PREV_SCALE=-2,re.PREV_SHEAR=-1,re.ROTATE=1,re.TRANSLATE=2,re.SCALE=3,re.SHEAR=4;const xe=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*xe.ENTRIES)}getPropertyId(){return(11<<24)+this.pathConstraintIndex}setFrame(c,t,n){c*=xe.ENTRIES,this.frames[c]=t,this.frames[c+xe.VALUE]=n}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.pathConstraints[this.pathConstraintIndex];if(n=l[l.length-xe.ENTRIES])a=l[l.length+xe.PREV_VALUE];else{const o=Ct.binarySearch(l,n,xe.ENTRIES);a=l[o+xe.PREV_VALUE];const d=l[o],f=this.getCurvePercent(o/xe.ENTRIES-1,1-(n-d)/(l[o+xe.PREV_TIME]-d));a+=(l[o+xe.VALUE]-a)*f}r==A.setup?s.position=s.data.position+(a-s.data.position)*i:s.position+=(a-s.position)*i}};let Ze=xe;Ze.ENTRIES=2,Ze.PREV_TIME=-2,Ze.PREV_VALUE=-1,Ze.VALUE=1;let Xe=class extends Ze{constructor(t){super(t)}getPropertyId(){return(12<<24)+this.pathConstraintIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(e=s[s.length-Xe.ENTRIES])o=s[s.length+Xe.PREV_VALUE];else{const d=Ct.binarySearch(s,e,Xe.ENTRIES);o=s[d+Xe.PREV_VALUE];const f=s[d],u=this.getCurvePercent(d/Xe.ENTRIES-1,1-(e-f)/(s[d+Xe.PREV_TIME]-f));o+=(s[d+Xe.VALUE]-o)*u}h==A.setup?a.spacing=a.data.spacing+(o-a.data.spacing)*r:a.spacing+=(o-a.spacing)*r}};const qt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*qt.ENTRIES)}getPropertyId(){return(13<<24)+this.pathConstraintIndex}setFrame(c,t,n,e){c*=qt.ENTRIES,this.frames[c]=t,this.frames[c+qt.ROTATE]=n,this.frames[c+qt.TRANSLATE]=e}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.pathConstraints[this.pathConstraintIndex];if(n=l[l.length-qt.ENTRIES])a=l[l.length+qt.PREV_ROTATE],o=l[l.length+qt.PREV_TRANSLATE];else{const d=Ct.binarySearch(l,n,qt.ENTRIES);a=l[d+qt.PREV_ROTATE],o=l[d+qt.PREV_TRANSLATE];const f=l[d],u=this.getCurvePercent(d/qt.ENTRIES-1,1-(n-f)/(l[d+qt.PREV_TIME]-f));a+=(l[d+qt.ROTATE]-a)*u,o+=(l[d+qt.TRANSLATE]-o)*u}r==A.setup?(s.rotateMix=s.data.rotateMix+(a-s.data.rotateMix)*i,s.translateMix=s.data.translateMix+(o-s.data.translateMix)*i):(s.rotateMix+=(a-s.rotateMix)*i,s.translateMix+=(o-s.translateMix)*i)}};let Ne=qt;Ne.ENTRIES=3,Ne.PREV_TIME=-3,Ne.PREV_ROTATE=-2,Ne.PREV_TRANSLATE=-1,Ne.ROTATE=1,Ne.TRANSLATE=2;const Pt=class{constructor(t){this.tracks=new Array,this.events=new Array,this.listeners=new Array,this.queue=new Ps(this),this.propertyIDs=new ns,this.animationsChanged=!1,this.timeScale=1,this.trackEntryPool=new An(()=>new _n),this.data=t}update(t){t*=this.timeScale;const n=this.tracks;for(let e=0,i=n.length;e0){if(r.delay-=h,r.delay>0)continue;h=-r.delay,r.delay=0}let l=r.next;if(l!=null){const s=r.trackLast-l.delay;if(s>=0){for(l.delay=0,l.trackTime=r.timeScale==0?0:(s/r.timeScale+t)*l.timeScale,r.trackTime+=h,this.setCurrent(e,l,!0);l.mixingFrom!=null;)l.mixTime+=t,l=l.mixingFrom;continue}}else if(r.trackLast>=r.trackEnd&&r.mixingFrom==null){n[e]=null,this.queue.end(r),this.disposeNext(r);continue}if(r.mixingFrom!=null&&this.updateMixingFrom(r,t)){let s=r.mixingFrom;for(r.mixingFrom=null,s!=null&&(s.mixingTo=null);s!=null;)this.queue.end(s),s=s.mixingFrom}r.trackTime+=h}this.queue.drain()}updateMixingFrom(t,n){const e=t.mixingFrom;if(e==null)return!0;const i=this.updateMixingFrom(e,n);return e.animationLast=e.nextAnimationLast,e.trackLast=e.nextTrackLast,t.mixTime>0&&t.mixTime>=t.mixDuration?((e.totalAlpha==0||t.mixDuration==0)&&(t.mixingFrom=e.mixingFrom,e.mixingFrom!=null&&(e.mixingFrom.mixingTo=t),t.interruptAlpha=e.interruptAlpha,this.queue.end(e)),i):(e.trackTime+=n*e.timeScale,t.mixTime+=n,!1)}apply(t){if(t==null)throw new Error("skeleton cannot be null.");this.animationsChanged&&this._animationsChanged();const n=this.events,e=this.tracks;let i=!1;for(let r=0,h=e.length;r0)continue;i=!0;const s=r==0?A.first:l.mixBlend;let a=l.alpha;l.mixingFrom!=null?a*=this.applyMixingFrom(l,t,s):l.trackTime>=l.trackEnd&&l.next==null&&(a=0);const o=l.animationLast,d=l.getAnimationTime(),f=l.animation.timelines.length,u=l.animation.timelines;if(r==0&&a==1||s==A.add)for(let m=0;m1&&(r=1),e!=A.first&&(e=i.mixBlend));const h=r0&&this.queueEvents(i,o),this.events.length=0,i.nextAnimationLast=o,i.nextTrackLast=i.trackTime,r}applyRotateTimeline(t,n,e,i,r,h,l,s){if(s&&(h[l]=0),i==1){t.apply(n,0,e,null,1,r,J.mixIn);return}const a=t,o=a.frames,d=n.bones[a.boneIndex];let f=0,u=0;if(e=o[o.length-$t.ENTRIES])u=d.data.rotation+o[o.length+$t.PREV_ROTATION];else{const x=Ct.binarySearch(o,e,$t.ENTRIES),E=o[x+$t.PREV_ROTATION],w=o[x],b=a.getCurvePercent((x>>1)-1,1-(e-w)/(o[x+$t.PREV_TIME]-w));u=o[x+$t.ROTATION]-E,u-=(16384-(16384.499999999996-u/360|0))*360,u=E+u*b+d.data.rotation,u-=(16384-(16384.499999999996-u/360|0))*360}let m=0,g=u-f;if(g-=(16384-(16384.499999999996-g/360|0))*360,g==0)m=h[l];else{let x=0,E=0;s?(x=0,E=g):(x=h[l],E=h[l+1]);const w=g>0;let b=x>=0;C.signum(E)!=C.signum(g)&&Math.abs(E)<=90&&(Math.abs(x)>180&&(x+=360*C.signum(x)),b=w),m=g+x-x%360,b!=w&&(m+=360*C.signum(x)),h[l]=m}h[l+1]=g,f+=m*i,d.rotation=f-(16384-(16384.499999999996-f/360|0))*360}queueEvents(t,n){const e=t.animationStart,i=t.animationEnd,r=i-e,h=t.trackLast%r,l=this.events;let s=0;const a=l.length;for(;si||this.queue.event(t,d)}let o=!1;for(t.loop?o=r==0||h>t.trackTime%r:o=n>=i&&t.animationLast=this.tracks.length)return;const n=this.tracks[t];if(n==null)return;this.queue.end(n),this.disposeNext(n);let e=n;for(;;){const i=e.mixingFrom;if(i==null)break;this.queue.end(i),e.mixingFrom=null,e.mixingTo=null,e=i}this.tracks[n.trackIndex]=null,this.queue.drain()}setCurrent(t,n,e){const i=this.expandToIndex(t);this.tracks[t]=n,i!=null&&(e&&this.queue.interrupt(i),n.mixingFrom=i,i.mixingTo=n,n.mixTime=0,i.mixingFrom!=null&&i.mixDuration>0&&(n.interruptAlpha*=Math.min(1,i.mixTime/i.mixDuration)),i.timelinesRotation.length=0),this.queue.start(n)}setAnimation(t,n,e){const i=this.data.skeletonData.findAnimation(n);if(i==null)throw new Error(`Animation not found: ${n}`);return this.setAnimationWith(t,i,e)}setAnimationWith(t,n,e){if(n==null)throw new Error("animation cannot be null.");let i=!0,r=this.expandToIndex(t);r!=null&&(r.nextTrackLast==-1?(this.tracks[t]=r.mixingFrom,this.queue.interrupt(r),this.queue.end(r),this.disposeNext(r),r=r.mixingFrom,i=!1):this.disposeNext(r));const h=this.trackEntry(t,n,e,r);return this.setCurrent(t,h,i),this.queue.drain(),h}addAnimation(t,n,e,i){const r=this.data.skeletonData.findAnimation(n);if(r==null)throw new Error(`Animation not found: ${n}`);return this.addAnimationWith(t,r,e,i)}addAnimationWith(t,n,e,i){if(n==null)throw new Error("animation cannot be null.");let r=this.expandToIndex(t);if(r!=null)for(;r.next!=null;)r=r.next;const h=this.trackEntry(t,n,e,r);if(r==null)this.setCurrent(t,h,!0),this.queue.drain();else if(r.next=h,i<=0){const l=r.animationEnd-r.animationStart;l!=0?(r.loop?i+=l*(1+(r.trackTime/l|0)):i+=Math.max(l,r.trackTime),i-=this.data.getMix(r.animation,n)):i=r.trackTime}return h.delay=i,h}setEmptyAnimation(t,n){const e=this.setAnimationWith(t,Pt.emptyAnimation,!1);return e.mixDuration=n,e.trackEnd=n,e}addEmptyAnimation(t,n,e){e<=0&&(e-=n);const i=this.addAnimationWith(t,Pt.emptyAnimation,!1,e);return i.mixDuration=n,i.trackEnd=n,i}setEmptyAnimations(t){const n=this.queue.drainDisabled;this.queue.drainDisabled=!0;for(let e=0,i=this.tracks.length;e0){r[s]=Pt.HOLD_MIX,h[s]=o;continue t}break}r[s]=Pt.HOLD}}}hasTimeline(t,n){const e=t.animation.timelines;for(let i=0,r=e.length;i=this.tracks.length?null:this.tracks[t]}addListener(t){if(t==null)throw new Error("listener cannot be null.");this.listeners.push(t)}removeListener(t){const n=this.listeners.indexOf(t);n>=0&&this.listeners.splice(n,1)}clearListeners(){this.listeners.length=0}clearListenerNotifications(){this.queue.clear()}setAnimationByName(t,n,e){Pt.deprecatedWarning1||(Pt.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on.")),this.setAnimation(t,n,e)}addAnimationByName(t,n,e,i){Pt.deprecatedWarning2||(Pt.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on.")),this.addAnimation(t,n,e,i)}hasAnimation(t){return this.data.skeletonData.findAnimation(t)!==null}hasAnimationByName(t){return Pt.deprecatedWarning3||(Pt.deprecatedWarning3=!0,console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on.")),this.hasAnimation(t)}};let Ie=Pt;Ie.emptyAnimation=new Ct("",[],0),Ie.SUBSEQUENT=0,Ie.FIRST=1,Ie.HOLD=2,Ie.HOLD_MIX=3,Ie.deprecatedWarning1=!1,Ie.deprecatedWarning2=!1,Ie.deprecatedWarning3=!1;const Be=class{constructor(){this.mixBlend=A.replace,this.timelineMode=new Array,this.timelineHoldMix=new Array,this.timelinesRotation=new Array}reset(){this.next=null,this.mixingFrom=null,this.mixingTo=null,this.animation=null,this.listener=null,this.timelineMode.length=0,this.timelineHoldMix.length=0,this.timelinesRotation.length=0}getAnimationTime(){if(this.loop){const t=this.animationEnd-this.animationStart;return t==0?this.animationStart:this.trackTime%t+this.animationStart}return Math.min(this.trackTime+this.animationStart,this.animationEnd)}setAnimationLast(t){this.animationLast=t,this.nextAnimationLast=t}isComplete(){return this.trackTime>=this.animationEnd-this.animationStart}resetRotationDirections(){this.timelinesRotation.length=0}get time(){return Be.deprecatedWarning1||(Be.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime}set time(t){Be.deprecatedWarning1||(Be.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime=t}get endTime(){return Be.deprecatedWarning2||(Be.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime}set endTime(t){Be.deprecatedWarning2||(Be.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime=t}loopsCount(){return Math.floor(this.trackTime/this.trackEnd)}};let _n=Be;_n.deprecatedWarning1=!1,_n.deprecatedWarning2=!1;const vs=class{constructor(c){this.objects=[],this.drainDisabled=!1,this.animState=c}start(c){this.objects.push(Zt.start),this.objects.push(c),this.animState.animationsChanged=!0}interrupt(c){this.objects.push(Zt.interrupt),this.objects.push(c)}end(c){this.objects.push(Zt.end),this.objects.push(c),this.animState.animationsChanged=!0}dispose(c){this.objects.push(Zt.dispose),this.objects.push(c)}complete(c){this.objects.push(Zt.complete),this.objects.push(c)}event(c,t){this.objects.push(Zt.event),this.objects.push(c),this.objects.push(t)}deprecateStuff(){return vs.deprecatedWarning1||(vs.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: onComplete, onStart, onEnd, onEvent art deprecated, please use listeners from now on. 'state.addListener({ complete: function(track, event) { } })'")),!0}drain(){if(this.drainDisabled)return;this.drainDisabled=!0;const c=this.objects,t=this.animState.listeners;for(let n=0;n(c[c.start=0]="start",c[c.interrupt=1]="interrupt",c[c.end=2]="end",c[c.dispose=3]="dispose",c[c.complete=4]="complete",c[c.event=5]="event",c))(Zt||{});class Dr{start(t){}interrupt(t){}end(t){}dispose(t){}complete(t){}event(t,n){}}const Vs=class{constructor(c){if(this.animationToMixTime={},this.defaultMix=0,c==null)throw new Error("skeletonData cannot be null.");this.skeletonData=c}setMix(c,t,n){const e=this.skeletonData.findAnimation(c);if(e==null)throw new Error(`Animation not found: ${c}`);const i=this.skeletonData.findAnimation(t);if(i==null)throw new Error(`Animation not found: ${t}`);this.setMixWith(e,i,n)}setMixByName(c,t,n){Vs.deprecatedWarning1||(Vs.deprecatedWarning1=!0,console.warn("Deprecation Warning: AnimationStateData.setMixByName is deprecated, please use setMix from now on.")),this.setMix(c,t,n)}setMixWith(c,t,n){if(c==null)throw new Error("from cannot be null.");if(t==null)throw new Error("to cannot be null.");const e=`${c.name}.${t.name}`;this.animationToMixTime[e]=n}getMix(c,t){const n=`${c.name}.${t.name}`,e=this.animationToMixTime[n];return e===void 0?this.defaultMix:e}};let Fs=Vs;Fs.deprecatedWarning1=!1;let Ui=class{constructor(t){this.atlas=t}newRegionAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (region attachment: ${n})`);const r=new K(n);return r.region=i,r}newMeshAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (mesh attachment: ${n})`);const r=new Is(n);return r.region=i,r}newBoundingBoxAttachment(t,n){return new Ni(n)}newPathAttachment(t,n){return new kn(n)}newPointAttachment(t,n){return new Di(n)}newClippingAttachment(t,n){return new Bi(n)}},Ys=class{constructor(t,n,e){if(this.matrix=new H.Matrix,this.children=new Array,this.x=0,this.y=0,this.rotation=0,this.scaleX=0,this.scaleY=0,this.shearX=0,this.shearY=0,this.ax=0,this.ay=0,this.arotation=0,this.ascaleX=0,this.ascaleY=0,this.ashearX=0,this.ashearY=0,this.appliedValid=!1,this.sorted=!1,this.active=!0,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.skeleton=n,this.parent=e,this.setToSetupPose()}get worldX(){return this.matrix.tx}get worldY(){return this.matrix.ty}update(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransform(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransformWith(t,n,e,i,r,h,l){this.ax=t,this.ay=n,this.arotation=e,this.ascaleX=i,this.ascaleY=r,this.ashearX=h,this.ashearY=l,this.appliedValid=!0;const s=this.parent,a=this.matrix,o=this.skeleton.scaleX,d=zt.yDown?-this.skeleton.scaleY:this.skeleton.scaleY;if(s==null){const x=this.skeleton,E=e+90+l;a.a=C.cosDeg(e+h)*i*o,a.c=C.cosDeg(E)*r*o,a.b=C.sinDeg(e+h)*i*d,a.d=C.sinDeg(E)*r*d,a.tx=t*o+x.x,a.ty=n*d+x.y;return}let f=s.matrix.a,u=s.matrix.c,m=s.matrix.b,g=s.matrix.d;switch(a.tx=f*t+u*n+s.matrix.tx,a.ty=m*t+g*n+s.matrix.ty,this.data.transformMode){case j.Normal:{const x=e+90+l,E=C.cosDeg(e+h)*i,w=C.cosDeg(x)*r,b=C.sinDeg(e+h)*i,p=C.sinDeg(x)*r;a.a=f*E+u*b,a.c=f*w+u*p,a.b=m*E+g*b,a.d=m*w+g*p;return}case j.OnlyTranslation:{const x=e+90+l;a.a=C.cosDeg(e+h)*i,a.c=C.cosDeg(x)*r,a.b=C.sinDeg(e+h)*i,a.d=C.sinDeg(x)*r;break}case j.NoRotationOrReflection:{let x=f*f+m*m,E=0;x>1e-4?(x=Math.abs(f*g-u*m)/x,u=m*x,g=f*x,E=Math.atan2(m,f)*C.radDeg):(f=0,m=0,E=90-Math.atan2(g,u)*C.radDeg);const w=e+h-E,b=e+l-E+90,p=C.cosDeg(w)*i,S=C.cosDeg(b)*r,y=C.sinDeg(w)*i,M=C.sinDeg(b)*r;a.a=f*p-u*y,a.c=f*S-u*M,a.b=m*p+g*y,a.d=m*S+g*M;break}case j.NoScale:case j.NoScaleOrReflection:{const x=C.cosDeg(e),E=C.sinDeg(e);let w=(f*x+u*E)/o,b=(m*x+g*E)/d,p=Math.sqrt(w*w+b*b);p>1e-5&&(p=1/p),w*=p,b*=p,p=Math.sqrt(w*w+b*b),this.data.transformMode==j.NoScale&&f*g-u*m<0!=(zt.yDown?this.skeleton.scaleX<0!=this.skeleton.scaleY>0:this.skeleton.scaleX<0!=this.skeleton.scaleY<0)&&(p=-p);const S=Math.PI/2+Math.atan2(b,w),y=Math.cos(S)*p,M=Math.sin(S)*p,T=C.cosDeg(h)*i,k=C.cosDeg(90+l)*r,I=C.sinDeg(h)*i,R=C.sinDeg(90+l)*r;a.a=w*T+y*I,a.c=w*k+y*R,a.b=b*T+M*I,a.d=b*k+M*R;break}}a.a*=o,a.c*=o,a.b*=d,a.d*=d}setToSetupPose(){const t=this.data;this.x=t.x,this.y=t.y,this.rotation=t.rotation,this.scaleX=t.scaleX,this.scaleY=t.scaleY,this.shearX=t.shearX,this.shearY=t.shearY}getWorldRotationX(){return Math.atan2(this.matrix.b,this.matrix.a)*C.radDeg}getWorldRotationY(){return Math.atan2(this.matrix.d,this.matrix.c)*C.radDeg}getWorldScaleX(){const t=this.matrix;return Math.sqrt(t.a*t.a+t.c*t.c)}getWorldScaleY(){const t=this.matrix;return Math.sqrt(t.b*t.b+t.d*t.d)}updateAppliedTransform(){this.appliedValid=!0;const t=this.parent,n=this.matrix;if(t==null){this.ax=n.tx,this.ay=n.ty,this.arotation=Math.atan2(n.b,n.a)*C.radDeg,this.ascaleX=Math.sqrt(n.a*n.a+n.b*n.b),this.ascaleY=Math.sqrt(n.c*n.c+n.d*n.d),this.ashearX=0,this.ashearY=Math.atan2(n.a*n.c+n.b*n.d,n.a*n.d-n.b*n.c)*C.radDeg;return}const e=t.matrix,i=1/(e.a*e.d-e.b*e.c),r=n.tx-e.tx,h=n.ty-e.ty;this.ax=r*e.d*i-h*e.c*i,this.ay=h*e.a*i-r*e.b*i;const l=i*e.d,s=i*e.a,a=i*e.c,o=i*e.b,d=l*n.a-a*n.b,f=l*n.c-a*n.d,u=s*n.b-o*n.a,m=s*n.d-o*n.c;if(this.ashearX=0,this.ascaleX=Math.sqrt(d*d+u*u),this.ascaleX>1e-4){const g=d*m-f*u;this.ascaleY=g/this.ascaleX,this.ashearY=Math.atan2(d*f+u*m,g)*C.radDeg,this.arotation=Math.atan2(u,d)*C.radDeg}else this.ascaleX=0,this.ascaleY=Math.sqrt(f*f+m*m),this.ashearY=0,this.arotation=90-Math.atan2(m,f)*C.radDeg}worldToLocal(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=1/(e*h-i*r),s=t.x-n.tx,a=t.y-n.ty;return t.x=s*h*l-a*i*l,t.y=a*e*l-s*r*l,t}localToWorld(t){const n=this.matrix,e=t.x,i=t.y;return t.x=e*n.a+i*n.c+n.tx,t.y=e*n.b+i*n.d+n.ty,t}worldToLocalRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(i.a*n-i.b*e,i.d*e-i.c*n)*C.radDeg}localToWorldRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(e*i.b+n*i.d,e*i.a+n*i.c)*C.radDeg}rotateWorld(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=C.cosDeg(t),s=C.sinDeg(t);n.a=l*e-s*r,n.c=l*i-s*h,n.b=s*e+l*r,n.d=s*i+l*h,this.appliedValid=!1}},zi=class{constructor(t,n,e){if(this.x=0,this.y=0,this.rotation=0,this.scaleX=1,this.scaleY=1,this.shearX=0,this.shearY=0,this.transformMode=j.Normal,t<0)throw new Error("index must be >= 0.");if(n==null)throw new Error("name cannot be null.");this.index=t,this.name=n,this.parent=e}},Hi=class{constructor(t,n){if(n==null)throw new Error("data cannot be null.");this.time=t,this.data=n}},Gi=class{constructor(t){this.name=t}},ji=class{constructor(t,n){if(this.bendDirection=0,this.compress=!1,this.stretch=!1,this.mix=1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.mix=t.mix,this.bendDirection=t.bendDirection,this.compress=t.compress,this.stretch=t.stretch,this.bones=new Array;for(let e=0;e180?m-=360:m<-180&&(m+=360);let g=t.ascaleX,x=t.ascaleY;if(i||r){const E=t.data.length*g,w=Math.sqrt(f*f+u*u);if(i&&wE&&E>1e-4){const b=(w/E-1)*l+1;g*=b,h&&(x*=b)}}t.updateWorldTransformWith(t.ax,t.ay,t.arotation+m*l,g,x,t.ashearX,t.ashearY)}apply2(t,n,e,i,r,h,l){if(l==0){n.updateWorldTransform();return}t.appliedValid||t.updateAppliedTransform(),n.appliedValid||n.updateAppliedTransform();const s=t.ax,a=t.ay;let o=t.ascaleX,d=o,f=t.ascaleY,u=n.ascaleX;const m=t.matrix;let g=0,x=0,E=0;o<0?(o=-o,g=180,E=-1):(g=0,E=1),f<0&&(f=-f,E=-E),u<0?(u=-u,x=180):x=0;const w=n.ax;let b=0,p=0,S=0,y=m.a,M=m.c,T=m.b,k=m.d;const I=Math.abs(o-f)<=1e-4;I?(b=n.ay,p=y*w+M*b+m.tx,S=T*w+k*b+m.ty):(b=0,p=y*w+m.tx,S=T*w+m.ty);const R=t.parent.matrix;y=R.a,M=R.c,T=R.b,k=R.d;const V=1/(y*k-M*T);let F=e-R.tx,B=i-R.ty;const Y=(F*k-B*M)*V-s,N=(B*y-F*T)*V-a,q=Y*Y+N*N;F=p-R.tx,B=S-R.ty;const z=(F*k-B*M)*V-s,D=(B*y-F*T)*V-a,X=Math.sqrt(z*z+D*D);let L=n.data.length*u,O=0,W=0;t:if(I){L*=o;let G=(q-X*X-L*L)/(2*X*L);G<-1?G=-1:G>1&&(G=1,h&&X+L>1e-4&&(d*=(Math.sqrt(q)/(X+L)-1)*l+1)),W=Math.acos(G)*r,y=X+L*G,M=L*Math.sin(W),O=Math.atan2(N*y-Y*M,Y*y+N*M)}else{y=o*L,M=f*L;const G=y*y,lt=M*M,It=Math.atan2(N,Y);T=lt*X*X+G*q-G*lt;const ct=-2*lt*X,Xt=lt-G;if(k=ct*ct-4*Xt*T,k>=0){let Kt=Math.sqrt(k);ct<0&&(Kt=-Kt),Kt=-(ct+Kt)/2;const ae=Kt/Xt,Ke=T/Kt,Nt=Math.abs(ae)=-1&&T<=1&&(T=Math.acos(T),F=y*Math.cos(T)+X,B=M*Math.sin(T),k=F*F+B*B,kCe&&(Ve=T,Ce=k,Ae=F,$e=B)),q<=(Me+Ce)/2?(O=It-Math.atan2(Oe*r,de),W=Ut*r):(O=It-Math.atan2($e*r,Ae),W=Ve*r)}const U=Math.atan2(b,w)*E;let $=t.arotation;O=(O-U)*C.radDeg+g-$,O>180?O-=360:O<-180&&(O+=360),t.updateWorldTransformWith(s,a,$+O*l,d,t.ascaleY,0,0),$=n.arotation,W=((W+U)*C.radDeg-n.ashearX)*E+x-$,W>180?W-=360:W<-180&&(W+=360),n.updateWorldTransformWith(w,b,$+W*l,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY)}},Zi=class{constructor(t){this.order=0,this.bones=new Array,this.bendDirection=1,this.compress=!1,this.stretch=!1,this.uniform=!1,this.mix=1,this.name=t}},Qi=class{constructor(t){this.order=0,this.bones=new Array,this.name=t}};var pe=(c=>(c[c.Length=0]="Length",c[c.Fixed=1]="Fixed",c[c.Percent=2]="Percent",c))(pe||{});const rn=class{constructor(t,n){if(this.position=0,this.spacing=0,this.rotateMix=0,this.translateMix=0,this.spaces=new Array,this.positions=new Array,this.world=new Array,this.curves=new Array,this.lengths=new Array,this.segments=new Array,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.bones=new Array;for(let e=0,i=t.bones.length;e0,r=n>0;if(!i&&!r)return;const h=this.data,l=h.spacingMode,s=l==pe.Length,a=h.rotateMode,o=a==pt.Tangent,d=a==pt.ChainScale,f=this.bones.length,u=o?f:f+1,m=this.bones,g=v.setArraySize(this.spaces,u);let x=null;const E=this.spacing;if(d||s){d&&(x=v.setArraySize(this.lengths,f));for(let M=0,T=u-1;M0?C.degRad:-C.degRad}for(let M=0,T=3;MC.PI?D-=C.PI2:D<-C.PI&&(D+=C.PI2),D*=n,X=Math.cos(D),L=Math.sin(D),I.a=X*Y-L*q,I.c=X*N-L*z,I.b=L*Y+X*q,I.d=L*N+X*z}k.appliedValid=!1}}computeWorldPositions(t,n,e,i,r){const h=this.target;let l=this.position;const s=this.spaces,a=v.setArraySize(this.positions,n*3+2);let o=null;const d=t.closed;let f=t.worldVerticesLength,u=f/6,m=rn.NONE;if(!t.constantSpeed){const D=t.lengths;u-=d?1:2;const X=D[u];if(i&&(l*=X),r)for(let L=0;LX){m!=rn.AFTER&&(m=rn.AFTER,t.computeWorldVertices(h,f-6,4,o,0,2)),this.addAfterPosition($-X,o,0,a,O);continue}for(;;W++){const G=D[W];if(!($>G)){if(W==0)$/=G;else{const lt=D[W-1];$=($-lt)/(G-lt)}break}}W!=m&&(m=W,d&&W==u?(t.computeWorldVertices(h,f-4,4,o,0,2),t.computeWorldVertices(h,0,4,o,4,2)):t.computeWorldVertices(h,W*6+2,8,o,0,2)),this.addCurvePosition($,o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7],a,O,e||L>0&&U==0)}return a}d?(f+=2,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f-4,o,0,2),t.computeWorldVertices(h,0,2,o,f-4,2),o[f-2]=o[0],o[f-1]=o[1]):(u--,f-=4,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f,o,0,2));const g=v.setArraySize(this.curves,u);let x=0,E=o[0],w=o[1],b=0,p=0,S=0,y=0,M=0,T=0,k=0,I=0,R=0,V=0,F=0,B=0,Y=0,N=0;for(let D=0,X=2;Dx){this.addAfterPosition(U-x,o,f-4,a,X);continue}for(;;L++){const $=g[L];if(!(U>$)){if(L==0)U/=$;else{const G=g[L-1];U=(U-G)/($-G)}break}}if(L!=m){m=L;let $=L*6;for(E=o[$],w=o[$+1],b=o[$+2],p=o[$+3],S=o[$+4],y=o[$+5],M=o[$+6],T=o[$+7],k=(E-b*2+S)*.03,I=(w-p*2+y)*.03,R=((b-S)*3-E+M)*.006,V=((p-y)*3-w+T)*.006,F=k*2+R,B=I*2+V,Y=(b-E)*.3+k+R*.16666667,N=(p-w)*.3+I+V*.16666667,z=Math.sqrt(Y*Y+N*N),q[0]=z,$=1;$<8;$++)Y+=F,N+=B,F+=R,B+=V,z+=Math.sqrt(Y*Y+N*N),q[$]=z;Y+=F,N+=B,z+=Math.sqrt(Y*Y+N*N),q[8]=z,Y+=F+R,N+=B+V,z+=Math.sqrt(Y*Y+N*N),q[9]=z,O=0}for(U*=z;;O++){const $=q[O];if(!(U>$)){if(O==0)U/=$;else{const G=q[O-1];U=O+(U-G)/($-G)}break}}this.addCurvePosition(U*.1,E,w,b,p,S,y,M,T,a,X,e||D>0&&W==0)}return a}addBeforePosition(t,n,e,i,r){const h=n[e],l=n[e+1],s=n[e+2]-h,a=n[e+3]-l,o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addAfterPosition(t,n,e,i,r){const h=n[e+2],l=n[e+3],s=h-n[e],a=l-n[e+1],o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addCurvePosition(t,n,e,i,r,h,l,s,a,o,d,f){(t==0||isNaN(t))&&(t=1e-4);const u=t*t,m=u*t,g=1-t,x=g*g,E=x*g,w=g*t,b=w*3,p=g*b,S=b*t,y=n*E+i*p+h*S+s*m,M=e*E+r*p+l*S+a*m;o[d]=y,o[d+1]=M,f&&(o[d+2]=Math.atan2(M-(e*x+r*w*2+l*u),y-(n*x+i*w*2+h*u)))}getOrder(){return this.data.order}};let wn=rn;wn.NONE=-1,wn.BEFORE=-2,wn.AFTER=-3,wn.epsilon=1e-5;let Ki=class{constructor(t,n){if(this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.temp=new un,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.rotateMix=t.rotateMix,this.translateMix=t.translateMix,this.scaleMix=t.scaleMix,this.shearMix=t.shearMix,this.bones=new Array;for(let e=0;e0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=(p.x-b.tx)*n,b.ty+=(p.y-b.ty)*n,w=!0}if(e>0){let p=Math.sqrt(b.a*b.a+b.b*b.b),S=Math.sqrt(l*l+a*a);p>1e-5&&(p=(p+(S-p+this.data.offsetScaleX)*e)/p),b.a*=p,b.b*=p,p=Math.sqrt(b.c*b.c+b.d*b.d),S=Math.sqrt(s*s+o*o),p>1e-5&&(p=(p+(S-p+this.data.offsetScaleY)*e)/p),b.c*=p,b.d*=p,w=!0}if(i>0){const p=b.c,S=b.d,y=Math.atan2(S,p);let M=Math.atan2(o,s)-Math.atan2(a,l)-(y-Math.atan2(b.b,b.a));M>C.PI?M-=C.PI2:M<-C.PI&&(M+=C.PI2),M=y+(M+u)*i;const T=Math.sqrt(p*p+S*S);b.c=Math.cos(M)*T,b.d=Math.sin(M)*T,w=!0}w&&(E.appliedValid=!1)}}applyRelativeWorld(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target,h=r.matrix,l=h.a,s=h.c,a=h.b,o=h.d,d=l*o-s*a>0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=p.x*n,b.ty+=p.y*n,w=!0}if(e>0){let p=(Math.sqrt(l*l+a*a)-1+this.data.offsetScaleX)*e+1;b.a*=p,b.b*=p,p=(Math.sqrt(s*s+o*o)-1+this.data.offsetScaleY)*e+1,b.c*=p,b.d*=p,w=!0}if(i>0){let p=Math.atan2(o,s)-Math.atan2(a,l);p>C.PI?p-=C.PI2:p<-C.PI&&(p+=C.PI2);const S=b.c,y=b.d;p=Math.atan2(y,S)+(p-C.PI/2+u)*i;const M=Math.sqrt(S*S+y*y);b.c=Math.cos(p)*M,b.d=Math.sin(p)*M,w=!0}w&&(E.appliedValid=!1)}}applyAbsoluteLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u=(u+(r.ascaleX-u+this.data.offsetScaleX)*e)/u),m>1e-5&&(m=(m+(r.ascaleY-m+this.data.offsetScaleY)*e)/m));const g=a.ashearY;if(i>0){let x=r.ashearY-g+this.data.offsetShearY;x-=(16384-(16384.499999999996-x/360|0))*360,a.shearY+=x*i}a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}applyRelativeLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u*=(r.ascaleX-1+this.data.offsetScaleX)*e+1),m>1e-5&&(m*=(r.ascaleY-1+this.data.offsetScaleY)*e+1));let g=a.ashearY;i>0&&(g+=(r.ashearY+this.data.offsetShearY)*i),a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}getOrder(){return this.data.order}};const In=class{constructor(t){if(this._updateCache=new Array,this.updateCacheReset=new Array,this.time=0,this.scaleX=1,this.scaleY=1,this.x=0,this.y=0,t==null)throw new Error("data cannot be null.");this.data=t,this.bones=new Array;for(let n=0;n1){const r=e[e.length-1];this._updateCache.indexOf(r)>-1||this.updateCacheReset.push(r)}this._updateCache.push(t),this.sortReset(i.children),e[e.length-1].sorted=!0}sortPathConstraint(t){const n=t.target,e=n.data.index,i=n.bone;this.skin!=null&&this.sortPathConstraintAttachment(this.skin,e,i),this.data.defaultSkin!=null&&this.data.defaultSkin!=this.skin&&this.sortPathConstraintAttachment(this.data.defaultSkin,e,i);for(let s=0,a=this.data.skins.length;s-1||this.updateCacheReset.push(r)}else for(let i=0;i= 0.");if(n==null)throw new Error("name cannot be null.");if(e==null)throw new Error("boneData cannot be null.");this.index=t,this.name=n,this.boneData=e}},er=class{constructor(t){if(this.order=0,this.bones=new Array,this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.offsetRotation=0,this.offsetX=0,this.offsetY=0,this.offsetScaleX=0,this.offsetScaleY=0,this.offsetShearY=0,this.relative=!1,this.local=!1,t==null)throw new Error("name cannot be null.");this.name=t}},nr=class{constructor(t){if(this.attachments=new Array,t==null)throw new Error("name cannot be null.");this.name=t}addAttachment(t,n,e){if(e==null)throw new Error("attachment cannot be null.");const i=this.attachments;t>=i.length&&(i.length=t+1),i[t]||(i[t]={}),i[t][n]=e}getAttachment(t,n){const e=this.attachments[t];return e?e[n]:null}attachAll(t,n){let e=0;for(let i=0;i=0;w--)u[w]==-1&&(u[w]=g[--E])}s.setFrame(o++,f.time,u)}r.push(s),h=Math.max(h,s.frames[s.getFrameCount()-1])}if(t.events){const s=new qi(t.events.length);let a=0;for(let o=0;o>1)*r;const h=c.bone.skeleton,l=c.deform;let s=this.vertices;const a=this.bones;if(!a){l.length>0&&(s=l);const u=c.bone.matrix,m=u.tx,g=u.ty,x=u.a,E=u.c,w=u.b,b=u.d;for(let p=t,S=i;S=this.regions.length&&(n=this.regions.length-1);const e=this.regions[n];t.region!=e&&(t.region=e)}getPath(c,t){let n=c;const e=(this.start+t).toString();for(let i=this.digits-e.length;i>0;i--)n+="0";return n+=e,n}static nextID(){return qn._nextID++}};let Un=qn;Un._nextID=0;var Re=(c=>(c[c.hold=0]="hold",c[c.once=1]="once",c[c.loop=2]="loop",c[c.pingpong=3]="pingpong",c[c.onceReverse=4]="onceReverse",c[c.loopReverse=5]="loopReverse",c[c.pingpongReverse=6]="pingpongReverse",c))(Re||{});const Bs=[0,1,2,3,4,5,6];class zn{constructor(t,n,e){if(this.timelines=[],this.timelineIds=new ss,!t)throw new Error("name cannot be null.");this.name=t,this.setTimelines(n),this.duration=e}setTimelines(t){if(!t)throw new Error("timelines cannot be null.");this.timelines=t,this.timelineIds.clear();for(let n=0;n0&&(n%=this.duration));const a=this.timelines;for(let o=0,d=a.length;on)return i-1;return e-1}static search(t,n,e){const i=t.length;for(let r=e;rn)return r-e;return i-e}}class be extends bt{constructor(t,n,e){super(t,e),this.curves=v.newFloatArray(t+n*18),this.curves[t-1]=1}setLinear(t){this.curves[t]=0}setStepped(t){this.curves[t]=1}shrink(t){const n=this.getFrameCount()+t*18;if(this.curves.length>n){const e=v.newFloatArray(n);v.arrayCopy(this.curves,0,e,0,n),this.curves=e}}setBezier(t,n,e,i,r,h,l,s,a,o,d){const f=this.curves;let u=this.getFrameCount()+t*18;e==0&&(f[n]=2+u);const m=(i-h*2+s)*.03,g=(r-l*2+a)*.03,x=((h-s)*3-i+o)*.006,E=((l-a)*3-r+d)*.006;let w=m*2+x,b=g*2+E,p=(h-i)*.3+m+x*.16666667,S=(l-r)*.3+g+E*.16666667,y=i+p,M=r+S;for(let T=u+18;ut){const a=this.frames[n],o=this.frames[n+e];return o+(t-a)/(r[i]-a)*(r[i+1]-o)}const h=i+18;for(i+=2;i=t){const a=r[i-2],o=r[i-1];return o+(t-a)/(r[i]-a)*(r[i+1]-o)}n+=this.getFrameEntries();const l=r[h-2],s=r[h-1];return s+(t-l)/(this.frames[n]-l)*(this.frames[n+e]-s)}}class Ee extends be{constructor(t,n,e){super(t,n,[e])}getFrameEntries(){return 2}setFrame(t,n,e){t<<=1,this.frames[t]=n,this.frames[t+1]=e}getCurveValue(t){const n=this.frames;let e=n.length-2;for(let r=2;r<=e;r+=2)if(n[r]>t){e=r-2;break}const i=this.curves[e>>1];switch(i){case 0:const r=n[e],h=n[e+1];return h+(t-r)/(n[e+2]-r)*(n[e+2+1]-h);case 1:return n[e+1]}return this.getBezierValue(t,e,1,i-2)}}class Hn extends be{constructor(t,n,e,i){super(t,n,[e,i])}getFrameEntries(){return 3}setFrame(t,n,e,i){t*=3,this.frames[t]=n,this.frames[t+1]=e,this.frames[t+2]=i}}class Rn extends Ee{constructor(t,n,e){super(t,n,`${ot.rotate}|${e}`),this.boneIndex=0,this.boneIndex=e}apply(t,n,e,i,r,h,l){const s=t.bones[this.boneIndex];if(!s.active)return;const a=this.frames;if(e>2];switch(g){case 0:const x=a[m];d=a[m+1],f=a[m+2],u=a[m+3];const E=(e-x)/(a[m+4]-x);d+=(a[m+4+1]-d)*E,f+=(a[m+4+2]-f)*E,u+=(a[m+4+3]-u)*E;break;case 1:d=a[m+1],f=a[m+2],u=a[m+3];break;default:d=this.getBezierValue(e,m,1,g-2),f=this.getBezierValue(e,m,2,g+18-2),u=this.getBezierValue(e,m,3,g+18*2-2)}if(r==1)o.r=d,o.g=f,o.b=u;else{if(h==A.setup){const x=s.data.color;o.r=x.r,o.g=x.g,o.b=x.b}o.r+=(d-o.r)*r,o.g+=(f-o.g)*r,o.b+=(u-o.b)*r}}}class js extends Ee{constructor(t,n,e){super(t,n,`${ot.alpha}|${e}`),this.slotIndex=0,this.slotIndex=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=s.color;if(e>3];switch(p){case 0:const S=a[b];f=a[b+1],u=a[b+2],m=a[b+3],g=a[b+4],x=a[b+5],E=a[b+6],w=a[b+7];const y=(e-S)/(a[b+8]-S);f+=(a[b+8+1]-f)*y,u+=(a[b+8+2]-u)*y,m+=(a[b+8+3]-m)*y,g+=(a[b+8+4]-g)*y,x+=(a[b+8+5]-x)*y,E+=(a[b+8+6]-E)*y,w+=(a[b+8+7]-w)*y;break;case 1:f=a[b+1],u=a[b+2],m=a[b+3],g=a[b+4],x=a[b+5],E=a[b+6],w=a[b+7];break;default:f=this.getBezierValue(e,b,1,p-2),u=this.getBezierValue(e,b,2,p+18-2),m=this.getBezierValue(e,b,3,p+18*2-2),g=this.getBezierValue(e,b,4,p+18*3-2),x=this.getBezierValue(e,b,5,p+18*4-2),E=this.getBezierValue(e,b,6,p+18*5-2),w=this.getBezierValue(e,b,7,p+18*6-2)}if(r==1)o.set(f,u,m,g),d.r=x,d.g=E,d.b=w;else{if(h==A.setup){o.setFromColor(s.data.color);const S=s.data.darkColor;d.r=S.r,d.g=S.g,d.b=S.b}o.add((f-o.r)*r,(u-o.g)*r,(m-o.b)*r,(g-o.a)*r),d.r+=(x-d.r)*r,d.g+=(E-d.g)*r,d.b+=(w-d.b)*r}}}class Qs extends be{constructor(t,n,e){super(t,n,[`${ot.rgb}|${e}`,`${ot.rgb2}|${e}`]),this.slotIndex=0,this.slotIndex=e}getFrameEntries(){return 7}setFrame(t,n,e,i,r,h,l,s){t*=7,this.frames[t]=n,this.frames[t+1]=e,this.frames[t+2]=i,this.frames[t+3]=r,this.frames[t+4]=h,this.frames[t+5]=l,this.frames[t+6]=s}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=this.frames,o=s.color,d=s.darkColor;if(et){const s=this.frames[n];return e[i+1]*(t-s)/(e[i]-s)}const r=i+18;for(i+=2;i=t){const s=e[i-2],a=e[i-1];return a+(t-s)/(e[i]-s)*(e[i+1]-a)}const h=e[r-2],l=e[r-1];return l+(1-l)*(t-h)/(this.frames[n+this.getFrameEntries()]-h)}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=s.getAttachment();if(!a||!(a instanceof we)||a.timelineAttachment!=this.attachment)return;const o=s.deform;o.length==0&&(h=A.setup);const d=this.vertices,f=d[0].length,u=this.frames;if(e=u[u.length-1]){const w=d[u.length-1];if(r==1)if(h==A.add){const b=a;if(b.bones)for(let p=0;pn)this.apply(c,t,Number.MAX_VALUE,e,i,r,h),t=-1;else if(t>=l[s-1])return;if(n0&&l[a-1]==o;)a--}for(;a=l[a];a++)e.push(this.events[a])}};let vn=rr;vn.propertyIds=[`${ot.event}`];const ar=class extends bt{constructor(c){super(c,ar.propertyIds),this.drawOrders=new Array(c)}getFrameCount(){return this.frames.length}setFrame(c,t,n){this.frames[c]=t,this.drawOrders[c]=n}apply(c,t,n,e,i,r,h){if(h==J.mixOut){r==A.setup&&v.arrayCopy(c.slots,0,c.drawOrder,0,c.slots.length);return}if(n>2];switch(m){case 0:const g=a[u];o=a[u+1],d=a[u+2],f=a[u+3];const x=(e-g)/(a[u+4]-g);o+=(a[u+4+1]-o)*x,d+=(a[u+4+2]-d)*x,f+=(a[u+4+3]-f)*x;break;case 1:o=a[u+1],d=a[u+2],f=a[u+3];break;default:o=this.getBezierValue(e,u,1,m-2),d=this.getBezierValue(e,u,2,m+18-2),f=this.getBezierValue(e,u,3,m+18*2-2)}if(h==A.setup){const g=s.data;s.mixRotate=g.mixRotate+(o-g.mixRotate)*r,s.mixX=g.mixX+(d-g.mixX)*r,s.mixY=g.mixY+(f-g.mixY)*r}else s.mixRotate+=(o-s.mixRotate)*r,s.mixX+=(d-s.mixX)*r,s.mixY+=(f-s.mixY)*r}}const Qe=class extends bt{constructor(c,t,n){super(c,[`${ot.sequence}|${t}|${n.sequence.id}`]),this.slotIndex=t,this.attachment=n}getFrameEntries(){return Qe.ENTRIES}getSlotIndex(){return this.slotIndex}getAttachment(){return this.attachment}setFrame(c,t,n,e,i){const r=this.frames;c*=Qe.ENTRIES,r[c]=t,r[c+Qe.MODE]=n|e<<4,r[c+Qe.DELAY]=i}apply(c,t,n,e,i,r,h){const l=c.slots[this.slotIndex];if(!l.bone.active)return;const s=l.attachment,a=this.attachment;if(s!=a&&(!(s instanceof we)||s.timelineAttachment!=a))return;const o=this.frames;if(n>4;const x=this.attachment.sequence.regions.length,E=Bs[u&15];if(E!=Re.hold)switch(g+=(n-f)/m+1e-5|0,E){case Re.once:g=Math.min(x-1,g);break;case Re.loop:g%=x;break;case Re.pingpong:{const w=(x<<1)-2;g=w==0?0:g%w,g>=x&&(g=w-g);break}case Re.onceReverse:g=Math.max(x-1-g,0);break;case Re.loopReverse:g=x-1-g%x;break;case Re.pingpongReverse:{const w=(x<<1)-2;g=w==0?0:(g+x-1)%w,g>=x&&(g=w-g)}}l.sequenceIndex=g}};let bn=Qe;bn.ENTRIES=3,bn.MODE=1,bn.DELAY=2;const ve=class{constructor(c){this.tracks=new Array,this.timeScale=1,this.unkeyedState=0,this.events=new Array,this.listeners=new Array,this.queue=new or(this),this.propertyIDs=new ss,this.animationsChanged=!1,this.trackEntryPool=new An(()=>new Gn),this.data=c}static emptyAnimation(){return ve._emptyAnimation}update(c){c*=this.timeScale;const t=this.tracks;for(let n=0,e=t.length;n0){if(i.delay-=r,i.delay>0)continue;r=-i.delay,i.delay=0}let h=i.next;if(h){const l=i.trackLast-h.delay;if(l>=0){for(h.delay=0,h.trackTime+=i.timeScale==0?0:(l/i.timeScale+c)*h.timeScale,i.trackTime+=r,this.setCurrent(n,h,!0);h.mixingFrom;)h.mixTime+=c,h=h.mixingFrom;continue}}else if(i.trackLast>=i.trackEnd&&!i.mixingFrom){t[n]=null,this.queue.end(i),this.clearNext(i);continue}if(i.mixingFrom&&this.updateMixingFrom(i,c)){let l=i.mixingFrom;for(i.mixingFrom=null,l&&(l.mixingTo=null);l;)this.queue.end(l),l=l.mixingFrom}i.trackTime+=r}this.queue.drain()}updateMixingFrom(c,t){const n=c.mixingFrom;if(!n)return!0;const e=this.updateMixingFrom(n,t);return n.animationLast=n.nextAnimationLast,n.trackLast=n.nextTrackLast,c.mixTime>0&&c.mixTime>=c.mixDuration?((n.totalAlpha==0||c.mixDuration==0)&&(c.mixingFrom=n.mixingFrom,n.mixingFrom&&(n.mixingFrom.mixingTo=c),c.interruptAlpha=n.interruptAlpha,this.queue.end(n)),e):(n.trackTime+=t*n.timeScale,c.mixTime+=t,!1)}apply(c){if(!c)throw new Error("skeleton cannot be null.");this.animationsChanged&&this._animationsChanged();const t=this.events,n=this.tracks;let e=!1;for(let h=0,l=n.length;h0)continue;e=!0;const a=h==0?A.first:s.mixBlend;let o=s.alpha;s.mixingFrom?o*=this.applyMixingFrom(s,c,a):s.trackTime>=s.trackEnd&&!s.next&&(o=0);const d=s.animationLast,f=s.getAnimationTime();let u=f,m=t;s.reverse&&(u=s.animation.duration-u,m=null);const g=s.animation.timelines,x=g.length;if(h==0&&o==1||a==A.add)for(let E=0;E1&&(i=1),n!=A.first&&(n=e.mixBlend));const r=i0&&this.queueEvents(e,f),this.events.length=0,e.nextAnimationLast=f,e.nextTrackLast=e.trackTime,i}applyAttachmentTimeline(c,t,n,e,i){const r=t.slots[c.slotIndex];r.bone.active&&(n0;let E=m>=0;C.signum(g)!=C.signum(u)&&Math.abs(g)<=90&&(Math.abs(m)>180&&(m+=360*C.signum(m)),E=x),f=u+m-m%360,E!=x&&(f+=360*C.signum(m)),r[h]=f}r[h+1]=u,s.rotation=o+f*e}queueEvents(c,t){const n=c.animationStart,e=c.animationEnd,i=e-n,r=c.trackLast%i,h=this.events;let l=0;const s=h.length;for(;le||this.queue.event(c,o)}let a=!1;for(c.loop?a=i==0||r>c.trackTime%i:a=t>=e&&c.animationLast=this.tracks.length)return;const t=this.tracks[c];if(!t)return;this.queue.end(t),this.clearNext(t);let n=t;for(;;){const e=n.mixingFrom;if(!e)break;this.queue.end(e),n.mixingFrom=null,n.mixingTo=null,n=e}this.tracks[t.trackIndex]=null,this.queue.drain()}setCurrent(c,t,n){const e=this.expandToIndex(c);this.tracks[c]=t,t.previous=null,e&&(n&&this.queue.interrupt(e),t.mixingFrom=e,e.mixingTo=t,t.mixTime=0,e.mixingFrom&&e.mixDuration>0&&(t.interruptAlpha*=Math.min(1,e.mixTime/e.mixDuration)),e.timelinesRotation.length=0),this.queue.start(t)}setAnimation(c,t,n=!1){const e=this.data.skeletonData.findAnimation(t);if(!e)throw new Error(`Animation not found: ${t}`);return this.setAnimationWith(c,e,n)}setAnimationWith(c,t,n=!1){if(!t)throw new Error("animation cannot be null.");let e=!0,i=this.expandToIndex(c);i&&(i.nextTrackLast==-1?(this.tracks[c]=i.mixingFrom,this.queue.interrupt(i),this.queue.end(i),this.clearNext(i),i=i.mixingFrom,e=!1):this.clearNext(i));const r=this.trackEntry(c,t,n,i);return this.setCurrent(c,r,e),this.queue.drain(),r}addAnimation(c,t,n=!1,e=0){const i=this.data.skeletonData.findAnimation(t);if(!i)throw new Error(`Animation not found: ${t}`);return this.addAnimationWith(c,i,n,e)}addAnimationWith(c,t,n=!1,e=0){if(!t)throw new Error("animation cannot be null.");let i=this.expandToIndex(c);if(i)for(;i.next;)i=i.next;const r=this.trackEntry(c,t,n,i);return i?(i.next=r,r.previous=i,e<=0&&(e+=i.getTrackComplete()-r.mixDuration)):(this.setCurrent(c,r,!0),this.queue.drain()),r.delay=e,r}setEmptyAnimation(c,t=0){const n=this.setAnimationWith(c,ve.emptyAnimation(),!1);return n.mixDuration=t,n.trackEnd=t,n}addEmptyAnimation(c,t=0,n=0){const e=this.addAnimationWith(c,ve.emptyAnimation(),!1,n);return n<=0&&(e.delay+=e.mixDuration-t),e.mixDuration=t,e.trackEnd=t,e}setEmptyAnimations(c=0){const t=this.queue.drainDisabled;this.queue.drainDisabled=!0;for(let n=0,e=this.tracks.length;n0){i[l]=Wr,r[l]=o;continue t}break}i[l]=ri}}}getCurrent(c){return c>=this.tracks.length?null:this.tracks[c]}addListener(c){if(!c)throw new Error("listener cannot be null.");this.listeners.push(c)}removeListener(c){const t=this.listeners.indexOf(c);t>=0&&this.listeners.splice(t,1)}clearListeners(){this.listeners.length=0}clearListenerNotifications(){this.queue.clear()}setAnimationByName(c,t,n){ve.deprecatedWarning1||(ve.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on.")),this.setAnimation(c,t,n)}addAnimationByName(c,t,n,e){ve.deprecatedWarning2||(ve.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on.")),this.addAnimation(c,t,n,e)}hasAnimation(c){return this.data.skeletonData.findAnimation(c)!==null}hasAnimationByName(c){return ve.deprecatedWarning3||(ve.deprecatedWarning3=!0,console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on.")),this.hasAnimation(c)}};let En=ve;En._emptyAnimation=new zn("",[],0),En.deprecatedWarning1=!1,En.deprecatedWarning2=!1,En.deprecatedWarning3=!1;const De=class{constructor(){this.animation=null,this.previous=null,this.next=null,this.mixingFrom=null,this.mixingTo=null,this.listener=null,this.trackIndex=0,this.loop=!1,this.holdPrevious=!1,this.reverse=!1,this.shortestRotation=!1,this.eventThreshold=0,this.attachmentThreshold=0,this.drawOrderThreshold=0,this.animationStart=0,this.animationEnd=0,this.animationLast=0,this.nextAnimationLast=0,this.delay=0,this.trackTime=0,this.trackLast=0,this.nextTrackLast=0,this.trackEnd=0,this.timeScale=0,this.alpha=0,this.mixTime=0,this.mixDuration=0,this.interruptAlpha=0,this.totalAlpha=0,this.mixBlend=A.replace,this.timelineMode=new Array,this.timelineHoldMix=new Array,this.timelinesRotation=new Array}reset(){this.next=null,this.previous=null,this.mixingFrom=null,this.mixingTo=null,this.animation=null,this.listener=null,this.timelineMode.length=0,this.timelineHoldMix.length=0,this.timelinesRotation.length=0}getAnimationTime(){if(this.loop){const c=this.animationEnd-this.animationStart;return c==0?this.animationStart:this.trackTime%c+this.animationStart}return Math.min(this.trackTime+this.animationStart,this.animationEnd)}setAnimationLast(c){this.animationLast=c,this.nextAnimationLast=c}isComplete(){return this.trackTime>=this.animationEnd-this.animationStart}resetRotationDirections(){this.timelinesRotation.length=0}getTrackComplete(){const c=this.animationEnd-this.animationStart;if(c!=0){if(this.loop)return c*(1+(this.trackTime/c|0));if(this.trackTime(c[c.start=0]="start",c[c.interrupt=1]="interrupt",c[c.end=2]="end",c[c.dispose=3]="dispose",c[c.complete=4]="complete",c[c.event=5]="event",c))(Qt||{});class $r{start(t){}interrupt(t){}end(t){}dispose(t){}complete(t){}event(t,n){}}const ii=0,lr=1,cr=2,ri=3,Wr=4,hr=1,qr=2;class dr{constructor(t){if(this.animationToMixTime={},this.defaultMix=0,!t)throw new Error("skeletonData cannot be null.");this.skeletonData=t}setMix(t,n,e){const i=this.skeletonData.findAnimation(t);if(!i)throw new Error(`Animation not found: ${t}`);const r=this.skeletonData.findAnimation(n);if(!r)throw new Error(`Animation not found: ${n}`);this.setMixWith(i,r,e)}setMixWith(t,n,e){if(!t)throw new Error("from cannot be null.");if(!n)throw new Error("to cannot be null.");const i=`${t.name}.${n.name}`;this.animationToMixTime[i]=e}getMix(t,n){const e=`${t.name}.${n.name}`,i=this.animationToMixTime[e];return i===void 0?this.defaultMix:i}}class ai{constructor(t){this.atlas=t}loadSequence(t,n,e){const i=e.regions;for(let r=0,h=i.length;r1e-4?(x=Math.abs(f*g-u*m)/x,f/=o,m/=d,u=m*x,g=f*x,E=Math.atan2(m,f)*C.radDeg):(f=0,m=0,E=90-Math.atan2(g,u)*C.radDeg);const w=e+h-E,b=e+l-E+90,p=C.cosDeg(w)*i,S=C.cosDeg(b)*r,y=C.sinDeg(w)*i,M=C.sinDeg(b)*r;a.a=f*p-u*y,a.c=f*S-u*M,a.b=m*p+g*y,a.d=m*S+g*M;break}case j.NoScale:case j.NoScaleOrReflection:{const x=C.cosDeg(e),E=C.sinDeg(e);let w=(f*x+u*E)/o,b=(m*x+g*E)/d,p=Math.sqrt(w*w+b*b);p>1e-5&&(p=1/p),w*=p,b*=p,p=Math.sqrt(w*w+b*b),this.data.transformMode==j.NoScale&&f*g-u*m<0!=(o<0!=d<0)&&(p=-p);const S=Math.PI/2+Math.atan2(b,w),y=Math.cos(S)*p,M=Math.sin(S)*p,T=C.cosDeg(h)*i,k=C.cosDeg(90+l)*r,I=C.sinDeg(h)*i,R=C.sinDeg(90+l)*r;a.a=w*T+y*I,a.c=w*k+y*R,a.b=b*T+M*I,a.d=b*k+M*R;break}}a.a*=o,a.c*=o,a.b*=d,a.d*=d}setToSetupPose(){const t=this.data;this.x=t.x,this.y=t.y,this.rotation=t.rotation,this.scaleX=t.scaleX,this.scaleY=t.scaleY,this.shearX=t.shearX,this.shearY=t.shearY}getWorldRotationX(){return Math.atan2(this.matrix.b,this.matrix.a)*C.radDeg}getWorldRotationY(){return Math.atan2(this.matrix.d,this.matrix.c)*C.radDeg}getWorldScaleX(){const t=this.matrix;return Math.sqrt(t.a*t.a+t.b*t.b)}getWorldScaleY(){const t=this.matrix;return Math.sqrt(t.c*t.c+t.d*t.d)}updateAppliedTransform(){const t=this.parent,n=this.matrix;if(!t){this.ax=n.tx-this.skeleton.x,this.ay=n.ty-this.skeleton.y,this.arotation=Math.atan2(n.b,n.a)*C.radDeg,this.ascaleX=Math.sqrt(n.a*n.a+n.b*n.b),this.ascaleY=Math.sqrt(n.c*n.c+n.d*n.d),this.ashearX=0,this.ashearY=Math.atan2(n.a*n.c+n.b*n.d,n.a*n.d-n.b*n.c)*C.radDeg;return}const e=t.matrix,i=1/(e.a*e.d-e.b*e.c),r=n.tx-e.tx,h=n.ty-e.ty;this.ax=r*e.d*i-h*e.c*i,this.ay=h*e.a*i-r*e.b*i;const l=i*e.d,s=i*e.a,a=i*e.c,o=i*e.b,d=l*n.a-a*n.b,f=l*n.c-a*n.d,u=s*n.b-o*n.a,m=s*n.d-o*n.c;if(this.ashearX=0,this.ascaleX=Math.sqrt(d*d+u*u),this.ascaleX>1e-4){const g=d*m-f*u;this.ascaleY=g/this.ascaleX,this.ashearY=Math.atan2(d*f+u*m,g)*C.radDeg,this.arotation=Math.atan2(u,d)*C.radDeg}else this.ascaleX=0,this.ascaleY=Math.sqrt(f*f+m*m),this.ashearY=0,this.arotation=90-Math.atan2(m,f)*C.radDeg}worldToLocal(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=1/(e*h-i*r),s=t.x-n.tx,a=t.y-n.ty;return t.x=s*h*l-a*i*l,t.y=a*e*l-s*r*l,t}localToWorld(t){const n=this.matrix,e=t.x,i=t.y;return t.x=e*n.a+i*n.c+n.tx,t.y=e*n.b+i*n.d+n.ty,t}worldToLocalRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(i.a*n-i.b*e,i.d*e-i.c*n)*C.radDeg}localToWorldRotation(t){t-=this.rotation-this.shearX;const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(e*i.b+n*i.d,e*i.a+n*i.c)*C.radDeg}rotateWorld(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=C.cosDeg(t),s=C.sinDeg(t);n.a=l*e-s*r,n.c=l*i-s*h,n.b=s*e+l*r,n.d=s*i+l*h}}class li{constructor(t,n,e){if(this.index=0,this.parent=null,this.length=0,this.x=0,this.y=0,this.rotation=0,this.scaleX=1,this.scaleY=1,this.shearX=0,this.shearY=0,this.transformMode=j.Normal,this.skinRequired=!1,this.color=new _,t<0)throw new Error("index must be >= 0.");if(!n)throw new Error("name cannot be null.");this.index=t,this.name=n,this.parent=e}}class jn{constructor(t,n,e){this.name=t,this.order=n,this.skinRequired=e}}class ci{constructor(t,n){if(this.intValue=0,this.floatValue=0,this.stringValue=null,this.time=0,this.volume=0,this.balance=0,!n)throw new Error("data cannot be null.");this.time=t,this.data=n}}class hi{constructor(t){this.intValue=0,this.floatValue=0,this.stringValue=null,this.audioPath=null,this.volume=0,this.balance=0,this.name=t}}class fr{constructor(t,n){if(this.bendDirection=0,this.compress=!1,this.stretch=!1,this.mix=1,this.softness=0,this.active=!1,!t)throw new Error("data cannot be null.");if(!n)throw new Error("skeleton cannot be null.");this.data=t,this.mix=t.mix,this.softness=t.softness,this.bendDirection=t.bendDirection,this.compress=t.compress,this.stretch=t.stretch,this.bones=new Array;for(let i=0;i180?u-=360:u<-180&&(u+=360);let w=t.ascaleX,b=t.ascaleY;if(i||r){switch(t.data.transformMode){case j.NoScale:case j.NoScaleOrReflection:m=n-t.worldX,g=e-t.worldY}const p=t.data.length*w,S=Math.sqrt(m*m+g*g);if(i&&Sp&&p>1e-4){const y=(S/p-1)*l+1;w*=y,h&&(b*=y)}}t.updateWorldTransformWith(t.ax,t.ay,t.arotation+u*l,w,b,t.ashearX,t.ashearY)}apply2(t,n,e,i,r,h,l,s,a){const o=t.ax,d=t.ay;let f=t.ascaleX,u=t.ascaleY,m=f,g=u,x=n.ascaleX;const E=t.matrix;let w=0,b=0,p=0;f<0?(f=-f,w=180,p=-1):(w=0,p=1),u<0&&(u=-u,p=-p),x<0?(x=-x,b=180):b=0;const S=n.ax;let y=0,M=0,T=0,k=E.a,I=E.c,R=E.b,V=E.d;const F=Math.abs(f-u)<=1e-4;!F||h?(y=0,M=k*S+E.tx,T=R*S+E.ty):(y=n.ay,M=k*S+I*y+E.tx,T=R*S+V*y+E.ty);const B=t.parent.matrix;if(!B)throw new Error("IK parent must itself have a parent.");k=B.a,I=B.c,R=B.b,V=B.d;const Y=1/(k*V-I*R);let N=M-B.tx,q=T-B.ty;const z=(N*V-q*I)*Y-o,D=(q*k-N*R)*Y-d,X=Math.sqrt(z*z+D*D);let L=n.data.length*x,O,W;if(X<1e-4){this.apply1(t,e,i,!1,h,!1,a),n.updateWorldTransformWith(S,y,0,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY);return}N=e-B.tx,q=i-B.ty;let U=(N*V-q*I)*Y-o,$=(q*k-N*R)*Y-d,G=U*U+$*$;if(s!=0){s*=f*(x+1)*.5;const ct=Math.sqrt(G),Xt=ct-X-L*f+s;if(Xt>0){let Ut=Math.min(1,Xt/(s*2))-1;Ut=(Xt-s*(1-Ut*Ut))/ct,U-=Ut*U,$-=Ut*$,G=U*U+$*$}}t:if(F){L*=f;let ct=(G-X*X-L*L)/(2*X*L);ct<-1?(ct=-1,W=Math.PI*r):ct>1?(ct=1,W=0,h&&(k=(Math.sqrt(G)/(X+L)-1)*a+1,m*=k,l&&(g*=k))):W=Math.acos(ct)*r,k=X+L*ct,I=L*Math.sin(W),O=Math.atan2($*k-U*I,U*k+$*I)}else{k=f*L,I=u*L;const ct=k*k,Xt=I*I,Ut=Math.atan2($,U);R=Xt*X*X+ct*G-ct*Xt;const de=-2*Xt*X,Me=Xt-ct;if(V=de*de-4*Me*R,V>=0){let Nt=Math.sqrt(V);de<0&&(Nt=-Nt),Nt=-(de+Nt)*.5;const We=Nt/Me,pr=R/Nt,yn=Math.abs(We)=-1&&R<=1&&(R=Math.acos(R),N=k*Math.cos(R)+X,q=I*Math.sin(R),V=N*N+q*q,Vae&&($e=R,ae=V,Kt=N,Ke=q)),G<=(Ae+ae)*.5?(O=Ut-Math.atan2(Ce*r,Ve),W=Oe*r):(O=Ut-Math.atan2(Ke*r,Kt),W=$e*r)}const lt=Math.atan2(y,S)*p;let It=t.arotation;O=(O-lt)*C.radDeg+w-It,O>180?O-=360:O<-180&&(O+=360),t.updateWorldTransformWith(o,d,It+O*a,m,g,0,0),It=n.arotation,W=((W+lt)*C.radDeg-n.ashearX)*p+b-It,W>180?W-=360:W<-180&&(W+=360),n.updateWorldTransformWith(S,y,It+W*a,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY)}}class di extends jn{constructor(t){super(t,0,!1),this.bones=new Array,this._target=null,this.bendDirection=1,this.compress=!1,this.stretch=!1,this.uniform=!1,this.mix=1,this.softness=0}set target(t){this._target=t}get target(){if(this._target)return this._target;throw new Error("BoneData not set.")}}class fi extends jn{constructor(t){super(t,0,!1),this.bones=new Array,this._target=null,this.positionMode=dt.Fixed,this.spacingMode=kt.Fixed,this.rotateMode=pt.Chain,this.offsetRotation=0,this.position=0,this.spacing=0,this.mixRotate=0,this.mixX=0,this.mixY=0}set target(t){this._target=t}get target(){if(this._target)return this._target;throw new Error("SlotData not set.")}}var kt=(c=>(c[c.Length=0]="Length",c[c.Fixed=1]="Fixed",c[c.Percent=2]="Percent",c[c.Proportional=3]="Proportional",c))(kt||{});const Le=class{constructor(c,t){if(this.position=0,this.spacing=0,this.mixRotate=0,this.mixX=0,this.mixY=0,this.spaces=new Array,this.positions=new Array,this.world=new Array,this.curves=new Array,this.lengths=new Array,this.segments=new Array,this.active=!1,!c)throw new Error("data cannot be null.");if(!t)throw new Error("skeleton cannot be null.");this.data=c,this.bones=new Array;for(let e=0,i=c.bones.length;e0){w=a/w*f;for(let p=1;p0?C.degRad:-C.degRad}for(let w=0,b=3;w0){const I=S.a,R=S.c,V=S.b,F=S.d;let B=0,Y=0,N=0;if(r?B=u[b-1]:o[w+1]==0?B=u[b+2]:B=Math.atan2(k,T),B-=Math.atan2(V,I),E){Y=Math.cos(B),N=Math.sin(B);const q=p.data.length;m+=(q*(Y*I-N*V)-T)*t,g+=(q*(N*I+Y*V)-k)*t}else B+=x;B>C.PI?B-=C.PI2:B<-C.PI&&(B+=C.PI2),B*=t,Y=Math.cos(B),N=Math.sin(B),S.a=Y*I-N*V,S.c=Y*R-N*F,S.b=N*I+Y*V,S.d=N*R+Y*F}p.updateAppliedTransform()}}computeWorldPositions(c,t,n){const e=this.target;let i=this.position;const r=this.spaces,h=v.setArraySize(this.positions,t*3+2);let l=this.world;const s=c.closed;let a=c.worldVerticesLength,o=a/6,d=Le.NONE;if(!c.constantSpeed){const q=c.lengths;o-=s?1:2;const z=q[o];this.data.positionMode==dt.Percent&&(i*=z);let D;switch(this.data.spacingMode){case kt.Percent:D=z;break;case kt.Proportional:D=z/t;break;default:D=1}l=v.setArraySize(this.world,8);for(let X=0,L=0,O=0;Xz){d!=Le.AFTER&&(d=Le.AFTER,c.computeWorldVertices(e,a-6,4,l,0,2)),this.addAfterPosition(U-z,l,0,h,L);continue}for(;;O++){const $=q[O];if(!(U>$)){if(O==0)U/=$;else{const G=q[O-1];U=(U-G)/($-G)}break}}O!=d&&(d=O,s&&O==o?(c.computeWorldVertices(e,a-4,4,l,0,2),c.computeWorldVertices(e,0,4,l,4,2)):c.computeWorldVertices(e,O*6+2,8,l,0,2)),this.addCurvePosition(U,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],h,L,n||X>0&&W==0)}return h}s?(a+=2,l=v.setArraySize(this.world,a),c.computeWorldVertices(e,2,a-4,l,0,2),c.computeWorldVertices(e,0,2,l,a-4,2),l[a-2]=l[0],l[a-1]=l[1]):(o--,a-=4,l=v.setArraySize(this.world,a),c.computeWorldVertices(e,2,a,l,0,2));const f=v.setArraySize(this.curves,o);let u=0,m=l[0],g=l[1],x=0,E=0,w=0,b=0,p=0,S=0,y=0,M=0,T=0,k=0,I=0,R=0,V=0,F=0;for(let q=0,z=2;qu){this.addAfterPosition(O-u,l,a-4,h,z);continue}for(;;D++){const W=f[D];if(!(O>W)){if(D==0)O/=W;else{const U=f[D-1];O=(O-U)/(W-U)}break}}if(D!=d){d=D;let W=D*6;for(m=l[W],g=l[W+1],x=l[W+2],E=l[W+3],w=l[W+4],b=l[W+5],p=l[W+6],S=l[W+7],y=(m-x*2+w)*.03,M=(g-E*2+b)*.03,T=((x-w)*3-m+p)*.006,k=((E-b)*3-g+S)*.006,I=y*2+T,R=M*2+k,V=(x-m)*.3+y+T*.16666667,F=(E-g)*.3+M+k*.16666667,N=Math.sqrt(V*V+F*F),Y[0]=N,W=1;W<8;W++)V+=I,F+=R,I+=T,R+=k,N+=Math.sqrt(V*V+F*F),Y[W]=N;V+=I,F+=R,N+=Math.sqrt(V*V+F*F),Y[8]=N,V+=I+T,F+=R+k,N+=Math.sqrt(V*V+F*F),Y[9]=N,X=0}for(O*=N;;X++){const W=Y[X];if(!(O>W)){if(X==0)O/=W;else{const U=Y[X-1];O=X+(O-U)/(W-U)}break}}this.addCurvePosition(O*.1,m,g,x,E,w,b,p,S,h,z,n||q>0&&L==0)}return h}addBeforePosition(c,t,n,e,i){const r=t[n],h=t[n+1],l=t[n+2]-r,s=t[n+3]-h,a=Math.atan2(s,l);e[i]=r+c*Math.cos(a),e[i+1]=h+c*Math.sin(a),e[i+2]=a}addAfterPosition(c,t,n,e,i){const r=t[n+2],h=t[n+3],l=r-t[n],s=h-t[n+1],a=Math.atan2(s,l);e[i]=r+c*Math.cos(a),e[i+1]=h+c*Math.sin(a),e[i+2]=a}addCurvePosition(c,t,n,e,i,r,h,l,s,a,o,d){if(c==0||isNaN(c)){a[o]=t,a[o+1]=n,a[o+2]=Math.atan2(i-n,e-t);return}const f=c*c,u=f*c,m=1-c,g=m*m,x=g*m,E=m*c,w=E*3,b=m*w,p=w*c,S=t*x+e*b+r*p+l*u,y=n*x+i*b+h*p+s*u;a[o]=S,a[o+1]=y,d&&(c<.001?a[o+2]=Math.atan2(i-n,e-t):a[o+2]=Math.atan2(y-(n*g+i*E*2+h*f),S-(t*g+e*E*2+r*f)))}};let Sn=Le;Sn.NONE=-1,Sn.BEFORE=-2,Sn.AFTER=-3,Sn.epsilon=1e-5;class ur{constructor(t,n){if(this.darkColor=null,this.attachment=null,this.attachmentState=0,this.sequenceIndex=-1,this.deform=new Array,!t)throw new Error("data cannot be null.");if(!n)throw new Error("bone cannot be null.");this.data=t,this.bone=n,this.color=new _,this.darkColor=t.darkColor?new _:null,this.setToSetupPose(),this.blendMode=this.data.blendMode}getSkeleton(){return this.bone.skeleton}getAttachment(){return this.attachment}setAttachment(t){this.attachment!=t&&((!(t instanceof we)||!(this.attachment instanceof we)||t.timelineAttachment!=this.attachment.timelineAttachment)&&(this.deform.length=0),this.attachment=t,this.sequenceIndex=-1)}setToSetupPose(){this.color.setFromColor(this.data.color),this.darkColor&&this.darkColor.setFromColor(this.data.darkColor),this.data.attachmentName?(this.attachment=null,this.setAttachment(this.bone.skeleton.getAttachment(this.data.index,this.data.attachmentName))):this.attachment=null}}class mr{constructor(t,n){if(this.mixRotate=0,this.mixX=0,this.mixY=0,this.mixScaleX=0,this.mixScaleY=0,this.mixShearY=0,this.temp=new un,this.active=!1,!t)throw new Error("data cannot be null.");if(!n)throw new Error("skeleton cannot be null.");this.data=t,this.mixRotate=t.mixRotate,this.mixX=t.mixX,this.mixY=t.mixY,this.mixScaleX=t.mixScaleX,this.mixScaleY=t.mixScaleY,this.mixShearY=t.mixShearY,this.bones=new Array;for(let i=0;i0?C.degRad:-C.degRad,g=this.data.offsetRotation*m,x=this.data.offsetShearY*m,E=this.bones;for(let w=0,b=E.length;wC.PI?I-=C.PI2:I<-C.PI&&(I+=C.PI2),I*=t;const R=Math.cos(I),V=Math.sin(I);S.a=R*y-V*T,S.c=R*M-V*k,S.b=V*y+R*T,S.d=V*M+R*k}if(l){const y=this.temp;s.localToWorld(y.set(this.data.offsetX,this.data.offsetY)),S.tx+=(y.x-S.tx)*n,S.ty+=(y.y-S.ty)*e}if(i!=0){let y=Math.sqrt(S.a*S.a+S.b*S.b);y!=0&&(y=(y+(Math.sqrt(o*o+f*f)-y+this.data.offsetScaleX)*i)/y),S.a*=y,S.b*=y}if(r!=0){let y=Math.sqrt(S.c*S.c+S.d*S.d);y!=0&&(y=(y+(Math.sqrt(d*d+u*u)-y+this.data.offsetScaleY)*r)/y),S.c*=y,S.d*=y}if(h>0){const y=S.c,M=S.d,T=Math.atan2(M,y);let k=Math.atan2(u,d)-Math.atan2(f,o)-(T-Math.atan2(S.b,S.a));k>C.PI?k-=C.PI2:k<-C.PI&&(k+=C.PI2),k=T+(k+x)*h;const I=Math.sqrt(y*y+M*M);S.c=Math.cos(k)*I,S.d=Math.sin(k)*I}p.updateAppliedTransform()}}applyRelativeWorld(){const t=this.mixRotate,n=this.mixX,e=this.mixY,i=this.mixScaleX,r=this.mixScaleY,h=this.mixShearY,l=n!=0||e!=0,s=this.target,a=s.matrix,o=a.a,d=a.c,f=a.b,u=a.d,m=o*u-d*f>0?C.degRad:-C.degRad,g=this.data.offsetRotation*m,x=this.data.offsetShearY*m,E=this.bones;for(let w=0,b=E.length;wC.PI?I-=C.PI2:I<-C.PI&&(I+=C.PI2),I*=t;const R=Math.cos(I),V=Math.sin(I);S.a=R*y-V*T,S.c=R*M-V*k,S.b=V*y+R*T,S.d=V*M+R*k}if(l){const y=this.temp;s.localToWorld(y.set(this.data.offsetX,this.data.offsetY)),S.tx+=y.x*n,S.ty+=y.y*e}if(i!=0){const y=(Math.sqrt(o*o+f*f)-1+this.data.offsetScaleX)*i+1;S.a*=y,S.b*=y}if(r!=0){const y=(Math.sqrt(d*d+u*u)-1+this.data.offsetScaleY)*r+1;S.c*=y,S.d*=y}if(h>0){let y=Math.atan2(u,d)-Math.atan2(f,o);y>C.PI?y-=C.PI2:y<-C.PI&&(y+=C.PI2);const M=S.c,T=S.d;y=Math.atan2(T,M)+(y-C.PI/2+x)*h;const k=Math.sqrt(M*M+T*T);S.c=Math.cos(y)*k,S.d=Math.sin(y)*k}p.updateAppliedTransform()}}applyAbsoluteLocal(){const t=this.mixRotate,n=this.mixX,e=this.mixY,i=this.mixScaleX,r=this.mixScaleY,h=this.mixShearY,l=this.target,s=this.bones;for(let a=0,o=s.length;a= 0.");if(!n)throw new Error("name cannot be null.");if(!e)throw new Error("boneData cannot be null.");this.index=t,this.name=n,this.boneData=e}}class xi extends jn{constructor(t){super(t,0,!1),this.bones=new Array,this._target=null,this.mixRotate=0,this.mixX=0,this.mixY=0,this.mixScaleX=0,this.mixScaleY=0,this.mixShearY=0,this.offsetRotation=0,this.offsetX=0,this.offsetY=0,this.offsetScaleX=0,this.offsetScaleY=0,this.offsetShearY=0,this.relative=!1,this.local=!1}set target(t){this._target=t}get target(){if(this._target)return this._target;throw new Error("BoneData not set.")}}class pi{constructor(t,n,e){this.slotIndex=t,this.name=n,this.attachment=e}}class Zn{constructor(t){if(this.attachments=new Array,this.bones=Array(),this.constraints=new Array,!t)throw new Error("name cannot be null.");this.name=t}setAttachment(t,n,e){if(!e)throw new Error("attachment cannot be null.");const i=this.attachments;t>=i.length&&(i.length=t+1),i[t]||(i[t]={}),i[t][n]=e}addSkin(t){for(let e=0;e>4,t.readFloat())}i.push(y);break}}}}}const h=t.readInt(!0);if(h>0){const a=new hn(h),o=e.slots.length;for(let d=0;d=0;w--)m[w]=-1;const g=v.newArray(o-u,0);let x=0,E=0;for(let w=0;w=0;w--)m[w]==-1&&(m[w]=g[--E]);a.setFrame(d,f,m)}i.push(a)}const l=t.readInt(!0);if(l>0){const a=new vn(l);for(let o=0;o=0;E--)f[E]==-1&&(f[E]=m[--x])}l.setFrame(a,P(d,"time",0),f)}r.push(l)}if(t.events){const l=new vn(t.events.length);let s=0;for(let a=0;a(c[c.UNKNOWN=0]="UNKNOWN",c[c.VER37=37]="VER37",c[c.VER38=38]="VER38",c[c.VER40=40]="VER40",c[c.VER41=41]="VER41",c))(he||{});function Kn(c){const t=c.substr(0,3),n=Math.floor(Number(t)*10+.001);return t==="3.7"?37:t==="3.8"?38:t==="4.0"?40:t==="4.1"?41:n<37?37:0}class ga{constructor(){this.scale=1}readSkeletonData(t,n){let e=null,i=this.readVersionOldFormat(n),r=Kn(i);if(r===he.VER38&&(e=new Mt(new gs(t))),i=this.readVersionNewFormat(n),r=Kn(i),(r===he.VER40||r===he.VER41)&&(e=new wi(new ai(t))),!e){const h=`Unsupported version of spine model ${i}, please update pixi-spine`;console.error(h)}return e.scale=this.scale,e.readSkeletonData(n)}readVersionOldFormat(t){const n=new Mn(t);let e;try{n.readString(),e=n.readString()}catch(i){e=""}return e||""}readVersionNewFormat(t){const n=new Mn(t);n.readInt32(),n.readInt32();let e;try{e=n.readString()}catch(i){e=""}return e||""}}class xa{constructor(){this.scale=1}readSkeletonData(t,n){const e=n.skeleton.spine,i=Kn(e);let r=null;if(i===he.VER37&&(r=new an(new Ui(t))),i===he.VER38&&(r=new sn(new gs(t))),(i===he.VER40||i===he.VER41)&&(r=new Qn(new ai(t))),!r){const h=`Unsupported version of spine model ${e}, please update pixi-spine`;console.error(h)}return r.scale=this.scale,r.readSkeletonData(n)}}class pa extends Rr{createBinaryParser(){return new ga}createJsonParser(){return new xa}parseData(t,n,e){return{spineData:t.readSkeletonData(n,e),spineAtlas:n}}}class wa extends tn{createSkeleton(t){const n=Kn(t.version);let e=null;if(n===he.VER37&&(e=Or),n===he.VER38&&(e=Nr),(n===he.VER40||n===he.VER41)&&(e=ma),!e){const i=`Cant detect version of spine model ${t.version}`;console.error(i)}this.skeleton=new e.Skeleton(t),this.skeleton.updateWorldTransform(),this.stateData=new e.AnimationStateData(t),this.state=new e.AnimationState(this.stateData)}}return new pa().installLoader(),tt.AttachmentType=Z,tt.BinaryInput=Mn,tt.Color=_,tt.DebugUtils=Mr,tt.IntSet=ns,tt.Interpolation=Si,tt.MathUtils=C,tt.MixBlend=A,tt.MixDirection=J,tt.Pool=An,tt.PositionMode=dt,tt.Pow=yi,tt.PowOut=is,tt.RotateMode=pt,tt.SkeletonBounds=xr,tt.SkeletonBoundsBase=Cn,tt.Spine=wa,tt.SpineBase=tn,tt.SpineDebugRenderer=Tr,tt.SpineMesh=Ai,tt.SpineSprite=Mi,tt.StringSet=ss,tt.TextureAtlas=Fn,tt.TextureAtlasPage=ts,tt.TextureAtlasRegion=es,tt.TextureFilter=Bt,tt.TextureRegion=Vn,tt.TextureWrap=fe,tt.TimeKeeper=Ar,tt.TransformMode=j,tt.Utils=v,tt.Vector2=un,tt.WindowedMean=Cr,tt.filterFromString=Jn,tt.settings=zt,tt.wrapFromString=Er,tt}({},PIXI,PIXI,PIXI,PIXI,PIXI,PIXI); -//# sourceMappingURL=pixi-spine.js.map diff --git a/GDJS/Runtime/pixi-renderers/pixi-spine.umd.js b/GDJS/Runtime/pixi-renderers/pixi-spine.umd.js deleted file mode 100644 index 7fcbf95b10af..000000000000 --- a/GDJS/Runtime/pixi-renderers/pixi-spine.umd.js +++ /dev/null @@ -1,13 +0,0 @@ -/*! - * pixi-spine - v4.0.4 - * Compiled Thu, 25 May 2023 20:30:28 UTC - * - * pixi-spine is licensed under the MIT License. - * http://www.opensource.org/licenses/mit-license - * - * Copyright 2023, Ivan Igorevich Popelyshev , All Rights Reserved -*/this.PIXI=this.PIXI||{},this.PIXI.spine=function(tt,H,dn,wr,br,oe,qe){"use strict";var Z=(c=>(c[c.Region=0]="Region",c[c.BoundingBox=1]="BoundingBox",c[c.Mesh=2]="Mesh",c[c.LinkedMesh=3]="LinkedMesh",c[c.Path=4]="Path",c[c.Point=5]="Point",c[c.Clipping=6]="Clipping",c))(Z||{});class Mn{constructor(t,n=new Array,e=0,i=new DataView(t.buffer)){this.strings=n,this.index=e,this.buffer=i}readByte(){return this.buffer.getInt8(this.index++)}readUnsignedByte(){return this.buffer.getUint8(this.index++)}readShort(){const t=this.buffer.getInt16(this.index);return this.index+=2,t}readInt32(){const t=this.buffer.getInt32(this.index);return this.index+=4,t}readInt(t){let n=this.readByte(),e=n&127;return n&128&&(n=this.readByte(),e|=(n&127)<<7,n&128&&(n=this.readByte(),e|=(n&127)<<14,n&128&&(n=this.readByte(),e|=(n&127)<<21,n&128&&(n=this.readByte(),e|=(n&127)<<28)))),t?e:e>>>1^-(e&1)}readStringRef(){const t=this.readInt(!0);return t==0?null:this.strings[t-1]}readString(){let t=this.readInt(!0);switch(t){case 0:return null;case 1:return""}t--;let n="";for(let e=0;e>4){case 12:case 13:n+=String.fromCharCode((i&31)<<6|this.readByte()&63),e+=2;break;case 14:n+=String.fromCharCode((i&15)<<12|(this.readByte()&63)<<6|this.readByte()&63),e+=3;break;default:n+=String.fromCharCode(i),e++}}return n}readFloat(){const t=this.buffer.getFloat32(this.index);return this.index+=4,t}readBoolean(){return this.readByte()!=0}}var A=(c=>(c[c.setup=0]="setup",c[c.first=1]="first",c[c.replace=2]="replace",c[c.add=3]="add",c))(A||{}),J=(c=>(c[c.mixIn=0]="mixIn",c[c.mixOut=1]="mixOut",c))(J||{}),dt=(c=>(c[c.Fixed=0]="Fixed",c[c.Percent=1]="Percent",c))(dt||{}),pt=(c=>(c[c.Tangent=0]="Tangent",c[c.Chain=1]="Chain",c[c.ChainScale=2]="ChainScale",c))(pt||{}),j=(c=>(c[c.Normal=0]="Normal",c[c.OnlyTranslation=1]="OnlyTranslation",c[c.NoRotationOrReflection=2]="NoRotationOrReflection",c[c.NoScale=3]="NoScale",c[c.NoScaleOrReflection=4]="NoScaleOrReflection",c))(j||{});function Jn(c){switch(c.toLowerCase()){case"nearest":return Bt.Nearest;case"linear":return Bt.Linear;case"mipmap":return Bt.MipMap;case"mipmapnearestnearest":return Bt.MipMapNearestNearest;case"mipmaplinearnearest":return Bt.MipMapLinearNearest;case"mipmapnearestlinear":return Bt.MipMapNearestLinear;case"mipmaplinearlinear":return Bt.MipMapLinearLinear;default:throw new Error(`Unknown texture filter ${c}`)}}function Er(c){switch(c.toLowerCase()){case"mirroredtepeat":return fe.MirroredRepeat;case"clamptoedge":return fe.ClampToEdge;case"repeat":return fe.Repeat;default:throw new Error(`Unknown texture wrap ${c}`)}}var Bt=(c=>(c[c.Nearest=9728]="Nearest",c[c.Linear=9729]="Linear",c[c.MipMap=9987]="MipMap",c[c.MipMapNearestNearest=9984]="MipMapNearestNearest",c[c.MipMapLinearNearest=9985]="MipMapLinearNearest",c[c.MipMapNearestLinear=9986]="MipMapNearestLinear",c[c.MipMapLinearLinear=9987]="MipMapLinearLinear",c))(Bt||{}),fe=(c=>(c[c.MirroredRepeat=33648]="MirroredRepeat",c[c.ClampToEdge=33071]="ClampToEdge",c[c.Repeat=10497]="Repeat",c))(fe||{});class Vn{constructor(){this.size=null,this.names=null,this.values=null,this.renderObject=null}get width(){const t=this.texture;return t.trim?t.trim.width:t.orig.width}get height(){const t=this.texture;return t.trim?t.trim.height:t.orig.height}get u(){return this.texture._uvs.x0}get v(){return this.texture._uvs.y0}get u2(){return this.texture._uvs.x2}get v2(){return this.texture._uvs.y2}get offsetX(){const t=this.texture;return t.trim?t.trim.x:0}get offsetY(){return this.spineOffsetY}get pixiOffsetY(){const t=this.texture;return t.trim?t.trim.y:0}get spineOffsetY(){const t=this.texture;return this.originalHeight-this.height-(t.trim?t.trim.y:0)}get originalWidth(){return this.texture.orig.width}get originalHeight(){return this.texture.orig.height}get x(){return this.texture.frame.x}get y(){return this.texture.frame.y}get rotate(){return this.texture.rotate!==0}get degrees(){return(360-this.texture.rotate*45)%360}}class Sr{constructor(){this.x=0,this.y=0,this.width=0,this.height=0,this.offsetX=0,this.offsetY=0,this.originalWidth=0,this.originalHeight=0,this.rotate=0,this.index=0}}class Fn{constructor(t,n,e){this.pages=new Array,this.regions=new Array,t&&this.addSpineAtlas(t,n,e)}addTexture(t,n){const e=this.pages;let i=null;for(let h=0;h{h.width=parseInt(r[1]),h.height=parseInt(r[2])},l.format=()=>{},l.filter=()=>{h.minFilter=Jn(r[1]),h.magFilter=Jn(r[2])},l.repeat=()=>{r[1].indexOf("x")!=-1&&(h.uWrap=fe.Repeat),r[1].indexOf("y")!=-1&&(h.vWrap=fe.Repeat)},l.pma=()=>{h.pma=r[1]=="true"};const a={};a.xy=()=>{s.x=parseInt(r[1]),s.y=parseInt(r[2])},a.size=()=>{s.width=parseInt(r[1]),s.height=parseInt(r[2])},a.bounds=()=>{s.x=parseInt(r[1]),s.y=parseInt(r[2]),s.width=parseInt(r[3]),s.height=parseInt(r[4])},a.offset=()=>{s.offsetX=parseInt(r[1]),s.offsetY=parseInt(r[2])},a.orig=()=>{s.originalWidth=parseInt(r[1]),s.originalHeight=parseInt(r[2])},a.offsets=()=>{s.offsetX=parseInt(r[1]),s.offsetY=parseInt(r[2]),s.originalWidth=parseInt(r[3]),s.originalHeight=parseInt(r[4])},a.rotate=()=>{const f=r[1];let u=0;f.toLocaleLowerCase()=="true"?u=6:f.toLocaleLowerCase()=="false"?u=0:u=(720-parseFloat(f))%360/45,s.rotate=u},a.index=()=>{s.index=parseInt(r[1])};let o=i.readLine();for(;o!=null&&o.trim().length==0;)o=i.readLine();for(;!(o==null||o.trim().length==0||i.readEntry(r,o)==0);)o=i.readLine();const d=()=>{for(;;){if(o==null)return e&&e(this);if(o.trim().length==0)h=null,o=i.readLine();else if(h===null){for(h=new ts,h.name=o.trim();i.readEntry(r,o=i.readLine())!=0;){const f=l[r[0]];f&&f()}this.pages.push(h),n(h.name,f=>{if(f===null)return this.pages.splice(this.pages.indexOf(h),1),e&&e(null);h.baseTexture=f,h.pma&&(f.alphaMode=H.ALPHA_MODES.PMA),f.valid||f.setSize(h.width,h.height),h.setFilters(),(!h.width||!h.height)&&(h.width=f.realWidth,h.height=f.realHeight,(!h.width||!h.height)&&console.log(`ERROR spine atlas page ${h.name}: meshes wont work if you dont specify size in atlas (http://www.html5gamedevs.com/topic/18888-pixi-spines-and-meshes/?p=107121)`)),d()});break}else{s=new Sr;const f=new es;f.name=o,f.page=h;let u=null,m=null;for(;;){const p=i.readEntry(r,o=i.readLine());if(p==0)break;const S=a[r[0]];if(S)S();else{u==null&&(u=[],m=[]),u.push(r[0]);const y=[];for(let M=0;M=this.lines.length?null:this.lines[this.index++]}readEntry(t,n){if(n==null||(n=n.trim(),n.length==0))return 0;const e=n.indexOf(":");if(e==-1)return 0;t[0]=n.substr(0,e).trim();for(let i=1,r=e+1;;i++){const h=n.indexOf(",",r);if(h==-1)return t[i]=n.substr(r).trim(),i;if(t[i]=n.substr(r,h-r).trim(),r=h+1,i==4)return 4}}}class ts{constructor(){this.minFilter=Bt.Nearest,this.magFilter=Bt.Nearest,this.uWrap=fe.ClampToEdge,this.vWrap=fe.ClampToEdge}setFilters(){const t=this.baseTexture,n=this.minFilter;n==Bt.Linear?t.scaleMode=H.SCALE_MODES.LINEAR:this.minFilter==Bt.Nearest?t.scaleMode=H.SCALE_MODES.NEAREST:(t.mipmap=H.MIPMAP_MODES.POW2,n==Bt.MipMapNearestNearest?t.scaleMode=H.SCALE_MODES.NEAREST:t.scaleMode=H.SCALE_MODES.LINEAR)}}class es extends Vn{}class ns{constructor(){this.array=new Array}add(t){const n=this.contains(t);return this.array[t|0]=t|0,!n}contains(t){return this.array[t|0]!=null}remove(t){this.array[t|0]=void 0}clear(){this.array.length=0}}class ss{constructor(){this.entries={},this.size=0}add(t){const n=this.entries[t];return this.entries[t]=!0,n?!1:(this.size++,!0)}addAll(t){const n=this.size;for(let e=0,i=t.length;e1&&(this.r=1),this.g<0?this.g=0:this.g>1&&(this.g=1),this.b<0?this.b=0:this.b>1&&(this.b=1),this.a<0?this.a=0:this.a>1&&(this.a=1),this}static rgba8888ToColor(c,t){c.r=((t&4278190080)>>>24)/255,c.g=((t&16711680)>>>16)/255,c.b=((t&65280)>>>8)/255,c.a=(t&255)/255}static rgb888ToColor(c,t){c.r=((t&16711680)>>>16)/255,c.g=((t&65280)>>>8)/255,c.b=(t&255)/255}static fromString(c){return new Je().setFromString(c)}};let _=Je;_.WHITE=new Je(1,1,1,1),_.RED=new Je(1,0,0,1),_.GREEN=new Je(0,1,0,1),_.BLUE=new Je(0,0,1,1),_.MAGENTA=new Je(1,0,1,1);const Fe=class{static clamp(c,t,n){return cn?n:c}static cosDeg(c){return Math.cos(c*Fe.degRad)}static sinDeg(c){return Math.sin(c*Fe.degRad)}static signum(c){return Math.sign(c)}static toInt(c){return c>0?Math.floor(c):Math.ceil(c)}static cbrt(c){const t=Math.pow(Math.abs(c),.3333333333333333);return c<0?-t:t}static randomTriangular(c,t){return Fe.randomTriangularWith(c,t,(c+t)*.5)}static randomTriangularWith(c,t,n){const e=Math.random(),i=t-c;return e<=(n-c)/i?c+Math.sqrt(e*i*(n-c)):t-Math.sqrt((1-e)*i*(t-n))}static isPowerOfTwo(c){return c&&(c&c-1)===0}};let C=Fe;C.PI=3.1415927,C.PI2=Fe.PI*2,C.radiansToDegrees=180/Fe.PI,C.radDeg=Fe.radiansToDegrees,C.degreesToRadians=Fe.PI/180,C.degRad=Fe.degreesToRadians;class Si{apply(t,n,e){return t+(n-t)*this.applyInternal(e)}}class yi extends Si{constructor(t){super(),this.power=2,this.power=t}applyInternal(t){return t<=.5?Math.pow(t*2,this.power)/2:Math.pow((t-1)*2,this.power)/(this.power%2==0?-2:2)+1}}class is extends yi{applyInternal(t){return Math.pow(t-1,this.power)*(this.power%2==0?-1:1)+1}}const fn=class{static arrayCopy(c,t,n,e,i){for(let r=t,h=e;r=t?c:fn.setArraySize(c,t,n)}static newArray(c,t){const n=new Array(c);for(let e=0;e0?this.items.pop():this.instantiator()}free(t){t.reset&&t.reset(),this.items.push(t)}freeAll(t){for(let n=0;nthis.maxDelta&&(this.delta=this.maxDelta),this.lastTime=t,this.frameCount++,this.frameTime>1&&(this.framesPerSecond=this.frameCount/this.frameTime,this.frameTime=0,this.frameCount=0)}}class Cr{constructor(t=32){this.addedValues=0,this.lastValue=0,this.mean=0,this.dirty=!0,this.values=new Array(t)}hasEnoughData(){return this.addedValues>=this.values.length}addValue(t){this.addedValuesthis.values.length-1&&(this.lastValue=0),this.dirty=!0}getMean(){if(this.hasEnoughData()){if(this.dirty){let t=0;for(let n=0;nv.newFloatArray(16))}update(t,n){if(!t)throw new Error("skeleton cannot be null.");const e=this.boundingBoxes,i=this.polygons,r=this.polygonPool,h=t.slots,l=h.length;e.length=0,r.freeAll(i),i.length=0;for(let s=0;s=this.minX&&t<=this.maxX&&n>=this.minY&&n<=this.maxY}aabbIntersectsSegment(t,n,e,i){const r=this.minX,h=this.minY,l=this.maxX,s=this.maxY;if(t<=r&&e<=r||n<=h&&i<=h||t>=l&&e>=l||n>=s&&i>=s)return!1;const a=(i-n)/(e-t);let o=a*(r-t)+n;if(o>h&&oh&&or&&dr&&dt.minX&&this.minYt.minY}containsPoint(t,n){const e=this.polygons;for(let i=0,r=e.length;i=e||o=e){const d=i[s];d+(e-a)/(o-a)*(i[h]-d)=d&&p<=m||p>=m&&p<=d)&&(p>=n&&p<=i||p>=i&&p<=n)){const S=(o*w-a*x)/b;if((S>=f&&S<=g||S>=g&&S<=f)&&(S>=e&&S<=r||S>=r&&S<=e))return!0}d=m,f=g}return!1}getPolygon(t){if(!t)throw new Error("boundingBox cannot be null.");const n=this.boundingBoxes.indexOf(t);return n==-1?null:this.polygons[n]}getWidth(){return this.maxX-this.minX}getHeight(){return this.maxY-this.minY}}const zt={yDown:!0,FAIL_ON_NON_EXISTING_SKIN:!1,GLOBAL_AUTO_UPDATE:!0,GLOBAL_DELAY_LIMIT:0},Ue=[0,0,0];class Mi extends wr.Sprite{constructor(){super(...arguments),this.region=null,this.attachment=null}}class Ai extends br.SimpleMesh{constructor(t,n,e,i,r){super(t,n,e,i,r),this.region=null,this.attachment=null}}const Ci=class extends dn.Container{constructor(c){if(super(),!c)throw new Error("The spineData param is required.");if(typeof c=="string")throw new Error('spineData param cant be string. Please use spine.Spine.fromAtlas("YOUR_RESOURCE_NAME") from now on.');this.spineData=c,this.createSkeleton(c),this.slotContainers=[],this.tempClipContainers=[];for(let t=0,n=this.skeleton.slots.length;tt&&(c=t),this.state.update(c),this.state.apply(this.skeleton),!this.skeleton)return;this.skeleton.updateWorldTransform();const n=this.skeleton.slots,e=this.color;let i=null,r=null;e?(i=e.light,r=e.dark):i=this.tintRgb;for(let o=0,d=n.length;o0;r--)n.bones.children[r-1].destroy({children:!0,texture:!0,baseTexture:!0});const e=t.scale.x||t.scale.y||1,i=this.lineWidth/e;this.drawBones&&this.drawBonesFunc(t,n,i,e),this.drawPaths&&this.drawPathsFunc(t,n,i),this.drawBoundingBoxes&&this.drawBoundingBoxesFunc(t,n,i),this.drawClipping&&this.drawClippingFunc(t,n,i),(this.drawMeshHull||this.drawMeshTriangles)&&this.drawMeshHullAndMeshTriangles(t,n,i),this.drawRegionAttachments&&this.drawRegionAttachmentsFunc(t,n,i)}drawBonesFunc(t,n,e,i){const r=t.skeleton,h=r.x,l=r.y,s=r.bones;n.skeletonXY.lineStyle(e,this.skeletonXYColor,1);for(let o=0,d=s.length;ox&&gx&&g>E?F=-I:mE?F=I:g===E&&mx?F=-90*k:m===x&&gE&&(F=0),R.rotation=F,R.lineStyle(e+V/2.4,this.bonesColor,1),R.beginFill(0,.6),R.drawCircle(0,M,V*1.2),R.endFill()}const a=e*3;n.skeletonXY.moveTo(h-a,l-a),n.skeletonXY.lineTo(h+a,l+a),n.skeletonXY.moveTo(h+a,l-a),n.skeletonXY.lineTo(h-a,l+a)}drawRegionAttachmentsFunc(t,n,e){const r=t.skeleton.slots;n.regionAttachmentsShape.lineStyle(e,this.regionAttachmentsColor,1);for(let h=0,l=r.length;h0){u=(u>>1)*2;let m=d[u-2],g=d[u-1];for(let x=0,E=u;x{if(n.boundingBoxesPolygon.lineStyle(e,this.boundingBoxesPolygonColor,1),n.boundingBoxesPolygon.beginFill(this.boundingBoxesPolygonColor,.1),a<3)throw new Error("Polygon must contain at least 3 vertices");const o=[],d=e*2;for(let f=0,u=l.length;f{r=o,h=d});let s;const a=o=>{o||h(`Something went terribly wrong loading a spine .atlas file -Most likely your texture failed to load.`),r(s)};if(e.image||e.images){const o=Object.assign(e.image?{default:e.image}:{},e.images);s=new Fn(c,(d,f)=>{const u=o[d]||o.default;u&&u.baseTexture?f(u.baseTexture):f(u)},a)}else s=new Fn(c,Ti(n,i,e.imageMetadata),a);return await l},unload(c){c.dispose()}}},Ti=(c,t,n)=>async(e,i)=>{const r=H.utils.path.normalize([...t.split(H.utils.path.sep),e].join(H.utils.path.sep)),h=await c.load({src:r,data:n});i(h.baseTexture)};H.extensions.add(kr);function ki(c){return c.hasOwnProperty("bones")}function Ir(c){return c instanceof ArrayBuffer}class Rr{constructor(){}installLoader(){const t=this,n={extension:H.ExtensionType.Asset,loader:{extension:{type:H.ExtensionType.LoadParser,priority:qe.LoaderParserPriority.Normal},test(e){return qe.checkExtension(e,".skel")},async load(e){return await(await H.settings.ADAPTER.fetch(e)).arrayBuffer()},testParse(e,i){var s;const r=qe.checkExtension(i.src,".json")&&ki(e),h=qe.checkExtension(i.src,".skel")&&Ir(e),l=((s=i.data)==null?void 0:s.spineAtlas)===!1;return Promise.resolve(r&&!l||h)},async parse(e,i,r){var w;const h=H.utils.path.extname(i.src).toLowerCase(),l=H.utils.path.basename(i.src,h);let s=H.utils.path.dirname(i.src);s&&s.lastIndexOf("/")!==s.length-1&&(s+="/");const a=qe.checkExtension(i.src,".json")&&ki(e);let o=null,d=e;a?o=t.createJsonParser():(o=t.createBinaryParser(),d=new Uint8Array(e));const f=i.data||{},u=(w=f==null?void 0:f.spineSkeletonScale)!=null?w:null;u&&(o.scale=u);const m=f.spineAtlas;if(m&&m.pages)return t.parseData(o,m,d);const g=f.atlasRawData;if(g){let b=null,p=null;const S=new Promise((T,k)=>{b=T,p=k}),y=new Fn(g,Ti(r,s,f.imageMetadata),T=>{T||p(`Something went terribly wrong loading a spine .atlas file -Most likely your texture failed to load.`),b(y)}),M=await S;return t.parseData(o,M,d)}let x=f.spineAtlasFile;x||(x=`${s+l}.atlas`);const E=await r.load({src:x,data:f,alias:f.spineAtlasAlias});return t.parseData(o,E,d)}}};return H.extensions.add(n),n}}let rs=class{constructor(t){if(t==null)throw new Error("name cannot be null.");this.name=t}};const Ii=class extends rs{constructor(t){super(t),this.id=(Ii.nextID++&65535)<<11,this.worldVerticesLength=0,this.deformAttachment=this}computeWorldVerticesOld(t,n){this.computeWorldVertices(t,0,this.worldVerticesLength,n,0,2)}computeWorldVertices(t,n,e,i,r,h){e=r+(e>>1)*h;const l=t.bone.skeleton,s=t.deform;let a=this.vertices;const o=this.bones;if(o==null){s.length>0&&(a=s);const m=t.bone.matrix,g=m.tx,x=m.ty,E=m.a,w=m.c,b=m.b,p=m.d;for(let S=n,y=r;y0&&(n%=this.duration));const a=this.timelines;for(let o=0,d=a.length;o>>1;for(;;){if(t[(h+1)*e]<=n?i=h+1:r=h,i==r)return(i+1)*e;h=i+r>>>1}}static linearSearch(t,n,e){for(let i=0,r=t.length-e;i<=r;i+=e)if(t[i]>n)return i;return-1}};var Pi=(c=>(c[c.rotate=0]="rotate",c[c.translate=1]="translate",c[c.scale=2]="scale",c[c.shear=3]="shear",c[c.attachment=4]="attachment",c[c.color=5]="color",c[c.deform=6]="deform",c[c.event=7]="event",c[c.drawOrder=8]="drawOrder",c[c.ikConstraint=9]="ikConstraint",c[c.transformConstraint=10]="transformConstraint",c[c.pathConstraintPosition=11]="pathConstraintPosition",c[c.pathConstraintSpacing=12]="pathConstraintSpacing",c[c.pathConstraintMix=13]="pathConstraintMix",c[c.twoColor=14]="twoColor",c))(Pi||{});const St=class{constructor(t){if(t<=0)throw new Error(`frameCount must be > 0: ${t}`);this.curves=v.newFloatArray((t-1)*St.BEZIER_SIZE)}getFrameCount(){return this.curves.length/St.BEZIER_SIZE+1}setLinear(t){this.curves[t*St.BEZIER_SIZE]=St.LINEAR}setStepped(t){this.curves[t*St.BEZIER_SIZE]=St.STEPPED}getCurveType(t){const n=t*St.BEZIER_SIZE;if(n==this.curves.length)return St.LINEAR;const e=this.curves[n];return e==St.LINEAR?St.LINEAR:e==St.STEPPED?St.STEPPED:St.BEZIER}setCurve(t,n,e,i,r){const h=(-n*2+i)*.03,l=(-e*2+r)*.03,s=((n-i)*3+1)*.006,a=((e-r)*3+1)*.006;let o=h*2+s,d=l*2+a,f=n*.3+h+s*.16666667,u=e*.3+l+a*.16666667,m=t*St.BEZIER_SIZE;const g=this.curves;g[m++]=St.BEZIER;let x=f,E=u;for(let w=m+St.BEZIER_SIZE-1;m=n){let o,d;return i==s?(o=0,d=0):(o=e[i-2],d=e[i-1]),d+(e[i+1]-d)*(n-o)/(h-o)}const l=e[i-1];return l+(1-l)*(n-h)/(1-h)}};let Ht=St;Ht.LINEAR=0,Ht.STEPPED=1,Ht.BEZIER=2,Ht.BEZIER_SIZE=10*2-1;const He=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t<<1)}getPropertyId(){return(0<<24)+this.boneIndex}setFrame(t,n,e){t<<=1,this.frames[t]=n,this.frames[t+He.ROTATION]=e}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-He.ENTRIES]){let g=s[s.length+He.PREV_ROTATION];switch(h){case A.setup:a.rotation=a.data.rotation+g*r;break;case A.first:case A.replace:g+=a.data.rotation-a.rotation,g-=(16384-(16384.499999999996-g/360|0))*360;case A.add:a.rotation+=g*r}return}const o=Et.binarySearch(s,e,He.ENTRIES),d=s[o+He.PREV_ROTATION],f=s[o],u=this.getCurvePercent((o>>1)-1,1-(e-f)/(s[o+He.PREV_TIME]-f));let m=s[o+He.ROTATION]-d;switch(m=d+(m-(16384-(16384.499999999996-m/360|0))*360)*u,h){case A.setup:a.rotation=a.data.rotation+(m-(16384-(16384.499999999996-m/360|0))*360)*r;break;case A.first:case A.replace:m+=a.data.rotation-a.rotation;case A.add:a.rotation+=(m-(16384-(16384.499999999996-m/360|0))*360)*r}}};let Vt=He;Vt.ENTRIES=2,Vt.PREV_TIME=-2,Vt.PREV_ROTATION=-1,Vt.ROTATION=1;const Dt=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*Dt.ENTRIES)}getPropertyId(){return(1<<24)+this.boneIndex}setFrame(t,n,e,i){t*=Dt.ENTRIES,this.frames[t]=n,this.frames[t+Dt.X]=e,this.frames[t+Dt.Y]=i}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-Dt.ENTRIES])o=s[s.length+Dt.PREV_X],d=s[s.length+Dt.PREV_Y];else{const f=Et.binarySearch(s,e,Dt.ENTRIES);o=s[f+Dt.PREV_X],d=s[f+Dt.PREV_Y];const u=s[f],m=this.getCurvePercent(f/Dt.ENTRIES-1,1-(e-u)/(s[f+Dt.PREV_TIME]-u));o+=(s[f+Dt.X]-o)*m,d+=(s[f+Dt.Y]-d)*m}switch(h){case A.setup:a.x=a.data.x+o*r,a.y=a.data.y+d*r;break;case A.first:case A.replace:a.x+=(a.data.x+o-a.x)*r,a.y+=(a.data.y+d-a.y)*r;break;case A.add:a.x+=o*r,a.y+=d*r}}};let Jt=Dt;Jt.ENTRIES=3,Jt.PREV_TIME=-3,Jt.PREV_X=-2,Jt.PREV_Y=-1,Jt.X=1,Jt.Y=2;let te=class extends Jt{constructor(t){super(t)}getPropertyId(){return(2<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-te.ENTRIES])o=s[s.length+te.PREV_X]*a.data.scaleX,d=s[s.length+te.PREV_Y]*a.data.scaleY;else{const f=Et.binarySearch(s,e,te.ENTRIES);o=s[f+te.PREV_X],d=s[f+te.PREV_Y];const u=s[f],m=this.getCurvePercent(f/te.ENTRIES-1,1-(e-u)/(s[f+te.PREV_TIME]-u));o=(o+(s[f+te.X]-o)*m)*a.data.scaleX,d=(d+(s[f+te.Y]-d)*m)*a.data.scaleY}if(r==1)h==A.add?(a.scaleX+=o-a.data.scaleX,a.scaleY+=d-a.data.scaleY):(a.scaleX=o,a.scaleY=d);else{let f=0,u=0;if(l==J.mixOut)switch(h){case A.setup:f=a.data.scaleX,u=a.data.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.first:case A.replace:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.add:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-a.data.scaleX)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-a.data.scaleY)*r}else switch(h){case A.setup:f=Math.abs(a.data.scaleX)*C.signum(o),u=Math.abs(a.data.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.first:case A.replace:f=Math.abs(a.scaleX)*C.signum(o),u=Math.abs(a.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.add:f=C.signum(o),u=C.signum(d),a.scaleX=Math.abs(a.scaleX)*f+(o-Math.abs(a.data.scaleX)*f)*r,a.scaleY=Math.abs(a.scaleY)*u+(d-Math.abs(a.data.scaleY)*u)*r}}}},ee=class extends Jt{constructor(t){super(t)}getPropertyId(){return(3<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(!a.active)return;if(e=s[s.length-ee.ENTRIES])o=s[s.length+ee.PREV_X],d=s[s.length+ee.PREV_Y];else{const f=Et.binarySearch(s,e,ee.ENTRIES);o=s[f+ee.PREV_X],d=s[f+ee.PREV_Y];const u=s[f],m=this.getCurvePercent(f/ee.ENTRIES-1,1-(e-u)/(s[f+ee.PREV_TIME]-u));o=o+(s[f+ee.X]-o)*m,d=d+(s[f+ee.Y]-d)*m}switch(h){case A.setup:a.shearX=a.data.shearX+o*r,a.shearY=a.data.shearY+d*r;break;case A.first:case A.replace:a.shearX+=(a.data.shearX+o-a.shearX)*r,a.shearY+=(a.data.shearY+d-a.shearY)*r;break;case A.add:a.shearX+=o*r,a.shearY+=d*r}}};const ft=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*ft.ENTRIES)}getPropertyId(){return(5<<24)+this.slotIndex}setFrame(t,n,e,i,r,h){t*=ft.ENTRIES,this.frames[t]=n,this.frames[t+ft.R]=e,this.frames[t+ft.G]=i,this.frames[t+ft.B]=r,this.frames[t+ft.A]=h}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=this.frames;if(e=a[a.length-ft.ENTRIES]){const m=a.length;o=a[m+ft.PREV_R],d=a[m+ft.PREV_G],f=a[m+ft.PREV_B],u=a[m+ft.PREV_A]}else{const m=Et.binarySearch(a,e,ft.ENTRIES);o=a[m+ft.PREV_R],d=a[m+ft.PREV_G],f=a[m+ft.PREV_B],u=a[m+ft.PREV_A];const g=a[m],x=this.getCurvePercent(m/ft.ENTRIES-1,1-(e-g)/(a[m+ft.PREV_TIME]-g));o+=(a[m+ft.R]-o)*x,d+=(a[m+ft.G]-d)*x,f+=(a[m+ft.B]-f)*x,u+=(a[m+ft.A]-u)*x}if(r==1)s.color.set(o,d,f,u);else{const m=s.color;h==A.setup&&m.setFromColor(s.data.color),m.add((o-m.r)*r,(d-m.g)*r,(f-m.b)*r,(u-m.a)*r)}}};let Lt=ft;Lt.ENTRIES=5,Lt.PREV_TIME=-5,Lt.PREV_R=-4,Lt.PREV_G=-3,Lt.PREV_B=-2,Lt.PREV_A=-1,Lt.R=1,Lt.G=2,Lt.B=3,Lt.A=4;const nt=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*nt.ENTRIES)}getPropertyId(){return(14<<24)+this.slotIndex}setFrame(t,n,e,i,r,h,l,s,a){t*=nt.ENTRIES,this.frames[t]=n,this.frames[t+nt.R]=e,this.frames[t+nt.G]=i,this.frames[t+nt.B]=r,this.frames[t+nt.A]=h,this.frames[t+nt.R2]=l,this.frames[t+nt.G2]=s,this.frames[t+nt.B2]=a}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=this.frames;if(e=a[a.length-nt.ENTRIES]){const E=a.length;o=a[E+nt.PREV_R],d=a[E+nt.PREV_G],f=a[E+nt.PREV_B],u=a[E+nt.PREV_A],m=a[E+nt.PREV_R2],g=a[E+nt.PREV_G2],x=a[E+nt.PREV_B2]}else{const E=Et.binarySearch(a,e,nt.ENTRIES);o=a[E+nt.PREV_R],d=a[E+nt.PREV_G],f=a[E+nt.PREV_B],u=a[E+nt.PREV_A],m=a[E+nt.PREV_R2],g=a[E+nt.PREV_G2],x=a[E+nt.PREV_B2];const w=a[E],b=this.getCurvePercent(E/nt.ENTRIES-1,1-(e-w)/(a[E+nt.PREV_TIME]-w));o+=(a[E+nt.R]-o)*b,d+=(a[E+nt.G]-d)*b,f+=(a[E+nt.B]-f)*b,u+=(a[E+nt.A]-u)*b,m+=(a[E+nt.R2]-m)*b,g+=(a[E+nt.G2]-g)*b,x+=(a[E+nt.B2]-x)*b}if(r==1)s.color.set(o,d,f,u),s.darkColor.set(m,g,x,1);else{const E=s.color,w=s.darkColor;h==A.setup&&(E.setFromColor(s.data.color),w.setFromColor(s.data.darkColor)),E.add((o-E.r)*r,(d-E.g)*r,(f-E.b)*r,(u-E.a)*r),w.add((m-w.r)*r,(g-w.g)*r,(x-w.b)*r,0)}}};let yt=nt;yt.ENTRIES=8,yt.PREV_TIME=-8,yt.PREV_R=-7,yt.PREV_G=-6,yt.PREV_B=-5,yt.PREV_A=-4,yt.PREV_R2=-3,yt.PREV_G2=-2,yt.PREV_B2=-1,yt.R=1,yt.G=2,yt.B=3,yt.A=4,yt.R2=5,yt.G2=6,yt.B2=7;let en=class{constructor(t){this.frames=v.newFloatArray(t),this.attachmentNames=new Array(t)}getPropertyId(){return(4<<24)+this.slotIndex}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.attachmentNames[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;if(l==J.mixOut){h==A.setup&&this.setAttachment(t,s,s.data.attachmentName);return}const a=this.frames;if(e=a[a.length-1]?o=a.length-1:o=Et.binarySearch(a,e,1)-1;const d=this.attachmentNames[o];t.slots[this.slotIndex].setAttachment(d==null?null:t.getAttachment(this.slotIndex,d))}setAttachment(t,n,e){n.setAttachment(e==null?null:t.getAttachment(this.slotIndex,e))}},Vi=null,hs=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t),this.frameVertices=new Array(t),Vi==null&&(Vi=v.newFloatArray(64))}getPropertyId(){return(6<<27)+Number(this.attachment.id)+this.slotIndex}setFrame(t,n,e){this.frames[t]=n,this.frameVertices[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=s.getAttachment();if(!(a instanceof ze)||a.deformAttachment!=this.attachment)return;const o=s.deform;o.length==0&&(h=A.setup);const d=this.frameVertices,f=d[0].length,u=this.frames;if(e=u[u.length-1]){const p=d[u.length-1];if(r==1)if(h==A.add){const S=a;if(S.bones==null){const y=S.vertices;for(let M=0;Me)this.apply(t,n,Number.MAX_VALUE,i,r,h,l),n=-1;else if(n>=s[a-1])return;if(e0&&s[o-1]==d;)o--}for(;o=s[o];o++)i.push(this.events[o])}},xn=class{constructor(t){this.frames=v.newFloatArray(t),this.drawOrders=new Array(t)}getPropertyId(){return 8<<24}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.drawOrders[t]=e}apply(t,n,e,i,r,h,l){const s=t.drawOrder,a=t.slots;if(l==J.mixOut&&h==A.setup){v.arrayCopy(t.slots,0,t.drawOrder,0,t.slots.length);return}const o=this.frames;if(e=o[o.length-1]?d=o.length-1:d=Et.binarySearch(o,e)-1;const f=this.drawOrders[d];if(f==null)v.arrayCopy(a,0,s,0,a.length);else for(let u=0,m=f.length;u=s[s.length-at.ENTRIES]){h==A.setup?(a.mix=a.data.mix+(s[s.length+at.PREV_MIX]-a.data.mix)*r,a.softness=a.data.softness+(s[s.length+at.PREV_SOFTNESS]-a.data.softness)*r,l==J.mixOut?(a.bendDirection=a.data.bendDirection,a.compress=a.data.compress,a.stretch=a.data.stretch):(a.bendDirection=s[s.length+at.PREV_BEND_DIRECTION],a.compress=s[s.length+at.PREV_COMPRESS]!=0,a.stretch=s[s.length+at.PREV_STRETCH]!=0)):(a.mix+=(s[s.length+at.PREV_MIX]-a.mix)*r,a.softness+=(s[s.length+at.PREV_SOFTNESS]-a.softness)*r,l==J.mixIn&&(a.bendDirection=s[s.length+at.PREV_BEND_DIRECTION],a.compress=s[s.length+at.PREV_COMPRESS]!=0,a.stretch=s[s.length+at.PREV_STRETCH]!=0));return}const o=Et.binarySearch(s,e,at.ENTRIES),d=s[o+at.PREV_MIX],f=s[o+at.PREV_SOFTNESS],u=s[o],m=this.getCurvePercent(o/at.ENTRIES-1,1-(e-u)/(s[o+at.PREV_TIME]-u));h==A.setup?(a.mix=a.data.mix+(d+(s[o+at.MIX]-d)*m-a.data.mix)*r,a.softness=a.data.softness+(f+(s[o+at.SOFTNESS]-f)*m-a.data.softness)*r,l==J.mixOut?(a.bendDirection=a.data.bendDirection,a.compress=a.data.compress,a.stretch=a.data.stretch):(a.bendDirection=s[o+at.PREV_BEND_DIRECTION],a.compress=s[o+at.PREV_COMPRESS]!=0,a.stretch=s[o+at.PREV_STRETCH]!=0)):(a.mix+=(d+(s[o+at.MIX]-d)*m-a.mix)*r,a.softness+=(f+(s[o+at.SOFTNESS]-f)*m-a.softness)*r,l==J.mixIn&&(a.bendDirection=s[o+at.PREV_BEND_DIRECTION],a.compress=s[o+at.PREV_COMPRESS]!=0,a.stretch=s[o+at.PREV_STRETCH]!=0))}};let Ft=at;Ft.ENTRIES=6,Ft.PREV_TIME=-6,Ft.PREV_MIX=-5,Ft.PREV_SOFTNESS=-4,Ft.PREV_BEND_DIRECTION=-3,Ft.PREV_COMPRESS=-2,Ft.PREV_STRETCH=-1,Ft.MIX=1,Ft.SOFTNESS=2,Ft.BEND_DIRECTION=3,Ft.COMPRESS=4,Ft.STRETCH=5;const ut=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*ut.ENTRIES)}getPropertyId(){return(10<<24)+this.transformConstraintIndex}setFrame(t,n,e,i,r,h){t*=ut.ENTRIES,this.frames[t]=n,this.frames[t+ut.ROTATE]=e,this.frames[t+ut.TRANSLATE]=i,this.frames[t+ut.SCALE]=r,this.frames[t+ut.SHEAR]=h}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.transformConstraints[this.transformConstraintIndex];if(!a.active)return;if(e=s[s.length-ut.ENTRIES]){const m=s.length;o=s[m+ut.PREV_ROTATE],d=s[m+ut.PREV_TRANSLATE],f=s[m+ut.PREV_SCALE],u=s[m+ut.PREV_SHEAR]}else{const m=Et.binarySearch(s,e,ut.ENTRIES);o=s[m+ut.PREV_ROTATE],d=s[m+ut.PREV_TRANSLATE],f=s[m+ut.PREV_SCALE],u=s[m+ut.PREV_SHEAR];const g=s[m],x=this.getCurvePercent(m/ut.ENTRIES-1,1-(e-g)/(s[m+ut.PREV_TIME]-g));o+=(s[m+ut.ROTATE]-o)*x,d+=(s[m+ut.TRANSLATE]-d)*x,f+=(s[m+ut.SCALE]-f)*x,u+=(s[m+ut.SHEAR]-u)*x}if(h==A.setup){const m=a.data;a.rotateMix=m.rotateMix+(o-m.rotateMix)*r,a.translateMix=m.translateMix+(d-m.translateMix)*r,a.scaleMix=m.scaleMix+(f-m.scaleMix)*r,a.shearMix=m.shearMix+(u-m.shearMix)*r}else a.rotateMix+=(o-a.rotateMix)*r,a.translateMix+=(d-a.translateMix)*r,a.scaleMix+=(f-a.scaleMix)*r,a.shearMix+=(u-a.shearMix)*r}};let _t=ut;_t.ENTRIES=5,_t.PREV_TIME=-5,_t.PREV_ROTATE=-4,_t.PREV_TRANSLATE=-3,_t.PREV_SCALE=-2,_t.PREV_SHEAR=-1,_t.ROTATE=1,_t.TRANSLATE=2,_t.SCALE=3,_t.SHEAR=4;const ue=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*ue.ENTRIES)}getPropertyId(){return(11<<24)+this.pathConstraintIndex}setFrame(t,n,e){t*=ue.ENTRIES,this.frames[t]=n,this.frames[t+ue.VALUE]=e}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(!a.active)return;if(e=s[s.length-ue.ENTRIES])o=s[s.length+ue.PREV_VALUE];else{const d=Et.binarySearch(s,e,ue.ENTRIES);o=s[d+ue.PREV_VALUE];const f=s[d],u=this.getCurvePercent(d/ue.ENTRIES-1,1-(e-f)/(s[d+ue.PREV_TIME]-f));o+=(s[d+ue.VALUE]-o)*u}h==A.setup?a.position=a.data.position+(o-a.data.position)*r:a.position+=(o-a.position)*r}};let Te=ue;Te.ENTRIES=2,Te.PREV_TIME=-2,Te.PREV_VALUE=-1,Te.VALUE=1;let ke=class extends Te{constructor(t){super(t)}getPropertyId(){return(12<<24)+this.pathConstraintIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(!a.active)return;if(e=s[s.length-ke.ENTRIES])o=s[s.length+ke.PREV_VALUE];else{const d=Et.binarySearch(s,e,ke.ENTRIES);o=s[d+ke.PREV_VALUE];const f=s[d],u=this.getCurvePercent(d/ke.ENTRIES-1,1-(e-f)/(s[d+ke.PREV_TIME]-f));o+=(s[d+ke.VALUE]-o)*u}h==A.setup?a.spacing=a.data.spacing+(o-a.data.spacing)*r:a.spacing+=(o-a.spacing)*r}};const Ot=class extends Ht{constructor(t){super(t),this.frames=v.newFloatArray(t*Ot.ENTRIES)}getPropertyId(){return(13<<24)+this.pathConstraintIndex}setFrame(t,n,e,i){t*=Ot.ENTRIES,this.frames[t]=n,this.frames[t+Ot.ROTATE]=e,this.frames[t+Ot.TRANSLATE]=i}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(!a.active)return;if(e=s[s.length-Ot.ENTRIES])o=s[s.length+Ot.PREV_ROTATE],d=s[s.length+Ot.PREV_TRANSLATE];else{const f=Et.binarySearch(s,e,Ot.ENTRIES);o=s[f+Ot.PREV_ROTATE],d=s[f+Ot.PREV_TRANSLATE];const u=s[f],m=this.getCurvePercent(f/Ot.ENTRIES-1,1-(e-u)/(s[f+Ot.PREV_TIME]-u));o+=(s[f+Ot.ROTATE]-o)*m,d+=(s[f+Ot.TRANSLATE]-d)*m}h==A.setup?(a.rotateMix=a.data.rotateMix+(o-a.data.rotateMix)*r,a.translateMix=a.data.translateMix+(d-a.data.translateMix)*r):(a.rotateMix+=(o-a.rotateMix)*r,a.translateMix+=(d-a.translateMix)*r)}};let me=Ot;me.ENTRIES=3,me.PREV_TIME=-3,me.PREV_ROTATE=-2,me.PREV_TRANSLATE=-1,me.ROTATE=1,me.TRANSLATE=2;const mt=class{constructor(t){this.tracks=new Array,this.timeScale=1,this.unkeyedState=0,this.events=new Array,this.listeners=new Array,this.queue=new fs(this),this.propertyIDs=new ns,this.animationsChanged=!1,this.trackEntryPool=new An(()=>new Xn),this.data=t}update(t){t*=this.timeScale;const n=this.tracks;for(let e=0,i=n.length;e0){if(r.delay-=h,r.delay>0)continue;h=-r.delay,r.delay=0}let l=r.next;if(l!=null){const s=r.trackLast-l.delay;if(s>=0){for(l.delay=0,l.trackTime+=r.timeScale==0?0:(s/r.timeScale+t)*l.timeScale,r.trackTime+=h,this.setCurrent(e,l,!0);l.mixingFrom!=null;)l.mixTime+=t,l=l.mixingFrom;continue}}else if(r.trackLast>=r.trackEnd&&r.mixingFrom==null){n[e]=null,this.queue.end(r),this.disposeNext(r);continue}if(r.mixingFrom!=null&&this.updateMixingFrom(r,t)){let s=r.mixingFrom;for(r.mixingFrom=null,s!=null&&(s.mixingTo=null);s!=null;)this.queue.end(s),s=s.mixingFrom}r.trackTime+=h}this.queue.drain()}updateMixingFrom(t,n){const e=t.mixingFrom;if(e==null)return!0;const i=this.updateMixingFrom(e,n);return e.animationLast=e.nextAnimationLast,e.trackLast=e.nextTrackLast,t.mixTime>0&&t.mixTime>=t.mixDuration?((e.totalAlpha==0||t.mixDuration==0)&&(t.mixingFrom=e.mixingFrom,e.mixingFrom!=null&&(e.mixingFrom.mixingTo=t),t.interruptAlpha=e.interruptAlpha,this.queue.end(e)),i):(e.trackTime+=n*e.timeScale,t.mixTime+=n,!1)}apply(t){if(t==null)throw new Error("skeleton cannot be null.");this.animationsChanged&&this._animationsChanged();const n=this.events,e=this.tracks;let i=!1;for(let l=0,s=e.length;l0)continue;i=!0;const o=l==0?A.first:a.mixBlend;let d=a.alpha;a.mixingFrom!=null?d*=this.applyMixingFrom(a,t,o):a.trackTime>=a.trackEnd&&a.next==null&&(d=0);const f=a.animationLast,u=a.getAnimationTime(),m=a.animation.timelines.length,g=a.animation.timelines;if(l==0&&d==1||o==A.add)for(let x=0;x1&&(r=1),e!=A.first&&(e=i.mixBlend));const h=r0&&this.queueEvents(i,o),this.events.length=0,i.nextAnimationLast=o,i.nextTrackLast=i.trackTime,r}applyAttachmentTimeline(t,n,e,i,r){const h=n.slots[t.slotIndex];if(!h.bone.active)return;const l=t.frames;if(e=l[l.length-1]?s=l.length-1:s=Et.binarySearch(l,e)-1,this.setAttachment(n,h,t.attachmentNames[s],r)}h.attachmentState<=this.unkeyedState&&(h.attachmentState=this.unkeyedState+mt.SETUP)}setAttachment(t,n,e,i){n.setAttachment(e==null?null:t.getAttachment(n.data.index,e)),i&&(n.attachmentState=this.unkeyedState+mt.CURRENT)}applyRotateTimeline(t,n,e,i,r,h,l,s){if(s&&(h[l]=0),i==1){t.apply(n,0,e,null,1,r,J.mixIn);return}const a=t,o=a.frames,d=n.bones[a.boneIndex];if(!d.active)return;let f=0,u=0;if(e=o[o.length-Vt.ENTRIES])u=d.data.rotation+o[o.length+Vt.PREV_ROTATION];else{const x=Et.binarySearch(o,e,Vt.ENTRIES),E=o[x+Vt.PREV_ROTATION],w=o[x],b=a.getCurvePercent((x>>1)-1,1-(e-w)/(o[x+Vt.PREV_TIME]-w));u=o[x+Vt.ROTATION]-E,u-=(16384-(16384.499999999996-u/360|0))*360,u=E+u*b+d.data.rotation,u-=(16384-(16384.499999999996-u/360|0))*360}let m=0,g=u-f;if(g-=(16384-(16384.499999999996-g/360|0))*360,g==0)m=h[l];else{let x=0,E=0;s?(x=0,E=g):(x=h[l],E=h[l+1]);const w=g>0;let b=x>=0;C.signum(E)!=C.signum(g)&&Math.abs(E)<=90&&(Math.abs(x)>180&&(x+=360*C.signum(x)),b=w),m=g+x-x%360,b!=w&&(m+=360*C.signum(x)),h[l]=m}h[l+1]=g,f+=m*i,d.rotation=f-(16384-(16384.499999999996-f/360|0))*360}queueEvents(t,n){const e=t.animationStart,i=t.animationEnd,r=i-e,h=t.trackLast%r,l=this.events;let s=0;const a=l.length;for(;si||this.queue.event(t,d)}let o=!1;for(t.loop?o=r==0||h>t.trackTime%r:o=n>=i&&t.animationLast=this.tracks.length)return;const n=this.tracks[t];if(n==null)return;this.queue.end(n),this.disposeNext(n);let e=n;for(;;){const i=e.mixingFrom;if(i==null)break;this.queue.end(i),e.mixingFrom=null,e.mixingTo=null,e=i}this.tracks[n.trackIndex]=null,this.queue.drain()}setCurrent(t,n,e){const i=this.expandToIndex(t);this.tracks[t]=n,i!=null&&(e&&this.queue.interrupt(i),n.mixingFrom=i,i.mixingTo=n,n.mixTime=0,i.mixingFrom!=null&&i.mixDuration>0&&(n.interruptAlpha*=Math.min(1,i.mixTime/i.mixDuration)),i.timelinesRotation.length=0),this.queue.start(n)}setAnimation(t,n,e){const i=this.data.skeletonData.findAnimation(n);if(i==null)throw new Error(`Animation not found: ${n}`);return this.setAnimationWith(t,i,e)}setAnimationWith(t,n,e){if(n==null)throw new Error("animation cannot be null.");let i=!0,r=this.expandToIndex(t);r!=null&&(r.nextTrackLast==-1?(this.tracks[t]=r.mixingFrom,this.queue.interrupt(r),this.queue.end(r),this.disposeNext(r),r=r.mixingFrom,i=!1):this.disposeNext(r));const h=this.trackEntry(t,n,e,r);return this.setCurrent(t,h,i),this.queue.drain(),h}addAnimation(t,n,e,i){const r=this.data.skeletonData.findAnimation(n);if(r==null)throw new Error(`Animation not found: ${n}`);return this.addAnimationWith(t,r,e,i)}addAnimationWith(t,n,e,i){if(n==null)throw new Error("animation cannot be null.");let r=this.expandToIndex(t);if(r!=null)for(;r.next!=null;)r=r.next;const h=this.trackEntry(t,n,e,r);if(r==null)this.setCurrent(t,h,!0),this.queue.drain();else if(r.next=h,i<=0){const l=r.animationEnd-r.animationStart;l!=0?(r.loop?i+=l*(1+(r.trackTime/l|0)):i+=Math.max(l,r.trackTime),i-=this.data.getMix(r.animation,n)):i=r.trackTime}return h.delay=i,h}setEmptyAnimation(t,n){const e=this.setAnimationWith(t,mt.emptyAnimation,!1);return e.mixDuration=n,e.trackEnd=n,e}addEmptyAnimation(t,n,e){e<=0&&(e-=n);const i=this.addAnimationWith(t,mt.emptyAnimation,!1,e);return i.mixDuration=n,i.trackEnd=n,i}setEmptyAnimations(t){const n=this.queue.drainDisabled;this.queue.drainDisabled=!0;for(let e=0,i=this.tracks.length;e0){r[s]=mt.HOLD_MIX,h[s]=d;continue t}break}r[s]=mt.HOLD_FIRST}}}getCurrent(t){return t>=this.tracks.length?null:this.tracks[t]}addListener(t){if(t==null)throw new Error("listener cannot be null.");this.listeners.push(t)}removeListener(t){const n=this.listeners.indexOf(t);n>=0&&this.listeners.splice(n,1)}clearListeners(){this.listeners.length=0}clearListenerNotifications(){this.queue.clear()}setAnimationByName(t,n,e){mt.deprecatedWarning1||(mt.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on.")),this.setAnimation(t,n,e)}addAnimationByName(t,n,e,i){mt.deprecatedWarning2||(mt.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on.")),this.addAnimation(t,n,e,i)}hasAnimation(t){return this.data.skeletonData.findAnimation(t)!==null}hasAnimationByName(t){return mt.deprecatedWarning3||(mt.deprecatedWarning3=!0,console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on.")),this.hasAnimation(t)}};let ne=mt;ne.emptyAnimation=new Et("",[],0),ne.SUBSEQUENT=0,ne.FIRST=1,ne.HOLD_SUBSEQUENT=2,ne.HOLD_FIRST=3,ne.HOLD_MIX=4,ne.SETUP=1,ne.CURRENT=2,ne.deprecatedWarning1=!1,ne.deprecatedWarning2=!1,ne.deprecatedWarning3=!1;const Ye=class{constructor(){this.mixBlend=A.replace,this.timelineMode=new Array,this.timelineHoldMix=new Array,this.timelinesRotation=new Array}reset(){this.next=null,this.mixingFrom=null,this.mixingTo=null,this.animation=null,this.listener=null,this.timelineMode.length=0,this.timelineHoldMix.length=0,this.timelinesRotation.length=0}getAnimationTime(){if(this.loop){const t=this.animationEnd-this.animationStart;return t==0?this.animationStart:this.trackTime%t+this.animationStart}return Math.min(this.trackTime+this.animationStart,this.animationEnd)}setAnimationLast(t){this.animationLast=t,this.nextAnimationLast=t}isComplete(){return this.trackTime>=this.animationEnd-this.animationStart}resetRotationDirections(){this.timelinesRotation.length=0}get time(){return Ye.deprecatedWarning1||(Ye.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime}set time(t){Ye.deprecatedWarning1||(Ye.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime=t}get endTime(){return Ye.deprecatedWarning2||(Ye.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime}set endTime(t){Ye.deprecatedWarning2||(Ye.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime=t}loopsCount(){return Math.floor(this.trackTime/this.trackEnd)}};let Xn=Ye;Xn.deprecatedWarning1=!1,Xn.deprecatedWarning2=!1;const ds=class{constructor(t){this.objects=[],this.drainDisabled=!1,this.animState=t}start(t){this.objects.push(Gt.start),this.objects.push(t),this.animState.animationsChanged=!0}interrupt(t){this.objects.push(Gt.interrupt),this.objects.push(t)}end(t){this.objects.push(Gt.end),this.objects.push(t),this.animState.animationsChanged=!0}dispose(t){this.objects.push(Gt.dispose),this.objects.push(t)}complete(t){this.objects.push(Gt.complete),this.objects.push(t)}event(t,n){this.objects.push(Gt.event),this.objects.push(t),this.objects.push(n)}deprecateStuff(){return ds.deprecatedWarning1||(ds.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: onComplete, onStart, onEnd, onEvent art deprecated, please use listeners from now on. 'state.addListener({ complete: function(track, event) { } })'")),!0}drain(){if(this.drainDisabled)return;this.drainDisabled=!0;const t=this.objects,n=this.animState.listeners;for(let e=0;e(c[c.start=0]="start",c[c.interrupt=1]="interrupt",c[c.end=2]="end",c[c.dispose=3]="dispose",c[c.complete=4]="complete",c[c.event=5]="event",c))(Gt||{});let Pr=class{start(t){}interrupt(t){}end(t){}dispose(t){}complete(t){}event(t,n){}};const us=class{constructor(t){if(this.animationToMixTime={},this.defaultMix=0,t==null)throw new Error("skeletonData cannot be null.");this.skeletonData=t}setMix(t,n,e){const i=this.skeletonData.findAnimation(t);if(i==null)throw new Error(`Animation not found: ${t}`);const r=this.skeletonData.findAnimation(n);if(r==null)throw new Error(`Animation not found: ${n}`);this.setMixWith(i,r,e)}setMixByName(t,n,e){us.deprecatedWarning1||(us.deprecatedWarning1=!0,console.warn("Deprecation Warning: AnimationStateData.setMixByName is deprecated, please use setMix from now on.")),this.setMix(t,n,e)}setMixWith(t,n,e){if(t==null)throw new Error("from cannot be null.");if(n==null)throw new Error("to cannot be null.");const i=`${t.name}.${n.name}`;this.animationToMixTime[i]=e}getMix(t,n){const e=`${t.name}.${n.name}`,i=this.animationToMixTime[e];return i===void 0?this.defaultMix:i}};let ms=us;ms.deprecatedWarning1=!1;let gs=class{constructor(t){this.atlas=t}newRegionAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (region attachment: ${n})`);const r=new Q(n);return r.region=i,r}newMeshAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (mesh attachment: ${n})`);const r=new mn(n);return r.region=i,r}newBoundingBoxAttachment(t,n){return new as(n)}newPathAttachment(t,n){return new gn(n)}newPointAttachment(t,n){return new ls(n)}newClippingAttachment(t,n){return new os(n)}},xs=class{constructor(t,n,e){if(this.matrix=new H.Matrix,this.children=new Array,this.x=0,this.y=0,this.rotation=0,this.scaleX=0,this.scaleY=0,this.shearX=0,this.shearY=0,this.ax=0,this.ay=0,this.arotation=0,this.ascaleX=0,this.ascaleY=0,this.ashearX=0,this.ashearY=0,this.appliedValid=!1,this.sorted=!1,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.skeleton=n,this.parent=e,this.setToSetupPose()}get worldX(){return this.matrix.tx}get worldY(){return this.matrix.ty}isActive(){return this.active}update(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransform(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransformWith(t,n,e,i,r,h,l){this.ax=t,this.ay=n,this.arotation=e,this.ascaleX=i,this.ascaleY=r,this.ashearX=h,this.ashearY=l,this.appliedValid=!0;const s=this.parent,a=this.matrix,o=this.skeleton.scaleX,d=zt.yDown?-this.skeleton.scaleY:this.skeleton.scaleY;if(s==null){const x=this.skeleton,E=e+90+l;a.a=C.cosDeg(e+h)*i*o,a.c=C.cosDeg(E)*r*o,a.b=C.sinDeg(e+h)*i*d,a.d=C.sinDeg(E)*r*d,a.tx=t*o+x.x,a.ty=n*d+x.y;return}let f=s.matrix.a,u=s.matrix.c,m=s.matrix.b,g=s.matrix.d;switch(a.tx=f*t+u*n+s.matrix.tx,a.ty=m*t+g*n+s.matrix.ty,this.data.transformMode){case j.Normal:{const x=e+90+l,E=C.cosDeg(e+h)*i,w=C.cosDeg(x)*r,b=C.sinDeg(e+h)*i,p=C.sinDeg(x)*r;a.a=f*E+u*b,a.c=f*w+u*p,a.b=m*E+g*b,a.d=m*w+g*p;return}case j.OnlyTranslation:{const x=e+90+l;a.a=C.cosDeg(e+h)*i,a.c=C.cosDeg(x)*r,a.b=C.sinDeg(e+h)*i,a.d=C.sinDeg(x)*r;break}case j.NoRotationOrReflection:{let x=f*f+m*m,E=0;x>1e-4?(x=Math.abs(f*g-u*m)/x,f/=this.skeleton.scaleX,m/=this.skeleton.scaleY,u=m*x,g=f*x,E=Math.atan2(m,f)*C.radDeg):(f=0,m=0,E=90-Math.atan2(g,u)*C.radDeg);const w=e+h-E,b=e+l-E+90,p=C.cosDeg(w)*i,S=C.cosDeg(b)*r,y=C.sinDeg(w)*i,M=C.sinDeg(b)*r;a.a=f*p-u*y,a.c=f*S-u*M,a.b=m*p+g*y,a.d=m*S+g*M;break}case j.NoScale:case j.NoScaleOrReflection:{const x=C.cosDeg(e),E=C.sinDeg(e);let w=(f*x+u*E)/o,b=(m*x+g*E)/d,p=Math.sqrt(w*w+b*b);p>1e-5&&(p=1/p),w*=p,b*=p,p=Math.sqrt(w*w+b*b),this.data.transformMode==j.NoScale&&f*g-u*m<0!=(zt.yDown?this.skeleton.scaleX<0!=this.skeleton.scaleY>0:this.skeleton.scaleX<0!=this.skeleton.scaleY<0)&&(p=-p);const S=Math.PI/2+Math.atan2(b,w),y=Math.cos(S)*p,M=Math.sin(S)*p,T=C.cosDeg(h)*i,k=C.cosDeg(90+l)*r,I=C.sinDeg(h)*i,R=C.sinDeg(90+l)*r;a.a=w*T+y*I,a.c=w*k+y*R,a.b=b*T+M*I,a.d=b*k+M*R;break}}a.a*=o,a.c*=o,a.b*=d,a.d*=d}setToSetupPose(){const t=this.data;this.x=t.x,this.y=t.y,this.rotation=t.rotation,this.scaleX=t.scaleX,this.scaleY=t.scaleY,this.shearX=t.shearX,this.shearY=t.shearY}getWorldRotationX(){return Math.atan2(this.matrix.b,this.matrix.a)*C.radDeg}getWorldRotationY(){return Math.atan2(this.matrix.d,this.matrix.c)*C.radDeg}getWorldScaleX(){const t=this.matrix;return Math.sqrt(t.a*t.a+t.c*t.c)}getWorldScaleY(){const t=this.matrix;return Math.sqrt(t.b*t.b+t.d*t.d)}updateAppliedTransform(){this.appliedValid=!0;const t=this.parent,n=this.matrix;if(t==null){this.ax=n.tx,this.ay=n.ty,this.arotation=Math.atan2(n.b,n.a)*C.radDeg,this.ascaleX=Math.sqrt(n.a*n.a+n.b*n.b),this.ascaleY=Math.sqrt(n.c*n.c+n.d*n.d),this.ashearX=0,this.ashearY=Math.atan2(n.a*n.c+n.b*n.d,n.a*n.d-n.b*n.c)*C.radDeg;return}const e=t.matrix,i=1/(e.a*e.d-e.b*e.c),r=n.tx-e.tx,h=n.ty-e.ty;this.ax=r*e.d*i-h*e.c*i,this.ay=h*e.a*i-r*e.b*i;const l=i*e.d,s=i*e.a,a=i*e.c,o=i*e.b,d=l*n.a-a*n.b,f=l*n.c-a*n.d,u=s*n.b-o*n.a,m=s*n.d-o*n.c;if(this.ashearX=0,this.ascaleX=Math.sqrt(d*d+u*u),this.ascaleX>1e-4){const g=d*m-f*u;this.ascaleY=g/this.ascaleX,this.ashearY=Math.atan2(d*f+u*m,g)*C.radDeg,this.arotation=Math.atan2(u,d)*C.radDeg}else this.ascaleX=0,this.ascaleY=Math.sqrt(f*f+m*m),this.ashearY=0,this.arotation=90-Math.atan2(m,f)*C.radDeg}worldToLocal(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=1/(e*h-i*r),s=t.x-n.tx,a=t.y-n.ty;return t.x=s*h*l-a*i*l,t.y=a*e*l-s*r*l,t}localToWorld(t){const n=this.matrix,e=t.x,i=t.y;return t.x=e*n.a+i*n.c+n.tx,t.y=e*n.b+i*n.d+n.ty,t}worldToLocalRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(i.a*n-i.b*e,i.d*e-i.c*n)*C.radDeg}localToWorldRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(e*i.b+n*i.d,e*i.a+n*i.c)*C.radDeg}rotateWorld(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=C.cosDeg(t),s=C.sinDeg(t);n.a=l*e-s*r,n.c=l*i-s*h,n.b=s*e+l*r,n.d=s*i+l*h,this.appliedValid=!1}},ps=class{constructor(t,n,e){if(this.x=0,this.y=0,this.rotation=0,this.scaleX=1,this.scaleY=1,this.shearX=0,this.shearY=0,this.transformMode=j.Normal,this.skinRequired=!1,this.color=new _,t<0)throw new Error("index must be >= 0.");if(n==null)throw new Error("name cannot be null.");this.index=t,this.name=n,this.parent=e}},Nn=class{constructor(t,n,e){this.name=t,this.order=n,this.skinRequired=e}},ws=class{constructor(t,n){if(n==null)throw new Error("data cannot be null.");this.time=t,this.data=n}},bs=class{constructor(t){this.name=t}},Fi=class{constructor(t,n){if(this.bendDirection=0,this.compress=!1,this.stretch=!1,this.mix=1,this.softness=0,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.mix=t.mix,this.softness=t.softness,this.bendDirection=t.bendDirection,this.compress=t.compress,this.stretch=t.stretch,this.bones=new Array;for(let e=0;e180?u-=360:u<-180&&(u+=360);let x=t.ascaleX,E=t.ascaleY;if(i||r){switch(t.data.transformMode){case j.NoScale:case j.NoScaleOrReflection:m=n-t.worldX,g=e-t.worldY}const w=t.data.length*x,b=Math.sqrt(m*m+g*g);if(i&&bw&&w>1e-4){const p=(b/w-1)*l+1;x*=p,h&&(E*=p)}}t.updateWorldTransformWith(t.ax,t.ay,t.arotation+u*l,x,E,t.ashearX,t.ashearY)}apply2(t,n,e,i,r,h,l,s){if(s==0){n.updateWorldTransform();return}t.appliedValid||t.updateAppliedTransform(),n.appliedValid||n.updateAppliedTransform();const a=t.ax,o=t.ay;let d=t.ascaleX,f=d,u=t.ascaleY,m=n.ascaleX;const g=t.matrix;let x=0,E=0,w=0;d<0?(d=-d,x=180,w=-1):(x=0,w=1),u<0&&(u=-u,w=-w),m<0?(m=-m,E=180):E=0;const b=n.ax;let p=0,S=0,y=0,M=g.a,T=g.c,k=g.b,I=g.d;const R=Math.abs(d-u)<=1e-4;R?(p=n.ay,S=M*b+T*p+g.tx,y=k*b+I*p+g.ty):(p=0,S=M*b+g.tx,y=k*b+g.ty);const V=t.parent.matrix;M=V.a,T=V.c,k=V.b,I=V.d;const F=1/(M*I-T*k);let B=S-V.tx,Y=y-V.ty;const N=(B*I-Y*T)*F-a,q=(Y*M-B*k)*F-o,z=Math.sqrt(N*N+q*q);let D=n.data.length*m,X,L;if(z<1e-4){this.apply1(t,e,i,!1,h,!1,s),n.updateWorldTransformWith(b,p,0,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY);return}B=e-V.tx,Y=i-V.ty;let O=(B*I-Y*T)*F-a,W=(Y*M-B*k)*F-o,U=O*O+W*W;if(l!=0){l*=d*(m+1)/2;const lt=Math.sqrt(U),It=lt-z-D*d+l;if(It>0){let ct=Math.min(1,It/(l*2))-1;ct=(It-l*(1-ct*ct))/lt,O-=ct*O,W-=ct*W,U=O*O+W*W}}t:if(R){D*=d;let lt=(U-z*z-D*D)/(2*z*D);lt<-1?lt=-1:lt>1&&(lt=1,h&&(f*=(Math.sqrt(U)/(z+D)-1)*s+1)),L=Math.acos(lt)*r,M=z+D*lt,T=D*Math.sin(L),X=Math.atan2(W*M-O*T,O*M+W*T)}else{M=d*D,T=u*D;const lt=M*M,It=T*T,ct=Math.atan2(W,O);k=It*z*z+lt*U-lt*It;const Xt=-2*It*z,Ut=It-lt;if(I=Xt*Xt-4*Ut*k,I>=0){let ae=Math.sqrt(I);Xt<0&&(ae=-ae),ae=-(Xt+ae)/2;const Ke=ae/Ut,Nt=k/ae,We=Math.abs(Ke)=-1&&k<=1&&(k=Math.acos(k),B=M*Math.cos(k)+z,Y=T*Math.sin(k),I=B*B+Y*Y,I$e&&(Ae=k,$e=I,Ce=B,Kt=Y)),U<=(Oe+$e)/2?(X=ct-Math.atan2(Ve*r,Me),L=de*r):(X=ct-Math.atan2(Kt*r,Ce),L=Ae*r)}const $=Math.atan2(p,b)*w;let G=t.arotation;X=(X-$)*C.radDeg+x-G,X>180?X-=360:X<-180&&(X+=360),t.updateWorldTransformWith(a,o,G+X*s,f,t.ascaleY,0,0),G=n.arotation,L=((L+$)*C.radDeg-n.ashearX)*w+E-G,L>180?L-=360:L<-180&&(L+=360),n.updateWorldTransformWith(b,p,G+L*s,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY)}},Es=class extends Nn{constructor(t){super(t,0,!1),this.bones=new Array,this.bendDirection=1,this.compress=!1,this.stretch=!1,this.uniform=!1,this.mix=1,this.softness=0}},Ss=class extends Nn{constructor(t){super(t,0,!1),this.bones=new Array}};var vt=(c=>(c[c.Length=0]="Length",c[c.Fixed=1]="Fixed",c[c.Percent=2]="Percent",c))(vt||{});const nn=class{constructor(t,n){if(this.position=0,this.spacing=0,this.rotateMix=0,this.translateMix=0,this.spaces=new Array,this.positions=new Array,this.world=new Array,this.curves=new Array,this.lengths=new Array,this.segments=new Array,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.bones=new Array;for(let e=0,i=t.bones.length;e0,r=n>0;if(!i&&!r)return;const h=this.data,l=h.spacingMode,s=l==vt.Length,a=h.rotateMode,o=a==pt.Tangent,d=a==pt.ChainScale,f=this.bones.length,u=o?f:f+1,m=this.bones,g=v.setArraySize(this.spaces,u);let x=null;const E=this.spacing;if(d||s){d&&(x=v.setArraySize(this.lengths,f));for(let M=0,T=u-1;M0?C.degRad:-C.degRad}for(let M=0,T=3;MC.PI?D-=C.PI2:D<-C.PI&&(D+=C.PI2),D*=n,X=Math.cos(D),L=Math.sin(D),I.a=X*Y-L*q,I.c=X*N-L*z,I.b=L*Y+X*q,I.d=L*N+X*z}k.appliedValid=!1}}computeWorldPositions(t,n,e,i,r){const h=this.target;let l=this.position;const s=this.spaces,a=v.setArraySize(this.positions,n*3+2);let o=null;const d=t.closed;let f=t.worldVerticesLength,u=f/6,m=nn.NONE;if(!t.constantSpeed){const D=t.lengths;u-=d?1:2;const X=D[u];if(i&&(l*=X),r)for(let L=0;LX){m!=nn.AFTER&&(m=nn.AFTER,t.computeWorldVertices(h,f-6,4,o,0,2)),this.addAfterPosition($-X,o,0,a,O);continue}for(;;W++){const G=D[W];if(!($>G)){if(W==0)$/=G;else{const lt=D[W-1];$=($-lt)/(G-lt)}break}}W!=m&&(m=W,d&&W==u?(t.computeWorldVertices(h,f-4,4,o,0,2),t.computeWorldVertices(h,0,4,o,4,2)):t.computeWorldVertices(h,W*6+2,8,o,0,2)),this.addCurvePosition($,o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7],a,O,e||L>0&&U==0)}return a}d?(f+=2,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f-4,o,0,2),t.computeWorldVertices(h,0,2,o,f-4,2),o[f-2]=o[0],o[f-1]=o[1]):(u--,f-=4,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f,o,0,2));const g=v.setArraySize(this.curves,u);let x=0,E=o[0],w=o[1],b=0,p=0,S=0,y=0,M=0,T=0,k=0,I=0,R=0,V=0,F=0,B=0,Y=0,N=0;for(let D=0,X=2;Dx){this.addAfterPosition(U-x,o,f-4,a,X);continue}for(;;L++){const $=g[L];if(!(U>$)){if(L==0)U/=$;else{const G=g[L-1];U=(U-G)/($-G)}break}}if(L!=m){m=L;let $=L*6;for(E=o[$],w=o[$+1],b=o[$+2],p=o[$+3],S=o[$+4],y=o[$+5],M=o[$+6],T=o[$+7],k=(E-b*2+S)*.03,I=(w-p*2+y)*.03,R=((b-S)*3-E+M)*.006,V=((p-y)*3-w+T)*.006,F=k*2+R,B=I*2+V,Y=(b-E)*.3+k+R*.16666667,N=(p-w)*.3+I+V*.16666667,z=Math.sqrt(Y*Y+N*N),q[0]=z,$=1;$<8;$++)Y+=F,N+=B,F+=R,B+=V,z+=Math.sqrt(Y*Y+N*N),q[$]=z;Y+=F,N+=B,z+=Math.sqrt(Y*Y+N*N),q[8]=z,Y+=F+R,N+=B+V,z+=Math.sqrt(Y*Y+N*N),q[9]=z,O=0}for(U*=z;;O++){const $=q[O];if(!(U>$)){if(O==0)U/=$;else{const G=q[O-1];U=O+(U-G)/($-G)}break}}this.addCurvePosition(U*.1,E,w,b,p,S,y,M,T,a,X,e||D>0&&W==0)}return a}addBeforePosition(t,n,e,i,r){const h=n[e],l=n[e+1],s=n[e+2]-h,a=n[e+3]-l,o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addAfterPosition(t,n,e,i,r){const h=n[e+2],l=n[e+3],s=h-n[e],a=l-n[e+1],o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addCurvePosition(t,n,e,i,r,h,l,s,a,o,d,f){(t==0||isNaN(t))&&(t=1e-4);const u=t*t,m=u*t,g=1-t,x=g*g,E=x*g,w=g*t,b=w*3,p=g*b,S=b*t,y=n*E+i*p+h*S+s*m,M=e*E+r*p+l*S+a*m;o[d]=y,o[d+1]=M,f&&(o[d+2]=Math.atan2(M-(e*x+r*w*2+l*u),y-(n*x+i*w*2+h*u)))}};let pn=nn;pn.NONE=-1,pn.BEFORE=-2,pn.AFTER=-3,pn.epsilon=1e-5;let Yi=class{constructor(t,n){if(this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.temp=new un,this.active=!1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.rotateMix=t.rotateMix,this.translateMix=t.translateMix,this.scaleMix=t.scaleMix,this.shearMix=t.shearMix,this.bones=new Array;for(let e=0;e0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=(p.x-b.tx)*n,b.ty+=(p.y-b.ty)*n,w=!0}if(e>0){let p=Math.sqrt(b.a*b.a+b.b*b.b),S=Math.sqrt(l*l+a*a);p>1e-5&&(p=(p+(S-p+this.data.offsetScaleX)*e)/p),b.a*=p,b.b*=p,p=Math.sqrt(b.c*b.c+b.d*b.d),S=Math.sqrt(s*s+o*o),p>1e-5&&(p=(p+(S-p+this.data.offsetScaleY)*e)/p),b.c*=p,b.d*=p,w=!0}if(i>0){const p=b.c,S=b.d,y=Math.atan2(S,p);let M=Math.atan2(o,s)-Math.atan2(a,l)-(y-Math.atan2(b.b,b.a));M>C.PI?M-=C.PI2:M<-C.PI&&(M+=C.PI2),M=y+(M+u)*i;const T=Math.sqrt(p*p+S*S);b.c=Math.cos(M)*T,b.d=Math.sin(M)*T,w=!0}w&&(E.appliedValid=!1)}}applyRelativeWorld(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target,h=r.matrix,l=h.a,s=h.c,a=h.b,o=h.d,d=l*o-s*a>0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=p.x*n,b.ty+=p.y*n,w=!0}if(e>0){let p=(Math.sqrt(l*l+a*a)-1+this.data.offsetScaleX)*e+1;b.a*=p,b.b*=p,p=(Math.sqrt(s*s+o*o)-1+this.data.offsetScaleY)*e+1,b.c*=p,b.d*=p,w=!0}if(i>0){let p=Math.atan2(o,s)-Math.atan2(a,l);p>C.PI?p-=C.PI2:p<-C.PI&&(p+=C.PI2);const S=b.c,y=b.d;p=Math.atan2(y,S)+(p-C.PI/2+u)*i;const M=Math.sqrt(S*S+y*y);b.c=Math.cos(p)*M,b.d=Math.sin(p)*M,w=!0}w&&(E.appliedValid=!1)}}applyAbsoluteLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u=(u+(r.ascaleX-u+this.data.offsetScaleX)*e)/u),m>1e-5&&(m=(m+(r.ascaleY-m+this.data.offsetScaleY)*e)/m));const g=a.ashearY;if(i>0){let x=r.ashearY-g+this.data.offsetShearY;x-=(16384-(16384.499999999996-x/360|0))*360,a.shearY+=x*i}a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}applyRelativeLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u*=(r.ascaleX-1+this.data.offsetScaleX)*e+1),m>1e-5&&(m*=(r.ascaleY-1+this.data.offsetScaleY)*e+1));let g=a.ashearY;i>0&&(g+=(r.ashearY+this.data.offsetShearY)*i),a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}};const Tn=class{constructor(t){if(this._updateCache=new Array,this.updateCacheReset=new Array,this.time=0,this.scaleX=1,this.scaleY=1,this.x=0,this.y=0,t==null)throw new Error("data cannot be null.");this.data=t,this.bones=new Array;for(let n=0;n1){const r=e[e.length-1];this._updateCache.indexOf(r)>-1||this.updateCacheReset.push(r)}this._updateCache.push(t),this.sortReset(i.children),e[e.length-1].sorted=!0}sortPathConstraint(t){if(t.active=t.target.bone.isActive()&&(!t.data.skinRequired||this.skin!=null&&v.contains(this.skin.constraints,t.data,!0)),!t.active)return;const n=t.target,e=n.data.index,i=n.bone;this.skin!=null&&this.sortPathConstraintAttachment(this.skin,e,i),this.data.defaultSkin!=null&&this.data.defaultSkin!=this.skin&&this.sortPathConstraintAttachment(this.data.defaultSkin,e,i);for(let s=0,a=this.data.skins.length;s-1||this.updateCacheReset.push(r)}else for(let i=0;i= 0.");if(n==null)throw new Error("name cannot be null.");if(e==null)throw new Error("boneData cannot be null.");this.index=t,this.name=n,this.boneData=e}},Cs=class extends Nn{constructor(t){super(t,0,!1),this.bones=new Array,this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.offsetRotation=0,this.offsetX=0,this.offsetY=0,this.offsetScaleX=0,this.offsetScaleY=0,this.offsetShearY=0,this.relative=!1,this.local=!1}},Ts=class{constructor(t,n,e){this.slotIndex=t,this.name=n,this.attachment=e}},Bn=class{constructor(t){if(this.attachments=new Array,this.bones=Array(),this.constraints=new Array,t==null)throw new Error("name cannot be null.");this.name=t}setAttachment(t,n,e){if(e==null)throw new Error("attachment cannot be null.");const i=this.attachments;t>=i.length&&(i.length=t+1),i[t]||(i[t]={}),i[t][n]=e}addSkin(t){for(let e=0;e0){const o=new xn(s),d=n.slots.length;for(let f=0;f=0;b--)g[b]=-1;const x=v.newArray(d-m,0);let E=0,w=0;for(let b=0;b=0;b--)g[b]==-1&&(g[b]=x[--w]);o.setFrame(f,u,g)}e.push(o),r=Math.max(r,o.frames[s-1])}const a=c.readInt(!0);if(a>0){const o=new Yn(a);for(let d=0;d=0;w--)u[w]==-1&&(u[w]=g[--E])}s.setFrame(o++,this.getValue(f,"time",0),u)}r.push(s),h=Math.max(h,s.frames[s.getFrameCount()-1])}if(t.events){const s=new Yn(t.events.length);let a=0;for(let o=0;o>1)*h;const l=t.bone.skeleton,s=t.attachmentVertices;let a=this.vertices;const o=this.bones;if(o==null){s.length>0&&(a=s);const m=t.bone.matrix,g=m.tx,x=m.ty,E=m.a,w=m.c,b=m.b,p=m.d;for(let S=n,y=r;y0&&(n%=this.duration));const a=this.timelines;for(let o=0,d=a.length;o>>1;for(;;){if(t[(h+1)*e]<=n?i=h+1:r=h,i==r)return(i+1)*e;h=i+r>>>1}}static linearSearch(t,n,e){for(let i=0,r=t.length-e;i<=r;i+=e)if(t[i]>n)return i;return-1}};var Oi=(c=>(c[c.rotate=0]="rotate",c[c.translate=1]="translate",c[c.scale=2]="scale",c[c.shear=3]="shear",c[c.attachment=4]="attachment",c[c.color=5]="color",c[c.deform=6]="deform",c[c.event=7]="event",c[c.drawOrder=8]="drawOrder",c[c.ikConstraint=9]="ikConstraint",c[c.transformConstraint=10]="transformConstraint",c[c.pathConstraintPosition=11]="pathConstraintPosition",c[c.pathConstraintSpacing=12]="pathConstraintSpacing",c[c.pathConstraintMix=13]="pathConstraintMix",c[c.twoColor=14]="twoColor",c))(Oi||{});const At=class{constructor(c){if(c<=0)throw new Error(`frameCount must be > 0: ${c}`);this.curves=v.newFloatArray((c-1)*At.BEZIER_SIZE)}getFrameCount(){return this.curves.length/At.BEZIER_SIZE+1}setLinear(c){this.curves[c*At.BEZIER_SIZE]=At.LINEAR}setStepped(c){this.curves[c*At.BEZIER_SIZE]=At.STEPPED}getCurveType(c){const t=c*At.BEZIER_SIZE;if(t==this.curves.length)return At.LINEAR;const n=this.curves[t];return n==At.LINEAR?At.LINEAR:n==At.STEPPED?At.STEPPED:At.BEZIER}setCurve(c,t,n,e,i){const r=(-t*2+e)*.03,h=(-n*2+i)*.03,l=((t-e)*3+1)*.006,s=((n-i)*3+1)*.006;let a=r*2+l,o=h*2+s,d=t*.3+r+l*.16666667,f=n*.3+h+s*.16666667,u=c*At.BEZIER_SIZE;const m=this.curves;m[u++]=At.BEZIER;let g=d,x=f;for(let E=u+At.BEZIER_SIZE-1;u=t){let a,o;return e==l?(a=0,o=0):(a=n[e-2],o=n[e-1]),o+(n[e+1]-o)*(t-a)/(r-a)}const h=n[e-1];return h+(1-h)*(t-r)/(1-r)}};let jt=At;jt.LINEAR=0,jt.STEPPED=1,jt.BEZIER=2,jt.BEZIER_SIZE=10*2-1;const je=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c<<1)}getPropertyId(){return(0<<24)+this.boneIndex}setFrame(c,t,n){c<<=1,this.frames[c]=t,this.frames[c+je.ROTATION]=n}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.bones[this.boneIndex];if(n=l[l.length-je.ENTRIES]){let m=l[l.length+je.PREV_ROTATION];switch(r){case A.setup:s.rotation=s.data.rotation+m*i;break;case A.first:case A.replace:m+=s.data.rotation-s.rotation,m-=(16384-(16384.499999999996-m/360|0))*360;case A.add:s.rotation+=m*i}return}const a=Ct.binarySearch(l,n,je.ENTRIES),o=l[a+je.PREV_ROTATION],d=l[a],f=this.getCurvePercent((a>>1)-1,1-(n-d)/(l[a+je.PREV_TIME]-d));let u=l[a+je.ROTATION]-o;switch(u=o+(u-(16384-(16384.499999999996-u/360|0))*360)*f,r){case A.setup:s.rotation=s.data.rotation+(u-(16384-(16384.499999999996-u/360|0))*360)*i;break;case A.first:case A.replace:u+=s.data.rotation-s.rotation;case A.add:s.rotation+=(u-(16384-(16384.499999999996-u/360|0))*360)*i}}};let $t=je;$t.ENTRIES=2,$t.PREV_TIME=-2,$t.PREV_ROTATION=-1,$t.ROTATION=1;const Wt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*Wt.ENTRIES)}getPropertyId(){return(1<<24)+this.boneIndex}setFrame(c,t,n,e){c*=Wt.ENTRIES,this.frames[c]=t,this.frames[c+Wt.X]=n,this.frames[c+Wt.Y]=e}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.bones[this.boneIndex];if(n=l[l.length-Wt.ENTRIES])a=l[l.length+Wt.PREV_X],o=l[l.length+Wt.PREV_Y];else{const d=Ct.binarySearch(l,n,Wt.ENTRIES);a=l[d+Wt.PREV_X],o=l[d+Wt.PREV_Y];const f=l[d],u=this.getCurvePercent(d/Wt.ENTRIES-1,1-(n-f)/(l[d+Wt.PREV_TIME]-f));a+=(l[d+Wt.X]-a)*u,o+=(l[d+Wt.Y]-o)*u}switch(r){case A.setup:s.x=s.data.x+a*i,s.y=s.data.y+o*i;break;case A.first:case A.replace:s.x+=(s.data.x+a-s.x)*i,s.y+=(s.data.y+o-s.y)*i;break;case A.add:s.x+=a*i,s.y+=o*i}}};let ge=Wt;ge.ENTRIES=3,ge.PREV_TIME=-3,ge.PREV_X=-2,ge.PREV_Y=-1,ge.X=1,ge.Y=2;let le=class extends ge{constructor(t){super(t)}getPropertyId(){return(2<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(e=s[s.length-le.ENTRIES])o=s[s.length+le.PREV_X]*a.data.scaleX,d=s[s.length+le.PREV_Y]*a.data.scaleY;else{const f=Ct.binarySearch(s,e,le.ENTRIES);o=s[f+le.PREV_X],d=s[f+le.PREV_Y];const u=s[f],m=this.getCurvePercent(f/le.ENTRIES-1,1-(e-u)/(s[f+le.PREV_TIME]-u));o=(o+(s[f+le.X]-o)*m)*a.data.scaleX,d=(d+(s[f+le.Y]-d)*m)*a.data.scaleY}if(r==1)h==A.add?(a.scaleX+=o-a.data.scaleX,a.scaleY+=d-a.data.scaleY):(a.scaleX=o,a.scaleY=d);else{let f=0,u=0;if(l==J.mixOut)switch(h){case A.setup:f=a.data.scaleX,u=a.data.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.first:case A.replace:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-f)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-u)*r;break;case A.add:f=a.scaleX,u=a.scaleY,a.scaleX=f+(Math.abs(o)*C.signum(f)-a.data.scaleX)*r,a.scaleY=u+(Math.abs(d)*C.signum(u)-a.data.scaleY)*r}else switch(h){case A.setup:f=Math.abs(a.data.scaleX)*C.signum(o),u=Math.abs(a.data.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.first:case A.replace:f=Math.abs(a.scaleX)*C.signum(o),u=Math.abs(a.scaleY)*C.signum(d),a.scaleX=f+(o-f)*r,a.scaleY=u+(d-u)*r;break;case A.add:f=C.signum(o),u=C.signum(d),a.scaleX=Math.abs(a.scaleX)*f+(o-Math.abs(a.data.scaleX)*f)*r,a.scaleY=Math.abs(a.scaleY)*u+(d-Math.abs(a.data.scaleY)*u)*r}}}},ce=class extends ge{constructor(t){super(t)}getPropertyId(){return(3<<24)+this.boneIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.bones[this.boneIndex];if(e=s[s.length-ce.ENTRIES])o=s[s.length+ce.PREV_X],d=s[s.length+ce.PREV_Y];else{const f=Ct.binarySearch(s,e,ce.ENTRIES);o=s[f+ce.PREV_X],d=s[f+ce.PREV_Y];const u=s[f],m=this.getCurvePercent(f/ce.ENTRIES-1,1-(e-u)/(s[f+ce.PREV_TIME]-u));o=o+(s[f+ce.X]-o)*m,d=d+(s[f+ce.Y]-d)*m}switch(h){case A.setup:a.shearX=a.data.shearX+o*r,a.shearY=a.data.shearY+d*r;break;case A.first:case A.replace:a.shearX+=(a.data.shearX+o-a.shearX)*r,a.shearY+=(a.data.shearY+d-a.shearY)*r;break;case A.add:a.shearX+=o*r,a.shearY+=d*r}}};const gt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*gt.ENTRIES)}getPropertyId(){return(5<<24)+this.slotIndex}setFrame(c,t,n,e,i,r){c*=gt.ENTRIES,this.frames[c]=t,this.frames[c+gt.R]=n,this.frames[c+gt.G]=e,this.frames[c+gt.B]=i,this.frames[c+gt.A]=r}apply(c,t,n,e,i,r,h){const l=c.slots[this.slotIndex],s=this.frames;if(n=s[s.length-gt.ENTRIES]){const u=s.length;a=s[u+gt.PREV_R],o=s[u+gt.PREV_G],d=s[u+gt.PREV_B],f=s[u+gt.PREV_A]}else{const u=Ct.binarySearch(s,n,gt.ENTRIES);a=s[u+gt.PREV_R],o=s[u+gt.PREV_G],d=s[u+gt.PREV_B],f=s[u+gt.PREV_A];const m=s[u],g=this.getCurvePercent(u/gt.ENTRIES-1,1-(n-m)/(s[u+gt.PREV_TIME]-m));a+=(s[u+gt.R]-a)*g,o+=(s[u+gt.G]-o)*g,d+=(s[u+gt.B]-d)*g,f+=(s[u+gt.A]-f)*g}if(i==1)l.color.set(a,o,d,f);else{const u=l.color;r==A.setup&&u.setFromColor(l.data.color),u.add((a-u.r)*i,(o-u.g)*i,(d-u.b)*i,(f-u.a)*i)}}};let se=gt;se.ENTRIES=5,se.PREV_TIME=-5,se.PREV_R=-4,se.PREV_G=-3,se.PREV_B=-2,se.PREV_A=-1,se.R=1,se.G=2,se.B=3,se.A=4;const st=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*st.ENTRIES)}getPropertyId(){return(14<<24)+this.slotIndex}setFrame(c,t,n,e,i,r,h,l,s){c*=st.ENTRIES,this.frames[c]=t,this.frames[c+st.R]=n,this.frames[c+st.G]=e,this.frames[c+st.B]=i,this.frames[c+st.A]=r,this.frames[c+st.R2]=h,this.frames[c+st.G2]=l,this.frames[c+st.B2]=s}apply(c,t,n,e,i,r,h){const l=c.slots[this.slotIndex],s=this.frames;if(n=s[s.length-st.ENTRIES]){const x=s.length;a=s[x+st.PREV_R],o=s[x+st.PREV_G],d=s[x+st.PREV_B],f=s[x+st.PREV_A],u=s[x+st.PREV_R2],m=s[x+st.PREV_G2],g=s[x+st.PREV_B2]}else{const x=Ct.binarySearch(s,n,st.ENTRIES);a=s[x+st.PREV_R],o=s[x+st.PREV_G],d=s[x+st.PREV_B],f=s[x+st.PREV_A],u=s[x+st.PREV_R2],m=s[x+st.PREV_G2],g=s[x+st.PREV_B2];const E=s[x],w=this.getCurvePercent(x/st.ENTRIES-1,1-(n-E)/(s[x+st.PREV_TIME]-E));a+=(s[x+st.R]-a)*w,o+=(s[x+st.G]-o)*w,d+=(s[x+st.B]-d)*w,f+=(s[x+st.A]-f)*w,u+=(s[x+st.R2]-u)*w,m+=(s[x+st.G2]-m)*w,g+=(s[x+st.B2]-g)*w}if(i==1)l.color.set(a,o,d,f),l.darkColor.set(u,m,g,1);else{const x=l.color,E=l.darkColor;r==A.setup&&(x.setFromColor(l.data.color),E.setFromColor(l.data.darkColor)),x.add((a-x.r)*i,(o-x.g)*i,(d-x.b)*i,(f-x.a)*i),E.add((u-E.r)*i,(m-E.g)*i,(g-E.b)*i,0)}}};let Tt=st;Tt.ENTRIES=8,Tt.PREV_TIME=-8,Tt.PREV_R=-7,Tt.PREV_G=-6,Tt.PREV_B=-5,Tt.PREV_A=-4,Tt.PREV_R2=-3,Tt.PREV_G2=-2,Tt.PREV_B2=-1,Tt.R=1,Tt.G=2,Tt.B=3,Tt.A=4,Tt.R2=5,Tt.G2=6,Tt.B2=7;let Dn=class{constructor(t){this.frames=v.newFloatArray(t),this.attachmentNames=new Array(t)}getPropertyId(){return(4<<24)+this.slotIndex}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.attachmentNames[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(l==J.mixOut&&h==A.setup){const f=s.data.attachmentName;s.setAttachment(f==null?null:t.getAttachment(this.slotIndex,f));return}const a=this.frames;if(e=a[a.length-1]?o=a.length-1:o=Ct.binarySearch(a,e,1)-1;const d=this.attachmentNames[o];t.slots[this.slotIndex].setAttachment(d==null?null:t.getAttachment(this.slotIndex,d))}},$i=null,Wi=class extends jt{constructor(t){super(t),this.frames=v.newFloatArray(t),this.frameVertices=new Array(t),$i==null&&($i=v.newFloatArray(64))}getPropertyId(){return(6<<27)+Number(this.attachment.id)+this.slotIndex}setFrame(t,n,e){this.frames[t]=n,this.frameVertices[t]=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex],a=s.getAttachment();if(!(a instanceof Ge)||!a.applyDeform(this.attachment))return;const o=s.attachmentVertices;o.length==0&&(h=A.setup);const d=this.frameVertices,f=d[0].length,u=this.frames;if(e=u[u.length-1]){const p=d[u.length-1];if(r==1)if(h==A.add){const S=a;if(S.bones==null){const y=S.vertices;for(let M=0;Me)this.apply(t,n,Number.MAX_VALUE,i,r,h,l),n=-1;else if(n>=s[a-1])return;if(e0&&s[o-1]==d;)o--}for(;o=s[o];o++)i.push(this.events[o])}},Ln=class{constructor(t){this.frames=v.newFloatArray(t),this.drawOrders=new Array(t)}getPropertyId(){return 8<<24}getFrameCount(){return this.frames.length}setFrame(t,n,e){this.frames[t]=n,this.drawOrders[t]=e}apply(t,n,e,i,r,h,l){const s=t.drawOrder,a=t.slots;if(l==J.mixOut&&h==A.setup){v.arrayCopy(t.slots,0,t.drawOrder,0,t.slots.length);return}const o=this.frames;if(e=o[o.length-1]?d=o.length-1:d=Ct.binarySearch(o,e)-1;const f=this.drawOrders[d];if(f==null)v.arrayCopy(a,0,s,0,a.length);else for(let u=0,m=f.length;u=l[l.length-ht.ENTRIES]){r==A.setup?(s.mix=s.data.mix+(l[l.length+ht.PREV_MIX]-s.data.mix)*i,h==J.mixOut?(s.bendDirection=s.data.bendDirection,s.compress=s.data.compress,s.stretch=s.data.stretch):(s.bendDirection=l[l.length+ht.PREV_BEND_DIRECTION],s.compress=l[l.length+ht.PREV_COMPRESS]!=0,s.stretch=l[l.length+ht.PREV_STRETCH]!=0)):(s.mix+=(l[l.length+ht.PREV_MIX]-s.mix)*i,h==J.mixIn&&(s.bendDirection=l[l.length+ht.PREV_BEND_DIRECTION],s.compress=l[l.length+ht.PREV_COMPRESS]!=0,s.stretch=l[l.length+ht.PREV_STRETCH]!=0));return}const a=Ct.binarySearch(l,n,ht.ENTRIES),o=l[a+ht.PREV_MIX],d=l[a],f=this.getCurvePercent(a/ht.ENTRIES-1,1-(n-d)/(l[a+ht.PREV_TIME]-d));r==A.setup?(s.mix=s.data.mix+(o+(l[a+ht.MIX]-o)*f-s.data.mix)*i,h==J.mixOut?(s.bendDirection=s.data.bendDirection,s.compress=s.data.compress,s.stretch=s.data.stretch):(s.bendDirection=l[a+ht.PREV_BEND_DIRECTION],s.compress=l[a+ht.PREV_COMPRESS]!=0,s.stretch=l[a+ht.PREV_STRETCH]!=0)):(s.mix+=(o+(l[a+ht.MIX]-o)*f-s.mix)*i,h==J.mixIn&&(s.bendDirection=l[a+ht.PREV_BEND_DIRECTION],s.compress=l[a+ht.PREV_COMPRESS]!=0,s.stretch=l[a+ht.PREV_STRETCH]!=0))}};let ie=ht;ie.ENTRIES=5,ie.PREV_TIME=-5,ie.PREV_MIX=-4,ie.PREV_BEND_DIRECTION=-3,ie.PREV_COMPRESS=-2,ie.PREV_STRETCH=-1,ie.MIX=1,ie.BEND_DIRECTION=2,ie.COMPRESS=3,ie.STRETCH=4;const xt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*xt.ENTRIES)}getPropertyId(){return(10<<24)+this.transformConstraintIndex}setFrame(c,t,n,e,i,r){c*=xt.ENTRIES,this.frames[c]=t,this.frames[c+xt.ROTATE]=n,this.frames[c+xt.TRANSLATE]=e,this.frames[c+xt.SCALE]=i,this.frames[c+xt.SHEAR]=r}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.transformConstraints[this.transformConstraintIndex];if(n=l[l.length-xt.ENTRIES]){const u=l.length;a=l[u+xt.PREV_ROTATE],o=l[u+xt.PREV_TRANSLATE],d=l[u+xt.PREV_SCALE],f=l[u+xt.PREV_SHEAR]}else{const u=Ct.binarySearch(l,n,xt.ENTRIES);a=l[u+xt.PREV_ROTATE],o=l[u+xt.PREV_TRANSLATE],d=l[u+xt.PREV_SCALE],f=l[u+xt.PREV_SHEAR];const m=l[u],g=this.getCurvePercent(u/xt.ENTRIES-1,1-(n-m)/(l[u+xt.PREV_TIME]-m));a+=(l[u+xt.ROTATE]-a)*g,o+=(l[u+xt.TRANSLATE]-o)*g,d+=(l[u+xt.SCALE]-d)*g,f+=(l[u+xt.SHEAR]-f)*g}if(r==A.setup){const u=s.data;s.rotateMix=u.rotateMix+(a-u.rotateMix)*i,s.translateMix=u.translateMix+(o-u.translateMix)*i,s.scaleMix=u.scaleMix+(d-u.scaleMix)*i,s.shearMix=u.shearMix+(f-u.shearMix)*i}else s.rotateMix+=(a-s.rotateMix)*i,s.translateMix+=(o-s.translateMix)*i,s.scaleMix+=(d-s.scaleMix)*i,s.shearMix+=(f-s.shearMix)*i}};let re=xt;re.ENTRIES=5,re.PREV_TIME=-5,re.PREV_ROTATE=-4,re.PREV_TRANSLATE=-3,re.PREV_SCALE=-2,re.PREV_SHEAR=-1,re.ROTATE=1,re.TRANSLATE=2,re.SCALE=3,re.SHEAR=4;const xe=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*xe.ENTRIES)}getPropertyId(){return(11<<24)+this.pathConstraintIndex}setFrame(c,t,n){c*=xe.ENTRIES,this.frames[c]=t,this.frames[c+xe.VALUE]=n}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.pathConstraints[this.pathConstraintIndex];if(n=l[l.length-xe.ENTRIES])a=l[l.length+xe.PREV_VALUE];else{const o=Ct.binarySearch(l,n,xe.ENTRIES);a=l[o+xe.PREV_VALUE];const d=l[o],f=this.getCurvePercent(o/xe.ENTRIES-1,1-(n-d)/(l[o+xe.PREV_TIME]-d));a+=(l[o+xe.VALUE]-a)*f}r==A.setup?s.position=s.data.position+(a-s.data.position)*i:s.position+=(a-s.position)*i}};let Ze=xe;Ze.ENTRIES=2,Ze.PREV_TIME=-2,Ze.PREV_VALUE=-1,Ze.VALUE=1;let Xe=class extends Ze{constructor(t){super(t)}getPropertyId(){return(12<<24)+this.pathConstraintIndex}apply(t,n,e,i,r,h,l){const s=this.frames,a=t.pathConstraints[this.pathConstraintIndex];if(e=s[s.length-Xe.ENTRIES])o=s[s.length+Xe.PREV_VALUE];else{const d=Ct.binarySearch(s,e,Xe.ENTRIES);o=s[d+Xe.PREV_VALUE];const f=s[d],u=this.getCurvePercent(d/Xe.ENTRIES-1,1-(e-f)/(s[d+Xe.PREV_TIME]-f));o+=(s[d+Xe.VALUE]-o)*u}h==A.setup?a.spacing=a.data.spacing+(o-a.data.spacing)*r:a.spacing+=(o-a.spacing)*r}};const qt=class extends jt{constructor(c){super(c),this.frames=v.newFloatArray(c*qt.ENTRIES)}getPropertyId(){return(13<<24)+this.pathConstraintIndex}setFrame(c,t,n,e){c*=qt.ENTRIES,this.frames[c]=t,this.frames[c+qt.ROTATE]=n,this.frames[c+qt.TRANSLATE]=e}apply(c,t,n,e,i,r,h){const l=this.frames,s=c.pathConstraints[this.pathConstraintIndex];if(n=l[l.length-qt.ENTRIES])a=l[l.length+qt.PREV_ROTATE],o=l[l.length+qt.PREV_TRANSLATE];else{const d=Ct.binarySearch(l,n,qt.ENTRIES);a=l[d+qt.PREV_ROTATE],o=l[d+qt.PREV_TRANSLATE];const f=l[d],u=this.getCurvePercent(d/qt.ENTRIES-1,1-(n-f)/(l[d+qt.PREV_TIME]-f));a+=(l[d+qt.ROTATE]-a)*u,o+=(l[d+qt.TRANSLATE]-o)*u}r==A.setup?(s.rotateMix=s.data.rotateMix+(a-s.data.rotateMix)*i,s.translateMix=s.data.translateMix+(o-s.data.translateMix)*i):(s.rotateMix+=(a-s.rotateMix)*i,s.translateMix+=(o-s.translateMix)*i)}};let Ne=qt;Ne.ENTRIES=3,Ne.PREV_TIME=-3,Ne.PREV_ROTATE=-2,Ne.PREV_TRANSLATE=-1,Ne.ROTATE=1,Ne.TRANSLATE=2;const Pt=class{constructor(t){this.tracks=new Array,this.events=new Array,this.listeners=new Array,this.queue=new Ps(this),this.propertyIDs=new ns,this.animationsChanged=!1,this.timeScale=1,this.trackEntryPool=new An(()=>new _n),this.data=t}update(t){t*=this.timeScale;const n=this.tracks;for(let e=0,i=n.length;e0){if(r.delay-=h,r.delay>0)continue;h=-r.delay,r.delay=0}let l=r.next;if(l!=null){const s=r.trackLast-l.delay;if(s>=0){for(l.delay=0,l.trackTime=r.timeScale==0?0:(s/r.timeScale+t)*l.timeScale,r.trackTime+=h,this.setCurrent(e,l,!0);l.mixingFrom!=null;)l.mixTime+=t,l=l.mixingFrom;continue}}else if(r.trackLast>=r.trackEnd&&r.mixingFrom==null){n[e]=null,this.queue.end(r),this.disposeNext(r);continue}if(r.mixingFrom!=null&&this.updateMixingFrom(r,t)){let s=r.mixingFrom;for(r.mixingFrom=null,s!=null&&(s.mixingTo=null);s!=null;)this.queue.end(s),s=s.mixingFrom}r.trackTime+=h}this.queue.drain()}updateMixingFrom(t,n){const e=t.mixingFrom;if(e==null)return!0;const i=this.updateMixingFrom(e,n);return e.animationLast=e.nextAnimationLast,e.trackLast=e.nextTrackLast,t.mixTime>0&&t.mixTime>=t.mixDuration?((e.totalAlpha==0||t.mixDuration==0)&&(t.mixingFrom=e.mixingFrom,e.mixingFrom!=null&&(e.mixingFrom.mixingTo=t),t.interruptAlpha=e.interruptAlpha,this.queue.end(e)),i):(e.trackTime+=n*e.timeScale,t.mixTime+=n,!1)}apply(t){if(t==null)throw new Error("skeleton cannot be null.");this.animationsChanged&&this._animationsChanged();const n=this.events,e=this.tracks;let i=!1;for(let r=0,h=e.length;r0)continue;i=!0;const s=r==0?A.first:l.mixBlend;let a=l.alpha;l.mixingFrom!=null?a*=this.applyMixingFrom(l,t,s):l.trackTime>=l.trackEnd&&l.next==null&&(a=0);const o=l.animationLast,d=l.getAnimationTime(),f=l.animation.timelines.length,u=l.animation.timelines;if(r==0&&a==1||s==A.add)for(let m=0;m1&&(r=1),e!=A.first&&(e=i.mixBlend));const h=r0&&this.queueEvents(i,o),this.events.length=0,i.nextAnimationLast=o,i.nextTrackLast=i.trackTime,r}applyRotateTimeline(t,n,e,i,r,h,l,s){if(s&&(h[l]=0),i==1){t.apply(n,0,e,null,1,r,J.mixIn);return}const a=t,o=a.frames,d=n.bones[a.boneIndex];let f=0,u=0;if(e=o[o.length-$t.ENTRIES])u=d.data.rotation+o[o.length+$t.PREV_ROTATION];else{const x=Ct.binarySearch(o,e,$t.ENTRIES),E=o[x+$t.PREV_ROTATION],w=o[x],b=a.getCurvePercent((x>>1)-1,1-(e-w)/(o[x+$t.PREV_TIME]-w));u=o[x+$t.ROTATION]-E,u-=(16384-(16384.499999999996-u/360|0))*360,u=E+u*b+d.data.rotation,u-=(16384-(16384.499999999996-u/360|0))*360}let m=0,g=u-f;if(g-=(16384-(16384.499999999996-g/360|0))*360,g==0)m=h[l];else{let x=0,E=0;s?(x=0,E=g):(x=h[l],E=h[l+1]);const w=g>0;let b=x>=0;C.signum(E)!=C.signum(g)&&Math.abs(E)<=90&&(Math.abs(x)>180&&(x+=360*C.signum(x)),b=w),m=g+x-x%360,b!=w&&(m+=360*C.signum(x)),h[l]=m}h[l+1]=g,f+=m*i,d.rotation=f-(16384-(16384.499999999996-f/360|0))*360}queueEvents(t,n){const e=t.animationStart,i=t.animationEnd,r=i-e,h=t.trackLast%r,l=this.events;let s=0;const a=l.length;for(;si||this.queue.event(t,d)}let o=!1;for(t.loop?o=r==0||h>t.trackTime%r:o=n>=i&&t.animationLast=this.tracks.length)return;const n=this.tracks[t];if(n==null)return;this.queue.end(n),this.disposeNext(n);let e=n;for(;;){const i=e.mixingFrom;if(i==null)break;this.queue.end(i),e.mixingFrom=null,e.mixingTo=null,e=i}this.tracks[n.trackIndex]=null,this.queue.drain()}setCurrent(t,n,e){const i=this.expandToIndex(t);this.tracks[t]=n,i!=null&&(e&&this.queue.interrupt(i),n.mixingFrom=i,i.mixingTo=n,n.mixTime=0,i.mixingFrom!=null&&i.mixDuration>0&&(n.interruptAlpha*=Math.min(1,i.mixTime/i.mixDuration)),i.timelinesRotation.length=0),this.queue.start(n)}setAnimation(t,n,e){const i=this.data.skeletonData.findAnimation(n);if(i==null)throw new Error(`Animation not found: ${n}`);return this.setAnimationWith(t,i,e)}setAnimationWith(t,n,e){if(n==null)throw new Error("animation cannot be null.");let i=!0,r=this.expandToIndex(t);r!=null&&(r.nextTrackLast==-1?(this.tracks[t]=r.mixingFrom,this.queue.interrupt(r),this.queue.end(r),this.disposeNext(r),r=r.mixingFrom,i=!1):this.disposeNext(r));const h=this.trackEntry(t,n,e,r);return this.setCurrent(t,h,i),this.queue.drain(),h}addAnimation(t,n,e,i){const r=this.data.skeletonData.findAnimation(n);if(r==null)throw new Error(`Animation not found: ${n}`);return this.addAnimationWith(t,r,e,i)}addAnimationWith(t,n,e,i){if(n==null)throw new Error("animation cannot be null.");let r=this.expandToIndex(t);if(r!=null)for(;r.next!=null;)r=r.next;const h=this.trackEntry(t,n,e,r);if(r==null)this.setCurrent(t,h,!0),this.queue.drain();else if(r.next=h,i<=0){const l=r.animationEnd-r.animationStart;l!=0?(r.loop?i+=l*(1+(r.trackTime/l|0)):i+=Math.max(l,r.trackTime),i-=this.data.getMix(r.animation,n)):i=r.trackTime}return h.delay=i,h}setEmptyAnimation(t,n){const e=this.setAnimationWith(t,Pt.emptyAnimation,!1);return e.mixDuration=n,e.trackEnd=n,e}addEmptyAnimation(t,n,e){e<=0&&(e-=n);const i=this.addAnimationWith(t,Pt.emptyAnimation,!1,e);return i.mixDuration=n,i.trackEnd=n,i}setEmptyAnimations(t){const n=this.queue.drainDisabled;this.queue.drainDisabled=!0;for(let e=0,i=this.tracks.length;e0){r[s]=Pt.HOLD_MIX,h[s]=o;continue t}break}r[s]=Pt.HOLD}}}hasTimeline(t,n){const e=t.animation.timelines;for(let i=0,r=e.length;i=this.tracks.length?null:this.tracks[t]}addListener(t){if(t==null)throw new Error("listener cannot be null.");this.listeners.push(t)}removeListener(t){const n=this.listeners.indexOf(t);n>=0&&this.listeners.splice(n,1)}clearListeners(){this.listeners.length=0}clearListenerNotifications(){this.queue.clear()}setAnimationByName(t,n,e){Pt.deprecatedWarning1||(Pt.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on.")),this.setAnimation(t,n,e)}addAnimationByName(t,n,e,i){Pt.deprecatedWarning2||(Pt.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on.")),this.addAnimation(t,n,e,i)}hasAnimation(t){return this.data.skeletonData.findAnimation(t)!==null}hasAnimationByName(t){return Pt.deprecatedWarning3||(Pt.deprecatedWarning3=!0,console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on.")),this.hasAnimation(t)}};let Ie=Pt;Ie.emptyAnimation=new Ct("",[],0),Ie.SUBSEQUENT=0,Ie.FIRST=1,Ie.HOLD=2,Ie.HOLD_MIX=3,Ie.deprecatedWarning1=!1,Ie.deprecatedWarning2=!1,Ie.deprecatedWarning3=!1;const Be=class{constructor(){this.mixBlend=A.replace,this.timelineMode=new Array,this.timelineHoldMix=new Array,this.timelinesRotation=new Array}reset(){this.next=null,this.mixingFrom=null,this.mixingTo=null,this.animation=null,this.listener=null,this.timelineMode.length=0,this.timelineHoldMix.length=0,this.timelinesRotation.length=0}getAnimationTime(){if(this.loop){const t=this.animationEnd-this.animationStart;return t==0?this.animationStart:this.trackTime%t+this.animationStart}return Math.min(this.trackTime+this.animationStart,this.animationEnd)}setAnimationLast(t){this.animationLast=t,this.nextAnimationLast=t}isComplete(){return this.trackTime>=this.animationEnd-this.animationStart}resetRotationDirections(){this.timelinesRotation.length=0}get time(){return Be.deprecatedWarning1||(Be.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime}set time(t){Be.deprecatedWarning1||(Be.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: TrackEntry.time is deprecated, please use trackTime from now on.")),this.trackTime=t}get endTime(){return Be.deprecatedWarning2||(Be.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime}set endTime(t){Be.deprecatedWarning2||(Be.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: TrackEntry.endTime is deprecated, please use trackEnd from now on.")),this.trackTime=t}loopsCount(){return Math.floor(this.trackTime/this.trackEnd)}};let _n=Be;_n.deprecatedWarning1=!1,_n.deprecatedWarning2=!1;const vs=class{constructor(c){this.objects=[],this.drainDisabled=!1,this.animState=c}start(c){this.objects.push(Zt.start),this.objects.push(c),this.animState.animationsChanged=!0}interrupt(c){this.objects.push(Zt.interrupt),this.objects.push(c)}end(c){this.objects.push(Zt.end),this.objects.push(c),this.animState.animationsChanged=!0}dispose(c){this.objects.push(Zt.dispose),this.objects.push(c)}complete(c){this.objects.push(Zt.complete),this.objects.push(c)}event(c,t){this.objects.push(Zt.event),this.objects.push(c),this.objects.push(t)}deprecateStuff(){return vs.deprecatedWarning1||(vs.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: onComplete, onStart, onEnd, onEvent art deprecated, please use listeners from now on. 'state.addListener({ complete: function(track, event) { } })'")),!0}drain(){if(this.drainDisabled)return;this.drainDisabled=!0;const c=this.objects,t=this.animState.listeners;for(let n=0;n(c[c.start=0]="start",c[c.interrupt=1]="interrupt",c[c.end=2]="end",c[c.dispose=3]="dispose",c[c.complete=4]="complete",c[c.event=5]="event",c))(Zt||{});class Dr{start(t){}interrupt(t){}end(t){}dispose(t){}complete(t){}event(t,n){}}const Vs=class{constructor(c){if(this.animationToMixTime={},this.defaultMix=0,c==null)throw new Error("skeletonData cannot be null.");this.skeletonData=c}setMix(c,t,n){const e=this.skeletonData.findAnimation(c);if(e==null)throw new Error(`Animation not found: ${c}`);const i=this.skeletonData.findAnimation(t);if(i==null)throw new Error(`Animation not found: ${t}`);this.setMixWith(e,i,n)}setMixByName(c,t,n){Vs.deprecatedWarning1||(Vs.deprecatedWarning1=!0,console.warn("Deprecation Warning: AnimationStateData.setMixByName is deprecated, please use setMix from now on.")),this.setMix(c,t,n)}setMixWith(c,t,n){if(c==null)throw new Error("from cannot be null.");if(t==null)throw new Error("to cannot be null.");const e=`${c.name}.${t.name}`;this.animationToMixTime[e]=n}getMix(c,t){const n=`${c.name}.${t.name}`,e=this.animationToMixTime[n];return e===void 0?this.defaultMix:e}};let Fs=Vs;Fs.deprecatedWarning1=!1;let Ui=class{constructor(t){this.atlas=t}newRegionAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (region attachment: ${n})`);const r=new K(n);return r.region=i,r}newMeshAttachment(t,n,e){const i=this.atlas.findRegion(e);if(i==null)throw new Error(`Region not found in atlas: ${e} (mesh attachment: ${n})`);const r=new Is(n);return r.region=i,r}newBoundingBoxAttachment(t,n){return new Ni(n)}newPathAttachment(t,n){return new kn(n)}newPointAttachment(t,n){return new Di(n)}newClippingAttachment(t,n){return new Bi(n)}},Ys=class{constructor(t,n,e){if(this.matrix=new H.Matrix,this.children=new Array,this.x=0,this.y=0,this.rotation=0,this.scaleX=0,this.scaleY=0,this.shearX=0,this.shearY=0,this.ax=0,this.ay=0,this.arotation=0,this.ascaleX=0,this.ascaleY=0,this.ashearX=0,this.ashearY=0,this.appliedValid=!1,this.sorted=!1,this.active=!0,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.skeleton=n,this.parent=e,this.setToSetupPose()}get worldX(){return this.matrix.tx}get worldY(){return this.matrix.ty}update(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransform(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransformWith(t,n,e,i,r,h,l){this.ax=t,this.ay=n,this.arotation=e,this.ascaleX=i,this.ascaleY=r,this.ashearX=h,this.ashearY=l,this.appliedValid=!0;const s=this.parent,a=this.matrix,o=this.skeleton.scaleX,d=zt.yDown?-this.skeleton.scaleY:this.skeleton.scaleY;if(s==null){const x=this.skeleton,E=e+90+l;a.a=C.cosDeg(e+h)*i*o,a.c=C.cosDeg(E)*r*o,a.b=C.sinDeg(e+h)*i*d,a.d=C.sinDeg(E)*r*d,a.tx=t*o+x.x,a.ty=n*d+x.y;return}let f=s.matrix.a,u=s.matrix.c,m=s.matrix.b,g=s.matrix.d;switch(a.tx=f*t+u*n+s.matrix.tx,a.ty=m*t+g*n+s.matrix.ty,this.data.transformMode){case j.Normal:{const x=e+90+l,E=C.cosDeg(e+h)*i,w=C.cosDeg(x)*r,b=C.sinDeg(e+h)*i,p=C.sinDeg(x)*r;a.a=f*E+u*b,a.c=f*w+u*p,a.b=m*E+g*b,a.d=m*w+g*p;return}case j.OnlyTranslation:{const x=e+90+l;a.a=C.cosDeg(e+h)*i,a.c=C.cosDeg(x)*r,a.b=C.sinDeg(e+h)*i,a.d=C.sinDeg(x)*r;break}case j.NoRotationOrReflection:{let x=f*f+m*m,E=0;x>1e-4?(x=Math.abs(f*g-u*m)/x,u=m*x,g=f*x,E=Math.atan2(m,f)*C.radDeg):(f=0,m=0,E=90-Math.atan2(g,u)*C.radDeg);const w=e+h-E,b=e+l-E+90,p=C.cosDeg(w)*i,S=C.cosDeg(b)*r,y=C.sinDeg(w)*i,M=C.sinDeg(b)*r;a.a=f*p-u*y,a.c=f*S-u*M,a.b=m*p+g*y,a.d=m*S+g*M;break}case j.NoScale:case j.NoScaleOrReflection:{const x=C.cosDeg(e),E=C.sinDeg(e);let w=(f*x+u*E)/o,b=(m*x+g*E)/d,p=Math.sqrt(w*w+b*b);p>1e-5&&(p=1/p),w*=p,b*=p,p=Math.sqrt(w*w+b*b),this.data.transformMode==j.NoScale&&f*g-u*m<0!=(zt.yDown?this.skeleton.scaleX<0!=this.skeleton.scaleY>0:this.skeleton.scaleX<0!=this.skeleton.scaleY<0)&&(p=-p);const S=Math.PI/2+Math.atan2(b,w),y=Math.cos(S)*p,M=Math.sin(S)*p,T=C.cosDeg(h)*i,k=C.cosDeg(90+l)*r,I=C.sinDeg(h)*i,R=C.sinDeg(90+l)*r;a.a=w*T+y*I,a.c=w*k+y*R,a.b=b*T+M*I,a.d=b*k+M*R;break}}a.a*=o,a.c*=o,a.b*=d,a.d*=d}setToSetupPose(){const t=this.data;this.x=t.x,this.y=t.y,this.rotation=t.rotation,this.scaleX=t.scaleX,this.scaleY=t.scaleY,this.shearX=t.shearX,this.shearY=t.shearY}getWorldRotationX(){return Math.atan2(this.matrix.b,this.matrix.a)*C.radDeg}getWorldRotationY(){return Math.atan2(this.matrix.d,this.matrix.c)*C.radDeg}getWorldScaleX(){const t=this.matrix;return Math.sqrt(t.a*t.a+t.c*t.c)}getWorldScaleY(){const t=this.matrix;return Math.sqrt(t.b*t.b+t.d*t.d)}updateAppliedTransform(){this.appliedValid=!0;const t=this.parent,n=this.matrix;if(t==null){this.ax=n.tx,this.ay=n.ty,this.arotation=Math.atan2(n.b,n.a)*C.radDeg,this.ascaleX=Math.sqrt(n.a*n.a+n.b*n.b),this.ascaleY=Math.sqrt(n.c*n.c+n.d*n.d),this.ashearX=0,this.ashearY=Math.atan2(n.a*n.c+n.b*n.d,n.a*n.d-n.b*n.c)*C.radDeg;return}const e=t.matrix,i=1/(e.a*e.d-e.b*e.c),r=n.tx-e.tx,h=n.ty-e.ty;this.ax=r*e.d*i-h*e.c*i,this.ay=h*e.a*i-r*e.b*i;const l=i*e.d,s=i*e.a,a=i*e.c,o=i*e.b,d=l*n.a-a*n.b,f=l*n.c-a*n.d,u=s*n.b-o*n.a,m=s*n.d-o*n.c;if(this.ashearX=0,this.ascaleX=Math.sqrt(d*d+u*u),this.ascaleX>1e-4){const g=d*m-f*u;this.ascaleY=g/this.ascaleX,this.ashearY=Math.atan2(d*f+u*m,g)*C.radDeg,this.arotation=Math.atan2(u,d)*C.radDeg}else this.ascaleX=0,this.ascaleY=Math.sqrt(f*f+m*m),this.ashearY=0,this.arotation=90-Math.atan2(m,f)*C.radDeg}worldToLocal(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=1/(e*h-i*r),s=t.x-n.tx,a=t.y-n.ty;return t.x=s*h*l-a*i*l,t.y=a*e*l-s*r*l,t}localToWorld(t){const n=this.matrix,e=t.x,i=t.y;return t.x=e*n.a+i*n.c+n.tx,t.y=e*n.b+i*n.d+n.ty,t}worldToLocalRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(i.a*n-i.b*e,i.d*e-i.c*n)*C.radDeg}localToWorldRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(e*i.b+n*i.d,e*i.a+n*i.c)*C.radDeg}rotateWorld(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=C.cosDeg(t),s=C.sinDeg(t);n.a=l*e-s*r,n.c=l*i-s*h,n.b=s*e+l*r,n.d=s*i+l*h,this.appliedValid=!1}},zi=class{constructor(t,n,e){if(this.x=0,this.y=0,this.rotation=0,this.scaleX=1,this.scaleY=1,this.shearX=0,this.shearY=0,this.transformMode=j.Normal,t<0)throw new Error("index must be >= 0.");if(n==null)throw new Error("name cannot be null.");this.index=t,this.name=n,this.parent=e}},Hi=class{constructor(t,n){if(n==null)throw new Error("data cannot be null.");this.time=t,this.data=n}},Gi=class{constructor(t){this.name=t}},ji=class{constructor(t,n){if(this.bendDirection=0,this.compress=!1,this.stretch=!1,this.mix=1,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.mix=t.mix,this.bendDirection=t.bendDirection,this.compress=t.compress,this.stretch=t.stretch,this.bones=new Array;for(let e=0;e180?m-=360:m<-180&&(m+=360);let g=t.ascaleX,x=t.ascaleY;if(i||r){const E=t.data.length*g,w=Math.sqrt(f*f+u*u);if(i&&wE&&E>1e-4){const b=(w/E-1)*l+1;g*=b,h&&(x*=b)}}t.updateWorldTransformWith(t.ax,t.ay,t.arotation+m*l,g,x,t.ashearX,t.ashearY)}apply2(t,n,e,i,r,h,l){if(l==0){n.updateWorldTransform();return}t.appliedValid||t.updateAppliedTransform(),n.appliedValid||n.updateAppliedTransform();const s=t.ax,a=t.ay;let o=t.ascaleX,d=o,f=t.ascaleY,u=n.ascaleX;const m=t.matrix;let g=0,x=0,E=0;o<0?(o=-o,g=180,E=-1):(g=0,E=1),f<0&&(f=-f,E=-E),u<0?(u=-u,x=180):x=0;const w=n.ax;let b=0,p=0,S=0,y=m.a,M=m.c,T=m.b,k=m.d;const I=Math.abs(o-f)<=1e-4;I?(b=n.ay,p=y*w+M*b+m.tx,S=T*w+k*b+m.ty):(b=0,p=y*w+m.tx,S=T*w+m.ty);const R=t.parent.matrix;y=R.a,M=R.c,T=R.b,k=R.d;const V=1/(y*k-M*T);let F=e-R.tx,B=i-R.ty;const Y=(F*k-B*M)*V-s,N=(B*y-F*T)*V-a,q=Y*Y+N*N;F=p-R.tx,B=S-R.ty;const z=(F*k-B*M)*V-s,D=(B*y-F*T)*V-a,X=Math.sqrt(z*z+D*D);let L=n.data.length*u,O=0,W=0;t:if(I){L*=o;let G=(q-X*X-L*L)/(2*X*L);G<-1?G=-1:G>1&&(G=1,h&&X+L>1e-4&&(d*=(Math.sqrt(q)/(X+L)-1)*l+1)),W=Math.acos(G)*r,y=X+L*G,M=L*Math.sin(W),O=Math.atan2(N*y-Y*M,Y*y+N*M)}else{y=o*L,M=f*L;const G=y*y,lt=M*M,It=Math.atan2(N,Y);T=lt*X*X+G*q-G*lt;const ct=-2*lt*X,Xt=lt-G;if(k=ct*ct-4*Xt*T,k>=0){let Kt=Math.sqrt(k);ct<0&&(Kt=-Kt),Kt=-(ct+Kt)/2;const ae=Kt/Xt,Ke=T/Kt,Nt=Math.abs(ae)=-1&&T<=1&&(T=Math.acos(T),F=y*Math.cos(T)+X,B=M*Math.sin(T),k=F*F+B*B,kCe&&(Ve=T,Ce=k,Ae=F,$e=B)),q<=(Me+Ce)/2?(O=It-Math.atan2(Oe*r,de),W=Ut*r):(O=It-Math.atan2($e*r,Ae),W=Ve*r)}const U=Math.atan2(b,w)*E;let $=t.arotation;O=(O-U)*C.radDeg+g-$,O>180?O-=360:O<-180&&(O+=360),t.updateWorldTransformWith(s,a,$+O*l,d,t.ascaleY,0,0),$=n.arotation,W=((W+U)*C.radDeg-n.ashearX)*E+x-$,W>180?W-=360:W<-180&&(W+=360),n.updateWorldTransformWith(w,b,$+W*l,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY)}},Zi=class{constructor(t){this.order=0,this.bones=new Array,this.bendDirection=1,this.compress=!1,this.stretch=!1,this.uniform=!1,this.mix=1,this.name=t}},Qi=class{constructor(t){this.order=0,this.bones=new Array,this.name=t}};var pe=(c=>(c[c.Length=0]="Length",c[c.Fixed=1]="Fixed",c[c.Percent=2]="Percent",c))(pe||{});const rn=class{constructor(t,n){if(this.position=0,this.spacing=0,this.rotateMix=0,this.translateMix=0,this.spaces=new Array,this.positions=new Array,this.world=new Array,this.curves=new Array,this.lengths=new Array,this.segments=new Array,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.bones=new Array;for(let e=0,i=t.bones.length;e0,r=n>0;if(!i&&!r)return;const h=this.data,l=h.spacingMode,s=l==pe.Length,a=h.rotateMode,o=a==pt.Tangent,d=a==pt.ChainScale,f=this.bones.length,u=o?f:f+1,m=this.bones,g=v.setArraySize(this.spaces,u);let x=null;const E=this.spacing;if(d||s){d&&(x=v.setArraySize(this.lengths,f));for(let M=0,T=u-1;M0?C.degRad:-C.degRad}for(let M=0,T=3;MC.PI?D-=C.PI2:D<-C.PI&&(D+=C.PI2),D*=n,X=Math.cos(D),L=Math.sin(D),I.a=X*Y-L*q,I.c=X*N-L*z,I.b=L*Y+X*q,I.d=L*N+X*z}k.appliedValid=!1}}computeWorldPositions(t,n,e,i,r){const h=this.target;let l=this.position;const s=this.spaces,a=v.setArraySize(this.positions,n*3+2);let o=null;const d=t.closed;let f=t.worldVerticesLength,u=f/6,m=rn.NONE;if(!t.constantSpeed){const D=t.lengths;u-=d?1:2;const X=D[u];if(i&&(l*=X),r)for(let L=0;LX){m!=rn.AFTER&&(m=rn.AFTER,t.computeWorldVertices(h,f-6,4,o,0,2)),this.addAfterPosition($-X,o,0,a,O);continue}for(;;W++){const G=D[W];if(!($>G)){if(W==0)$/=G;else{const lt=D[W-1];$=($-lt)/(G-lt)}break}}W!=m&&(m=W,d&&W==u?(t.computeWorldVertices(h,f-4,4,o,0,2),t.computeWorldVertices(h,0,4,o,4,2)):t.computeWorldVertices(h,W*6+2,8,o,0,2)),this.addCurvePosition($,o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7],a,O,e||L>0&&U==0)}return a}d?(f+=2,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f-4,o,0,2),t.computeWorldVertices(h,0,2,o,f-4,2),o[f-2]=o[0],o[f-1]=o[1]):(u--,f-=4,o=v.setArraySize(this.world,f),t.computeWorldVertices(h,2,f,o,0,2));const g=v.setArraySize(this.curves,u);let x=0,E=o[0],w=o[1],b=0,p=0,S=0,y=0,M=0,T=0,k=0,I=0,R=0,V=0,F=0,B=0,Y=0,N=0;for(let D=0,X=2;Dx){this.addAfterPosition(U-x,o,f-4,a,X);continue}for(;;L++){const $=g[L];if(!(U>$)){if(L==0)U/=$;else{const G=g[L-1];U=(U-G)/($-G)}break}}if(L!=m){m=L;let $=L*6;for(E=o[$],w=o[$+1],b=o[$+2],p=o[$+3],S=o[$+4],y=o[$+5],M=o[$+6],T=o[$+7],k=(E-b*2+S)*.03,I=(w-p*2+y)*.03,R=((b-S)*3-E+M)*.006,V=((p-y)*3-w+T)*.006,F=k*2+R,B=I*2+V,Y=(b-E)*.3+k+R*.16666667,N=(p-w)*.3+I+V*.16666667,z=Math.sqrt(Y*Y+N*N),q[0]=z,$=1;$<8;$++)Y+=F,N+=B,F+=R,B+=V,z+=Math.sqrt(Y*Y+N*N),q[$]=z;Y+=F,N+=B,z+=Math.sqrt(Y*Y+N*N),q[8]=z,Y+=F+R,N+=B+V,z+=Math.sqrt(Y*Y+N*N),q[9]=z,O=0}for(U*=z;;O++){const $=q[O];if(!(U>$)){if(O==0)U/=$;else{const G=q[O-1];U=O+(U-G)/($-G)}break}}this.addCurvePosition(U*.1,E,w,b,p,S,y,M,T,a,X,e||D>0&&W==0)}return a}addBeforePosition(t,n,e,i,r){const h=n[e],l=n[e+1],s=n[e+2]-h,a=n[e+3]-l,o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addAfterPosition(t,n,e,i,r){const h=n[e+2],l=n[e+3],s=h-n[e],a=l-n[e+1],o=Math.atan2(a,s);i[r]=h+t*Math.cos(o),i[r+1]=l+t*Math.sin(o),i[r+2]=o}addCurvePosition(t,n,e,i,r,h,l,s,a,o,d,f){(t==0||isNaN(t))&&(t=1e-4);const u=t*t,m=u*t,g=1-t,x=g*g,E=x*g,w=g*t,b=w*3,p=g*b,S=b*t,y=n*E+i*p+h*S+s*m,M=e*E+r*p+l*S+a*m;o[d]=y,o[d+1]=M,f&&(o[d+2]=Math.atan2(M-(e*x+r*w*2+l*u),y-(n*x+i*w*2+h*u)))}getOrder(){return this.data.order}};let wn=rn;wn.NONE=-1,wn.BEFORE=-2,wn.AFTER=-3,wn.epsilon=1e-5;let Ki=class{constructor(t,n){if(this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.temp=new un,t==null)throw new Error("data cannot be null.");if(n==null)throw new Error("skeleton cannot be null.");this.data=t,this.rotateMix=t.rotateMix,this.translateMix=t.translateMix,this.scaleMix=t.scaleMix,this.shearMix=t.shearMix,this.bones=new Array;for(let e=0;e0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=(p.x-b.tx)*n,b.ty+=(p.y-b.ty)*n,w=!0}if(e>0){let p=Math.sqrt(b.a*b.a+b.b*b.b),S=Math.sqrt(l*l+a*a);p>1e-5&&(p=(p+(S-p+this.data.offsetScaleX)*e)/p),b.a*=p,b.b*=p,p=Math.sqrt(b.c*b.c+b.d*b.d),S=Math.sqrt(s*s+o*o),p>1e-5&&(p=(p+(S-p+this.data.offsetScaleY)*e)/p),b.c*=p,b.d*=p,w=!0}if(i>0){const p=b.c,S=b.d,y=Math.atan2(S,p);let M=Math.atan2(o,s)-Math.atan2(a,l)-(y-Math.atan2(b.b,b.a));M>C.PI?M-=C.PI2:M<-C.PI&&(M+=C.PI2),M=y+(M+u)*i;const T=Math.sqrt(p*p+S*S);b.c=Math.cos(M)*T,b.d=Math.sin(M)*T,w=!0}w&&(E.appliedValid=!1)}}applyRelativeWorld(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target,h=r.matrix,l=h.a,s=h.c,a=h.b,o=h.d,d=l*o-s*a>0?C.degRad:-C.degRad,f=this.data.offsetRotation*d,u=this.data.offsetShearY*d,m=this.bones;for(let g=0,x=m.length;gC.PI?T-=C.PI2:T<-C.PI&&(T+=C.PI2),T*=t;const k=Math.cos(T),I=Math.sin(T);b.a=k*p-I*y,b.c=k*S-I*M,b.b=I*p+k*y,b.d=I*S+k*M,w=!0}if(n!=0){const p=this.temp;r.localToWorld(p.set(this.data.offsetX,this.data.offsetY)),b.tx+=p.x*n,b.ty+=p.y*n,w=!0}if(e>0){let p=(Math.sqrt(l*l+a*a)-1+this.data.offsetScaleX)*e+1;b.a*=p,b.b*=p,p=(Math.sqrt(s*s+o*o)-1+this.data.offsetScaleY)*e+1,b.c*=p,b.d*=p,w=!0}if(i>0){let p=Math.atan2(o,s)-Math.atan2(a,l);p>C.PI?p-=C.PI2:p<-C.PI&&(p+=C.PI2);const S=b.c,y=b.d;p=Math.atan2(y,S)+(p-C.PI/2+u)*i;const M=Math.sqrt(S*S+y*y);b.c=Math.cos(p)*M,b.d=Math.sin(p)*M,w=!0}w&&(E.appliedValid=!1)}}applyAbsoluteLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u=(u+(r.ascaleX-u+this.data.offsetScaleX)*e)/u),m>1e-5&&(m=(m+(r.ascaleY-m+this.data.offsetScaleY)*e)/m));const g=a.ashearY;if(i>0){let x=r.ashearY-g+this.data.offsetShearY;x-=(16384-(16384.499999999996-x/360|0))*360,a.shearY+=x*i}a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}applyRelativeLocal(){const t=this.rotateMix,n=this.translateMix,e=this.scaleMix,i=this.shearMix,r=this.target;r.appliedValid||r.updateAppliedTransform();const h=this.bones;for(let l=0,s=h.length;l0&&(u>1e-5&&(u*=(r.ascaleX-1+this.data.offsetScaleX)*e+1),m>1e-5&&(m*=(r.ascaleY-1+this.data.offsetScaleY)*e+1));let g=a.ashearY;i>0&&(g+=(r.ashearY+this.data.offsetShearY)*i),a.updateWorldTransformWith(d,f,o,u,m,a.ashearX,g)}}getOrder(){return this.data.order}};const In=class{constructor(t){if(this._updateCache=new Array,this.updateCacheReset=new Array,this.time=0,this.scaleX=1,this.scaleY=1,this.x=0,this.y=0,t==null)throw new Error("data cannot be null.");this.data=t,this.bones=new Array;for(let n=0;n1){const r=e[e.length-1];this._updateCache.indexOf(r)>-1||this.updateCacheReset.push(r)}this._updateCache.push(t),this.sortReset(i.children),e[e.length-1].sorted=!0}sortPathConstraint(t){const n=t.target,e=n.data.index,i=n.bone;this.skin!=null&&this.sortPathConstraintAttachment(this.skin,e,i),this.data.defaultSkin!=null&&this.data.defaultSkin!=this.skin&&this.sortPathConstraintAttachment(this.data.defaultSkin,e,i);for(let s=0,a=this.data.skins.length;s-1||this.updateCacheReset.push(r)}else for(let i=0;i= 0.");if(n==null)throw new Error("name cannot be null.");if(e==null)throw new Error("boneData cannot be null.");this.index=t,this.name=n,this.boneData=e}},er=class{constructor(t){if(this.order=0,this.bones=new Array,this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.offsetRotation=0,this.offsetX=0,this.offsetY=0,this.offsetScaleX=0,this.offsetScaleY=0,this.offsetShearY=0,this.relative=!1,this.local=!1,t==null)throw new Error("name cannot be null.");this.name=t}},nr=class{constructor(t){if(this.attachments=new Array,t==null)throw new Error("name cannot be null.");this.name=t}addAttachment(t,n,e){if(e==null)throw new Error("attachment cannot be null.");const i=this.attachments;t>=i.length&&(i.length=t+1),i[t]||(i[t]={}),i[t][n]=e}getAttachment(t,n){const e=this.attachments[t];return e?e[n]:null}attachAll(t,n){let e=0;for(let i=0;i=0;w--)u[w]==-1&&(u[w]=g[--E])}s.setFrame(o++,f.time,u)}r.push(s),h=Math.max(h,s.frames[s.getFrameCount()-1])}if(t.events){const s=new qi(t.events.length);let a=0;for(let o=0;o>1)*r;const h=c.bone.skeleton,l=c.deform;let s=this.vertices;const a=this.bones;if(!a){l.length>0&&(s=l);const u=c.bone.matrix,m=u.tx,g=u.ty,x=u.a,E=u.c,w=u.b,b=u.d;for(let p=t,S=i;S=this.regions.length&&(n=this.regions.length-1);const e=this.regions[n];t.region!=e&&(t.region=e)}getPath(c,t){let n=c;const e=(this.start+t).toString();for(let i=this.digits-e.length;i>0;i--)n+="0";return n+=e,n}static nextID(){return qn._nextID++}};let Un=qn;Un._nextID=0;var Re=(c=>(c[c.hold=0]="hold",c[c.once=1]="once",c[c.loop=2]="loop",c[c.pingpong=3]="pingpong",c[c.onceReverse=4]="onceReverse",c[c.loopReverse=5]="loopReverse",c[c.pingpongReverse=6]="pingpongReverse",c))(Re||{});const Bs=[0,1,2,3,4,5,6];class zn{constructor(t,n,e){if(this.timelines=[],this.timelineIds=new ss,!t)throw new Error("name cannot be null.");this.name=t,this.setTimelines(n),this.duration=e}setTimelines(t){if(!t)throw new Error("timelines cannot be null.");this.timelines=t,this.timelineIds.clear();for(let n=0;n0&&(n%=this.duration));const a=this.timelines;for(let o=0,d=a.length;on)return i-1;return e-1}static search(t,n,e){const i=t.length;for(let r=e;rn)return r-e;return i-e}}class be extends bt{constructor(t,n,e){super(t,e),this.curves=v.newFloatArray(t+n*18),this.curves[t-1]=1}setLinear(t){this.curves[t]=0}setStepped(t){this.curves[t]=1}shrink(t){const n=this.getFrameCount()+t*18;if(this.curves.length>n){const e=v.newFloatArray(n);v.arrayCopy(this.curves,0,e,0,n),this.curves=e}}setBezier(t,n,e,i,r,h,l,s,a,o,d){const f=this.curves;let u=this.getFrameCount()+t*18;e==0&&(f[n]=2+u);const m=(i-h*2+s)*.03,g=(r-l*2+a)*.03,x=((h-s)*3-i+o)*.006,E=((l-a)*3-r+d)*.006;let w=m*2+x,b=g*2+E,p=(h-i)*.3+m+x*.16666667,S=(l-r)*.3+g+E*.16666667,y=i+p,M=r+S;for(let T=u+18;ut){const a=this.frames[n],o=this.frames[n+e];return o+(t-a)/(r[i]-a)*(r[i+1]-o)}const h=i+18;for(i+=2;i=t){const a=r[i-2],o=r[i-1];return o+(t-a)/(r[i]-a)*(r[i+1]-o)}n+=this.getFrameEntries();const l=r[h-2],s=r[h-1];return s+(t-l)/(this.frames[n]-l)*(this.frames[n+e]-s)}}class Ee extends be{constructor(t,n,e){super(t,n,[e])}getFrameEntries(){return 2}setFrame(t,n,e){t<<=1,this.frames[t]=n,this.frames[t+1]=e}getCurveValue(t){const n=this.frames;let e=n.length-2;for(let r=2;r<=e;r+=2)if(n[r]>t){e=r-2;break}const i=this.curves[e>>1];switch(i){case 0:const r=n[e],h=n[e+1];return h+(t-r)/(n[e+2]-r)*(n[e+2+1]-h);case 1:return n[e+1]}return this.getBezierValue(t,e,1,i-2)}}class Hn extends be{constructor(t,n,e,i){super(t,n,[e,i])}getFrameEntries(){return 3}setFrame(t,n,e,i){t*=3,this.frames[t]=n,this.frames[t+1]=e,this.frames[t+2]=i}}class Rn extends Ee{constructor(t,n,e){super(t,n,`${ot.rotate}|${e}`),this.boneIndex=0,this.boneIndex=e}apply(t,n,e,i,r,h,l){const s=t.bones[this.boneIndex];if(!s.active)return;const a=this.frames;if(e>2];switch(g){case 0:const x=a[m];d=a[m+1],f=a[m+2],u=a[m+3];const E=(e-x)/(a[m+4]-x);d+=(a[m+4+1]-d)*E,f+=(a[m+4+2]-f)*E,u+=(a[m+4+3]-u)*E;break;case 1:d=a[m+1],f=a[m+2],u=a[m+3];break;default:d=this.getBezierValue(e,m,1,g-2),f=this.getBezierValue(e,m,2,g+18-2),u=this.getBezierValue(e,m,3,g+18*2-2)}if(r==1)o.r=d,o.g=f,o.b=u;else{if(h==A.setup){const x=s.data.color;o.r=x.r,o.g=x.g,o.b=x.b}o.r+=(d-o.r)*r,o.g+=(f-o.g)*r,o.b+=(u-o.b)*r}}}class js extends Ee{constructor(t,n,e){super(t,n,`${ot.alpha}|${e}`),this.slotIndex=0,this.slotIndex=e}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=s.color;if(e>3];switch(p){case 0:const S=a[b];f=a[b+1],u=a[b+2],m=a[b+3],g=a[b+4],x=a[b+5],E=a[b+6],w=a[b+7];const y=(e-S)/(a[b+8]-S);f+=(a[b+8+1]-f)*y,u+=(a[b+8+2]-u)*y,m+=(a[b+8+3]-m)*y,g+=(a[b+8+4]-g)*y,x+=(a[b+8+5]-x)*y,E+=(a[b+8+6]-E)*y,w+=(a[b+8+7]-w)*y;break;case 1:f=a[b+1],u=a[b+2],m=a[b+3],g=a[b+4],x=a[b+5],E=a[b+6],w=a[b+7];break;default:f=this.getBezierValue(e,b,1,p-2),u=this.getBezierValue(e,b,2,p+18-2),m=this.getBezierValue(e,b,3,p+18*2-2),g=this.getBezierValue(e,b,4,p+18*3-2),x=this.getBezierValue(e,b,5,p+18*4-2),E=this.getBezierValue(e,b,6,p+18*5-2),w=this.getBezierValue(e,b,7,p+18*6-2)}if(r==1)o.set(f,u,m,g),d.r=x,d.g=E,d.b=w;else{if(h==A.setup){o.setFromColor(s.data.color);const S=s.data.darkColor;d.r=S.r,d.g=S.g,d.b=S.b}o.add((f-o.r)*r,(u-o.g)*r,(m-o.b)*r,(g-o.a)*r),d.r+=(x-d.r)*r,d.g+=(E-d.g)*r,d.b+=(w-d.b)*r}}}class Qs extends be{constructor(t,n,e){super(t,n,[`${ot.rgb}|${e}`,`${ot.rgb2}|${e}`]),this.slotIndex=0,this.slotIndex=e}getFrameEntries(){return 7}setFrame(t,n,e,i,r,h,l,s){t*=7,this.frames[t]=n,this.frames[t+1]=e,this.frames[t+2]=i,this.frames[t+3]=r,this.frames[t+4]=h,this.frames[t+5]=l,this.frames[t+6]=s}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=this.frames,o=s.color,d=s.darkColor;if(et){const s=this.frames[n];return e[i+1]*(t-s)/(e[i]-s)}const r=i+18;for(i+=2;i=t){const s=e[i-2],a=e[i-1];return a+(t-s)/(e[i]-s)*(e[i+1]-a)}const h=e[r-2],l=e[r-1];return l+(1-l)*(t-h)/(this.frames[n+this.getFrameEntries()]-h)}apply(t,n,e,i,r,h,l){const s=t.slots[this.slotIndex];if(!s.bone.active)return;const a=s.getAttachment();if(!a||!(a instanceof we)||a.timelineAttachment!=this.attachment)return;const o=s.deform;o.length==0&&(h=A.setup);const d=this.vertices,f=d[0].length,u=this.frames;if(e=u[u.length-1]){const w=d[u.length-1];if(r==1)if(h==A.add){const b=a;if(b.bones)for(let p=0;pn)this.apply(c,t,Number.MAX_VALUE,e,i,r,h),t=-1;else if(t>=l[s-1])return;if(n0&&l[a-1]==o;)a--}for(;a=l[a];a++)e.push(this.events[a])}};let vn=rr;vn.propertyIds=[`${ot.event}`];const ar=class extends bt{constructor(c){super(c,ar.propertyIds),this.drawOrders=new Array(c)}getFrameCount(){return this.frames.length}setFrame(c,t,n){this.frames[c]=t,this.drawOrders[c]=n}apply(c,t,n,e,i,r,h){if(h==J.mixOut){r==A.setup&&v.arrayCopy(c.slots,0,c.drawOrder,0,c.slots.length);return}if(n>2];switch(m){case 0:const g=a[u];o=a[u+1],d=a[u+2],f=a[u+3];const x=(e-g)/(a[u+4]-g);o+=(a[u+4+1]-o)*x,d+=(a[u+4+2]-d)*x,f+=(a[u+4+3]-f)*x;break;case 1:o=a[u+1],d=a[u+2],f=a[u+3];break;default:o=this.getBezierValue(e,u,1,m-2),d=this.getBezierValue(e,u,2,m+18-2),f=this.getBezierValue(e,u,3,m+18*2-2)}if(h==A.setup){const g=s.data;s.mixRotate=g.mixRotate+(o-g.mixRotate)*r,s.mixX=g.mixX+(d-g.mixX)*r,s.mixY=g.mixY+(f-g.mixY)*r}else s.mixRotate+=(o-s.mixRotate)*r,s.mixX+=(d-s.mixX)*r,s.mixY+=(f-s.mixY)*r}}const Qe=class extends bt{constructor(c,t,n){super(c,[`${ot.sequence}|${t}|${n.sequence.id}`]),this.slotIndex=t,this.attachment=n}getFrameEntries(){return Qe.ENTRIES}getSlotIndex(){return this.slotIndex}getAttachment(){return this.attachment}setFrame(c,t,n,e,i){const r=this.frames;c*=Qe.ENTRIES,r[c]=t,r[c+Qe.MODE]=n|e<<4,r[c+Qe.DELAY]=i}apply(c,t,n,e,i,r,h){const l=c.slots[this.slotIndex];if(!l.bone.active)return;const s=l.attachment,a=this.attachment;if(s!=a&&(!(s instanceof we)||s.timelineAttachment!=a))return;const o=this.frames;if(n>4;const x=this.attachment.sequence.regions.length,E=Bs[u&15];if(E!=Re.hold)switch(g+=(n-f)/m+1e-5|0,E){case Re.once:g=Math.min(x-1,g);break;case Re.loop:g%=x;break;case Re.pingpong:{const w=(x<<1)-2;g=w==0?0:g%w,g>=x&&(g=w-g);break}case Re.onceReverse:g=Math.max(x-1-g,0);break;case Re.loopReverse:g=x-1-g%x;break;case Re.pingpongReverse:{const w=(x<<1)-2;g=w==0?0:(g+x-1)%w,g>=x&&(g=w-g)}}l.sequenceIndex=g}};let bn=Qe;bn.ENTRIES=3,bn.MODE=1,bn.DELAY=2;const ve=class{constructor(c){this.tracks=new Array,this.timeScale=1,this.unkeyedState=0,this.events=new Array,this.listeners=new Array,this.queue=new or(this),this.propertyIDs=new ss,this.animationsChanged=!1,this.trackEntryPool=new An(()=>new Gn),this.data=c}static emptyAnimation(){return ve._emptyAnimation}update(c){c*=this.timeScale;const t=this.tracks;for(let n=0,e=t.length;n0){if(i.delay-=r,i.delay>0)continue;r=-i.delay,i.delay=0}let h=i.next;if(h){const l=i.trackLast-h.delay;if(l>=0){for(h.delay=0,h.trackTime+=i.timeScale==0?0:(l/i.timeScale+c)*h.timeScale,i.trackTime+=r,this.setCurrent(n,h,!0);h.mixingFrom;)h.mixTime+=c,h=h.mixingFrom;continue}}else if(i.trackLast>=i.trackEnd&&!i.mixingFrom){t[n]=null,this.queue.end(i),this.clearNext(i);continue}if(i.mixingFrom&&this.updateMixingFrom(i,c)){let l=i.mixingFrom;for(i.mixingFrom=null,l&&(l.mixingTo=null);l;)this.queue.end(l),l=l.mixingFrom}i.trackTime+=r}this.queue.drain()}updateMixingFrom(c,t){const n=c.mixingFrom;if(!n)return!0;const e=this.updateMixingFrom(n,t);return n.animationLast=n.nextAnimationLast,n.trackLast=n.nextTrackLast,c.mixTime>0&&c.mixTime>=c.mixDuration?((n.totalAlpha==0||c.mixDuration==0)&&(c.mixingFrom=n.mixingFrom,n.mixingFrom&&(n.mixingFrom.mixingTo=c),c.interruptAlpha=n.interruptAlpha,this.queue.end(n)),e):(n.trackTime+=t*n.timeScale,c.mixTime+=t,!1)}apply(c){if(!c)throw new Error("skeleton cannot be null.");this.animationsChanged&&this._animationsChanged();const t=this.events,n=this.tracks;let e=!1;for(let h=0,l=n.length;h0)continue;e=!0;const a=h==0?A.first:s.mixBlend;let o=s.alpha;s.mixingFrom?o*=this.applyMixingFrom(s,c,a):s.trackTime>=s.trackEnd&&!s.next&&(o=0);const d=s.animationLast,f=s.getAnimationTime();let u=f,m=t;s.reverse&&(u=s.animation.duration-u,m=null);const g=s.animation.timelines,x=g.length;if(h==0&&o==1||a==A.add)for(let E=0;E1&&(i=1),n!=A.first&&(n=e.mixBlend));const r=i0&&this.queueEvents(e,f),this.events.length=0,e.nextAnimationLast=f,e.nextTrackLast=e.trackTime,i}applyAttachmentTimeline(c,t,n,e,i){const r=t.slots[c.slotIndex];r.bone.active&&(n0;let E=m>=0;C.signum(g)!=C.signum(u)&&Math.abs(g)<=90&&(Math.abs(m)>180&&(m+=360*C.signum(m)),E=x),f=u+m-m%360,E!=x&&(f+=360*C.signum(m)),r[h]=f}r[h+1]=u,s.rotation=o+f*e}queueEvents(c,t){const n=c.animationStart,e=c.animationEnd,i=e-n,r=c.trackLast%i,h=this.events;let l=0;const s=h.length;for(;le||this.queue.event(c,o)}let a=!1;for(c.loop?a=i==0||r>c.trackTime%i:a=t>=e&&c.animationLast=this.tracks.length)return;const t=this.tracks[c];if(!t)return;this.queue.end(t),this.clearNext(t);let n=t;for(;;){const e=n.mixingFrom;if(!e)break;this.queue.end(e),n.mixingFrom=null,n.mixingTo=null,n=e}this.tracks[t.trackIndex]=null,this.queue.drain()}setCurrent(c,t,n){const e=this.expandToIndex(c);this.tracks[c]=t,t.previous=null,e&&(n&&this.queue.interrupt(e),t.mixingFrom=e,e.mixingTo=t,t.mixTime=0,e.mixingFrom&&e.mixDuration>0&&(t.interruptAlpha*=Math.min(1,e.mixTime/e.mixDuration)),e.timelinesRotation.length=0),this.queue.start(t)}setAnimation(c,t,n=!1){const e=this.data.skeletonData.findAnimation(t);if(!e)throw new Error(`Animation not found: ${t}`);return this.setAnimationWith(c,e,n)}setAnimationWith(c,t,n=!1){if(!t)throw new Error("animation cannot be null.");let e=!0,i=this.expandToIndex(c);i&&(i.nextTrackLast==-1?(this.tracks[c]=i.mixingFrom,this.queue.interrupt(i),this.queue.end(i),this.clearNext(i),i=i.mixingFrom,e=!1):this.clearNext(i));const r=this.trackEntry(c,t,n,i);return this.setCurrent(c,r,e),this.queue.drain(),r}addAnimation(c,t,n=!1,e=0){const i=this.data.skeletonData.findAnimation(t);if(!i)throw new Error(`Animation not found: ${t}`);return this.addAnimationWith(c,i,n,e)}addAnimationWith(c,t,n=!1,e=0){if(!t)throw new Error("animation cannot be null.");let i=this.expandToIndex(c);if(i)for(;i.next;)i=i.next;const r=this.trackEntry(c,t,n,i);return i?(i.next=r,r.previous=i,e<=0&&(e+=i.getTrackComplete()-r.mixDuration)):(this.setCurrent(c,r,!0),this.queue.drain()),r.delay=e,r}setEmptyAnimation(c,t=0){const n=this.setAnimationWith(c,ve.emptyAnimation(),!1);return n.mixDuration=t,n.trackEnd=t,n}addEmptyAnimation(c,t=0,n=0){const e=this.addAnimationWith(c,ve.emptyAnimation(),!1,n);return n<=0&&(e.delay+=e.mixDuration-t),e.mixDuration=t,e.trackEnd=t,e}setEmptyAnimations(c=0){const t=this.queue.drainDisabled;this.queue.drainDisabled=!0;for(let n=0,e=this.tracks.length;n0){i[l]=Wr,r[l]=o;continue t}break}i[l]=ri}}}getCurrent(c){return c>=this.tracks.length?null:this.tracks[c]}addListener(c){if(!c)throw new Error("listener cannot be null.");this.listeners.push(c)}removeListener(c){const t=this.listeners.indexOf(c);t>=0&&this.listeners.splice(t,1)}clearListeners(){this.listeners.length=0}clearListenerNotifications(){this.queue.clear()}setAnimationByName(c,t,n){ve.deprecatedWarning1||(ve.deprecatedWarning1=!0,console.warn("Spine Deprecation Warning: AnimationState.setAnimationByName is deprecated, please use setAnimation from now on.")),this.setAnimation(c,t,n)}addAnimationByName(c,t,n,e){ve.deprecatedWarning2||(ve.deprecatedWarning2=!0,console.warn("Spine Deprecation Warning: AnimationState.addAnimationByName is deprecated, please use addAnimation from now on.")),this.addAnimation(c,t,n,e)}hasAnimation(c){return this.data.skeletonData.findAnimation(c)!==null}hasAnimationByName(c){return ve.deprecatedWarning3||(ve.deprecatedWarning3=!0,console.warn("Spine Deprecation Warning: AnimationState.hasAnimationByName is deprecated, please use hasAnimation from now on.")),this.hasAnimation(c)}};let En=ve;En._emptyAnimation=new zn("",[],0),En.deprecatedWarning1=!1,En.deprecatedWarning2=!1,En.deprecatedWarning3=!1;const De=class{constructor(){this.animation=null,this.previous=null,this.next=null,this.mixingFrom=null,this.mixingTo=null,this.listener=null,this.trackIndex=0,this.loop=!1,this.holdPrevious=!1,this.reverse=!1,this.shortestRotation=!1,this.eventThreshold=0,this.attachmentThreshold=0,this.drawOrderThreshold=0,this.animationStart=0,this.animationEnd=0,this.animationLast=0,this.nextAnimationLast=0,this.delay=0,this.trackTime=0,this.trackLast=0,this.nextTrackLast=0,this.trackEnd=0,this.timeScale=0,this.alpha=0,this.mixTime=0,this.mixDuration=0,this.interruptAlpha=0,this.totalAlpha=0,this.mixBlend=A.replace,this.timelineMode=new Array,this.timelineHoldMix=new Array,this.timelinesRotation=new Array}reset(){this.next=null,this.previous=null,this.mixingFrom=null,this.mixingTo=null,this.animation=null,this.listener=null,this.timelineMode.length=0,this.timelineHoldMix.length=0,this.timelinesRotation.length=0}getAnimationTime(){if(this.loop){const c=this.animationEnd-this.animationStart;return c==0?this.animationStart:this.trackTime%c+this.animationStart}return Math.min(this.trackTime+this.animationStart,this.animationEnd)}setAnimationLast(c){this.animationLast=c,this.nextAnimationLast=c}isComplete(){return this.trackTime>=this.animationEnd-this.animationStart}resetRotationDirections(){this.timelinesRotation.length=0}getTrackComplete(){const c=this.animationEnd-this.animationStart;if(c!=0){if(this.loop)return c*(1+(this.trackTime/c|0));if(this.trackTime(c[c.start=0]="start",c[c.interrupt=1]="interrupt",c[c.end=2]="end",c[c.dispose=3]="dispose",c[c.complete=4]="complete",c[c.event=5]="event",c))(Qt||{});class $r{start(t){}interrupt(t){}end(t){}dispose(t){}complete(t){}event(t,n){}}const ii=0,lr=1,cr=2,ri=3,Wr=4,hr=1,qr=2;class dr{constructor(t){if(this.animationToMixTime={},this.defaultMix=0,!t)throw new Error("skeletonData cannot be null.");this.skeletonData=t}setMix(t,n,e){const i=this.skeletonData.findAnimation(t);if(!i)throw new Error(`Animation not found: ${t}`);const r=this.skeletonData.findAnimation(n);if(!r)throw new Error(`Animation not found: ${n}`);this.setMixWith(i,r,e)}setMixWith(t,n,e){if(!t)throw new Error("from cannot be null.");if(!n)throw new Error("to cannot be null.");const i=`${t.name}.${n.name}`;this.animationToMixTime[i]=e}getMix(t,n){const e=`${t.name}.${n.name}`,i=this.animationToMixTime[e];return i===void 0?this.defaultMix:i}}class ai{constructor(t){this.atlas=t}loadSequence(t,n,e){const i=e.regions;for(let r=0,h=i.length;r1e-4?(x=Math.abs(f*g-u*m)/x,f/=o,m/=d,u=m*x,g=f*x,E=Math.atan2(m,f)*C.radDeg):(f=0,m=0,E=90-Math.atan2(g,u)*C.radDeg);const w=e+h-E,b=e+l-E+90,p=C.cosDeg(w)*i,S=C.cosDeg(b)*r,y=C.sinDeg(w)*i,M=C.sinDeg(b)*r;a.a=f*p-u*y,a.c=f*S-u*M,a.b=m*p+g*y,a.d=m*S+g*M;break}case j.NoScale:case j.NoScaleOrReflection:{const x=C.cosDeg(e),E=C.sinDeg(e);let w=(f*x+u*E)/o,b=(m*x+g*E)/d,p=Math.sqrt(w*w+b*b);p>1e-5&&(p=1/p),w*=p,b*=p,p=Math.sqrt(w*w+b*b),this.data.transformMode==j.NoScale&&f*g-u*m<0!=(o<0!=d<0)&&(p=-p);const S=Math.PI/2+Math.atan2(b,w),y=Math.cos(S)*p,M=Math.sin(S)*p,T=C.cosDeg(h)*i,k=C.cosDeg(90+l)*r,I=C.sinDeg(h)*i,R=C.sinDeg(90+l)*r;a.a=w*T+y*I,a.c=w*k+y*R,a.b=b*T+M*I,a.d=b*k+M*R;break}}a.a*=o,a.c*=o,a.b*=d,a.d*=d}setToSetupPose(){const t=this.data;this.x=t.x,this.y=t.y,this.rotation=t.rotation,this.scaleX=t.scaleX,this.scaleY=t.scaleY,this.shearX=t.shearX,this.shearY=t.shearY}getWorldRotationX(){return Math.atan2(this.matrix.b,this.matrix.a)*C.radDeg}getWorldRotationY(){return Math.atan2(this.matrix.d,this.matrix.c)*C.radDeg}getWorldScaleX(){const t=this.matrix;return Math.sqrt(t.a*t.a+t.b*t.b)}getWorldScaleY(){const t=this.matrix;return Math.sqrt(t.c*t.c+t.d*t.d)}updateAppliedTransform(){const t=this.parent,n=this.matrix;if(!t){this.ax=n.tx-this.skeleton.x,this.ay=n.ty-this.skeleton.y,this.arotation=Math.atan2(n.b,n.a)*C.radDeg,this.ascaleX=Math.sqrt(n.a*n.a+n.b*n.b),this.ascaleY=Math.sqrt(n.c*n.c+n.d*n.d),this.ashearX=0,this.ashearY=Math.atan2(n.a*n.c+n.b*n.d,n.a*n.d-n.b*n.c)*C.radDeg;return}const e=t.matrix,i=1/(e.a*e.d-e.b*e.c),r=n.tx-e.tx,h=n.ty-e.ty;this.ax=r*e.d*i-h*e.c*i,this.ay=h*e.a*i-r*e.b*i;const l=i*e.d,s=i*e.a,a=i*e.c,o=i*e.b,d=l*n.a-a*n.b,f=l*n.c-a*n.d,u=s*n.b-o*n.a,m=s*n.d-o*n.c;if(this.ashearX=0,this.ascaleX=Math.sqrt(d*d+u*u),this.ascaleX>1e-4){const g=d*m-f*u;this.ascaleY=g/this.ascaleX,this.ashearY=Math.atan2(d*f+u*m,g)*C.radDeg,this.arotation=Math.atan2(u,d)*C.radDeg}else this.ascaleX=0,this.ascaleY=Math.sqrt(f*f+m*m),this.ashearY=0,this.arotation=90-Math.atan2(m,f)*C.radDeg}worldToLocal(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=1/(e*h-i*r),s=t.x-n.tx,a=t.y-n.ty;return t.x=s*h*l-a*i*l,t.y=a*e*l-s*r*l,t}localToWorld(t){const n=this.matrix,e=t.x,i=t.y;return t.x=e*n.a+i*n.c+n.tx,t.y=e*n.b+i*n.d+n.ty,t}worldToLocalRotation(t){const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(i.a*n-i.b*e,i.d*e-i.c*n)*C.radDeg}localToWorldRotation(t){t-=this.rotation-this.shearX;const n=C.sinDeg(t),e=C.cosDeg(t),i=this.matrix;return Math.atan2(e*i.b+n*i.d,e*i.a+n*i.c)*C.radDeg}rotateWorld(t){const n=this.matrix,e=n.a,i=n.c,r=n.b,h=n.d,l=C.cosDeg(t),s=C.sinDeg(t);n.a=l*e-s*r,n.c=l*i-s*h,n.b=s*e+l*r,n.d=s*i+l*h}}class li{constructor(t,n,e){if(this.index=0,this.parent=null,this.length=0,this.x=0,this.y=0,this.rotation=0,this.scaleX=1,this.scaleY=1,this.shearX=0,this.shearY=0,this.transformMode=j.Normal,this.skinRequired=!1,this.color=new _,t<0)throw new Error("index must be >= 0.");if(!n)throw new Error("name cannot be null.");this.index=t,this.name=n,this.parent=e}}class jn{constructor(t,n,e){this.name=t,this.order=n,this.skinRequired=e}}class ci{constructor(t,n){if(this.intValue=0,this.floatValue=0,this.stringValue=null,this.time=0,this.volume=0,this.balance=0,!n)throw new Error("data cannot be null.");this.time=t,this.data=n}}class hi{constructor(t){this.intValue=0,this.floatValue=0,this.stringValue=null,this.audioPath=null,this.volume=0,this.balance=0,this.name=t}}class fr{constructor(t,n){if(this.bendDirection=0,this.compress=!1,this.stretch=!1,this.mix=1,this.softness=0,this.active=!1,!t)throw new Error("data cannot be null.");if(!n)throw new Error("skeleton cannot be null.");this.data=t,this.mix=t.mix,this.softness=t.softness,this.bendDirection=t.bendDirection,this.compress=t.compress,this.stretch=t.stretch,this.bones=new Array;for(let i=0;i180?u-=360:u<-180&&(u+=360);let w=t.ascaleX,b=t.ascaleY;if(i||r){switch(t.data.transformMode){case j.NoScale:case j.NoScaleOrReflection:m=n-t.worldX,g=e-t.worldY}const p=t.data.length*w,S=Math.sqrt(m*m+g*g);if(i&&Sp&&p>1e-4){const y=(S/p-1)*l+1;w*=y,h&&(b*=y)}}t.updateWorldTransformWith(t.ax,t.ay,t.arotation+u*l,w,b,t.ashearX,t.ashearY)}apply2(t,n,e,i,r,h,l,s,a){const o=t.ax,d=t.ay;let f=t.ascaleX,u=t.ascaleY,m=f,g=u,x=n.ascaleX;const E=t.matrix;let w=0,b=0,p=0;f<0?(f=-f,w=180,p=-1):(w=0,p=1),u<0&&(u=-u,p=-p),x<0?(x=-x,b=180):b=0;const S=n.ax;let y=0,M=0,T=0,k=E.a,I=E.c,R=E.b,V=E.d;const F=Math.abs(f-u)<=1e-4;!F||h?(y=0,M=k*S+E.tx,T=R*S+E.ty):(y=n.ay,M=k*S+I*y+E.tx,T=R*S+V*y+E.ty);const B=t.parent.matrix;if(!B)throw new Error("IK parent must itself have a parent.");k=B.a,I=B.c,R=B.b,V=B.d;const Y=1/(k*V-I*R);let N=M-B.tx,q=T-B.ty;const z=(N*V-q*I)*Y-o,D=(q*k-N*R)*Y-d,X=Math.sqrt(z*z+D*D);let L=n.data.length*x,O,W;if(X<1e-4){this.apply1(t,e,i,!1,h,!1,a),n.updateWorldTransformWith(S,y,0,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY);return}N=e-B.tx,q=i-B.ty;let U=(N*V-q*I)*Y-o,$=(q*k-N*R)*Y-d,G=U*U+$*$;if(s!=0){s*=f*(x+1)*.5;const ct=Math.sqrt(G),Xt=ct-X-L*f+s;if(Xt>0){let Ut=Math.min(1,Xt/(s*2))-1;Ut=(Xt-s*(1-Ut*Ut))/ct,U-=Ut*U,$-=Ut*$,G=U*U+$*$}}t:if(F){L*=f;let ct=(G-X*X-L*L)/(2*X*L);ct<-1?(ct=-1,W=Math.PI*r):ct>1?(ct=1,W=0,h&&(k=(Math.sqrt(G)/(X+L)-1)*a+1,m*=k,l&&(g*=k))):W=Math.acos(ct)*r,k=X+L*ct,I=L*Math.sin(W),O=Math.atan2($*k-U*I,U*k+$*I)}else{k=f*L,I=u*L;const ct=k*k,Xt=I*I,Ut=Math.atan2($,U);R=Xt*X*X+ct*G-ct*Xt;const de=-2*Xt*X,Me=Xt-ct;if(V=de*de-4*Me*R,V>=0){let Nt=Math.sqrt(V);de<0&&(Nt=-Nt),Nt=-(de+Nt)*.5;const We=Nt/Me,pr=R/Nt,yn=Math.abs(We)=-1&&R<=1&&(R=Math.acos(R),N=k*Math.cos(R)+X,q=I*Math.sin(R),V=N*N+q*q,Vae&&($e=R,ae=V,Kt=N,Ke=q)),G<=(Ae+ae)*.5?(O=Ut-Math.atan2(Ce*r,Ve),W=Oe*r):(O=Ut-Math.atan2(Ke*r,Kt),W=$e*r)}const lt=Math.atan2(y,S)*p;let It=t.arotation;O=(O-lt)*C.radDeg+w-It,O>180?O-=360:O<-180&&(O+=360),t.updateWorldTransformWith(o,d,It+O*a,m,g,0,0),It=n.arotation,W=((W+lt)*C.radDeg-n.ashearX)*p+b-It,W>180?W-=360:W<-180&&(W+=360),n.updateWorldTransformWith(S,y,It+W*a,n.ascaleX,n.ascaleY,n.ashearX,n.ashearY)}}class di extends jn{constructor(t){super(t,0,!1),this.bones=new Array,this._target=null,this.bendDirection=1,this.compress=!1,this.stretch=!1,this.uniform=!1,this.mix=1,this.softness=0}set target(t){this._target=t}get target(){if(this._target)return this._target;throw new Error("BoneData not set.")}}class fi extends jn{constructor(t){super(t,0,!1),this.bones=new Array,this._target=null,this.positionMode=dt.Fixed,this.spacingMode=kt.Fixed,this.rotateMode=pt.Chain,this.offsetRotation=0,this.position=0,this.spacing=0,this.mixRotate=0,this.mixX=0,this.mixY=0}set target(t){this._target=t}get target(){if(this._target)return this._target;throw new Error("SlotData not set.")}}var kt=(c=>(c[c.Length=0]="Length",c[c.Fixed=1]="Fixed",c[c.Percent=2]="Percent",c[c.Proportional=3]="Proportional",c))(kt||{});const Le=class{constructor(c,t){if(this.position=0,this.spacing=0,this.mixRotate=0,this.mixX=0,this.mixY=0,this.spaces=new Array,this.positions=new Array,this.world=new Array,this.curves=new Array,this.lengths=new Array,this.segments=new Array,this.active=!1,!c)throw new Error("data cannot be null.");if(!t)throw new Error("skeleton cannot be null.");this.data=c,this.bones=new Array;for(let e=0,i=c.bones.length;e0){w=a/w*f;for(let p=1;p0?C.degRad:-C.degRad}for(let w=0,b=3;w0){const I=S.a,R=S.c,V=S.b,F=S.d;let B=0,Y=0,N=0;if(r?B=u[b-1]:o[w+1]==0?B=u[b+2]:B=Math.atan2(k,T),B-=Math.atan2(V,I),E){Y=Math.cos(B),N=Math.sin(B);const q=p.data.length;m+=(q*(Y*I-N*V)-T)*t,g+=(q*(N*I+Y*V)-k)*t}else B+=x;B>C.PI?B-=C.PI2:B<-C.PI&&(B+=C.PI2),B*=t,Y=Math.cos(B),N=Math.sin(B),S.a=Y*I-N*V,S.c=Y*R-N*F,S.b=N*I+Y*V,S.d=N*R+Y*F}p.updateAppliedTransform()}}computeWorldPositions(c,t,n){const e=this.target;let i=this.position;const r=this.spaces,h=v.setArraySize(this.positions,t*3+2);let l=this.world;const s=c.closed;let a=c.worldVerticesLength,o=a/6,d=Le.NONE;if(!c.constantSpeed){const q=c.lengths;o-=s?1:2;const z=q[o];this.data.positionMode==dt.Percent&&(i*=z);let D;switch(this.data.spacingMode){case kt.Percent:D=z;break;case kt.Proportional:D=z/t;break;default:D=1}l=v.setArraySize(this.world,8);for(let X=0,L=0,O=0;Xz){d!=Le.AFTER&&(d=Le.AFTER,c.computeWorldVertices(e,a-6,4,l,0,2)),this.addAfterPosition(U-z,l,0,h,L);continue}for(;;O++){const $=q[O];if(!(U>$)){if(O==0)U/=$;else{const G=q[O-1];U=(U-G)/($-G)}break}}O!=d&&(d=O,s&&O==o?(c.computeWorldVertices(e,a-4,4,l,0,2),c.computeWorldVertices(e,0,4,l,4,2)):c.computeWorldVertices(e,O*6+2,8,l,0,2)),this.addCurvePosition(U,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],h,L,n||X>0&&W==0)}return h}s?(a+=2,l=v.setArraySize(this.world,a),c.computeWorldVertices(e,2,a-4,l,0,2),c.computeWorldVertices(e,0,2,l,a-4,2),l[a-2]=l[0],l[a-1]=l[1]):(o--,a-=4,l=v.setArraySize(this.world,a),c.computeWorldVertices(e,2,a,l,0,2));const f=v.setArraySize(this.curves,o);let u=0,m=l[0],g=l[1],x=0,E=0,w=0,b=0,p=0,S=0,y=0,M=0,T=0,k=0,I=0,R=0,V=0,F=0;for(let q=0,z=2;qu){this.addAfterPosition(O-u,l,a-4,h,z);continue}for(;;D++){const W=f[D];if(!(O>W)){if(D==0)O/=W;else{const U=f[D-1];O=(O-U)/(W-U)}break}}if(D!=d){d=D;let W=D*6;for(m=l[W],g=l[W+1],x=l[W+2],E=l[W+3],w=l[W+4],b=l[W+5],p=l[W+6],S=l[W+7],y=(m-x*2+w)*.03,M=(g-E*2+b)*.03,T=((x-w)*3-m+p)*.006,k=((E-b)*3-g+S)*.006,I=y*2+T,R=M*2+k,V=(x-m)*.3+y+T*.16666667,F=(E-g)*.3+M+k*.16666667,N=Math.sqrt(V*V+F*F),Y[0]=N,W=1;W<8;W++)V+=I,F+=R,I+=T,R+=k,N+=Math.sqrt(V*V+F*F),Y[W]=N;V+=I,F+=R,N+=Math.sqrt(V*V+F*F),Y[8]=N,V+=I+T,F+=R+k,N+=Math.sqrt(V*V+F*F),Y[9]=N,X=0}for(O*=N;;X++){const W=Y[X];if(!(O>W)){if(X==0)O/=W;else{const U=Y[X-1];O=X+(O-U)/(W-U)}break}}this.addCurvePosition(O*.1,m,g,x,E,w,b,p,S,h,z,n||q>0&&L==0)}return h}addBeforePosition(c,t,n,e,i){const r=t[n],h=t[n+1],l=t[n+2]-r,s=t[n+3]-h,a=Math.atan2(s,l);e[i]=r+c*Math.cos(a),e[i+1]=h+c*Math.sin(a),e[i+2]=a}addAfterPosition(c,t,n,e,i){const r=t[n+2],h=t[n+3],l=r-t[n],s=h-t[n+1],a=Math.atan2(s,l);e[i]=r+c*Math.cos(a),e[i+1]=h+c*Math.sin(a),e[i+2]=a}addCurvePosition(c,t,n,e,i,r,h,l,s,a,o,d){if(c==0||isNaN(c)){a[o]=t,a[o+1]=n,a[o+2]=Math.atan2(i-n,e-t);return}const f=c*c,u=f*c,m=1-c,g=m*m,x=g*m,E=m*c,w=E*3,b=m*w,p=w*c,S=t*x+e*b+r*p+l*u,y=n*x+i*b+h*p+s*u;a[o]=S,a[o+1]=y,d&&(c<.001?a[o+2]=Math.atan2(i-n,e-t):a[o+2]=Math.atan2(y-(n*g+i*E*2+h*f),S-(t*g+e*E*2+r*f)))}};let Sn=Le;Sn.NONE=-1,Sn.BEFORE=-2,Sn.AFTER=-3,Sn.epsilon=1e-5;class ur{constructor(t,n){if(this.darkColor=null,this.attachment=null,this.attachmentState=0,this.sequenceIndex=-1,this.deform=new Array,!t)throw new Error("data cannot be null.");if(!n)throw new Error("bone cannot be null.");this.data=t,this.bone=n,this.color=new _,this.darkColor=t.darkColor?new _:null,this.setToSetupPose(),this.blendMode=this.data.blendMode}getSkeleton(){return this.bone.skeleton}getAttachment(){return this.attachment}setAttachment(t){this.attachment!=t&&((!(t instanceof we)||!(this.attachment instanceof we)||t.timelineAttachment!=this.attachment.timelineAttachment)&&(this.deform.length=0),this.attachment=t,this.sequenceIndex=-1)}setToSetupPose(){this.color.setFromColor(this.data.color),this.darkColor&&this.darkColor.setFromColor(this.data.darkColor),this.data.attachmentName?(this.attachment=null,this.setAttachment(this.bone.skeleton.getAttachment(this.data.index,this.data.attachmentName))):this.attachment=null}}class mr{constructor(t,n){if(this.mixRotate=0,this.mixX=0,this.mixY=0,this.mixScaleX=0,this.mixScaleY=0,this.mixShearY=0,this.temp=new un,this.active=!1,!t)throw new Error("data cannot be null.");if(!n)throw new Error("skeleton cannot be null.");this.data=t,this.mixRotate=t.mixRotate,this.mixX=t.mixX,this.mixY=t.mixY,this.mixScaleX=t.mixScaleX,this.mixScaleY=t.mixScaleY,this.mixShearY=t.mixShearY,this.bones=new Array;for(let i=0;i0?C.degRad:-C.degRad,g=this.data.offsetRotation*m,x=this.data.offsetShearY*m,E=this.bones;for(let w=0,b=E.length;wC.PI?I-=C.PI2:I<-C.PI&&(I+=C.PI2),I*=t;const R=Math.cos(I),V=Math.sin(I);S.a=R*y-V*T,S.c=R*M-V*k,S.b=V*y+R*T,S.d=V*M+R*k}if(l){const y=this.temp;s.localToWorld(y.set(this.data.offsetX,this.data.offsetY)),S.tx+=(y.x-S.tx)*n,S.ty+=(y.y-S.ty)*e}if(i!=0){let y=Math.sqrt(S.a*S.a+S.b*S.b);y!=0&&(y=(y+(Math.sqrt(o*o+f*f)-y+this.data.offsetScaleX)*i)/y),S.a*=y,S.b*=y}if(r!=0){let y=Math.sqrt(S.c*S.c+S.d*S.d);y!=0&&(y=(y+(Math.sqrt(d*d+u*u)-y+this.data.offsetScaleY)*r)/y),S.c*=y,S.d*=y}if(h>0){const y=S.c,M=S.d,T=Math.atan2(M,y);let k=Math.atan2(u,d)-Math.atan2(f,o)-(T-Math.atan2(S.b,S.a));k>C.PI?k-=C.PI2:k<-C.PI&&(k+=C.PI2),k=T+(k+x)*h;const I=Math.sqrt(y*y+M*M);S.c=Math.cos(k)*I,S.d=Math.sin(k)*I}p.updateAppliedTransform()}}applyRelativeWorld(){const t=this.mixRotate,n=this.mixX,e=this.mixY,i=this.mixScaleX,r=this.mixScaleY,h=this.mixShearY,l=n!=0||e!=0,s=this.target,a=s.matrix,o=a.a,d=a.c,f=a.b,u=a.d,m=o*u-d*f>0?C.degRad:-C.degRad,g=this.data.offsetRotation*m,x=this.data.offsetShearY*m,E=this.bones;for(let w=0,b=E.length;wC.PI?I-=C.PI2:I<-C.PI&&(I+=C.PI2),I*=t;const R=Math.cos(I),V=Math.sin(I);S.a=R*y-V*T,S.c=R*M-V*k,S.b=V*y+R*T,S.d=V*M+R*k}if(l){const y=this.temp;s.localToWorld(y.set(this.data.offsetX,this.data.offsetY)),S.tx+=y.x*n,S.ty+=y.y*e}if(i!=0){const y=(Math.sqrt(o*o+f*f)-1+this.data.offsetScaleX)*i+1;S.a*=y,S.b*=y}if(r!=0){const y=(Math.sqrt(d*d+u*u)-1+this.data.offsetScaleY)*r+1;S.c*=y,S.d*=y}if(h>0){let y=Math.atan2(u,d)-Math.atan2(f,o);y>C.PI?y-=C.PI2:y<-C.PI&&(y+=C.PI2);const M=S.c,T=S.d;y=Math.atan2(T,M)+(y-C.PI/2+x)*h;const k=Math.sqrt(M*M+T*T);S.c=Math.cos(y)*k,S.d=Math.sin(y)*k}p.updateAppliedTransform()}}applyAbsoluteLocal(){const t=this.mixRotate,n=this.mixX,e=this.mixY,i=this.mixScaleX,r=this.mixScaleY,h=this.mixShearY,l=this.target,s=this.bones;for(let a=0,o=s.length;a= 0.");if(!n)throw new Error("name cannot be null.");if(!e)throw new Error("boneData cannot be null.");this.index=t,this.name=n,this.boneData=e}}class xi extends jn{constructor(t){super(t,0,!1),this.bones=new Array,this._target=null,this.mixRotate=0,this.mixX=0,this.mixY=0,this.mixScaleX=0,this.mixScaleY=0,this.mixShearY=0,this.offsetRotation=0,this.offsetX=0,this.offsetY=0,this.offsetScaleX=0,this.offsetScaleY=0,this.offsetShearY=0,this.relative=!1,this.local=!1}set target(t){this._target=t}get target(){if(this._target)return this._target;throw new Error("BoneData not set.")}}class pi{constructor(t,n,e){this.slotIndex=t,this.name=n,this.attachment=e}}class Zn{constructor(t){if(this.attachments=new Array,this.bones=Array(),this.constraints=new Array,!t)throw new Error("name cannot be null.");this.name=t}setAttachment(t,n,e){if(!e)throw new Error("attachment cannot be null.");const i=this.attachments;t>=i.length&&(i.length=t+1),i[t]||(i[t]={}),i[t][n]=e}addSkin(t){for(let e=0;e>4,t.readFloat())}i.push(y);break}}}}}const h=t.readInt(!0);if(h>0){const a=new hn(h),o=e.slots.length;for(let d=0;d=0;w--)m[w]=-1;const g=v.newArray(o-u,0);let x=0,E=0;for(let w=0;w=0;w--)m[w]==-1&&(m[w]=g[--E]);a.setFrame(d,f,m)}i.push(a)}const l=t.readInt(!0);if(l>0){const a=new vn(l);for(let o=0;o=0;E--)f[E]==-1&&(f[E]=m[--x])}l.setFrame(a,P(d,"time",0),f)}r.push(l)}if(t.events){const l=new vn(t.events.length);let s=0;for(let a=0;a(c[c.UNKNOWN=0]="UNKNOWN",c[c.VER37=37]="VER37",c[c.VER38=38]="VER38",c[c.VER40=40]="VER40",c[c.VER41=41]="VER41",c))(he||{});function Kn(c){const t=c.substr(0,3),n=Math.floor(Number(t)*10+.001);return t==="3.7"?37:t==="3.8"?38:t==="4.0"?40:t==="4.1"?41:n<37?37:0}class ga{constructor(){this.scale=1}readSkeletonData(t,n){let e=null,i=this.readVersionOldFormat(n),r=Kn(i);if(r===he.VER38&&(e=new Mt(new gs(t))),i=this.readVersionNewFormat(n),r=Kn(i),(r===he.VER40||r===he.VER41)&&(e=new wi(new ai(t))),!e){const h=`Unsupported version of spine model ${i}, please update pixi-spine`;console.error(h)}return e.scale=this.scale,e.readSkeletonData(n)}readVersionOldFormat(t){const n=new Mn(t);let e;try{n.readString(),e=n.readString()}catch(i){e=""}return e||""}readVersionNewFormat(t){const n=new Mn(t);n.readInt32(),n.readInt32();let e;try{e=n.readString()}catch(i){e=""}return e||""}}class xa{constructor(){this.scale=1}readSkeletonData(t,n){const e=n.skeleton.spine,i=Kn(e);let r=null;if(i===he.VER37&&(r=new an(new Ui(t))),i===he.VER38&&(r=new sn(new gs(t))),(i===he.VER40||i===he.VER41)&&(r=new Qn(new ai(t))),!r){const h=`Unsupported version of spine model ${e}, please update pixi-spine`;console.error(h)}return r.scale=this.scale,r.readSkeletonData(n)}}class pa extends Rr{createBinaryParser(){return new ga}createJsonParser(){return new xa}parseData(t,n,e){return{spineData:t.readSkeletonData(n,e),spineAtlas:n}}}class wa extends tn{createSkeleton(t){const n=Kn(t.version);let e=null;if(n===he.VER37&&(e=Or),n===he.VER38&&(e=Nr),(n===he.VER40||n===he.VER41)&&(e=ma),!e){const i=`Cant detect version of spine model ${t.version}`;console.error(i)}this.skeleton=new e.Skeleton(t),this.skeleton.updateWorldTransform(),this.stateData=new e.AnimationStateData(t),this.state=new e.AnimationState(this.stateData)}}return new pa().installLoader(),tt.AttachmentType=Z,tt.BinaryInput=Mn,tt.Color=_,tt.DebugUtils=Mr,tt.IntSet=ns,tt.Interpolation=Si,tt.MathUtils=C,tt.MixBlend=A,tt.MixDirection=J,tt.Pool=An,tt.PositionMode=dt,tt.Pow=yi,tt.PowOut=is,tt.RotateMode=pt,tt.SkeletonBounds=xr,tt.SkeletonBoundsBase=Cn,tt.Spine=wa,tt.SpineBase=tn,tt.SpineDebugRenderer=Tr,tt.SpineMesh=Ai,tt.SpineSprite=Mi,tt.StringSet=ss,tt.TextureAtlas=Fn,tt.TextureAtlasPage=ts,tt.TextureAtlasRegion=es,tt.TextureFilter=Bt,tt.TextureRegion=Vn,tt.TextureWrap=fe,tt.TimeKeeper=Ar,tt.TransformMode=j,tt.Utils=v,tt.Vector2=un,tt.WindowedMean=Cr,tt.filterFromString=Jn,tt.settings=zt,tt.wrapFromString=Er,tt}({},PIXI,PIXI,PIXI,PIXI,PIXI,PIXI); -var pixi_spine = this.PIXI.spine; -//# sourceMappingURL=pixi-spine.js.map diff --git a/GDJS/package.json b/GDJS/package.json index d7614ef7fc71..8b9e81b72cf0 100644 --- a/GDJS/package.json +++ b/GDJS/package.json @@ -36,7 +36,7 @@ } }, "scripts": { - "postinstall": "patch-package && cp node_modules/pixi-spine/dist/pixi-spine.js Runtime/pixi-renderers", + "postinstall": "patch-package && node scripts/install-spine.js", "check-types": "tsc", "build": "node scripts/build.js", "test": "cd tests && npm run test-benchmark", diff --git a/GDJS/scripts/install-spine.js b/GDJS/scripts/install-spine.js new file mode 100644 index 000000000000..3677a718121f --- /dev/null +++ b/GDJS/scripts/install-spine.js @@ -0,0 +1,10 @@ +const fs = require('fs'); +const path = require('path'); + +const originalSpinePath = path.join('node_modules/pixi-spine/dist', 'pixi-spine.js'); +const originalPixiSpine = fs.readFileSync(originalSpinePath); + +const varSpineExport = '\nvar pixi_spine = this.PIXI.spine;\n'; +const runtimeSpinePath = path.join('Runtime/pixi-renderers', 'pixi-spine.js'); + +fs.writeFileSync(runtimeSpinePath, originalPixiSpine + varSpineExport); \ No newline at end of file From 25cdc638af79573edb9d4ff6aa242559efea3b68 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 14 Nov 2023 16:51:13 +0200 Subject: [PATCH 17/80] cover errors on spine loading with incompatible files --- GDJS/Runtime/runtimegame.ts | 2 +- .../src/ObjectEditor/Editors/SpineEditor.js | 18 +- .../ObjectsRendering/PixiResourcesLoader.js | 102 +- newIDE/electron-app/yarn.lock | 3493 ++++++++--------- 4 files changed, 1763 insertions(+), 1852 deletions(-) diff --git a/GDJS/Runtime/runtimegame.ts b/GDJS/Runtime/runtimegame.ts index da88dab738b4..094e3154c6d1 100644 --- a/GDJS/Runtime/runtimegame.ts +++ b/GDJS/Runtime/runtimegame.ts @@ -747,7 +747,7 @@ namespace gdjs { loadedAssets += await this._soundManager.preloadAudio(onProgress); loadedAssets += await this._fontManager.loadFonts(onProgress); loadedAssets += await this._atlasManager.preloadAll(onProgress); - loadedAssets += await this._jsonManager.preloadJsons(onProgress); + loadedAssets += await this._jsonManager.preloadAll(onProgress); loadedAssets += await this._model3DManager.loadModels(onProgress); await this._bitmapFontManager.loadBitmapFontData(onProgress); await loadingScreen.unload(); diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index b7410e3b02ad..68d059c4f7a0 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -114,16 +114,18 @@ const SpineEditor = ({ resName => !resName ) ) { - return; + return Promise.resolve(undefined); } - PixiResourcesLoader.getSpineData( + return PixiResourcesLoader.getSpineData( project, jsonResourceName, imageResourceName, atlasResourceName ).then(newSkeleton => { setSkeleton(newSkeleton); + + return newSkeleton; }); }, [project] @@ -146,7 +148,9 @@ const SpineEditor = ({ jsonResourceName, properties.get('imageResourceName').getValue(), atlasResourceName - ); + ).then(newSkeleton => { + spineConfiguration.removeAllAnimations(); + }); }, [getSkeleton] ); @@ -166,7 +170,9 @@ const SpineEditor = ({ properties.get('jsonResourceName').getValue(), imageResourceName, atlasResourceName - ); + ).then(newSkeleton => { + spineConfiguration.removeAllAnimations(); + }); }, [getSkeleton] ); @@ -182,7 +188,9 @@ const SpineEditor = ({ properties.get('jsonResourceName').getValue(), imageResourceName, atlasResourceName - ); + ).then(newSkeleton => { + spineConfiguration.removeAllAnimations(); + }); }, [getSkeleton] ); diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 81fcd5c54695..e409ec961440 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -15,15 +15,15 @@ const gd: libGDevelop = global.gd; type ResourcePromise = { [resourceName: string]: Promise }; -const loadedBitmapFonts = {}; -const loadedFontFamilies = {}; -const loadedTextures = {}; -const invalidTexture = PIXI.Texture.from('res/error48.png'); -const loadedThreeTextures = {}; -const loadedThreeMaterials = {}; -const loadedOrLoading3DModelPromises: ResourcePromise = {}; -const atlasPromises: ResourcePromise = {}; -const spineDataPromises: ResourcePromise = {}; +let loadedBitmapFonts = {}; +let loadedFontFamilies = {}; +let loadedTextures = {}; +let invalidTexture = PIXI.Texture.from('res/error48.png'); +let loadedThreeTextures = {}; +let loadedThreeMaterials = {}; +let loadedOrLoading3DModelPromises: ResourcePromise = {}; +let atlasPromises: ResourcePromise = {}; +let spineDataPromises: ResourcePromise = {}; const createInvalidModel = (): GLTF => { /** @@ -162,6 +162,8 @@ export default class PixiResourcesLoader { loadedThreeTextures = {}; loadedThreeMaterials = {}; loadedOrLoading3DModelPromises = {}; + atlasPromises = {}; + spineDataPromises = {}; } static async reloadTextureForResource( @@ -466,7 +468,6 @@ export default class PixiResourcesLoader { atlasImageName: string, atlasTextName: string ): Promise { - const loader = PIXI.Assets.loader; const resourceManager = project.getResourcesManager(); const resourcesData = [ [spineName, 'json'], @@ -488,38 +489,71 @@ export default class PixiResourcesLoader { // https://github.com/pixijs/spine/blob/master/examples/preload_atlas_text.md if (!atlasPromises[atlasTextName]) { atlasPromises[atlasTextName] = new Promise(resolve => { - const atlasUrl = ResourcesLoader.getResourceFullUrl(project, atlasTextName, { - isResourceForPixi: true, - }); - PIXI.Assets.setPreferences({ - preferWorkers: false, - crossOrigin: checkIfCredentialsRequired(atlasUrl) - ? 'use-credentials' - : 'anonymous', - }); - PIXI.Assets.add(atlasTextName, atlasUrl, { image: this.getPIXITexture(project, atlasImageName) }); - PIXI.Assets.load(atlasTextName).then((atlas) => { - resolve(atlas); - }); - }); - } + const onError = (err) => { + console.error(`Error during ${atlasTextName} atlas loading: ${err}.\nCheck if you selected correct pair of atlas and image files.`); + resolve(undefined); + }; - if (!spineDataPromises[spineName]) { - spineDataPromises[spineName] = new Promise(resolve => { - atlasPromises[atlasTextName].then(spineAtlas => { - const jsonUrl = ResourcesLoader.getResourceFullUrl(project, spineName, { + try { + const atlasUrl = ResourcesLoader.getResourceFullUrl(project, atlasTextName, { isResourceForPixi: true, }); + const atlasImage = this.getPIXITexture(project, atlasImageName); PIXI.Assets.setPreferences({ preferWorkers: false, - crossOrigin: checkIfCredentialsRequired(jsonUrl) + crossOrigin: checkIfCredentialsRequired(atlasUrl) ? 'use-credentials' : 'anonymous', }); - PIXI.Assets.add(spineName, jsonUrl, { spineAtlas }) - PIXI.Assets.load(jsonUrl).then((jsonData) => { - resolve(jsonData.spineData) - }); + PIXI.Assets.add(atlasTextName, atlasUrl, { image: atlasImage }); + PIXI.Assets.load(atlasTextName) + .then((atlas) => { + if (typeof atlas === 'string') { + new PIXI_SPINE.TextureAtlas(atlas, (_, textureCb) => textureCb(atlasImage.baseTexture), resolve); + } else { + resolve(atlas); + } + }) + .catch(onError); + } catch (err) { + onError(err); + } + }); + } + + if (!spineDataPromises[spineName]) { + spineDataPromises[spineName] = new Promise(resolve => { + atlasPromises[atlasTextName].then(spineAtlas => { + if (!spineAtlas) { + console.error(`Cannot load ${spineName} spine. Atlas ${atlasTextName} is undefined. Check if you selected correct files.`); + return resolve(undefined); + } + + const onError = (err) => { + console.error(`Error during ${spineName} spine loading: ${err}.\nCheck if you selected correct files.`); + resolve(undefined); + }; + + try { + const jsonUrl = ResourcesLoader.getResourceFullUrl(project, spineName, { + isResourceForPixi: true, + }); + PIXI.Assets.setPreferences({ + preferWorkers: false, + crossOrigin: checkIfCredentialsRequired(jsonUrl) + ? 'use-credentials' + : 'anonymous', + }); + PIXI.Assets.add(spineName, jsonUrl, { spineAtlas }) + + PIXI.Assets.load(spineName) + .then((jsonData) => { + resolve(jsonData.spineData) + }) + .catch(onError); + } catch (err) { + onError(err); + } }); }); } diff --git a/newIDE/electron-app/yarn.lock b/newIDE/electron-app/yarn.lock index f6efc243b56b..9352b3f42d22 100644 --- a/newIDE/electron-app/yarn.lock +++ b/newIDE/electron-app/yarn.lock @@ -3,1930 +3,1799 @@ "@develar/schema-utils@~2.6.5": - "integrity" "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==" - "resolved" "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz" - "version" "2.6.5" + version "2.6.5" + resolved "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz" + integrity sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig== dependencies: - "ajv" "^6.12.0" - "ajv-keywords" "^3.4.1" + ajv "^6.12.0" + ajv-keywords "^3.4.1" "@electron/get@^1.13.0": - "integrity" "sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw==" - "resolved" "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz" - "version" "1.14.1" - dependencies: - "debug" "^4.1.1" - "env-paths" "^2.2.0" - "fs-extra" "^8.1.0" - "got" "^9.6.0" - "progress" "^2.0.3" - "semver" "^6.2.0" - "sumchecker" "^3.0.1" + version "1.14.1" + resolved "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz" + integrity sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw== + dependencies: + debug "^4.1.1" + env-paths "^2.2.0" + fs-extra "^8.1.0" + got "^9.6.0" + progress "^2.0.3" + semver "^6.2.0" + sumchecker "^3.0.1" optionalDependencies: - "global-agent" "^3.0.0" - "global-tunnel-ng" "^2.7.1" + global-agent "^3.0.0" + global-tunnel-ng "^2.7.1" "@electron/notarize@^2.1.0": - "integrity" "sha512-Q02xem1D0sg4v437xHgmBLxI2iz/fc0D4K7fiVWHa/AnW8o7D751xyKNXgziA6HrTOme9ul1JfWN5ark8WH1xA==" - "resolved" "https://registry.npmjs.org/@electron/notarize/-/notarize-2.1.0.tgz" - "version" "2.1.0" + version "2.1.0" + resolved "https://registry.npmjs.org/@electron/notarize/-/notarize-2.1.0.tgz" + integrity sha512-Q02xem1D0sg4v437xHgmBLxI2iz/fc0D4K7fiVWHa/AnW8o7D751xyKNXgziA6HrTOme9ul1JfWN5ark8WH1xA== dependencies: - "debug" "^4.1.1" - "fs-extra" "^9.0.1" - "promise-retry" "^2.0.1" + debug "^4.1.1" + fs-extra "^9.0.1" + promise-retry "^2.0.1" "@electron/remote@^2.0.8": - "integrity" "sha512-P10v3+iFCIvEPeYzTWWGwwHmqWnjoh8RYnbtZAb3RlQefy4guagzIwcWtfftABIfm6JJTNQf4WPSKWZOpLmHXw==" - "resolved" "https://registry.npmjs.org/@electron/remote/-/remote-2.0.8.tgz" - "version" "2.0.8" + version "2.0.8" + resolved "https://registry.npmjs.org/@electron/remote/-/remote-2.0.8.tgz" + integrity sha512-P10v3+iFCIvEPeYzTWWGwwHmqWnjoh8RYnbtZAb3RlQefy4guagzIwcWtfftABIfm6JJTNQf4WPSKWZOpLmHXw== "@electron/universal@1.2.1": - "integrity" "sha512-7323HyMh7KBAl/nPDppdLsC87G6RwRU02dy5FPeGB1eS7rUePh55+WNWiDPLhFQqqVPHzh77M69uhmoT8XnwMQ==" - "resolved" "https://registry.npmjs.org/@electron/universal/-/universal-1.2.1.tgz" - "version" "1.2.1" + version "1.2.1" + resolved "https://registry.npmjs.org/@electron/universal/-/universal-1.2.1.tgz" + integrity sha512-7323HyMh7KBAl/nPDppdLsC87G6RwRU02dy5FPeGB1eS7rUePh55+WNWiDPLhFQqqVPHzh77M69uhmoT8XnwMQ== dependencies: "@malept/cross-spawn-promise" "^1.1.0" - "asar" "^3.1.0" - "debug" "^4.3.1" - "dir-compare" "^2.4.0" - "fs-extra" "^9.0.1" - "minimatch" "^3.0.4" - "plist" "^3.0.4" + asar "^3.1.0" + debug "^4.3.1" + dir-compare "^2.4.0" + fs-extra "^9.0.1" + minimatch "^3.0.4" + plist "^3.0.4" "@malept/cross-spawn-promise@^1.1.0": - "integrity" "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==" - "resolved" "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz" - "version" "1.1.1" + version "1.1.1" + resolved "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz" + integrity sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ== dependencies: - "cross-spawn" "^7.0.1" + cross-spawn "^7.0.1" "@malept/flatpak-bundler@^0.4.0": - "integrity" "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==" - "resolved" "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz" - "version" "0.4.0" + version "0.4.0" + resolved "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz" + integrity sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q== dependencies: - "debug" "^4.1.1" - "fs-extra" "^9.0.0" - "lodash" "^4.17.15" - "tmp-promise" "^3.0.2" + debug "^4.1.1" + fs-extra "^9.0.0" + lodash "^4.17.15" + tmp-promise "^3.0.2" "@sindresorhus/is@^0.14.0": - "integrity" "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" - "resolved" "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz" - "version" "0.14.0" + version "0.14.0" + resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== "@szmarczak/http-timer@^1.1.2": - "integrity" "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==" - "resolved" "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz" - "version" "1.1.2" + version "1.1.2" + resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== dependencies: - "defer-to-connect" "^1.0.1" + defer-to-connect "^1.0.1" "@tootallnate/once@2": - "integrity" "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" - "resolved" "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" - "version" "2.0.0" + version "2.0.0" + resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== "@types/debug@^4.1.6": - "integrity" "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==" - "resolved" "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz" - "version" "4.1.7" + version "4.1.7" + resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz" + integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== dependencies: "@types/ms" "*" "@types/fs-extra@^9.0.11": - "integrity" "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==" - "resolved" "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz" - "version" "9.0.13" + version "9.0.13" + resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz" + integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== dependencies: "@types/node" "*" "@types/glob@^7.1.1": - "integrity" "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==" - "resolved" "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" - "version" "7.2.0" + version "7.2.0" + resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== dependencies: "@types/minimatch" "*" "@types/node" "*" "@types/minimatch@*": - "integrity" "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==" - "resolved" "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz" - "version" "5.1.2" + version "5.1.2" + resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== "@types/ms@*": - "integrity" "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" - "resolved" "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" - "version" "0.7.31" + version "0.7.31" + resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" + integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== "@types/node@*", "@types/node@^16.11.26": - "integrity" "sha512-0PJ0vg+JyU0MIan58IOIFRtSvsb7Ri+7Wltx2qAg94eMOrpg4+uuP3aUHCpxXc1i0jCXiC+zIamSZh3l9AbcQA==" - "resolved" "https://registry.npmjs.org/@types/node/-/node-16.11.33.tgz" - "version" "16.11.33" + version "16.11.33" + resolved "https://registry.npmjs.org/@types/node/-/node-16.11.33.tgz" + integrity sha512-0PJ0vg+JyU0MIan58IOIFRtSvsb7Ri+7Wltx2qAg94eMOrpg4+uuP3aUHCpxXc1i0jCXiC+zIamSZh3l9AbcQA== "@types/plist@^3.0.1": - "integrity" "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==" - "resolved" "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz" - "version" "3.0.2" + version "3.0.2" + resolved "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz" + integrity sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw== dependencies: "@types/node" "*" - "xmlbuilder" ">=11.0.1" + xmlbuilder ">=11.0.1" "@types/verror@^1.10.3": - "integrity" "sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==" - "resolved" "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz" - "version" "1.10.6" + version "1.10.6" + resolved "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz" + integrity sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ== "@types/yargs-parser@*": - "integrity" "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" - "resolved" "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz" - "version" "21.0.0" + version "21.0.0" + resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== "@types/yargs@^17.0.1": - "integrity" "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==" - "resolved" "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz" - "version" "17.0.10" + version "17.0.10" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz" + integrity sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA== dependencies: "@types/yargs-parser" "*" "7zip-bin@~5.1.1": - "integrity" "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==" - "resolved" "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz" - "version" "5.1.1" - -"adm-zip@^0.5.10": - "integrity" "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==" - "resolved" "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz" - "version" "0.5.10" - -"agent-base@6": - "integrity" "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==" - "resolved" "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - "version" "6.0.2" - dependencies: - "debug" "4" - -"ajv-keywords@^3.4.1": - "integrity" "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" - "resolved" "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" - "version" "3.5.2" - -"ajv@^6.10.0", "ajv@^6.12.0", "ajv@^6.9.1": - "integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==" - "resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - "version" "6.12.6" - dependencies: - "fast-deep-equal" "^3.1.1" - "fast-json-stable-stringify" "^2.0.0" - "json-schema-traverse" "^0.4.1" - "uri-js" "^4.2.2" - -"ansi-regex@^5.0.1": - "integrity" "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - "version" "5.0.1" - -"ansi-styles@^4.0.0", "ansi-styles@^4.1.0": - "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" - "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - "version" "4.3.0" - dependencies: - "color-convert" "^2.0.1" - -"app-builder-bin@4.0.0": - "integrity" "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==" - "resolved" "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz" - "version" "4.0.0" - -"app-builder-lib@23.6.0": - "integrity" "sha512-dQYDuqm/rmy8GSCE6Xl/3ShJg6Ab4bZJMT8KaTKGzT436gl1DN4REP3FCWfXoh75qGTJ+u+WsdnnpO9Jl8nyMA==" - "resolved" "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.6.0.tgz" - "version" "23.6.0" + version "5.1.1" + resolved "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz" + integrity sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ== + +adm-zip@^0.5.10: + version "0.5.10" + resolved "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz" + integrity sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ== + +agent-base@6: + version "6.0.2" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +ajv-keywords@^3.4.1: + version "3.5.2" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.10.0, ajv@^6.12.0, ajv@^6.9.1: + version "6.12.6" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +app-builder-bin@4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz" + integrity sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA== + +app-builder-lib@23.6.0: + version "23.6.0" + resolved "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.6.0.tgz" + integrity sha512-dQYDuqm/rmy8GSCE6Xl/3ShJg6Ab4bZJMT8KaTKGzT436gl1DN4REP3FCWfXoh75qGTJ+u+WsdnnpO9Jl8nyMA== dependencies: "@develar/schema-utils" "~2.6.5" "@electron/universal" "1.2.1" "@malept/flatpak-bundler" "^0.4.0" "7zip-bin" "~5.1.1" - "async-exit-hook" "^2.0.1" - "bluebird-lst" "^1.0.9" - "builder-util" "23.6.0" - "builder-util-runtime" "9.1.1" - "chromium-pickle-js" "^0.2.0" - "debug" "^4.3.4" - "ejs" "^3.1.7" - "electron-osx-sign" "^0.6.0" - "electron-publish" "23.6.0" - "form-data" "^4.0.0" - "fs-extra" "^10.1.0" - "hosted-git-info" "^4.1.0" - "is-ci" "^3.0.0" - "isbinaryfile" "^4.0.10" - "js-yaml" "^4.1.0" - "lazy-val" "^1.0.5" - "minimatch" "^3.1.2" - "read-config-file" "6.2.0" - "sanitize-filename" "^1.6.3" - "semver" "^7.3.7" - "tar" "^6.1.11" - "temp-file" "^3.4.0" - -"argparse@^2.0.1": - "integrity" "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - "resolved" "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - "version" "2.0.1" - -"asar@^3.1.0": - "integrity" "sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==" - "resolved" "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz" - "version" "3.2.0" - dependencies: - "chromium-pickle-js" "^0.2.0" - "commander" "^5.0.0" - "glob" "^7.1.6" - "minimatch" "^3.0.4" + async-exit-hook "^2.0.1" + bluebird-lst "^1.0.9" + builder-util "23.6.0" + builder-util-runtime "9.1.1" + chromium-pickle-js "^0.2.0" + debug "^4.3.4" + ejs "^3.1.7" + electron-osx-sign "^0.6.0" + electron-publish "23.6.0" + form-data "^4.0.0" + fs-extra "^10.1.0" + hosted-git-info "^4.1.0" + is-ci "^3.0.0" + isbinaryfile "^4.0.10" + js-yaml "^4.1.0" + lazy-val "^1.0.5" + minimatch "^3.1.2" + read-config-file "6.2.0" + sanitize-filename "^1.6.3" + semver "^7.3.7" + tar "^6.1.11" + temp-file "^3.4.0" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +asar@^3.1.0: + version "3.2.0" + resolved "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz" + integrity sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg== + dependencies: + chromium-pickle-js "^0.2.0" + commander "^5.0.0" + glob "^7.1.6" + minimatch "^3.0.4" optionalDependencies: "@types/glob" "^7.1.1" -"assert-plus@^1.0.0": - "integrity" "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - "resolved" "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - "version" "1.0.0" - -"astral-regex@^2.0.0": - "integrity" "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" - "resolved" "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" - "version" "2.0.0" - -"async-exit-hook@^2.0.1": - "integrity" "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==" - "resolved" "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz" - "version" "2.0.1" - -"async@^3.2.3": - "integrity" "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - "resolved" "https://registry.npmjs.org/async/-/async-3.2.4.tgz" - "version" "3.2.4" - -"asynckit@^0.4.0": - "integrity" "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - "resolved" "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" - "version" "0.4.0" - -"at-least-node@^1.0.0": - "integrity" "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - "resolved" "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" - "version" "1.0.0" - -"balanced-match@^1.0.0": - "integrity" "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" - "version" "1.0.0" - -"base64-js@^1.3.1", "base64-js@^1.5.1": - "integrity" "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - "resolved" "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" - "version" "1.5.1" - -"bluebird-lst@^1.0.9": - "integrity" "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==" - "resolved" "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz" - "version" "1.0.9" - dependencies: - "bluebird" "^3.5.5" - -"bluebird@^3.5.0", "bluebird@^3.5.5": - "integrity" "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - "resolved" "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" - "version" "3.7.2" - -"boolean@^3.0.1": - "integrity" "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==" - "resolved" "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz" - "version" "3.2.0" - -"brace-expansion@^1.1.7": - "integrity" "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==" - "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - "version" "1.1.11" - dependencies: - "balanced-match" "^1.0.0" - "concat-map" "0.0.1" - -"brace-expansion@^2.0.1": - "integrity" "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==" - "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" - "version" "2.0.1" - dependencies: - "balanced-match" "^1.0.0" - -"buffer-alloc-unsafe@^1.1.0": - "integrity" "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" - "resolved" "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz" - "version" "1.1.0" - -"buffer-alloc@^1.2.0": - "integrity" "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==" - "resolved" "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz" - "version" "1.2.0" - dependencies: - "buffer-alloc-unsafe" "^1.1.0" - "buffer-fill" "^1.0.0" - -"buffer-crc32@~0.2.3": - "integrity" "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" - "resolved" "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" - "version" "0.2.13" - -"buffer-equal@1.0.0": - "integrity" "sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==" - "resolved" "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz" - "version" "1.0.0" - -"buffer-fill@^1.0.0": - "integrity" "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" - "resolved" "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz" - "version" "1.0.0" - -"buffer-from@^1.0.0": - "integrity" "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - "resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" - "version" "1.1.2" - -"buffer@^5.1.0": - "integrity" "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==" - "resolved" "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" - "version" "5.7.1" - dependencies: - "base64-js" "^1.3.1" - "ieee754" "^1.1.13" - -"builder-util-runtime@9.1.1": - "integrity" "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==" - "resolved" "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz" - "version" "9.1.1" - dependencies: - "debug" "^4.3.4" - "sax" "^1.2.4" - -"builder-util@23.6.0": - "integrity" "sha512-QiQHweYsh8o+U/KNCZFSvISRnvRctb8m/2rB2I1JdByzvNKxPeFLlHFRPQRXab6aYeXc18j9LpsDLJ3sGQmWTQ==" - "resolved" "https://registry.npmjs.org/builder-util/-/builder-util-23.6.0.tgz" - "version" "23.6.0" +assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async-exit-hook@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz" + integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw== + +async@^3.2.3: + version "3.2.4" + resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.3.1, base64-js@^1.5.1: + version "1.5.1" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bluebird-lst@^1.0.9: + version "1.0.9" + resolved "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz" + integrity sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw== + dependencies: + bluebird "^3.5.5" + +bluebird@^3.5.0, bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +boolean@^3.0.1: + version "3.2.0" + resolved "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz" + integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer-equal@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz" + integrity sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ== + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@^5.1.0: + version "5.7.1" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +builder-util-runtime@9.1.1: + version "9.1.1" + resolved "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz" + integrity sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw== + dependencies: + debug "^4.3.4" + sax "^1.2.4" + +builder-util@23.6.0: + version "23.6.0" + resolved "https://registry.npmjs.org/builder-util/-/builder-util-23.6.0.tgz" + integrity sha512-QiQHweYsh8o+U/KNCZFSvISRnvRctb8m/2rB2I1JdByzvNKxPeFLlHFRPQRXab6aYeXc18j9LpsDLJ3sGQmWTQ== dependencies: "@types/debug" "^4.1.6" "@types/fs-extra" "^9.0.11" "7zip-bin" "~5.1.1" - "app-builder-bin" "4.0.0" - "bluebird-lst" "^1.0.9" - "builder-util-runtime" "9.1.1" - "chalk" "^4.1.1" - "cross-spawn" "^7.0.3" - "debug" "^4.3.4" - "fs-extra" "^10.0.0" - "http-proxy-agent" "^5.0.0" - "https-proxy-agent" "^5.0.0" - "is-ci" "^3.0.0" - "js-yaml" "^4.1.0" - "source-map-support" "^0.5.19" - "stat-mode" "^1.0.0" - "temp-file" "^3.4.0" - -"cacheable-request@^6.0.0": - "integrity" "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==" - "resolved" "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz" - "version" "6.1.0" - dependencies: - "clone-response" "^1.0.2" - "get-stream" "^5.1.0" - "http-cache-semantics" "^4.0.0" - "keyv" "^3.0.0" - "lowercase-keys" "^2.0.0" - "normalize-url" "^4.1.0" - "responselike" "^1.0.2" - -"chalk@^4.0.2", "chalk@^4.1.1": - "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" - "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - "version" "4.1.2" - dependencies: - "ansi-styles" "^4.1.0" - "supports-color" "^7.1.0" - -"chownr@^2.0.0": - "integrity" "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - "resolved" "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" - "version" "2.0.0" - -"chromium-pickle-js@^0.2.0": - "integrity" "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==" - "resolved" "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz" - "version" "0.2.0" - -"ci-info@^3.2.0": - "integrity" "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==" - "resolved" "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz" - "version" "3.8.0" - -"cli-truncate@^2.1.0": - "integrity" "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==" - "resolved" "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" - "version" "2.1.0" - dependencies: - "slice-ansi" "^3.0.0" - "string-width" "^4.2.0" - -"cliui@^8.0.1": - "integrity" "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==" - "resolved" "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" - "version" "8.0.1" - dependencies: - "string-width" "^4.2.0" - "strip-ansi" "^6.0.1" - "wrap-ansi" "^7.0.0" - -"clone-response@^1.0.2": - "integrity" "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=" - "resolved" "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz" - "version" "1.0.2" - dependencies: - "mimic-response" "^1.0.0" - -"color-convert@^2.0.1": - "integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==" - "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - "version" "2.0.1" - dependencies: - "color-name" "~1.1.4" - -"color-name@~1.1.4": - "integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - "version" "1.1.4" - -"colors@1.0.3": - "integrity" "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==" - "resolved" "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz" - "version" "1.0.3" - -"combined-stream@^1.0.8": - "integrity" "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==" - "resolved" "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" - "version" "1.0.8" - dependencies: - "delayed-stream" "~1.0.0" - -"commander@^5.0.0": - "integrity" "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" - "resolved" "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz" - "version" "5.1.0" - -"commander@2.9.0": - "integrity" "sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==" - "resolved" "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz" - "version" "2.9.0" - dependencies: - "graceful-readlink" ">= 1.0.0" - -"compare-version@^0.1.2": - "integrity" "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==" - "resolved" "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz" - "version" "0.1.2" - -"concat-map@0.0.1": - "integrity" "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - "resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - "version" "0.0.1" - -"concat-stream@^1.6.2": - "integrity" "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==" - "resolved" "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz" - "version" "1.6.2" - dependencies: - "buffer-from" "^1.0.0" - "inherits" "^2.0.3" - "readable-stream" "^2.2.2" - "typedarray" "^0.0.6" - -"config-chain@^1.1.11": - "integrity" "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==" - "resolved" "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz" - "version" "1.1.13" - dependencies: - "ini" "^1.3.4" - "proto-list" "~1.2.1" - -"core-util-is@~1.0.0", "core-util-is@1.0.2": - "integrity" "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - "resolved" "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - "version" "1.0.2" - -"crc@^3.8.0": - "integrity" "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==" - "resolved" "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz" - "version" "3.8.0" - dependencies: - "buffer" "^5.1.0" - -"cross-spawn@^7.0.1", "cross-spawn@^7.0.3": - "integrity" "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==" - "resolved" "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - "version" "7.0.3" - dependencies: - "path-key" "^3.1.0" - "shebang-command" "^2.0.0" - "which" "^2.0.1" - -"debug@^2.6.8": - "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" - "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - "version" "2.6.9" - dependencies: - "ms" "2.0.0" - -"debug@^2.6.9": - "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" - "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - "version" "2.6.9" - dependencies: - "ms" "2.0.0" - -"debug@^4.1.0", "debug@^4.1.1", "debug@^4.3.1", "debug@^4.3.4", "debug@4": - "integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==" - "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - "version" "4.3.4" - dependencies: - "ms" "2.1.2" - -"decompress-response@^3.3.0": - "integrity" "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=" - "resolved" "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz" - "version" "3.3.0" - dependencies: - "mimic-response" "^1.0.0" - -"defer-to-connect@^1.0.1": - "integrity" "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" - "resolved" "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz" - "version" "1.1.3" - -"define-properties@^1.1.3": - "integrity" "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==" - "resolved" "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz" - "version" "1.1.4" - dependencies: - "has-property-descriptors" "^1.0.0" - "object-keys" "^1.1.1" - -"delayed-stream@~1.0.0": - "integrity" "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - "resolved" "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" - "version" "1.0.0" - -"detect-node@^2.0.4": - "integrity" "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - "resolved" "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" - "version" "2.1.0" - -"dir-compare@^2.4.0": - "integrity" "sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA==" - "resolved" "https://registry.npmjs.org/dir-compare/-/dir-compare-2.4.0.tgz" - "version" "2.4.0" - dependencies: - "buffer-equal" "1.0.0" - "colors" "1.0.3" - "commander" "2.9.0" - "minimatch" "3.0.4" - -"dmg-builder@23.6.0": - "integrity" "sha512-jFZvY1JohyHarIAlTbfQOk+HnceGjjAdFjVn3n8xlDWKsYNqbO4muca6qXEZTfGXeQMG7TYim6CeS5XKSfSsGA==" - "resolved" "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.6.0.tgz" - "version" "23.6.0" - dependencies: - "app-builder-lib" "23.6.0" - "builder-util" "23.6.0" - "builder-util-runtime" "9.1.1" - "fs-extra" "^10.0.0" - "iconv-lite" "^0.6.2" - "js-yaml" "^4.1.0" + app-builder-bin "4.0.0" + bluebird-lst "^1.0.9" + builder-util-runtime "9.1.1" + chalk "^4.1.1" + cross-spawn "^7.0.3" + debug "^4.3.4" + fs-extra "^10.0.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-ci "^3.0.0" + js-yaml "^4.1.0" + source-map-support "^0.5.19" + stat-mode "^1.0.0" + temp-file "^3.4.0" + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +chalk@^4.0.2, chalk@^4.1.1: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +chromium-pickle-js@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz" + integrity sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw== + +ci-info@^3.2.0: + version "3.8.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz" + integrity sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== + +commander@2.9.0: + version "2.9.0" + resolved "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz" + integrity sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A== + dependencies: + graceful-readlink ">= 1.0.0" + +compare-version@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz" + integrity sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.6.2: + version "1.6.2" + resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +config-chain@^1.1.11: + version "1.1.13" + resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +core-util-is@~1.0.0, core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +crc@^3.8.0: + version "3.8.0" + resolved "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz" + integrity sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ== + dependencies: + buffer "^5.1.0" + +cross-spawn@^7.0.1, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@^2.6.8: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4, debug@4: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +define-properties@^1.1.3: + version "1.1.4" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +dir-compare@^2.4.0: + version "2.4.0" + resolved "https://registry.npmjs.org/dir-compare/-/dir-compare-2.4.0.tgz" + integrity sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA== + dependencies: + buffer-equal "1.0.0" + colors "1.0.3" + commander "2.9.0" + minimatch "3.0.4" + +dmg-builder@23.6.0: + version "23.6.0" + resolved "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.6.0.tgz" + integrity sha512-jFZvY1JohyHarIAlTbfQOk+HnceGjjAdFjVn3n8xlDWKsYNqbO4muca6qXEZTfGXeQMG7TYim6CeS5XKSfSsGA== + dependencies: + app-builder-lib "23.6.0" + builder-util "23.6.0" + builder-util-runtime "9.1.1" + fs-extra "^10.0.0" + iconv-lite "^0.6.2" + js-yaml "^4.1.0" optionalDependencies: - "dmg-license" "^1.0.11" + dmg-license "^1.0.11" -"dmg-license@^1.0.11": - "integrity" "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==" - "resolved" "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz" - "version" "1.0.11" +dmg-license@^1.0.11: + version "1.0.11" + resolved "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz" + integrity sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q== dependencies: "@types/plist" "^3.0.1" "@types/verror" "^1.10.3" - "ajv" "^6.10.0" - "crc" "^3.8.0" - "iconv-corefoundation" "^1.1.7" - "plist" "^3.0.4" - "smart-buffer" "^4.0.2" - "verror" "^1.10.0" - -"dotenv-expand@^5.1.0": - "integrity" "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" - "resolved" "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz" - "version" "5.1.0" - -"dotenv@^8.2.0": - "integrity" "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" - "resolved" "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz" - "version" "8.2.0" - -"dotenv@^9.0.2": - "integrity" "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==" - "resolved" "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz" - "version" "9.0.2" - -"duplexer3@^0.1.4": - "integrity" "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - "resolved" "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz" - "version" "0.1.4" - -"ejs@^3.1.7": - "integrity" "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==" - "resolved" "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz" - "version" "3.1.9" - dependencies: - "jake" "^10.8.5" - -"electron-builder@^23.6.0": - "integrity" "sha512-y8D4zO+HXGCNxFBV/JlyhFnoQ0Y0K7/sFH+XwIbj47pqaW8S6PGYQbjoObolKBR1ddQFPt4rwp4CnwMJrW3HAw==" - "resolved" "https://registry.npmjs.org/electron-builder/-/electron-builder-23.6.0.tgz" - "version" "23.6.0" + ajv "^6.10.0" + crc "^3.8.0" + iconv-corefoundation "^1.1.7" + plist "^3.0.4" + smart-buffer "^4.0.2" + verror "^1.10.0" + +dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv@^8.2.0: + version "8.2.0" + resolved "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + +dotenv@^9.0.2: + version "9.0.2" + resolved "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz" + integrity sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg== + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +ejs@^3.1.7: + version "3.1.9" + resolved "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz" + integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== + dependencies: + jake "^10.8.5" + +electron-builder@^23.6.0: + version "23.6.0" + resolved "https://registry.npmjs.org/electron-builder/-/electron-builder-23.6.0.tgz" + integrity sha512-y8D4zO+HXGCNxFBV/JlyhFnoQ0Y0K7/sFH+XwIbj47pqaW8S6PGYQbjoObolKBR1ddQFPt4rwp4CnwMJrW3HAw== dependencies: "@types/yargs" "^17.0.1" - "app-builder-lib" "23.6.0" - "builder-util" "23.6.0" - "builder-util-runtime" "9.1.1" - "chalk" "^4.1.1" - "dmg-builder" "23.6.0" - "fs-extra" "^10.0.0" - "is-ci" "^3.0.0" - "lazy-val" "^1.0.5" - "read-config-file" "6.2.0" - "simple-update-notifier" "^1.0.7" - "yargs" "^17.5.1" - -"electron-is-dev@^0.3.0": - "integrity" "sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4=" - "resolved" "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.3.0.tgz" - "version" "0.3.0" - -"electron-is@^2.4.0": - "integrity" "sha512-cWPJVsyfU1lTbUCwOyEhTChl+dU5OTPgQ/qffX72aBaWE2YcgmUriRrDioBn5gnlMok/LctTzcnJSVSTUJJMjg==" - "resolved" "https://registry.npmjs.org/electron-is/-/electron-is-2.4.1.tgz" - "version" "2.4.1" - dependencies: - "electron-is-dev" "^0.3.0" - "semver" "^5.3.0" - -<<<<<<< HEAD -"electron-notarize@^0.2.1": - "integrity" "sha512-oZ6/NhKeXmEKNROiFmRNfytqu3cxqC95sjooG7kBXQVEUSQkZnbiAhxVh5jXngL881G197pbwpeVPJyM7Ikmxw==" - "resolved" "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.2.1.tgz" - "version" "0.2.1" - dependencies: - "debug" "^4.1.1" - "fs-extra" "^8.1.0" - -"electron-osx-sign@^0.6.0": - "integrity" "sha512-+hiIEb2Xxk6eDKJ2FFlpofCnemCbjbT5jz+BKGpVBrRNT3kWTGs4DfNX6IzGwgi33hUcXF+kFs9JW+r6Wc1LRg==" - "resolved" "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.6.0.tgz" - "version" "0.6.0" - dependencies: - "bluebird" "^3.5.0" - "compare-version" "^0.1.2" - "debug" "^2.6.8" - "isbinaryfile" "^3.0.2" - "minimist" "^1.2.0" - "plist" "^3.0.1" - -======= -"electron-osx-sign@^0.6.0": - "integrity" "sha512-+hiIEb2Xxk6eDKJ2FFlpofCnemCbjbT5jz+BKGpVBrRNT3kWTGs4DfNX6IzGwgi33hUcXF+kFs9JW+r6Wc1LRg==" - "resolved" "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.6.0.tgz" - "version" "0.6.0" - dependencies: - "bluebird" "^3.5.0" - "compare-version" "^0.1.2" - "debug" "^2.6.8" - "isbinaryfile" "^3.0.2" - "minimist" "^1.2.0" - "plist" "^3.0.1" - ->>>>>>> master -"electron-publish@23.6.0": - "integrity" "sha512-jPj3y+eIZQJF/+t5SLvsI5eS4mazCbNYqatv5JihbqOstIM13k0d1Z3vAWntvtt13Itl61SO6seicWdioOU5dg==" - "resolved" "https://registry.npmjs.org/electron-publish/-/electron-publish-23.6.0.tgz" - "version" "23.6.0" + app-builder-lib "23.6.0" + builder-util "23.6.0" + builder-util-runtime "9.1.1" + chalk "^4.1.1" + dmg-builder "23.6.0" + fs-extra "^10.0.0" + is-ci "^3.0.0" + lazy-val "^1.0.5" + read-config-file "6.2.0" + simple-update-notifier "^1.0.7" + yargs "^17.5.1" + +electron-is-dev@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.3.0.tgz" + integrity sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4= + +electron-is@^2.4.0: + version "2.4.1" + resolved "https://registry.npmjs.org/electron-is/-/electron-is-2.4.1.tgz" + integrity sha512-cWPJVsyfU1lTbUCwOyEhTChl+dU5OTPgQ/qffX72aBaWE2YcgmUriRrDioBn5gnlMok/LctTzcnJSVSTUJJMjg== + dependencies: + electron-is-dev "^0.3.0" + semver "^5.3.0" + +electron-osx-sign@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.6.0.tgz" + integrity sha512-+hiIEb2Xxk6eDKJ2FFlpofCnemCbjbT5jz+BKGpVBrRNT3kWTGs4DfNX6IzGwgi33hUcXF+kFs9JW+r6Wc1LRg== + dependencies: + bluebird "^3.5.0" + compare-version "^0.1.2" + debug "^2.6.8" + isbinaryfile "^3.0.2" + minimist "^1.2.0" + plist "^3.0.1" + +electron-publish@23.6.0: + version "23.6.0" + resolved "https://registry.npmjs.org/electron-publish/-/electron-publish-23.6.0.tgz" + integrity sha512-jPj3y+eIZQJF/+t5SLvsI5eS4mazCbNYqatv5JihbqOstIM13k0d1Z3vAWntvtt13Itl61SO6seicWdioOU5dg== dependencies: "@types/fs-extra" "^9.0.11" - "builder-util" "23.6.0" - "builder-util-runtime" "9.1.1" - "chalk" "^4.1.1" - "fs-extra" "^10.0.0" - "lazy-val" "^1.0.5" - "mime" "^2.5.2" - -"electron@>= 13.0.0", "electron@18.2.2": - "integrity" "sha512-o9/9+ntxZ0RoVtllH1e9FDLiCLVg00EO8AJZoCR1cVt7l7AVpRgynZdSczaUtTb9XJpWv7U02R6hoWALl55opQ==" - "resolved" "https://registry.npmjs.org/electron/-/electron-18.2.2.tgz" - "version" "18.2.2" + builder-util "23.6.0" + builder-util-runtime "9.1.1" + chalk "^4.1.1" + fs-extra "^10.0.0" + lazy-val "^1.0.5" + mime "^2.5.2" + +"electron@>= 13.0.0", electron@18.2.2: + version "18.2.2" + resolved "https://registry.npmjs.org/electron/-/electron-18.2.2.tgz" + integrity sha512-o9/9+ntxZ0RoVtllH1e9FDLiCLVg00EO8AJZoCR1cVt7l7AVpRgynZdSczaUtTb9XJpWv7U02R6hoWALl55opQ== dependencies: "@electron/get" "^1.13.0" "@types/node" "^16.11.26" - "extract-zip" "^1.0.3" - -"emoji-regex@^8.0.0": - "integrity" "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" - "version" "8.0.0" - -"encodeurl@^1.0.2": - "integrity" "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - "resolved" "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" - "version" "1.0.2" - -"end-of-stream@^1.1.0": - "integrity" "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==" - "resolved" "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" - "version" "1.4.4" - dependencies: - "once" "^1.4.0" - -"env-paths@^2.2.0": - "integrity" "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" - "resolved" "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" - "version" "2.2.1" - -<<<<<<< HEAD -"es6-error@^4.1.1": - "integrity" "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" - "resolved" "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz" - "version" "4.1.1" - -"escalade@^3.1.1": - "integrity" "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - "resolved" "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - "version" "3.1.1" - -"escape-string-regexp@^4.0.0": - "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - "version" "4.0.0" - -======= -"err-code@^2.0.2": - "integrity" "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" - "resolved" "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" - "version" "2.0.3" - -"es6-error@^4.1.1": - "integrity" "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" - "resolved" "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz" - "version" "4.1.1" - -"escalade@^3.1.1": - "integrity" "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - "resolved" "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - "version" "3.1.1" - -"escape-string-regexp@^4.0.0": - "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - "version" "4.0.0" - ->>>>>>> master -"extract-zip@^1.0.3": - "integrity" "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==" - "resolved" "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz" - "version" "1.7.0" - dependencies: - "concat-stream" "^1.6.2" - "debug" "^2.6.9" - "mkdirp" "^0.5.4" - "yauzl" "^2.10.0" - -"extsprintf@^1.2.0": - "integrity" "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==" - "resolved" "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz" - "version" "1.4.1" - -"fast-deep-equal@^3.1.1": - "integrity" "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - "resolved" "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" - "version" "3.1.3" - -"fast-json-stable-stringify@^2.0.0": - "integrity" "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - "resolved" "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" - "version" "2.1.0" - -"fd-slicer@~1.1.0": - "integrity" "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=" - "resolved" "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz" - "version" "1.1.0" - dependencies: - "pend" "~1.2.0" - -"filelist@^1.0.1": - "integrity" "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==" - "resolved" "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz" - "version" "1.0.4" - dependencies: - "minimatch" "^5.0.1" - -"form-data@^4.0.0": - "integrity" "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==" - "resolved" "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" - "version" "4.0.0" - dependencies: - "asynckit" "^0.4.0" - "combined-stream" "^1.0.8" - "mime-types" "^2.1.12" - -"fs-extra@^10.0.0": - "integrity" "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==" - "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" - "version" "10.1.0" - dependencies: - "graceful-fs" "^4.2.0" - "jsonfile" "^6.0.1" - "universalify" "^2.0.0" - -"fs-extra@^10.1.0": - "integrity" "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==" - "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" - "version" "10.1.0" - dependencies: - "graceful-fs" "^4.2.0" - "jsonfile" "^6.0.1" - "universalify" "^2.0.0" - -"fs-extra@^8.1.0": - "integrity" "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==" - "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" - "version" "8.1.0" - dependencies: - "graceful-fs" "^4.2.0" - "jsonfile" "^4.0.0" - "universalify" "^0.1.0" - -"fs-extra@^9.0.0": - "integrity" "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==" - "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" - "version" "9.1.0" - dependencies: - "at-least-node" "^1.0.0" - "graceful-fs" "^4.2.0" - "jsonfile" "^6.0.1" - "universalify" "^2.0.0" - -"fs-extra@^9.0.1": - "integrity" "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==" - "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" - "version" "9.1.0" - dependencies: - "at-least-node" "^1.0.0" - "graceful-fs" "^4.2.0" - "jsonfile" "^6.0.1" - "universalify" "^2.0.0" - -"fs-minipass@^2.0.0": - "integrity" "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==" - "resolved" "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" - "version" "2.1.0" - dependencies: - "minipass" "^3.0.0" - -"fs.realpath@^1.0.0": - "integrity" "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - "version" "1.0.0" - -"function-bind@^1.1.1": - "integrity" "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - "resolved" "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - "version" "1.1.1" - -"get-caller-file@^2.0.5": - "integrity" "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - "resolved" "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" - "version" "2.0.5" - -"get-intrinsic@^1.1.1": - "integrity" "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==" - "resolved" "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" - "version" "1.1.1" - dependencies: - "function-bind" "^1.1.1" - "has" "^1.0.3" - "has-symbols" "^1.0.1" - -"get-stream@^4.1.0": - "integrity" "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==" - "resolved" "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz" - "version" "4.1.0" - dependencies: - "pump" "^3.0.0" - -"get-stream@^5.1.0": - "integrity" "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==" - "resolved" "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" - "version" "5.2.0" - dependencies: - "pump" "^3.0.0" - -"glob@^7.0.0", "glob@^7.1.3", "glob@^7.1.6": - "integrity" "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==" - "resolved" "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" - "version" "7.1.6" - dependencies: - "fs.realpath" "^1.0.0" - "inflight" "^1.0.4" - "inherits" "2" - "minimatch" "^3.0.4" - "once" "^1.3.0" - "path-is-absolute" "^1.0.0" - -"global-agent@^3.0.0": - "integrity" "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==" - "resolved" "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz" - "version" "3.0.0" - dependencies: - "boolean" "^3.0.1" - "es6-error" "^4.1.1" - "matcher" "^3.0.0" - "roarr" "^2.15.3" - "semver" "^7.3.2" - "serialize-error" "^7.0.1" - -"global-tunnel-ng@^2.7.1": - "integrity" "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==" - "resolved" "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz" - "version" "2.7.1" - dependencies: - "encodeurl" "^1.0.2" - "lodash" "^4.17.10" - "npm-conf" "^1.1.3" - "tunnel" "^0.0.6" - -"globalthis@^1.0.1": - "integrity" "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==" - "resolved" "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz" - "version" "1.0.2" - dependencies: - "define-properties" "^1.1.3" - -"got@^9.6.0": - "integrity" "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==" - "resolved" "https://registry.npmjs.org/got/-/got-9.6.0.tgz" - "version" "9.6.0" + extract-zip "^1.0.3" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + +es6-error@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +extract-zip@^1.0.3: + version "1.7.0" + resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz" + integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA== + dependencies: + concat-stream "^1.6.2" + debug "^2.6.9" + mkdirp "^0.5.4" + yauzl "^2.10.0" + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +filelist@^1.0.1: + version "1.0.4" + resolved "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +fs-extra@^10.0.0: + version "10.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^9.0.0: + version "9.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +glob@^7.0.0, glob@^7.1.3, glob@^7.1.6: + version "7.1.6" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-agent@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz" + integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q== + dependencies: + boolean "^3.0.1" + es6-error "^4.1.1" + matcher "^3.0.0" + roarr "^2.15.3" + semver "^7.3.2" + serialize-error "^7.0.1" + +global-tunnel-ng@^2.7.1: + version "2.7.1" + resolved "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz" + integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg== + dependencies: + encodeurl "^1.0.2" + lodash "^4.17.10" + npm-conf "^1.1.3" + tunnel "^0.0.6" + +globalthis@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz" + integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ== + dependencies: + define-properties "^1.1.3" + +got@^9.6.0: + version "9.6.0" + resolved "https://registry.npmjs.org/got/-/got-9.6.0.tgz" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== dependencies: "@sindresorhus/is" "^0.14.0" "@szmarczak/http-timer" "^1.1.2" - "cacheable-request" "^6.0.0" - "decompress-response" "^3.3.0" - "duplexer3" "^0.1.4" - "get-stream" "^4.1.0" - "lowercase-keys" "^1.0.1" - "mimic-response" "^1.0.1" - "p-cancelable" "^1.0.0" - "to-readable-stream" "^1.0.0" - "url-parse-lax" "^3.0.0" - -"graceful-fs@^4.1.6", "graceful-fs@^4.2.0": - "integrity" "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" - "resolved" "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz" - "version" "4.2.4" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.4" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== "graceful-readlink@>= 1.0.0": - "integrity" "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==" - "resolved" "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" - "version" "1.0.1" + version "1.0.1" + resolved "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" + integrity sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w== -"has-flag@^4.0.0": - "integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - "version" "4.0.0" +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -"has-property-descriptors@^1.0.0": - "integrity" "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==" - "resolved" "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" - "version" "1.0.0" +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== dependencies: - "get-intrinsic" "^1.1.1" + get-intrinsic "^1.1.1" -"has-symbols@^1.0.1": - "integrity" "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - "resolved" "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" - "version" "1.0.3" +has-symbols@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -"has@^1.0.3": - "integrity" "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==" - "resolved" "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - "version" "1.0.3" +has@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: - "function-bind" "^1.1.1" + function-bind "^1.1.1" -"hosted-git-info@^4.1.0": - "integrity" "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==" - "resolved" "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz" - "version" "4.1.0" +hosted-git-info@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz" + integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== dependencies: - "lru-cache" "^6.0.0" + lru-cache "^6.0.0" -"http-cache-semantics@^4.0.0": - "integrity" "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" - "resolved" "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" - "version" "4.1.0" +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== -"http-proxy-agent@^5.0.0": - "integrity" "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==" - "resolved" "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" - "version" "5.0.0" +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== dependencies: "@tootallnate/once" "2" - "agent-base" "6" - "debug" "4" - -"https-proxy-agent@^5.0.0": - "integrity" "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==" - "resolved" "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" - "version" "5.0.1" - dependencies: - "agent-base" "6" - "debug" "4" - -"iconv-corefoundation@^1.1.7": - "integrity" "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==" - "resolved" "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz" - "version" "1.1.7" - dependencies: - "cli-truncate" "^2.1.0" - "node-addon-api" "^1.6.3" - -"iconv-lite@^0.6.2": - "integrity" "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==" - "resolved" "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" - "version" "0.6.3" - dependencies: - "safer-buffer" ">= 2.1.2 < 3.0.0" - -"ieee754@^1.1.13": - "integrity" "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - "resolved" "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" - "version" "1.2.1" - -"inflight@^1.0.4": - "integrity" "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=" - "resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - "version" "1.0.6" - dependencies: - "once" "^1.3.0" - "wrappy" "1" - -"inherits@^2.0.3", "inherits@~2.0.3", "inherits@2": - "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - "version" "2.0.4" - -"ini@^1.3.4": - "integrity" "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - "resolved" "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" - "version" "1.3.8" - -"interpret@^1.0.0": - "integrity" "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" - "resolved" "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz" - "version" "1.4.0" - -"is-ci@^3.0.0": - "integrity" "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==" - "resolved" "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz" - "version" "3.0.1" - dependencies: - "ci-info" "^3.2.0" - -"is-fullwidth-code-point@^3.0.0": - "integrity" "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - "resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" - "version" "3.0.0" - -"isarray@~1.0.0": - "integrity" "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - "resolved" "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - "version" "1.0.0" - -"isbinaryfile@^3.0.2": - "integrity" "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==" - "resolved" "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz" - "version" "3.0.3" - dependencies: - "buffer-alloc" "^1.2.0" - -"isbinaryfile@^4.0.10": - "integrity" "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==" - "resolved" "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz" - "version" "4.0.10" - -"isexe@^2.0.0": - "integrity" "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - "resolved" "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - "version" "2.0.0" - -"jake@^10.8.5": - "integrity" "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==" - "resolved" "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz" - "version" "10.8.5" - dependencies: - "async" "^3.2.3" - "chalk" "^4.0.2" - "filelist" "^1.0.1" - "minimatch" "^3.0.4" - -"js-yaml@^4.1.0": - "integrity" "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==" - "resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - "version" "4.1.0" - dependencies: - "argparse" "^2.0.1" - -"json-buffer@3.0.0": - "integrity" "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" - "resolved" "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz" - "version" "3.0.0" - -"json-schema-traverse@^0.4.1": - "integrity" "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - "resolved" "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - "version" "0.4.1" - -"json-stringify-safe@^5.0.1": - "integrity" "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - "resolved" "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - "version" "5.0.1" - -"json5@^2.2.0": - "integrity" "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - "resolved" "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" - "version" "2.2.3" - -"jsonfile@^4.0.0": - "integrity" "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=" - "resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" - "version" "4.0.0" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +iconv-corefoundation@^1.1.7: + version "1.1.7" + resolved "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz" + integrity sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ== + dependencies: + cli-truncate "^2.1.0" + node-addon-api "^1.6.3" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@^2.0.3, inherits@~2.0.3, inherits@2: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@^1.3.4: + version "1.3.8" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +is-ci@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== + dependencies: + ci-info "^3.2.0" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isbinaryfile@^3.0.2: + version "3.0.3" + resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz" + integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== + dependencies: + buffer-alloc "^1.2.0" + +isbinaryfile@^4.0.10: + version "4.0.10" + resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jake@^10.8.5: + version "10.8.5" + resolved "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz" + integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.1" + minimatch "^3.0.4" + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stringify-safe@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5@^2.2.0: + version "2.2.3" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= optionalDependencies: - "graceful-fs" "^4.1.6" + graceful-fs "^4.1.6" -"jsonfile@^6.0.1": - "integrity" "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==" - "resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" - "version" "6.1.0" +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== dependencies: - "universalify" "^2.0.0" + universalify "^2.0.0" optionalDependencies: - "graceful-fs" "^4.1.6" + graceful-fs "^4.1.6" -"keyv@^3.0.0": - "integrity" "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==" - "resolved" "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz" - "version" "3.1.0" +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== dependencies: - "json-buffer" "3.0.0" + json-buffer "3.0.0" -"lazy-val@^1.0.4", "lazy-val@^1.0.5": - "integrity" "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==" - "resolved" "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz" - "version" "1.0.5" +lazy-val@^1.0.4, lazy-val@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz" + integrity sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q== -"lodash@^4.17.10", "lodash@^4.17.15": - "integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - "resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - "version" "4.17.21" +lodash@^4.17.10, lodash@^4.17.15: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -"lowercase-keys@^1.0.0", "lowercase-keys@^1.0.1": - "integrity" "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" - "resolved" "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz" - "version" "1.0.1" +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== -"lowercase-keys@^2.0.0": - "integrity" "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - "resolved" "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" - "version" "2.0.0" +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== -"lru-cache@^6.0.0": - "integrity" "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==" - "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - "version" "6.0.0" +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: - "yallist" "^4.0.0" - -"matcher@^3.0.0": - "integrity" "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==" - "resolved" "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz" - "version" "3.0.0" - dependencies: - "escape-string-regexp" "^4.0.0" + yallist "^4.0.0" + +matcher@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz" + integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng== + dependencies: + escape-string-regexp "^4.0.0" -"mime-db@1.52.0": - "integrity" "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - "resolved" "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - "version" "1.52.0" - -"mime-types@^2.1.12": - "integrity" "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==" - "resolved" "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" - "version" "2.1.35" - dependencies: - "mime-db" "1.52.0" - -"mime@^2.5.2": - "integrity" "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" - "resolved" "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" - "version" "2.6.0" - -"mimic-response@^1.0.0", "mimic-response@^1.0.1": - "integrity" "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - "resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" - "version" "1.0.1" - -"minimatch@^3.0.4", "minimatch@^3.1.2": - "integrity" "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==" - "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - "version" "3.1.2" - dependencies: - "brace-expansion" "^1.1.7" - -"minimatch@^5.0.1": - "integrity" "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==" - "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" - "version" "5.1.6" - dependencies: - "brace-expansion" "^2.0.1" - -"minimatch@3.0.4": - "integrity" "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==" - "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" - "version" "3.0.4" - dependencies: - "brace-expansion" "^1.1.7" - -"minimist@^1.2.0", "minimist@^1.2.3", "minimist@^1.2.5": - "integrity" "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - "resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" - "version" "1.2.5" - -"minipass@^3.0.0": - "integrity" "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==" - "resolved" "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" - "version" "3.3.6" - dependencies: - "yallist" "^4.0.0" - -"minipass@^4.0.0": - "integrity" "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==" - "resolved" "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz" - "version" "4.2.8" - -"minizlib@^2.1.1": - "integrity" "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==" - "resolved" "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" - "version" "2.1.2" - dependencies: - "minipass" "^3.0.0" - "yallist" "^4.0.0" - -"mkdirp@^0.5.4": - "integrity" "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==" - "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" - "version" "0.5.5" - dependencies: - "minimist" "^1.2.5" - -"mkdirp@^1.0.3": - "integrity" "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - "version" "1.0.4" - -"ms@2.0.0": - "integrity" "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - "resolved" "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - "version" "2.0.0" - -"ms@2.1.2": - "integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - "version" "2.1.2" - -"node-addon-api@^1.6.3": - "integrity" "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==" - "resolved" "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz" - "version" "1.7.2" - -"normalize-url@^4.1.0": - "integrity" "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" - "resolved" "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz" - "version" "4.5.1" - -"npm-conf@^1.1.3": - "integrity" "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==" - "resolved" "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz" - "version" "1.1.3" - dependencies: - "config-chain" "^1.1.11" - "pify" "^3.0.0" - -"object-keys@^1.1.1": - "integrity" "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - "resolved" "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" - "version" "1.1.1" - -"once@^1.3.0", "once@^1.3.1", "once@^1.4.0": - "integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" - "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - "version" "1.4.0" - dependencies: - "wrappy" "1" - -"p-cancelable@^1.0.0": - "integrity" "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" - "resolved" "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz" - "version" "1.1.0" - -"path-is-absolute@^1.0.0": - "integrity" "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - "resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - "version" "1.0.1" - -"path-key@^3.1.0": - "integrity" "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - "resolved" "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - "version" "3.1.1" - -"path-parse@^1.0.6": - "integrity" "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - "resolved" "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz" - "version" "1.0.6" - -"pend@~1.2.0": - "integrity" "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" - "resolved" "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" - "version" "1.2.0" - -"pify@^3.0.0": - "integrity" "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - "resolved" "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" - "version" "3.0.0" - -"plist@^3.0.1", "plist@^3.0.4": - "integrity" "sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==" - "resolved" "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz" - "version" "3.0.6" - dependencies: - "base64-js" "^1.5.1" - "xmlbuilder" "^15.1.1" - -"prepend-http@^2.0.0": - "integrity" "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" - "resolved" "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz" - "version" "2.0.0" - -"prettier@1.15.3": - "integrity" "sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==" - "resolved" "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz" - "version" "1.15.3" - -"process-nextick-args@~2.0.0": - "integrity" "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - "resolved" "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" - "version" "2.0.1" - -"progress@^2.0.3": - "integrity" "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - "resolved" "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" - "version" "2.0.3" - -<<<<<<< HEAD -"proto-list@~1.2.1": - "integrity" "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" - "resolved" "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz" - "version" "1.2.4" - -"pump@^3.0.0": - "integrity" "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==" - "resolved" "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" - "version" "3.0.0" - dependencies: - "end-of-stream" "^1.1.0" - "once" "^1.3.1" - -"punycode@^2.1.0": - "integrity" "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" - "resolved" "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - "version" "2.3.0" - -"read-config-file@6.2.0": - "integrity" "sha512-gx7Pgr5I56JtYz+WuqEbQHj/xWo+5Vwua2jhb1VwM4Wid5PqYmZ4i00ZB0YEGIfkVBsCv9UrjgyqCiQfS/Oosg==" - "resolved" "https://registry.npmjs.org/read-config-file/-/read-config-file-6.2.0.tgz" - "version" "6.2.0" - dependencies: - "dotenv" "^9.0.2" - "dotenv-expand" "^5.1.0" - "js-yaml" "^4.1.0" - "json5" "^2.2.0" - "lazy-val" "^1.0.4" - -"readable-stream@^2.2.2": - "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==" - "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" - "version" "2.3.7" - dependencies: - "core-util-is" "~1.0.0" - "inherits" "~2.0.3" - "isarray" "~1.0.0" - "process-nextick-args" "~2.0.0" - "safe-buffer" "~5.1.1" - "string_decoder" "~1.1.1" - "util-deprecate" "~1.0.1" - -"rechoir@^0.6.2": - "integrity" "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=" - "resolved" "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" - "version" "0.6.2" - dependencies: - "resolve" "^1.1.6" - -"require-directory@^2.1.1": - "integrity" "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" - "resolved" "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" - "version" "2.1.1" - -"resolve@^1.1.6": - "integrity" "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==" - "resolved" "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz" - "version" "1.17.0" - dependencies: - "path-parse" "^1.0.6" - -"responselike@^1.0.2": - "integrity" "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=" - "resolved" "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz" - "version" "1.0.2" - dependencies: - "lowercase-keys" "^1.0.0" - -"rimraf@^3.0.0": - "integrity" "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==" - "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - "version" "3.0.2" - dependencies: - "glob" "^7.1.3" - -"roarr@^2.15.3": - "integrity" "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==" - "resolved" "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz" - "version" "2.15.4" - dependencies: - "boolean" "^3.0.1" - "detect-node" "^2.0.4" - "globalthis" "^1.0.1" - "json-stringify-safe" "^5.0.1" - "semver-compare" "^1.0.0" - "sprintf-js" "^1.1.2" - -======= -"promise-retry@^2.0.1": - "integrity" "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==" - "resolved" "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz" - "version" "2.0.1" - dependencies: - "err-code" "^2.0.2" - "retry" "^0.12.0" - -"proto-list@~1.2.1": - "integrity" "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" - "resolved" "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz" - "version" "1.2.4" - -"pump@^3.0.0": - "integrity" "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==" - "resolved" "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" - "version" "3.0.0" - dependencies: - "end-of-stream" "^1.1.0" - "once" "^1.3.1" - -"punycode@^2.1.0": - "integrity" "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" - "resolved" "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - "version" "2.3.0" - -"read-config-file@6.2.0": - "integrity" "sha512-gx7Pgr5I56JtYz+WuqEbQHj/xWo+5Vwua2jhb1VwM4Wid5PqYmZ4i00ZB0YEGIfkVBsCv9UrjgyqCiQfS/Oosg==" - "resolved" "https://registry.npmjs.org/read-config-file/-/read-config-file-6.2.0.tgz" - "version" "6.2.0" - dependencies: - "dotenv" "^9.0.2" - "dotenv-expand" "^5.1.0" - "js-yaml" "^4.1.0" - "json5" "^2.2.0" - "lazy-val" "^1.0.4" - -"readable-stream@^2.2.2": - "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==" - "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" - "version" "2.3.7" - dependencies: - "core-util-is" "~1.0.0" - "inherits" "~2.0.3" - "isarray" "~1.0.0" - "process-nextick-args" "~2.0.0" - "safe-buffer" "~5.1.1" - "string_decoder" "~1.1.1" - "util-deprecate" "~1.0.1" - -"rechoir@^0.6.2": - "integrity" "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=" - "resolved" "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" - "version" "0.6.2" - dependencies: - "resolve" "^1.1.6" - -"require-directory@^2.1.1": - "integrity" "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" - "resolved" "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" - "version" "2.1.1" - -"resolve@^1.1.6": - "integrity" "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==" - "resolved" "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz" - "version" "1.17.0" - dependencies: - "path-parse" "^1.0.6" - -"responselike@^1.0.2": - "integrity" "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=" - "resolved" "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz" - "version" "1.0.2" - dependencies: - "lowercase-keys" "^1.0.0" - -"retry@^0.12.0": - "integrity" "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" - "resolved" "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" - "version" "0.12.0" - -"rimraf@^3.0.0": - "integrity" "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==" - "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - "version" "3.0.2" - dependencies: - "glob" "^7.1.3" - -"roarr@^2.15.3": - "integrity" "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==" - "resolved" "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz" - "version" "2.15.4" - dependencies: - "boolean" "^3.0.1" - "detect-node" "^2.0.4" - "globalthis" "^1.0.1" - "json-stringify-safe" "^5.0.1" - "semver-compare" "^1.0.0" - "sprintf-js" "^1.1.2" - ->>>>>>> master -"safe-buffer@~5.1.0", "safe-buffer@~5.1.1": - "integrity" "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - "version" "5.1.2" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +minimatch@^3.0.4, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass@^3.0.0: + version "3.3.6" + resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^4.0.0: + version "4.2.8" + resolved "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz" + integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== + +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp@^0.5.4: + version "0.5.5" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +node-addon-api@^1.6.3: + version "1.7.2" + resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz" + integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg== + +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + +npm-conf@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz" + integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +plist@^3.0.1, plist@^3.0.4: + version "3.0.6" + resolved "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz" + integrity sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA== + dependencies: + base64-js "^1.5.1" + xmlbuilder "^15.1.1" + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +prettier@1.15.3: + version "1.15.3" + resolved "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz" + integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +progress@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +read-config-file@6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/read-config-file/-/read-config-file-6.2.0.tgz" + integrity sha512-gx7Pgr5I56JtYz+WuqEbQHj/xWo+5Vwua2jhb1VwM4Wid5PqYmZ4i00ZB0YEGIfkVBsCv9UrjgyqCiQfS/Oosg== + dependencies: + dotenv "^9.0.2" + dotenv-expand "^5.1.0" + js-yaml "^4.1.0" + json5 "^2.2.0" + lazy-val "^1.0.4" + +readable-stream@^2.2.2: + version "2.3.7" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve@^1.1.6: + version "1.17.0" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +roarr@^2.15.3: + version "2.15.4" + resolved "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz" + integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A== + dependencies: + boolean "^3.0.1" + detect-node "^2.0.4" + globalthis "^1.0.1" + json-stringify-safe "^5.0.1" + semver-compare "^1.0.0" + sprintf-js "^1.1.2" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== "safer-buffer@>= 2.1.2 < 3.0.0": - "integrity" "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - "resolved" "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - "version" "2.1.2" - -"sanitize-filename@^1.6.3": - "integrity" "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==" - "resolved" "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz" - "version" "1.6.3" - dependencies: - "truncate-utf8-bytes" "^1.0.0" - -"sax@^1.2.4": - "integrity" "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - "resolved" "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" - "version" "1.2.4" - -"semver-compare@^1.0.0": - "integrity" "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" - "resolved" "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" - "version" "1.0.0" - -"semver@^5.3.0": - "integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - "resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" - "version" "5.7.1" - -"semver@^6.2.0": - "integrity" "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - "resolved" "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" - "version" "6.3.0" - -"semver@^7.3.2": - "integrity" "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==" - "resolved" "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz" - "version" "7.3.7" - dependencies: - "lru-cache" "^6.0.0" - -"semver@^7.3.7": - "integrity" "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==" - "resolved" "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz" - "version" "7.5.0" - dependencies: - "lru-cache" "^6.0.0" - -"semver@~7.0.0": - "integrity" "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" - "resolved" "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz" - "version" "7.0.0" - -"serialize-error@^7.0.1": - "integrity" "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==" - "resolved" "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz" - "version" "7.0.1" - dependencies: - "type-fest" "^0.13.1" - -"shebang-command@^2.0.0": - "integrity" "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==" - "resolved" "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - "version" "2.0.0" - dependencies: - "shebang-regex" "^3.0.0" - -"shebang-regex@^3.0.0": - "integrity" "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - "resolved" "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - "version" "3.0.0" - -"shelljs@0.8.4": - "integrity" "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==" - "resolved" "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz" - "version" "0.8.4" - dependencies: - "glob" "^7.0.0" - "interpret" "^1.0.0" - "rechoir" "^0.6.2" - -"simple-update-notifier@^1.0.7": - "integrity" "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==" - "resolved" "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz" - "version" "1.1.0" - dependencies: - "semver" "~7.0.0" - -"slice-ansi@^3.0.0": - "integrity" "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==" - "resolved" "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" - "version" "3.0.0" - dependencies: - "ansi-styles" "^4.0.0" - "astral-regex" "^2.0.0" - "is-fullwidth-code-point" "^3.0.0" - -"smart-buffer@^4.0.2": - "integrity" "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" - "resolved" "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" - "version" "4.2.0" - -"source-map-support@^0.5.19": - "integrity" "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==" - "resolved" "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" - "version" "0.5.21" - dependencies: - "buffer-from" "^1.0.0" - "source-map" "^0.6.0" - -"source-map@^0.6.0": - "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - "version" "0.6.1" - -"sprintf-js@^1.1.2": - "integrity" "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" - "resolved" "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz" - "version" "1.1.2" - -"stat-mode@^1.0.0": - "integrity" "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==" - "resolved" "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz" - "version" "1.0.0" - -"string_decoder@~1.1.1": - "integrity" "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==" - "resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - "version" "1.1.1" - dependencies: - "safe-buffer" "~5.1.0" - -"string-width@^4.1.0", "string-width@^4.2.0", "string-width@^4.2.3": - "integrity" "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==" - "resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - "version" "4.2.3" - dependencies: - "emoji-regex" "^8.0.0" - "is-fullwidth-code-point" "^3.0.0" - "strip-ansi" "^6.0.1" - -"strip-ansi@^6.0.0", "strip-ansi@^6.0.1": - "integrity" "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==" - "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - "version" "6.0.1" - dependencies: - "ansi-regex" "^5.0.1" - -"sumchecker@^3.0.1": - "integrity" "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==" - "resolved" "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz" - "version" "3.0.1" - dependencies: - "debug" "^4.1.0" - -"supports-color@^7.1.0": - "integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==" - "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - "version" "7.2.0" - dependencies: - "has-flag" "^4.0.0" - -"tar@^6.1.11": - "integrity" "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==" - "resolved" "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz" - "version" "6.1.13" - dependencies: - "chownr" "^2.0.0" - "fs-minipass" "^2.0.0" - "minipass" "^4.0.0" - "minizlib" "^2.1.1" - "mkdirp" "^1.0.3" - "yallist" "^4.0.0" - -"temp-file@^3.4.0": - "integrity" "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==" - "resolved" "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz" - "version" "3.4.0" - dependencies: - "async-exit-hook" "^2.0.1" - "fs-extra" "^10.0.0" - -"tmp-promise@^3.0.2": - "integrity" "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==" - "resolved" "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz" - "version" "3.0.3" - dependencies: - "tmp" "^0.2.0" - -"tmp@^0.2.0": - "integrity" "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==" - "resolved" "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" - "version" "0.2.1" - dependencies: - "rimraf" "^3.0.0" - -"to-readable-stream@^1.0.0": - "integrity" "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" - "resolved" "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz" - "version" "1.0.0" - -"truncate-utf8-bytes@^1.0.0": - "integrity" "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==" - "resolved" "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz" - "version" "1.0.2" - dependencies: - "utf8-byte-length" "^1.0.1" - -"tunnel@^0.0.6": - "integrity" "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" - "resolved" "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz" - "version" "0.0.6" - -"type-fest@^0.13.1": - "integrity" "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==" - "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz" - "version" "0.13.1" - -"typedarray@^0.0.6": - "integrity" "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - "resolved" "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" - "version" "0.0.6" - -"universalify@^0.1.0": - "integrity" "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - "resolved" "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" - "version" "0.1.2" - -"universalify@^2.0.0": - "integrity" "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" - "resolved" "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" - "version" "2.0.0" - -"uri-js@^4.2.2": - "integrity" "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==" - "resolved" "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - "version" "4.4.1" - dependencies: - "punycode" "^2.1.0" - -"url-parse-lax@^3.0.0": - "integrity" "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=" - "resolved" "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz" - "version" "3.0.0" - dependencies: - "prepend-http" "^2.0.0" - -"utf8-byte-length@^1.0.1": - "integrity" "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==" - "resolved" "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz" - "version" "1.0.4" - -"util-deprecate@~1.0.1": - "integrity" "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - "resolved" "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - "version" "1.0.2" - -"verror@^1.10.0": - "integrity" "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==" - "resolved" "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz" - "version" "1.10.1" - dependencies: - "assert-plus" "^1.0.0" - "core-util-is" "1.0.2" - "extsprintf" "^1.2.0" - -"which@^2.0.1": - "integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==" - "resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - "version" "2.0.2" - dependencies: - "isexe" "^2.0.0" - -"wrap-ansi@^7.0.0": - "integrity" "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==" - "resolved" "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - "version" "7.0.0" - dependencies: - "ansi-styles" "^4.0.0" - "string-width" "^4.1.0" - "strip-ansi" "^6.0.0" - -"wrappy@1": - "integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - "version" "1.0.2" - -"xmlbuilder@^15.1.1", "xmlbuilder@>=11.0.1": - "integrity" "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==" - "resolved" "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz" - "version" "15.1.1" - -"y18n@^5.0.5": - "integrity" "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - "resolved" "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" - "version" "5.0.8" - -"yallist@^4.0.0": - "integrity" "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - "resolved" "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - "version" "4.0.0" - -"yargs-parser@^21.1.1": - "integrity" "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" - "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" - "version" "21.1.1" - -"yargs@^17.5.1": - "integrity" "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==" - "resolved" "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" - "version" "17.7.2" - dependencies: - "cliui" "^8.0.1" - "escalade" "^3.1.1" - "get-caller-file" "^2.0.5" - "require-directory" "^2.1.1" - "string-width" "^4.2.3" - "y18n" "^5.0.5" - "yargs-parser" "^21.1.1" - -"yauzl@^2.10.0": - "integrity" "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=" - "resolved" "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz" - "version" "2.10.0" - dependencies: - "buffer-crc32" "~0.2.3" - "fd-slicer" "~1.1.0" + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sanitize-filename@^1.6.3: + version "1.6.3" + resolved "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz" + integrity sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg== + dependencies: + truncate-utf8-bytes "^1.0.0" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + +semver@^5.3.0: + version "5.7.1" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.2.0: + version "6.3.0" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.2: + version "7.3.7" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + +semver@^7.3.7: + version "7.5.0" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz" + integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== + dependencies: + lru-cache "^6.0.0" + +semver@~7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +serialize-error@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz" + integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw== + dependencies: + type-fest "^0.13.1" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shelljs@0.8.4: + version "0.8.4" + resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz" + integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +simple-update-notifier@^1.0.7: + version "1.1.0" + resolved "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz" + integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== + dependencies: + semver "~7.0.0" + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +smart-buffer@^4.0.2: + version "4.2.0" + resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +source-map-support@^0.5.19: + version "0.5.21" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== + +stat-mode@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz" + integrity sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg== + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +sumchecker@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz" + integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg== + dependencies: + debug "^4.1.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +tar@^6.1.11: + version "6.1.13" + resolved "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz" + integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^4.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +temp-file@^3.4.0: + version "3.4.0" + resolved "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz" + integrity sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg== + dependencies: + async-exit-hook "^2.0.1" + fs-extra "^10.0.0" + +tmp-promise@^3.0.2: + version "3.0.3" + resolved "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz" + integrity sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ== + dependencies: + tmp "^0.2.0" + +tmp@^0.2.0: + version "0.2.1" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +truncate-utf8-bytes@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz" + integrity sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ== + dependencies: + utf8-byte-length "^1.0.1" + +tunnel@^0.0.6: + version "0.0.6" + resolved "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz" + integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== + +type-fest@^0.13.1: + version "0.13.1" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz" + integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +utf8-byte-length@^1.0.1: + version "1.0.4" + resolved "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz" + integrity sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA== + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +verror@^1.10.0: + version "1.10.1" + resolved "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz" + integrity sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +xmlbuilder@^15.1.1, xmlbuilder@>=11.0.1: + version "15.1.1" + resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz" + integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.5.1: + version "17.7.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" From a982540b61862fb5ca88ae525031a800c602cd79 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 15 Nov 2023 14:44:37 +0200 Subject: [PATCH 18/80] remove pixi-spine import in global d.ts files, remove animations ui if incorrect spine files used --- GDJS/Runtime/types/global-pixi-spine.d.ts | 1 - GDJS/Runtime/types/global-pixi.d.ts | 1 - .../src/ObjectEditor/Editors/SpineEditor.js | 292 +++++++++--------- 3 files changed, 148 insertions(+), 146 deletions(-) diff --git a/GDJS/Runtime/types/global-pixi-spine.d.ts b/GDJS/Runtime/types/global-pixi-spine.d.ts index 82a3859e3e76..e7dd424df922 100644 --- a/GDJS/Runtime/types/global-pixi-spine.d.ts +++ b/GDJS/Runtime/types/global-pixi-spine.d.ts @@ -1,4 +1,3 @@ -import 'pixi-spine'; import * as pixi_spine from 'pixi-spine'; export = pixi_spine; diff --git a/GDJS/Runtime/types/global-pixi.d.ts b/GDJS/Runtime/types/global-pixi.d.ts index 230b9e2b5575..d1d5786c0bbf 100644 --- a/GDJS/Runtime/types/global-pixi.d.ts +++ b/GDJS/Runtime/types/global-pixi.d.ts @@ -1,4 +1,3 @@ -import 'pixi-spine'; import * as PIXI from 'pixi.js'; export = PIXI; diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 68d059c4f7a0..dff309910bcf 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -412,159 +412,163 @@ const SpineEditor = ({ objectConfiguration={objectConfiguration} propertyName="timeScale" /> - Animations - - {spineConfiguration.getAnimationsCount() === 0 ? ( - - Add your first animation} - description={ - Animations are a sequence of images. - } - actionLabel={Add an animation} - helpPagePath="/objects/sprite" - tutorialId="intermediate-changing-animations" - onAction={addAnimation} - /> - - ) : ( - - {mapFor( - 0, - spineConfiguration.getAnimationsCount(), - animationIndex => { - const animation = spineConfiguration.getAnimation( - animationIndex - ); - - const animationRef = - justAddedAnimationName === animation.getName() - ? justAddedAnimationElement - : null; - - return ( - { - draggedAnimationIndex.current = animationIndex; - return {}; - }} - canDrag={() => true} - canDrop={() => true} - drop={() => { - moveAnimation(animationIndex); - }} - > - {({ - connectDragSource, - connectDropTarget, - isOver, - canDrop, - }) => - connectDropTarget( -
- {isOver && } + {sourceSelectOptions.length && + <> + Animations + + {spineConfiguration.getAnimationsCount() === 0 ? ( + + Add your first animation} + description={ + Animations are a sequence of images. + } + actionLabel={Add an animation} + helpPagePath="/objects/sprite" + tutorialId="intermediate-changing-animations" + onAction={addAnimation} + /> + + ) : ( + + {mapFor( + 0, + spineConfiguration.getAnimationsCount(), + animationIndex => { + const animation = spineConfiguration.getAnimation( + animationIndex + ); + + const animationRef = + justAddedAnimationName === animation.getName() + ? justAddedAnimationElement + : null; + + return ( + { + draggedAnimationIndex.current = animationIndex; + return {}; + }} + canDrag={() => true} + canDrop={() => true} + drop={() => { + moveAnimation(animationIndex); + }} + > + {({ + connectDragSource, + connectDropTarget, + isOver, + canDrop, + }) => + connectDropTarget(
- - {connectDragSource( - - - - - - )} - - Animation #{animationIndex} - + {isOver && } +
+ + {connectDragSource( + + + + + + )} + + Animation #{animationIndex} + + + + changeAnimationName(animationIndex, text) + } + fullWidth + /> + + removeAnimation(animationIndex) + } + > + + + - - changeAnimationName(animationIndex, text) - } +
+ + + { + animation.setSource(event.target.value); + forceUpdate(); + }} + margin="dense" fullWidth - /> - - removeAnimation(animationIndex) + floatingLabelText={ + Spine animation name } + translatableHintText={t`Choose an animation`} > - - -
- + {sourceSelectOptions} + + Loop} + checked={animation.shouldLoop()} + onCheck={(e, checked) => { + animation.setShouldLoop(checked); + forceUpdate(); + }} + /> +
- - - { - animation.setSource(event.target.value); - forceUpdate(); - }} - margin="dense" - fullWidth - floatingLabelText={ - Spine animation name - } - translatableHintText={t`Choose an animation`} - > - {sourceSelectOptions} - - Loop} - checked={animation.shouldLoop()} - onCheck={(e, checked) => { - animation.setShouldLoop(checked); - forceUpdate(); - }} - /> - -
- ) - } -
- ); - } - )} -
- )} -
+ ) + } + + ); + } + )} + + )} + + + + Scan missing animations} + onClick={scanNewAnimations} + /> + Add an animation} + primary + onClick={addAnimation} + icon={} + /> + + + + } - - - Scan missing animations} - onClick={scanNewAnimations} - /> - Add an animation} - primary - onClick={addAnimation} - icon={} - /> - - ); }; From b466d4dd657382bfd022167a81c2932262f884f5 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 15 Nov 2023 14:49:17 +0200 Subject: [PATCH 19/80] run format --- .../src/ObjectEditor/Editors/SpineEditor.js | 278 +++++++++--------- .../ObjectsRenderingService.js | 2 +- .../ObjectsRendering/PixiResourcesLoader.js | 52 ++-- 3 files changed, 179 insertions(+), 153 deletions(-) diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index dff309910bcf..6beb77300fc0 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -50,24 +50,25 @@ const SpineEditor = ({ }: EditorProps) => { const scrollView = React.useRef(null); - const getResource = (name) => { + const getResource = name => { const resourcesManager = project.getResourcesManager(); - return resourcesManager.hasResource(name) ? - resourcesManager.getResource(name) : - null; + return resourcesManager.hasResource(name) + ? resourcesManager.getResource(name) + : null; }; - const getMetadata = (resource) => { + const getMetadata = resource => { const metadataString = resource.getMetadata(); - return !!metadataString ? JSON.parse(metadataString) : { }; + return !!metadataString ? JSON.parse(metadataString) : {}; }; - const setMetadata = (resource, metadata) => resource?.setMetadata(JSON.stringify(metadata)); + const setMetadata = (resource, metadata) => + resource?.setMetadata(JSON.stringify(metadata)); const extendMetadata = (resourceName, metadata) => { const resource = getResource(resourceName); - + setMetadata(resource, Object.assign(getMetadata(resource), metadata)); - } + }; const [ justAddedAnimationName, setJustAddedAnimationName, @@ -412,141 +413,148 @@ const SpineEditor = ({ objectConfiguration={objectConfiguration} propertyName="timeScale" /> - {sourceSelectOptions.length && + {sourceSelectOptions.length && ( <> Animations - {spineConfiguration.getAnimationsCount() === 0 ? ( - - Add your first animation} - description={ - Animations are a sequence of images. - } - actionLabel={Add an animation} - helpPagePath="/objects/sprite" - tutorialId="intermediate-changing-animations" - onAction={addAnimation} - /> - - ) : ( - - {mapFor( - 0, - spineConfiguration.getAnimationsCount(), - animationIndex => { - const animation = spineConfiguration.getAnimation( - animationIndex - ); - - const animationRef = - justAddedAnimationName === animation.getName() - ? justAddedAnimationElement - : null; - - return ( - { - draggedAnimationIndex.current = animationIndex; - return {}; - }} - canDrag={() => true} - canDrop={() => true} - drop={() => { - moveAnimation(animationIndex); - }} - > - {({ - connectDragSource, - connectDropTarget, - isOver, - canDrop, - }) => - connectDropTarget( -
- {isOver && } + {spineConfiguration.getAnimationsCount() === 0 ? ( + + Add your first animation} + description={ + Animations are a sequence of images. + } + actionLabel={Add an animation} + helpPagePath="/objects/sprite" + tutorialId="intermediate-changing-animations" + onAction={addAnimation} + /> + + ) : ( + + {mapFor( + 0, + spineConfiguration.getAnimationsCount(), + animationIndex => { + const animation = spineConfiguration.getAnimation( + animationIndex + ); + + const animationRef = + justAddedAnimationName === animation.getName() + ? justAddedAnimationElement + : null; + + return ( + { + draggedAnimationIndex.current = animationIndex; + return {}; + }} + canDrag={() => true} + canDrop={() => true} + drop={() => { + moveAnimation(animationIndex); + }} + > + {({ + connectDragSource, + connectDropTarget, + isOver, + canDrop, + }) => + connectDropTarget(
- - {connectDragSource( - - - - - - )} - - Animation #{animationIndex} - + {isOver && ( + + )} +
+ + {connectDragSource( + + + + + + )} + + + Animation #{animationIndex} + + + + + changeAnimationName( + animationIndex, + text + ) + } + fullWidth + /> + + removeAnimation(animationIndex) + } + > + + + - - changeAnimationName(animationIndex, text) - } +
+ + + { + animation.setSource(event.target.value); + forceUpdate(); + }} + margin="dense" fullWidth - /> - - removeAnimation(animationIndex) + floatingLabelText={ + Spine animation name } + translatableHintText={t`Choose an animation`} > - - -
- + {sourceSelectOptions} + + Loop} + checked={animation.shouldLoop()} + onCheck={(e, checked) => { + animation.setShouldLoop(checked); + forceUpdate(); + }} + /> +
- - - { - animation.setSource(event.target.value); - forceUpdate(); - }} - margin="dense" - fullWidth - floatingLabelText={ - Spine animation name - } - translatableHintText={t`Choose an animation`} - > - {sourceSelectOptions} - - Loop} - checked={animation.shouldLoop()} - onCheck={(e, checked) => { - animation.setShouldLoop(checked); - forceUpdate(); - }} - /> - -
- ) - } -
- ); - } - )} -
- )} + ) + } + + ); + } + )} + + )}
- } + )} diff --git a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js index 48f7e7b883eb..2a1b5e9aafb5 100644 --- a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js +++ b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js @@ -1,5 +1,5 @@ // @flow -import 'pixi-spine' +import 'pixi-spine'; import RenderedUnknownInstance from './Renderers/RenderedUnknownInstance'; import RenderedSpriteInstance from './Renderers/RenderedSpriteInstance'; import RenderedTiledSpriteInstance from './Renderers/RenderedTiledSpriteInstance'; diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index e409ec961440..dcd28e5d635b 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -489,15 +489,21 @@ export default class PixiResourcesLoader { // https://github.com/pixijs/spine/blob/master/examples/preload_atlas_text.md if (!atlasPromises[atlasTextName]) { atlasPromises[atlasTextName] = new Promise(resolve => { - const onError = (err) => { - console.error(`Error during ${atlasTextName} atlas loading: ${err}.\nCheck if you selected correct pair of atlas and image files.`); + const onError = err => { + console.error( + `Error during ${atlasTextName} atlas loading: ${err}.\nCheck if you selected correct pair of atlas and image files.` + ); resolve(undefined); }; try { - const atlasUrl = ResourcesLoader.getResourceFullUrl(project, atlasTextName, { - isResourceForPixi: true, - }); + const atlasUrl = ResourcesLoader.getResourceFullUrl( + project, + atlasTextName, + { + isResourceForPixi: true, + } + ); const atlasImage = this.getPIXITexture(project, atlasImageName); PIXI.Assets.setPreferences({ preferWorkers: false, @@ -507,9 +513,13 @@ export default class PixiResourcesLoader { }); PIXI.Assets.add(atlasTextName, atlasUrl, { image: atlasImage }); PIXI.Assets.load(atlasTextName) - .then((atlas) => { + .then(atlas => { if (typeof atlas === 'string') { - new PIXI_SPINE.TextureAtlas(atlas, (_, textureCb) => textureCb(atlasImage.baseTexture), resolve); + new PIXI_SPINE.TextureAtlas( + atlas, + (_, textureCb) => textureCb(atlasImage.baseTexture), + resolve + ); } else { resolve(atlas); } @@ -525,32 +535,40 @@ export default class PixiResourcesLoader { spineDataPromises[spineName] = new Promise(resolve => { atlasPromises[atlasTextName].then(spineAtlas => { if (!spineAtlas) { - console.error(`Cannot load ${spineName} spine. Atlas ${atlasTextName} is undefined. Check if you selected correct files.`); + console.error( + `Cannot load ${spineName} spine. Atlas ${atlasTextName} is undefined. Check if you selected correct files.` + ); return resolve(undefined); } - const onError = (err) => { - console.error(`Error during ${spineName} spine loading: ${err}.\nCheck if you selected correct files.`); + const onError = err => { + console.error( + `Error during ${spineName} spine loading: ${err}.\nCheck if you selected correct files.` + ); resolve(undefined); }; try { - const jsonUrl = ResourcesLoader.getResourceFullUrl(project, spineName, { - isResourceForPixi: true, - }); + const jsonUrl = ResourcesLoader.getResourceFullUrl( + project, + spineName, + { + isResourceForPixi: true, + } + ); PIXI.Assets.setPreferences({ preferWorkers: false, crossOrigin: checkIfCredentialsRequired(jsonUrl) ? 'use-credentials' : 'anonymous', }); - PIXI.Assets.add(spineName, jsonUrl, { spineAtlas }) + PIXI.Assets.add(spineName, jsonUrl, { spineAtlas }); PIXI.Assets.load(spineName) - .then((jsonData) => { - resolve(jsonData.spineData) + .then(jsonData => { + resolve(jsonData.spineData); }) - .catch(onError); + .catch(onError); } catch (err) { onError(err); } From 55fcf456972297d924ec71e55aef8ff0e18f5135 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 15 Nov 2023 14:58:18 +0200 Subject: [PATCH 20/80] fix flow issues --- newIDE/app/src/ObjectEditor/Editors/SpineEditor.js | 9 ++++++--- newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js | 2 +- .../ParameterFields/ResourceFields.stories.js | 5 ++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 6beb77300fc0..d67bb8fd637b 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -58,12 +58,15 @@ const SpineEditor = ({ : null; }; const getMetadata = resource => { - const metadataString = resource.getMetadata(); + const metadataString = resource ? resource.getMetadata() : ''; return !!metadataString ? JSON.parse(metadataString) : {}; }; - const setMetadata = (resource, metadata) => - resource?.setMetadata(JSON.stringify(metadata)); + const setMetadata = (resource, metadata) => { + if (resource) { + resource.setMetadata(JSON.stringify(metadata)); + } + } const extendMetadata = (resourceName, metadata) => { const resource = getResource(resourceName); diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index dcd28e5d635b..e59160d0a382 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -22,7 +22,7 @@ let invalidTexture = PIXI.Texture.from('res/error48.png'); let loadedThreeTextures = {}; let loadedThreeMaterials = {}; let loadedOrLoading3DModelPromises: ResourcePromise = {}; -let atlasPromises: ResourcePromise = {}; +let atlasPromises: ResourcePromise = {}; let spineDataPromises: ResourcePromise = {}; const createInvalidModel = (): GLTF => { diff --git a/newIDE/app/src/stories/componentStories/ParameterFields/ResourceFields.stories.js b/newIDE/app/src/stories/componentStories/ParameterFields/ResourceFields.stories.js index 8c4ad15e9edf..49cf447cc6bd 100644 --- a/newIDE/app/src/stories/componentStories/ParameterFields/ResourceFields.stories.js +++ b/newIDE/app/src/stories/componentStories/ParameterFields/ResourceFields.stories.js @@ -188,7 +188,10 @@ export const AllResourceFields = () => ( render={(value, onChange) => ( Date: Wed, 15 Nov 2023 15:04:29 +0200 Subject: [PATCH 21/80] fix react warnings --- .../app/src/ObjectEditor/Editors/SpineEditor.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index d67bb8fd637b..6adad6ee8679 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -50,13 +50,13 @@ const SpineEditor = ({ }: EditorProps) => { const scrollView = React.useRef(null); - const getResource = name => { + const getResource = React.useCallback((name) => { const resourcesManager = project.getResourcesManager(); return resourcesManager.hasResource(name) ? resourcesManager.getResource(name) : null; - }; + }, [project]); const getMetadata = resource => { const metadataString = resource ? resource.getMetadata() : ''; @@ -66,12 +66,12 @@ const SpineEditor = ({ if (resource) { resource.setMetadata(JSON.stringify(metadata)); } - } - const extendMetadata = (resourceName, metadata) => { + }; + const extendMetadata = React.useCallback((resourceName, metadata) => { const resource = getResource(resourceName); setMetadata(resource, Object.assign(getMetadata(resource), metadata)); - }; + }, [getResource]); const [ justAddedAnimationName, setJustAddedAnimationName, @@ -156,7 +156,7 @@ const SpineEditor = ({ spineConfiguration.removeAllAnimations(); }); }, - [getSkeleton] + [getSkeleton, extendMetadata, properties, spineConfiguration] ); const onChangeAtlasResourceName = React.useCallback( (atlasResourceName: string) => { @@ -178,7 +178,7 @@ const SpineEditor = ({ spineConfiguration.removeAllAnimations(); }); }, - [getSkeleton] + [getSkeleton, extendMetadata, properties, spineConfiguration] ); const onChangeImageResourceName = React.useCallback( (imageResourceName: string) => { @@ -196,7 +196,7 @@ const SpineEditor = ({ spineConfiguration.removeAllAnimations(); }); }, - [getSkeleton] + [getSkeleton, extendMetadata, properties, spineConfiguration] ); const scanNewAnimations = React.useCallback( From fc941b0498167aee8452a0dae5c1d90e152f8595 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 15 Nov 2023 15:06:20 +0200 Subject: [PATCH 22/80] run format and flow --- .../src/ObjectEditor/Editors/SpineEditor.js | 26 ++++++++++++------- .../ObjectsRendering/PixiResourcesLoader.js | 4 ++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 6adad6ee8679..0c8dc0240924 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -50,13 +50,16 @@ const SpineEditor = ({ }: EditorProps) => { const scrollView = React.useRef(null); - const getResource = React.useCallback((name) => { - const resourcesManager = project.getResourcesManager(); + const getResource = React.useCallback( + name => { + const resourcesManager = project.getResourcesManager(); - return resourcesManager.hasResource(name) - ? resourcesManager.getResource(name) - : null; - }, [project]); + return resourcesManager.hasResource(name) + ? resourcesManager.getResource(name) + : null; + }, + [project] + ); const getMetadata = resource => { const metadataString = resource ? resource.getMetadata() : ''; @@ -67,11 +70,14 @@ const SpineEditor = ({ resource.setMetadata(JSON.stringify(metadata)); } }; - const extendMetadata = React.useCallback((resourceName, metadata) => { - const resource = getResource(resourceName); + const extendMetadata = React.useCallback( + (resourceName, metadata) => { + const resource = getResource(resourceName); - setMetadata(resource, Object.assign(getMetadata(resource), metadata)); - }, [getResource]); + setMetadata(resource, Object.assign(getMetadata(resource), metadata)); + }, + [getResource] + ); const [ justAddedAnimationName, setJustAddedAnimationName, diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index e59160d0a382..191789e67377 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -22,7 +22,9 @@ let invalidTexture = PIXI.Texture.from('res/error48.png'); let loadedThreeTextures = {}; let loadedThreeMaterials = {}; let loadedOrLoading3DModelPromises: ResourcePromise = {}; -let atlasPromises: ResourcePromise = {}; +let atlasPromises: ResourcePromise< + PIXI_SPINE.TextureAtlas | typeof undefined +> = {}; let spineDataPromises: ResourcePromise = {}; const createInvalidModel = (): GLTF => { From 71333b7bfc82c5f1ff2b2d04e51321f3e1a30f99 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 15 Nov 2023 15:30:56 +0200 Subject: [PATCH 23/80] update spine configuration page --- newIDE/app/src/ObjectEditor/Editors/SpineEditor.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 0c8dc0240924..5f4d067e2938 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -431,11 +431,12 @@ const SpineEditor = ({ Add your first animation} description={ - Animations are a sequence of images. + + Import one or more animations that available in spine + file. + } actionLabel={Add an animation} - helpPagePath="/objects/sprite" - tutorialId="intermediate-changing-animations" onAction={addAnimation} /> From ee70d968c192deae6a3fa9c949dc7dd6dd6f076c Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 15 Nov 2023 16:01:03 +0200 Subject: [PATCH 24/80] update typings and docs --- .../pixi-renderers/pixi-atlas-manager.ts | 26 ++++++++++------- .../pixi-renderers/pixi-json-manager.ts | 28 +++++++++++++++++-- .../pixi-renderers/pixi-spine-manager.ts | 18 ++++++------ .../ObjectsRendering/PixiResourcesLoader.js | 2 +- 4 files changed, 50 insertions(+), 24 deletions(-) diff --git a/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts index 1053622d8fdd..d6d5acd193a1 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts @@ -20,7 +20,7 @@ namespace gdjs { atlasKinds.includes(resource.kind); /** - * AtlasManager loads text files (using `XMLHttpRequest`), using the "atlas" resources + * AtlasManager loads atlas files with pixi loader, using the "atlas" resources * registered in the game resources and process them to Pixi TextureAtlas. * * Contrary to audio/fonts, text files are loaded asynchronously, when requested. @@ -58,11 +58,11 @@ namespace gdjs { /** * Request all the text resources to be preloaded (unless they are marked as not preloaded). * - * Note that even if a text is already loaded, it will be reloaded (useful for hot-reloading, - * as text files can have been modified without the editor knowing). + * Note that even if a atlas is already loaded, it will be reloaded (useful for hot-reloading, + * as atlas files can have been modified without the editor knowing). * - * @param onProgress The function called after each texts is loaded. - * @param onComplete The function called when all texts are loaded. + * @param onProgress The function called after each atlas is loaded. + * @param onComplete The function called when all atlases are loaded. */ async preloadAll( onProgress: AtlasManagerOnProgressCallback, @@ -89,6 +89,12 @@ namespace gdjs { return Promise.resolve(atlasResources.length); } + /** + * Load specified atlas resource and pass it to callback once it is loaded. + * + * @param resources The data of resource to load. + * @param callback The callback to pass atlas to it once it is loaded. + */ load(resource: ResourceData, callback: AtlasManagerRequestCallback): void { if (!isAtlasResource(resource)) callback(new Error(`${resource.name} is on atlas!`)); @@ -122,9 +128,9 @@ namespace gdjs { } /** - * Check if the given text resource was loaded (preloaded or loaded with `loadText`). - * @param resourceName The name of the text resource. - * @returns true if the content of the text resource is loaded. false otherwise. + * Check if the given atlas resource was loaded (preloaded or loaded with `load`). + * @param resourceName The name of the atlas resource. + * @returns true if the content of the atlas resource is loaded, false otherwise. */ isLoaded(resourceName: string): boolean { return resourceName in this._loadedAtlases; @@ -133,8 +139,8 @@ namespace gdjs { /** * Get the Pixi TextureAtlas for the given resource that is already loaded (preloaded or loaded with `load`). * If the resource is not loaded, `null` will be returned. - * @param resourceName The name of the text resource. - * @returns the TextureAtlas of the atlas, if loaded. `null` otherwise. + * @param resourceName The name of the atlas resource. + * @returns the TextureAtlas of the atlas if loaded, `null` otherwise. */ getAtlasTexture(resourceName: string): pixi_spine.TextureAtlas | null { return this._loadedAtlases[resourceName] || null; diff --git a/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts index 95bd5f16efd9..525923618d30 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts @@ -14,7 +14,7 @@ namespace gdjs { ) => void; /** - * JsonManager loads json files (using `XMLHttpRequest`), using the "json" resources + * JsonManager loads json files with pixi loader, using the "json" resources * registered in the game resources. * * Contrary to audio/fonts, json files are loaded asynchronously, when requested. @@ -65,6 +65,14 @@ namespace gdjs { } } + /** + * Request all the json resources to be preloaded (unless they are marked as not preloaded). + * + * Note that even if a JSON is already loaded, it will be reloaded (useful for hot-reloading, + * as JSON files can have been modified without the editor knowing). + * + * @param onProgress The function called after each json is loaded. + */ async preloadAll( onProgress: (loadingCount: integer, totalCount: integer) => void ): Promise { @@ -108,6 +116,12 @@ namespace gdjs { return loadedNumber; } + /** + * Request the json file from the given resource name. + * Returns the promise of loading atlas. + * + * @param resourceName The resource pointing to the json file to load. + */ loadJsonAsync(resourceName: string): Promise { const that = this; return new Promise((resolve, reject) => { @@ -120,6 +134,14 @@ namespace gdjs { }); } + /** + * Request the json file from the given resource name. + * This method is asynchronous. When loaded, the `callback` is called with the error + * (null if none) and the loaded json (a JS Object). + * + * @param resourceName The resource pointing to the json file to load. + * @param callback The callback function called when json is loaded (or an error occurred). + */ load(resourceName: string, callback: JsonManagerRequestCallback): void { const resource = this._resources.get(resourceName); if (!resource) { @@ -198,7 +220,7 @@ namespace gdjs { /** * Check if the given json resource was loaded (preloaded or loaded with `loadJson`). * @param resourceName The name of the json resource. - * @returns true if the content of the json resource is loaded. false otherwise. + * @returns true if the content of the json resource is loaded, false otherwise. */ isJsonLoaded(resourceName: string): boolean { return !!this._loadedJsons[resourceName]; @@ -209,7 +231,7 @@ namespace gdjs { * If the resource is not loaded, `null` will be returned. * * @param resourceName The name of the json resource. - * @returns the content of the json resource, if loaded. `null` otherwise. + * @returns the content of the json resource if loaded, `null` otherwise. */ getLoadedJson(resourceName: string): Object | null { return this._loadedJsons[resourceName] || null; diff --git a/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts index 38753b672811..2d71148ca553 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts @@ -7,12 +7,10 @@ namespace gdjs { const logger = new gdjs.Logger('Spine Manager'); /** - * JsonManager loads json files (using `XMLHttpRequest`), using the "json" resources - * registered in the game resources. + * SpineManager manages pixi spine skeleton data. * - * Contrary to audio/fonts, json files are loaded asynchronously, when requested. - * You should properly handle errors, and give the developer/player a way to know - * that loading failed. + * It doesn`t load data by itself but it is designed to store data that was loaded by some other managers. + * E.g. spine skeleton can be loaded in JsonManager as we don`t know real meaning of json file. */ export class SpineManager { _spineData: { [key: string]: pixi_spine.ISkeletonData } = {}; @@ -25,17 +23,17 @@ namespace gdjs { * Get the object for the given resource that is already loaded (preloaded or loaded with `loadJson`). * If the resource is not loaded, `null` will be returned. * - * @param resourceName The name of the json resource. - * @returns the content of the json resource, if loaded. `null` otherwise. + * @param resourceName The name of the spine skeleton. + * @returns the spine skeleton if loaded, `null` otherwise. */ getSpine(resourceName: string): pixi_spine.ISkeletonData { return this._spineData[resourceName] || null; } /** - * Check if the given json resource was loaded (preloaded or loaded with `loadJson`). - * @param resourceName The name of the json resource. - * @returns true if the content of the json resource is loaded. false otherwise. + * Check if the given spine skeleton was loaded. + * @param resourceName The name of the spine skeleton. + * @returns true if the content of the spine skeleton is loaded, false otherwise. */ isSpineLoaded(resourceName: string): boolean { return !!this._spineData[resourceName]; diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 191789e67377..864903e24e99 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -469,7 +469,7 @@ export default class PixiResourcesLoader { spineName: string, atlasImageName: string, atlasTextName: string - ): Promise { + ): Promise { const resourceManager = project.getResourcesManager(); const resourcesData = [ [spineName, 'json'], From 75da727da70cde56e11518aebbe94a8aeb63cfb4 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 15 Nov 2023 16:09:40 +0200 Subject: [PATCH 25/80] remove dev console.logs --- .../ObjectAnimationNameField.js | 1 - .../ObjectsRenderingService.js | 3 -- .../ObjectsRendering/PixiResourcesLoader.js | 2 +- .../ResourcesList/BrowserResourceSources.js | 31 +++++++++---------- .../src/ResourcesList/LocalResourceSources.js | 31 +++++++++---------- .../app/src/ResourcesList/ResourceSelector.js | 5 +-- 6 files changed, 30 insertions(+), 43 deletions(-) diff --git a/newIDE/app/src/EventsSheet/ParameterFields/ObjectAnimationNameField.js b/newIDE/app/src/EventsSheet/ParameterFields/ObjectAnimationNameField.js index b738d091eb24..196370ca2f18 100644 --- a/newIDE/app/src/EventsSheet/ParameterFields/ObjectAnimationNameField.js +++ b/newIDE/app/src/EventsSheet/ParameterFields/ObjectAnimationNameField.js @@ -106,7 +106,6 @@ export default React.forwardRef( }; const animationNames = getAnimationNames(); - console.log('newIDE ObjectAnimationNameField ', animationNames); const isCurrentValueInAnimationNamesList = !!animationNames.find( animationName => `"${animationName}"` === props.value diff --git a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js index 2a1b5e9aafb5..f0419f46af53 100644 --- a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js +++ b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js @@ -22,11 +22,8 @@ import { rgbOrHexToHexNumber } from '../Utils/ColorTransformer'; const path = optionalRequire('path'); const electron = optionalRequire('electron'); const gd: libGDevelop = global.gd; -// const PIXI = PIXI_LEGACY; const PIXI = { ...PIXI_LEGACY, ...PIXI_SPINE }; -console.log(PIXI_LEGACY, PIXI_SPINE, PIXI); - // Some PixiJS plugins like pixi-tilemap are not distributed as UMD modules, // or still require a global PIXI object to be accessible, so we expose PIXI here. // This can be removed if no more extension PixiJS plugin requires this. diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 864903e24e99..72b849bae092 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -18,7 +18,7 @@ type ResourcePromise = { [resourceName: string]: Promise }; let loadedBitmapFonts = {}; let loadedFontFamilies = {}; let loadedTextures = {}; -let invalidTexture = PIXI.Texture.from('res/error48.png'); +const invalidTexture = PIXI.Texture.from('res/error48.png'); let loadedThreeTextures = {}; let loadedThreeMaterials = {}; let loadedOrLoading3DModelPromises: ResourcePromise = {}; diff --git a/newIDE/app/src/ResourcesList/BrowserResourceSources.js b/newIDE/app/src/ResourcesList/BrowserResourceSources.js index 8c67d5aa890d..ac671b90ee4e 100644 --- a/newIDE/app/src/ResourcesList/BrowserResourceSources.js +++ b/newIDE/app/src/ResourcesList/BrowserResourceSources.js @@ -197,23 +197,20 @@ const browserResourceSources: Array = [ /> ), })), - ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => { - console.log('Choose from asset store Browser'); - return { - name: `resource-store-${kind}`, - displayName: t`Choose from asset store`, - displayTab: 'standalone', - kind, - renderComponent: (props: ResourceSourceComponentProps) => ( - - ), - }; - }), + ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => ({ + name: `resource-store-${kind}`, + displayName: t`Choose from asset store`, + displayTab: 'standalone', + kind, + renderComponent: (props: ResourceSourceComponentProps) => ( + + ), + })), ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => ({ name: `url-chooser-${kind}`, displayName: t`Use a public URL`, diff --git a/newIDE/app/src/ResourcesList/LocalResourceSources.js b/newIDE/app/src/ResourcesList/LocalResourceSources.js index 19074a650aaa..e8bb4550f27c 100644 --- a/newIDE/app/src/ResourcesList/LocalResourceSources.js +++ b/newIDE/app/src/ResourcesList/LocalResourceSources.js @@ -229,23 +229,20 @@ const localResourceSources: Array = [ /> ), })), - ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => { - console.log('Choose from asset store Local'); - return { - name: `resource-store-${kind}`, - displayName: t`Choose from asset store`, - displayTab: 'standalone', - kind, - renderComponent: (props: ResourceSourceComponentProps) => ( - - ), - }; - }), + ...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => ({ + name: `resource-store-${kind}`, + displayName: t`Choose from asset store`, + displayTab: 'standalone', + kind, + renderComponent: (props: ResourceSourceComponentProps) => ( + + ), + })), ]; export default localResourceSources; diff --git a/newIDE/app/src/ResourcesList/ResourceSelector.js b/newIDE/app/src/ResourcesList/ResourceSelector.js index d2696d522aaf..55b14eb35303 100644 --- a/newIDE/app/src/ResourcesList/ResourceSelector.js +++ b/newIDE/app/src/ResourcesList/ResourceSelector.js @@ -182,10 +182,7 @@ const ResourceSelector = React.forwardRef( const addFrom = React.useCallback( async (source: ResourceSource) => { try { - if (!source) { - console.log('source is undef'); - return; - } + if (!source) return; const resources = await resourceManagementProps.onChooseResource({ initialSourceName: source.name, From a7c5c1ad6d0b0f2808e455c140714033fb779a16 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Thu, 16 Nov 2023 13:57:06 +0200 Subject: [PATCH 26/80] use PixiFiltersTools from gdjs namespace, use correct onDestroy method --- Extensions/Spine/spineruntimeobject.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 74e70cc30317..5e91f696170c 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -97,8 +97,8 @@ namespace gdjs { } } - onDestroyFromScene(instanceContainer: gdjs.RuntimeInstanceContainer): void { - super.onDestroyFromScene(instanceContainer); + onDestroyed(): void { + super.onDestroyed(); this._renderer.onDestroy(); } @@ -137,7 +137,7 @@ namespace gdjs { } setOpacity(opacity: float): void { - this._opacity = PixiFiltersTools.clampValue(opacity, 0, 255); + this._opacity = gdjs.PixiFiltersTools.clampValue(opacity, 0, 255); this._renderer.updateOpacity(); } From e7c69e9fd55a17b87f1d1b3c61137529fdf40bab Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Mon, 20 Nov 2023 14:26:17 +0200 Subject: [PATCH 27/80] format runtime code, update install-spine script --- Extensions/Spine/JsExtension.js | 189 ++++++++++-------- Extensions/Spine/SpineObjectConfiguration.cpp | 3 +- Extensions/Spine/SpineObjectConfiguration.h | 5 +- .../Spine/spineruntimeobject-pixi-renderer.ts | 50 +++-- Extensions/Spine/spineruntimeobject.ts | 16 +- .../pixi-renderers/pixi-atlas-manager.ts | 63 +++--- .../pixi-renderers/pixi-json-manager.ts | 97 +++++---- .../pixi-renderers/pixi-spine-manager.ts | 59 +++--- GDJS/scripts/install-spine.js | 12 +- .../ObjectsRenderingService.js | 1 - 10 files changed, 287 insertions(+), 208 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index fdd516487ad2..b3c15a3b832a 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -45,7 +45,9 @@ module.exports = { .addObject( 'SpineObject', _('Spine'), - _('Display and animate Spine skeleton. Select Spine files (json, atlas, image).'), + _( + 'Display and animate Spine skeleton. Select Spine files (json, atlas, image).' + ), 'CppPlatform/Extensions/spriteicon.png', new gd.SpineObjectConfiguration() ) @@ -93,74 +95,73 @@ module.exports = { .setFunctionName('setScale') .setGetter('getScale'); - object - .addCondition( - 'isAnimationComplete', - _('Animation complete'), - _('Check if the animation being played by the Spine object is complete.'), - _('The animation of _PARAM0_ is complete'), - _('Animations and images'), - 'res/conditions/animation24.png', - 'res/conditions/animation.png' - ) - .addParameter('object', _('Spine'), 'SpineObject') - .markAsSimple() - .setFunctionName('isAnimationComplete'); - - object - .addExpressionAndConditionAndAction( - 'boolean', - 'Updatable', - _('Updatable'), - _('an animation is updatable'), - _('Updatable'), - '', - 'res/conditions/animation.png' - ) - .addParameter('object', _('Spine'), 'SpineObject') - .useStandardParameters('boolean', gd.ParameterOptions.makeNewOptions()) - .setFunctionName('setIsUpdatable') - .setGetter('isUpdatable'); - - object - .addExpressionAndConditionAndAction( - 'number', - 'Animation', - _('Animation (by number)'), - _( - 'the number of the animation played by the object (the number from the animations list)' - ), - _('the number of the animation'), - _('Animations and images'), - 'res/actions/animation24.png' - ) - .addParameter('object', _('Spine'), 'SpineObject') - .useStandardParameters('number', gd.ParameterOptions.makeNewOptions()) - .markAsSimple() - .setFunctionName('setAnimationIndex') - .setGetter('getCurrentAnimationIndex'); - - object - .addExpressionAndConditionAndAction( - 'string', - 'AnimationName', - _('Animation (by name)'), - _('the animation played by the object'), - _('the animation'), - _('Animations and images'), - 'res/actions/animation24.png' - ) - .addParameter('object', _('Spine'), 'SpineObject') - .useStandardParameters( - 'objectAnimationName', - gd.ParameterOptions.makeNewOptions().setDescription( - _('Animation name') - ) - ) - .markAsAdvanced() - .setFunctionName('setAnimationName') - .setGetter('getAnimationName'); + object + .addCondition( + 'isAnimationComplete', + _('Animation complete'), + _( + 'Check if the animation being played by the Spine object is complete.' + ), + _('The animation of _PARAM0_ is complete'), + _('Animations and images'), + 'res/conditions/animation24.png', + 'res/conditions/animation.png' + ) + .addParameter('object', _('Spine'), 'SpineObject') + .markAsSimple() + .setFunctionName('isAnimationComplete'); + object + .addExpressionAndConditionAndAction( + 'boolean', + 'Updatable', + _('Updatable'), + _('an animation is updatable'), + _('Updatable'), + '', + 'res/conditions/animation.png' + ) + .addParameter('object', _('Spine'), 'SpineObject') + .useStandardParameters('boolean', gd.ParameterOptions.makeNewOptions()) + .setFunctionName('setIsUpdatable') + .setGetter('isUpdatable'); + + object + .addExpressionAndConditionAndAction( + 'number', + 'Animation', + _('Animation (by number)'), + _( + 'the number of the animation played by the object (the number from the animations list)' + ), + _('the number of the animation'), + _('Animations and images'), + 'res/actions/animation24.png' + ) + .addParameter('object', _('Spine'), 'SpineObject') + .useStandardParameters('number', gd.ParameterOptions.makeNewOptions()) + .markAsSimple() + .setFunctionName('setAnimationIndex') + .setGetter('getCurrentAnimationIndex'); + + object + .addExpressionAndConditionAndAction( + 'string', + 'AnimationName', + _('Animation (by name)'), + _('the animation played by the object'), + _('the animation'), + _('Animations and images'), + 'res/actions/animation24.png' + ) + .addParameter('object', _('Spine'), 'SpineObject') + .useStandardParameters( + 'objectAnimationName', + gd.ParameterOptions.makeNewOptions().setDescription(_('Animation name')) + ) + .markAsAdvanced() + .setFunctionName('setAnimationName') + .setGetter('getAnimationName'); return extension; }, @@ -245,12 +246,23 @@ module.exports = { } loadSpine() { - const jsonResourceName = this.properties.get('jsonResourceName').getValue(); - const imageResourceName = this.properties.get('imageResourceName').getValue(); - const atlasResourceName = this.properties.get('atlasResourceName').getValue(); + const jsonResourceName = this.properties + .get('jsonResourceName') + .getValue(); + const imageResourceName = this.properties + .get('imageResourceName') + .getValue(); + const atlasResourceName = this.properties + .get('atlasResourceName') + .getValue(); this._pixiResourcesLoader - .getSpineData(this._project, jsonResourceName, imageResourceName, atlasResourceName) + .getSpineData( + this._project, + jsonResourceName, + imageResourceName, + atlasResourceName + ) .then((spineData) => { if (!spineData) return; @@ -261,7 +273,10 @@ module.exports = { } update() { - this._pixiObject.position.set(this._instance.getX(), this._instance.getY()); + this._pixiObject.position.set( + this._instance.getX(), + this._instance.getY() + ); this.setAnimation(this._instance.getRawDoubleProperty('animation')); @@ -269,8 +284,8 @@ module.exports = { const height = this.getHeight(); this._rect.clear(); - this._rect.beginFill(0xFFFFFF); - this._rect.lineStyle(0, 0xFFFFFF); + this._rect.beginFill(0xffffff); + this._rect.lineStyle(0, 0xffffff); this._rect.drawRect(0, 0, width, height); const s = this._spine; @@ -279,19 +294,26 @@ module.exports = { s.height = height; s.alpha = this.properties.get('opacity').getValue() / 255; const localBounds = s.getLocalBounds(undefined, true); - s.position.set(-localBounds.x * s.scale.x, -localBounds.y * s.scale.y); + s.position.set( + -localBounds.x * s.scale.x, + -localBounds.y * s.scale.y + ); } this._pixiObject.calculateBounds(); } /** - * @param {number} animation index + * @param {number} index - animation index */ setAnimation(index) { - const {configuration, _spine:s} = this; + const { configuration, _spine: s } = this; - if (!s || configuration.hasNoAnimations() || index === this._animationIndex) { + if ( + !s || + configuration.hasNoAnimations() || + index === this._animationIndex + ) { return; } @@ -303,7 +325,6 @@ module.exports = { this._animationIndex = index; const animation = configuration.getAnimation(index); - const name = animation.getName(); const source = animation.getSource(); const shouldLoop = animation.shouldLoop(); @@ -324,7 +345,9 @@ module.exports = { getDefaultWidth() { const scale = Number(this.properties.get('scale').getValue()) || 1; - return typeof this._initialWidth === 'number' ? this._initialWidth * scale : 256; + return typeof this._initialWidth === 'number' + ? this._initialWidth * scale + : 256; } /** @@ -333,7 +356,9 @@ module.exports = { getDefaultHeight() { const scale = Number(this.properties.get('scale').getValue()) || 1; - return typeof this._initialHeight === 'number' ? this._initialHeight * scale : 256; + return typeof this._initialHeight === 'number' + ? this._initialHeight * scale + : 256; } get configuration() { diff --git a/Extensions/Spine/SpineObjectConfiguration.cpp b/Extensions/Spine/SpineObjectConfiguration.cpp index 597da2690f25..5228df1a65ca 100644 --- a/Extensions/Spine/SpineObjectConfiguration.cpp +++ b/Extensions/Spine/SpineObjectConfiguration.cpp @@ -1,6 +1,5 @@ /** - -GDevelop - Particle System Extension +GDevelop - Spine Extension Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com) This project is released under the MIT License. */ diff --git a/Extensions/Spine/SpineObjectConfiguration.h b/Extensions/Spine/SpineObjectConfiguration.h index 4462d582dc75..4c14d5d0bb57 100644 --- a/Extensions/Spine/SpineObjectConfiguration.h +++ b/Extensions/Spine/SpineObjectConfiguration.h @@ -1,6 +1,5 @@ /** - -GDevelop - Particle System Extension +GDevelop - Spine Extension Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com) This project is released under the MIT License. */ @@ -55,7 +54,7 @@ class GD_EXTENSION_API SpineAnimation { }; /** - * \brief Particle Emitter object used for storage and for the IDE. + * \brief Spine object configuration is used for storage and for the IDE. */ class GD_EXTENSION_API SpineObjectConfiguration : public gd::ObjectConfiguration { public: diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index 4abba0104558..ac2832d6803c 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -1,12 +1,12 @@ namespace gdjs { - - const isSpine = (obj: any): obj is pixi_spine.Spine => obj instanceof pixi_spine.Spine; + const isSpine = (obj: any): obj is pixi_spine.Spine => + obj instanceof pixi_spine.Spine; export class SpineRuntimeObjectPixiRenderer { private _object: gdjs.SpineRuntimeObject; - private _rendererObject!: pixi_spine.Spine | PIXI.Container; + private _rendererObject: pixi_spine.Spine | PIXI.Container; private _isAnimationComplete = true; - private _spinePropertiesReplacer: Record = { }; + private _autoUpdateReplacer: boolean = true; /** * @param runtimeObject The object to render @@ -17,8 +17,8 @@ namespace gdjs { private instanceContainer: gdjs.RuntimeInstanceContainer ) { this._object = runtimeObject; + this._rendererObject = this.constructrendererObject(); - this.constructSpine(); this.updateTimeScale(); this.updatePosition(); this.updateAngle(); @@ -88,10 +88,21 @@ namespace gdjs { setAnimation(animation: string, loop: boolean): void { if (isSpine(this._rendererObject)) { + const onCompleteListener: pixi_spine.IAnimationStateListener = { + complete: () => { + this._isAnimationComplete = true; + setTimeout( + () => + (this._rendererObject as pixi_spine.Spine).state.removeListener( + onCompleteListener + ), + 0 + ); + }, + }; + this._isAnimationComplete = false; - this._rendererObject.state.addListener({ - complete: () => (this._isAnimationComplete = true), - }); + this._rendererObject.state.addListener(onCompleteListener); this._rendererObject.state.setAnimation(0, animation, loop); this._rendererObject.update(0); this.updateBounds(); @@ -100,7 +111,7 @@ namespace gdjs { } } - isAnimationCompelete(): boolean { + isAnimationComplete(): boolean { return this._isAnimationComplete; } @@ -109,22 +120,27 @@ namespace gdjs { return this._rendererObject.autoUpdate; } - return !!this._spinePropertiesReplacer.autoUpdate; + return !!this._autoUpdateReplacer; } setIsUpdatable(isUpdatable: boolean): void { if (isSpine(this._rendererObject)) { this._rendererObject.autoUpdate = isUpdatable; } else { - this._spinePropertiesReplacer.autoUpdate = isUpdatable; + this._autoUpdateReplacer = isUpdatable; } } - private constructSpine(): void { + private constructrendererObject(): pixi_spine.Spine | PIXI.Container { const game = this.instanceContainer.getGame(); - const spineData = game.getSpineManager().getSpine(this._object.jsonResourceName); + const spineData = game + .getSpineManager() + .getSpine(this._object.jsonResourceName); + const rendererObject = spineData + ? new pixi_spine.Spine(spineData) + : new PIXI.Container(); - this._rendererObject = spineData ? new pixi_spine.Spine(spineData) : new PIXI.Container(); + return rendererObject; } private updateBounds(): void { @@ -133,8 +149,10 @@ namespace gdjs { const localBounds = this._rendererObject.getLocalBounds(undefined, true); - this._rendererObject.position.x -= localBounds.x * this._rendererObject.scale.x; - this._rendererObject.position.y -= localBounds.y * this._rendererObject.scale.y; + this._rendererObject.position.x -= + localBounds.x * this._rendererObject.scale.x; + this._rendererObject.position.y -= + localBounds.y * this._rendererObject.scale.y; } } export const SpineRuntimeObjectRenderer = SpineRuntimeObjectPixiRenderer; diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 5e91f696170c..521dd7587b99 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -1,4 +1,3 @@ - namespace gdjs { type SpineAnimation = { name: string; source: string; loop: boolean }; @@ -79,12 +78,13 @@ namespace gdjs { extraInitializationFromInitialInstance( initialInstanceData: InstanceData ): void { - let animationIndex = this._currentAnimationIndex; - for (const extraData of initialInstanceData.numberProperties || []) { - if (extraData.name === 'animation') { - animationIndex = extraData.value; - } - } + const animationData = initialInstanceData.numberProperties?.find( + (data) => data.name === 'animation' + ); + const animationIndex = animationData + ? animationData.value + : this._currentAnimationIndex; + this.setAnimationIndex(animationIndex); if (initialInstanceData.customSize) { @@ -202,7 +202,7 @@ namespace gdjs { } isAnimationComplete(): boolean { - return this._renderer.isAnimationCompelete(); + return this._renderer.isAnimationComplete(); } isCurrentAnimationName(name: string): boolean { diff --git a/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts index d6d5acd193a1..4034f0d8dfcb 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts @@ -28,10 +28,9 @@ namespace gdjs { * that loading failed. */ export class AtlasManager { - _resourcesLoader: RuntimeGameResourcesLoader; - _resources: ResourceData[]; - _loadedAtlases: { [key: string]: pixi_spine.TextureAtlas } = {}; - _callbacks: { [key: string]: Array } = {}; + private _resourcesLoader: RuntimeGameResourcesLoader; + private _resources: ResourceData[]; + private _loadedAtlases: { [key: string]: pixi_spine.TextureAtlas } = {}; /** * @param resources The resources data of the game. @@ -65,7 +64,7 @@ namespace gdjs { * @param onComplete The function called when all atlases are loaded. */ async preloadAll( - onProgress: AtlasManagerOnProgressCallback, + onProgress: AtlasManagerOnProgressCallback ): Promise { const atlasResources = this._resources.filter( (resource) => isAtlasResource(resource) && !resource.disablePreload @@ -73,17 +72,22 @@ namespace gdjs { let loaded = 0; await Promise.all( - atlasResources.map((resource, i) => new Promise((resolve) => { - const onLoad: AtlasManagerRequestCallback = (error) => { - if (error) { - logger.error('Error while preloading a text resource:' + error); - } - onProgress(loaded, atlasResources.length); - resolve(); - }; - - this.load(atlasResources[i], onLoad); - })) + atlasResources.map( + (resource, i) => + new Promise((resolve) => { + const onLoad: AtlasManagerRequestCallback = (error) => { + if (error) { + logger.error( + 'Error while preloading a text resource:' + error + ); + } + onProgress(loaded, atlasResources.length); + resolve(); + }; + + this.load(atlasResources[i], onLoad); + }) + ) ); return Promise.resolve(atlasResources.length); @@ -96,11 +100,13 @@ namespace gdjs { * @param callback The callback to pass atlas to it once it is loaded. */ load(resource: ResourceData, callback: AtlasManagerRequestCallback): void { - if (!isAtlasResource(resource)) callback(new Error(`${resource.name} is on atlas!`)); + if (!isAtlasResource(resource)) + callback(new Error(`${resource.name} is on atlas!`)); - const metadata = resource.metadata ? JSON.parse(resource.metadata) : { }; + const metadata = resource.metadata ? JSON.parse(resource.metadata) : {}; - if (!metadata.image) callback(new Error(`${resource.name} do not have image metadata!`)); + if (!metadata.image) + callback(new Error(`${resource.name} do not have image metadata!`)); const image = this._imageManager.getPIXITexture(metadata.image); const onLoad = (atlas: pixi_spine.TextureAtlas) => { @@ -108,7 +114,6 @@ namespace gdjs { callback(null, atlas); }; - PIXI.Assets.setPreferences({ preferWorkers: false, crossOrigin: this._resourcesLoader.checkIfCredentialsRequired( @@ -118,13 +123,19 @@ namespace gdjs { : 'anonymous', }); PIXI.Assets.add(resource.name, resource.file, { image }); - PIXI.Assets.load(resource.name).then((atlas) => { - if (typeof atlas === 'string') { - new pixi_spine.TextureAtlas(atlas, (_, textureCb) => textureCb(image.baseTexture), onLoad); - } else { - onLoad(atlas); + PIXI.Assets.load(resource.name).then( + (atlas) => { + if (typeof atlas === 'string') { + new pixi_spine.TextureAtlas( + atlas, + (_, textureCb) => textureCb(image.baseTexture), + onLoad + ); + } else { + onLoad(atlas); + } } - }); + ); } /** diff --git a/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts index 525923618d30..aff68a32c4bc 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts @@ -6,7 +6,6 @@ namespace gdjs { const logger = new gdjs.Logger('Json Manager'); - /** The callback called when a json that was requested is loaded (or an error occurred). */ export type JsonManagerRequestCallback = ( error: Error | null, @@ -22,13 +21,14 @@ namespace gdjs { * that loading failed. */ export class JsonManager { - _resourcesLoader: RuntimeGameResourcesLoader; - _resources: Map; - - _loadedJsons: { [key: string]: Object } = {}; - _callbacks: { [key: string]: Array } = {}; - _spineManager: SpineManager; - _atlasManager: AtlasManager; + private _resourcesLoader: RuntimeGameResourcesLoader; + private _resources: Map; + private _loadedJsons: { [key: string]: Object } = {}; + private _callbacks: { + [key: string]: Array; + } = {}; + private _spineManager: SpineManager; + private _atlasManager: AtlasManager; /** * @param resourceDataArray The resources data of the game. @@ -38,7 +38,7 @@ namespace gdjs { resourceDataArray: ResourceData[], resourcesLoader: RuntimeGameResourcesLoader, spineManager: SpineManager, - atlasManager: AtlasManager, + atlasManager: AtlasManager ) { this._resources = new Map(); this.setResources(resourceDataArray); @@ -72,29 +72,49 @@ namespace gdjs { * as JSON files can have been modified without the editor knowing). * * @param onProgress The function called after each json is loaded. + * @returns the promise of loaded jsons count. */ async preloadAll( onProgress: (loadingCount: integer, totalCount: integer) => void ): Promise { let loadedNumber = 0; - const getPreferences = (file: string) => ({ - preferWorkers: false, - crossOrigin: this._resourcesLoader.checkIfCredentialsRequired(file) - ? 'use-credentials' - : 'anonymous', - } as Partial); - const jsonPromises = Array.from(this._resources.values(), async (resource) => { + const getPreferences = (file: string) => + ({ + preferWorkers: false, + crossOrigin: this._resourcesLoader.checkIfCredentialsRequired(file) + ? 'use-credentials' + : 'anonymous', + } as Partial); + const jsonPromises = Array.from( + this._resources.values(), + async (resource) => { try { if (resource.kind === 'json') { - const metadata = resource.metadata ? JSON.parse(resource.metadata) : { }; - const atlasInDependencies = !!metadata.atlas && this._atlasManager.isLoaded(metadata.atlas); + const metadata = resource.metadata + ? JSON.parse(resource.metadata) + : {}; + const atlasInDependencies = + !!metadata.atlas && this._atlasManager.isLoaded(metadata.atlas); PIXI.Assets.setPreferences(getPreferences(resource.file)); - PIXI.Assets.add(resource.name, resource.file, atlasInDependencies ? { spineAtlas: this._atlasManager.getAtlasTexture(metadata.atlas) } : undefined) - let loadedJson = await PIXI.Assets.load(resource.name); - + PIXI.Assets.add( + resource.name, + resource.file, + atlasInDependencies + ? { + spineAtlas: this._atlasManager.getAtlasTexture( + metadata.atlas + ), + } + : undefined + ); + const loadedJson = await PIXI.Assets.load(resource.name); + if (loadedJson.spineData) { - this._spineManager.setSpine(resource.name, loadedJson.spineData) + this._spineManager.setSpine( + resource.name, + loadedJson.spineData + ); } else { this._loadedJsons[resource.name] = loadedJson; } @@ -109,7 +129,8 @@ namespace gdjs { } onProgress(loadedNumber++, this._resources.size); - }); + } + ); await Promise.all(jsonPromises); @@ -118,9 +139,9 @@ namespace gdjs { /** * Request the json file from the given resource name. - * Returns the promise of loading atlas. * * @param resourceName The resource pointing to the json file to load. + * @returns the promise of loaded json or promise of null if loading is failed. */ loadJsonAsync(resourceName: string): Promise { const that = this; @@ -145,23 +166,28 @@ namespace gdjs { load(resourceName: string, callback: JsonManagerRequestCallback): void { const resource = this._resources.get(resourceName); if (!resource) { - return callback(new Error(`Can't find resource with name: "${resourceName}" (or is not a json resource).`), null); + return callback( + new Error( + `Can't find resource with name: "${resourceName}" (or is not a json resource).` + ), + null + ); } // Don't fetch again an object that is already in memory if (this._loadedJsons[resourceName]) { return callback(null, this._loadedJsons[resourceName]); } + // Don't fetch again an object that is already being fetched. - { - const callbacks = this._callbacks[resourceName]; - if (callbacks) { - callbacks.push(callback); - return; - } else { - this._callbacks[resourceName] = [callback]; - } + const resourceCallbacks = this._callbacks[resourceName]; + if (resourceCallbacks) { + resourceCallbacks.push(callback); + return; + } else { + this._callbacks[resourceName] = [callback]; } + const that = this; const xhr = new XMLHttpRequest(); xhr.responseType = 'json'; @@ -171,9 +197,8 @@ namespace gdjs { xhr.open('GET', this._resourcesLoader.getFullUrl(resource.file)); xhr.onload = function () { const callbacks = that._callbacks[resourceName]; - if (!callbacks) { - return; - } + + if (!callbacks) return; if (xhr.status !== 200) { for (const callback of callbacks) { callback( diff --git a/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts index 2d71148ca553..89d49333aaf9 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts @@ -4,40 +4,39 @@ * This project is released under the MIT License. */ namespace gdjs { - const logger = new gdjs.Logger('Spine Manager'); + const logger = new gdjs.Logger('Spine Manager'); + + /** + * SpineManager manages pixi spine skeleton data. + * + * It doesn`t load data by itself but it is designed to store data that was loaded by some other managers. + * E.g. spine skeleton can be loaded in JsonManager as we don`t know real meaning of json file. + */ + export class SpineManager { + _spineData: { [key: string]: pixi_spine.ISkeletonData } = {}; + + setSpine(resourceName: string, spineData: pixi_spine.ISkeletonData) { + this._spineData[resourceName] = spineData; + } /** - * SpineManager manages pixi spine skeleton data. + * Get the object for the given resource that is already loaded (preloaded or loaded with `loadJson`). + * If the resource is not loaded, `null` will be returned. * - * It doesn`t load data by itself but it is designed to store data that was loaded by some other managers. - * E.g. spine skeleton can be loaded in JsonManager as we don`t know real meaning of json file. + * @param resourceName The name of the spine skeleton. + * @returns the spine skeleton if loaded, `null` otherwise. */ - export class SpineManager { - _spineData: { [key: string]: pixi_spine.ISkeletonData } = {}; - - setSpine(resourceName: string, spineData: pixi_spine.ISkeletonData) { - this._spineData[resourceName] = spineData; - } + getSpine(resourceName: string): pixi_spine.ISkeletonData { + return this._spineData[resourceName] || null; + } - /** - * Get the object for the given resource that is already loaded (preloaded or loaded with `loadJson`). - * If the resource is not loaded, `null` will be returned. - * - * @param resourceName The name of the spine skeleton. - * @returns the spine skeleton if loaded, `null` otherwise. - */ - getSpine(resourceName: string): pixi_spine.ISkeletonData { - return this._spineData[resourceName] || null; - } - - /** - * Check if the given spine skeleton was loaded. - * @param resourceName The name of the spine skeleton. - * @returns true if the content of the spine skeleton is loaded, false otherwise. - */ - isSpineLoaded(resourceName: string): boolean { - return !!this._spineData[resourceName]; - } + /** + * Check if the given spine skeleton was loaded. + * @param resourceName The name of the spine skeleton. + * @returns true if the content of the spine skeleton is loaded, false otherwise. + */ + isSpineLoaded(resourceName: string): boolean { + return !!this._spineData[resourceName]; } } - \ No newline at end of file +} diff --git a/GDJS/scripts/install-spine.js b/GDJS/scripts/install-spine.js index 3677a718121f..c7a362f0adb2 100644 --- a/GDJS/scripts/install-spine.js +++ b/GDJS/scripts/install-spine.js @@ -1,10 +1,14 @@ const fs = require('fs'); const path = require('path'); -const originalSpinePath = path.join('node_modules/pixi-spine/dist', 'pixi-spine.js'); -const originalPixiSpine = fs.readFileSync(originalSpinePath); +const format = 'utf8'; + +const originalSpineDir = path.resolve('node_modules/pixi-spine'); +const originalSpinePackage = JSON.parse(fs.readFileSync(path.join(originalSpineDir, 'package.json'), format)); +const originalSpinePath = path.join(originalSpineDir, originalSpinePackage.extensionConfig.bundle); +const originalSpine = fs.readFileSync(originalSpinePath, format); const varSpineExport = '\nvar pixi_spine = this.PIXI.spine;\n'; -const runtimeSpinePath = path.join('Runtime/pixi-renderers', 'pixi-spine.js'); +const runtimeSpinePath = 'Runtime/pixi-renderers/pixi-spine.js'; -fs.writeFileSync(runtimeSpinePath, originalPixiSpine + varSpineExport); \ No newline at end of file +fs.writeFileSync(runtimeSpinePath, originalSpine + varSpineExport, format); \ No newline at end of file diff --git a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js index f0419f46af53..fff4f7d4192b 100644 --- a/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js +++ b/newIDE/app/src/ObjectsRendering/ObjectsRenderingService.js @@ -27,7 +27,6 @@ const PIXI = { ...PIXI_LEGACY, ...PIXI_SPINE }; // Some PixiJS plugins like pixi-tilemap are not distributed as UMD modules, // or still require a global PIXI object to be accessible, so we expose PIXI here. // This can be removed if no more extension PixiJS plugin requires this. -// global.PIXI = PIXI; global.PIXI = PIXI; const requirableModules = {}; From 63e98934051ff3e105a5ceb9ef90f323adfb954f Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 22 Nov 2023 15:34:43 +0200 Subject: [PATCH 28/80] update spine extenstion --- Extensions/Spine/JsExtension.js | 133 +++++++++++++------------ Extensions/Spine/spineruntimeobject.ts | 2 +- 2 files changed, 73 insertions(+), 62 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index b3c15a3b832a..6ed32e49d892 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -208,11 +208,11 @@ module.exports = { const { PIXI, RenderedInstance, gd } = objectsRenderingService; class RenderedSpineInstance extends RenderedInstance { - _spine; + _spine = null; _rect = new PIXI.Graphics(); - _initialWidth; - _initialHeight; - _animationIndex; + _initialWidth = null; + _initialHeight = null; + _animationIndex = -1; constructor( project, @@ -238,40 +238,13 @@ module.exports = { this._pixiObject.addChild(this._rect); this._pixiContainer.addChild(this._pixiObject); - this.loadSpine(); + this._loadSpine(); } static getThumbnail(project, resourcesLoader, objectConfiguration) { return 'CppPlatform/Extensions/spriteicon.png'; } - loadSpine() { - const jsonResourceName = this.properties - .get('jsonResourceName') - .getValue(); - const imageResourceName = this.properties - .get('imageResourceName') - .getValue(); - const atlasResourceName = this.properties - .get('atlasResourceName') - .getValue(); - - this._pixiResourcesLoader - .getSpineData( - this._project, - jsonResourceName, - imageResourceName, - atlasResourceName - ) - .then((spineData) => { - if (!spineData) return; - - this._spine = new PIXI.Spine(spineData); - this._pixiObject.addChild(this._spine); - this.update(); - }); - } - update() { this._pixiObject.position.set( this._instance.getX(), @@ -288,15 +261,15 @@ module.exports = { this._rect.lineStyle(0, 0xffffff); this._rect.drawRect(0, 0, width, height); - const s = this._spine; - if (s) { - s.width = width; - s.height = height; - s.alpha = this.properties.get('opacity').getValue() / 255; - const localBounds = s.getLocalBounds(undefined, true); - s.position.set( - -localBounds.x * s.scale.x, - -localBounds.y * s.scale.y + const { _spine: spine } = this; + if (spine) { + spine.width = width; + spine.height = height; + spine.alpha = this._getProperties().get('opacity').getValue() / 255; + const localBounds = spine.getLocalBounds(undefined, true); + spine.position.set( + -localBounds.x * spine.scale.x, + -localBounds.y * spine.scale.y ); } @@ -307,10 +280,11 @@ module.exports = { * @param {number} index - animation index */ setAnimation(index) { - const { configuration, _spine: s } = this; + const { _spine: spine } = this; + const configuration = this._getConfiguration(); if ( - !s || + !spine || configuration.hasNoAnimations() || index === this._animationIndex ) { @@ -330,44 +304,81 @@ module.exports = { // reset scale to track new animation range // if custom size is set it will be reinitialized in update method - s.scale.set(1, 1); - s.state.setAnimation(0, source, shouldLoop); - s.state.tracks[0].trackTime = 0; - s.update(0); - s.autoUpdate = false; - this._initialWidth = s.width; - this._initialHeight = s.height; + spine.scale.set(1, 1); + spine.state.setAnimation(0, source, shouldLoop); + spine.state.tracks[0].trackTime = 0; + spine.update(0); + spine.autoUpdate = false; + this._initialWidth = spine.width; + this._initialHeight = spine.height; } /** * @returns {number} default width */ getDefaultWidth() { - const scale = Number(this.properties.get('scale').getValue()) || 1; - - return typeof this._initialWidth === 'number' - ? this._initialWidth * scale - : 256; + return (this._initialWidth !== null + ? this._initialWidth * this.getScale() + : 256); } /** * @returns {number} default height */ getDefaultHeight() { - const scale = Number(this.properties.get('scale').getValue()) || 1; + return (this._initialHeight !== null + ? this._initialHeight * this.getScale() + : 256); + } - return typeof this._initialHeight === 'number' - ? this._initialHeight * scale - : 256; + /** + * @returns {number} defined scale + */ + getScale() { + return Number(this._getProperties().get('scale').getValue()) || 1; } - get configuration() { + /** + * @returns this spine object configuration + */ + _getConfiguration() { return gd.asSpineConfiguration(this._associatedObjectConfiguration); } - get properties() { + /** + * @returns this object properties container + */ + _getProperties() { return this._associatedObjectConfiguration.getProperties(); } + + _loadSpine() { + const properties = this._getProperties(); + const jsonResourceName = properties + .get('jsonResourceName') + .getValue(); + const imageResourceName = properties + .get('imageResourceName') + .getValue(); + const atlasResourceName = properties + .get('atlasResourceName') + .getValue(); + + this._pixiResourcesLoader + .getSpineData( + this._project, + jsonResourceName, + imageResourceName, + atlasResourceName + ) + .then((spineData) => { + if (!spineData) return; + + this._spine = new PIXI.Spine(spineData); + this._pixiObject.addChild(this._spine); + this.update(); + }); + } } objectsRenderingService.registerInstanceRenderer( diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 521dd7587b99..207fdc33133d 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -78,7 +78,7 @@ namespace gdjs { extraInitializationFromInitialInstance( initialInstanceData: InstanceData ): void { - const animationData = initialInstanceData.numberProperties?.find( + const animationData = initialInstanceData.numberProperties.find( (data) => data.name === 'animation' ); const animationIndex = animationData From 1520bbb6f818a68bdcccf53f497e8f6ceebf8a56 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 22 Nov 2023 15:55:47 +0200 Subject: [PATCH 29/80] add badAnimation SpineObjectConfiguration --- Extensions/Spine/SpineObjectConfiguration.cpp | 10 ++++------ Extensions/Spine/SpineObjectConfiguration.h | 6 ++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Extensions/Spine/SpineObjectConfiguration.cpp b/Extensions/Spine/SpineObjectConfiguration.cpp index 5228df1a65ca..10dc25dc89ff 100644 --- a/Extensions/Spine/SpineObjectConfiguration.cpp +++ b/Extensions/Spine/SpineObjectConfiguration.cpp @@ -18,6 +18,8 @@ This project is released under the MIT License. using namespace std; +SpineAnimation SpineObjectConfiguration::badAnimation; + SpineObjectConfiguration::SpineObjectConfiguration() : scale(1), opacity(255), timeScale(1), jsonResourceName(""), imageResourceName(""), atlasResourceName("") {}; @@ -166,17 +168,13 @@ void SpineObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker &work const SpineAnimation & SpineObjectConfiguration::GetAnimation(std::size_t nb) const { - if (nb >= animations.size()) { - nb = nb % animations.size(); - } + if (nb >= animations.size()) return badAnimation; return animations[nb]; } SpineAnimation &SpineObjectConfiguration::GetAnimation(std::size_t nb) { - if (nb >= animations.size()) { - nb = nb % animations.size(); - } + if (nb >= animations.size()) return badAnimation; return animations[nb]; } diff --git a/Extensions/Spine/SpineObjectConfiguration.h b/Extensions/Spine/SpineObjectConfiguration.h index 4c14d5d0bb57..183784245f83 100644 --- a/Extensions/Spine/SpineObjectConfiguration.h +++ b/Extensions/Spine/SpineObjectConfiguration.h @@ -28,12 +28,12 @@ class GD_EXTENSION_API SpineAnimation { void SetName(const gd::String &name_) { name = name_; } /** - * \brief Return the name of the animation from the GLB file. + * \brief Return the name of the animation from the spine file. */ const gd::String &GetSource() const { return source; } /** - * \brief Change the name of the animation from the GLB file. + * \brief Change the name of the animation from the spine file. */ void SetSource(const gd::String &source_) { source = source_; } @@ -161,4 +161,6 @@ class GD_EXTENSION_API SpineObjectConfiguration : public gd::ObjectConfiguration gd::String atlasResourceName; std::vector animations; + + static SpineAnimation badAnimation; }; From cccb1b975dd36b68a15a85b4bd3e884b7ed993e4 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 22 Nov 2023 15:57:50 +0200 Subject: [PATCH 30/80] solve typo --- Extensions/Spine/spineruntimeobject-pixi-renderer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index ac2832d6803c..9e4e2c20582e 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -17,7 +17,7 @@ namespace gdjs { private instanceContainer: gdjs.RuntimeInstanceContainer ) { this._object = runtimeObject; - this._rendererObject = this.constructrendererObject(); + this._rendererObject = this.constructRendererObject(); this.updateTimeScale(); this.updatePosition(); @@ -131,7 +131,7 @@ namespace gdjs { } } - private constructrendererObject(): pixi_spine.Spine | PIXI.Container { + private constructRendererObject(): pixi_spine.Spine | PIXI.Container { const game = this.instanceContainer.getGame(); const spineData = game .getSpineManager() From 135100a3040e71a20a6a8851b592dec5c4e5fbe4 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 22 Nov 2023 15:58:53 +0200 Subject: [PATCH 31/80] comment sourcemap back in runtime pixi.js --- GDJS/Runtime/pixi-renderers/pixi.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GDJS/Runtime/pixi-renderers/pixi.js b/GDJS/Runtime/pixi-renderers/pixi.js index 46bf49637041..5f885b19830e 100644 --- a/GDJS/Runtime/pixi-renderers/pixi.js +++ b/GDJS/Runtime/pixi-renderers/pixi.js @@ -1160,4 +1160,4 @@ void main(void)\r font-display: ${e.display}; }`,this._stylesheet)}get stylesheet(){return this._stylesheet}set stylesheet(t){this._stylesheet!==t&&(this._stylesheet=t,this.styleID++)}normalizeColor(t){return Array.isArray(t)&&(t=To(t)),typeof t=="number"?bo(t):t}dropShadowToCSS(){let t=this.normalizeColor(this.dropShadowColor);const e=this.dropShadowAlpha,s=Math.round(Math.cos(this.dropShadowAngle)*this.dropShadowDistance),r=Math.round(Math.sin(this.dropShadowAngle)*this.dropShadowDistance);t.startsWith("#")&&e<1&&(t+=(e*255|0).toString(16).padStart(2,"0"));const n=`${s}px ${r}px`;return this.dropShadowBlur>0?`text-shadow: ${n} ${this.dropShadowBlur}px ${t}`:`text-shadow: ${n} ${t}`}reset(){Object.assign(this,os.defaultOptions)}onBeforeDraw(){const{fontsDirty:t}=this;return this.fontsDirty=!1,this.isSafari&&this._fonts.length>0&&t?new Promise(e=>setTimeout(e,100)):Promise.resolve()}get isSafari(){const{userAgent:t}=N.ADAPTER.getNavigator();return/^((?!chrome|android).)*safari/i.test(t)}set fillGradientStops(t){console.warn("[HTMLTextStyle] fillGradientStops is not supported by HTMLText")}get fillGradientStops(){return super.fillGradientStops}set fillGradientType(t){console.warn("[HTMLTextStyle] fillGradientType is not supported by HTMLText")}get fillGradientType(){return super.fillGradientType}set miterLimit(t){console.warn("[HTMLTextStyle] miterLimit is not supported by HTMLText")}get miterLimit(){return super.miterLimit}set trim(t){console.warn("[HTMLTextStyle] trim is not supported by HTMLText")}get trim(){return super.trim}set textBaseline(t){console.warn("[HTMLTextStyle] textBaseline is not supported by HTMLText")}get textBaseline(){return super.textBaseline}set leading(t){console.warn("[HTMLTextStyle] leading is not supported by HTMLText")}get leading(){return super.leading}set lineJoin(t){console.warn("[HTMLTextStyle] lineJoin is not supported by HTMLText")}get lineJoin(){return super.lineJoin}};ma.availableFonts={},ma.defaultOptions={align:"left",breakWords:!1,dropShadow:!1,dropShadowAlpha:1,dropShadowAngle:Math.PI/6,dropShadowBlur:0,dropShadowColor:"black",dropShadowDistance:5,fill:"black",fontFamily:"Arial",fontSize:26,fontStyle:"normal",fontVariant:"normal",fontWeight:"normal",letterSpacing:0,lineHeight:0,padding:0,stroke:"black",strokeThickness:0,whiteSpace:"normal",wordWrap:!1,wordWrapWidth:100};let _r=ma;const ti=class hs extends Ut{constructor(t="",e={}){var s;super(L.EMPTY),this._text=null,this._style=null,this._autoResolution=!0,this.localStyleID=-1,this.dirty=!1,this._updateID=0,this.ownsStyle=!1;const r=new Image,n=L.from(r,{scaleMode:N.SCALE_MODE,resourceOptions:{autoLoad:!1}});n.orig=new z,n.trim=new z,this.texture=n;const a="http://www.w3.org/2000/svg",o="http://www.w3.org/1999/xhtml",h=document.createElementNS(a,"svg"),l=document.createElementNS(a,"foreignObject"),u=document.createElementNS(o,"div"),c=document.createElementNS(o,"style");l.setAttribute("width","10000"),l.setAttribute("height","10000"),l.style.overflow="hidden",h.appendChild(l),this.maxWidth=hs.defaultMaxWidth,this.maxHeight=hs.defaultMaxHeight,this._domElement=u,this._styleElement=c,this._svgRoot=h,this._foreignObject=l,this._foreignObject.appendChild(c),this._foreignObject.appendChild(u),this._image=r,this._loadImage=new Image,this._autoResolution=hs.defaultAutoResolution,this._resolution=(s=hs.defaultResolution)!=null?s:N.RESOLUTION,this.text=t,this.style=e}measureText(t){var e,s;const{text:r,style:n,resolution:a}=Object.assign({text:this._text,style:this._style,resolution:this._resolution},t);Object.assign(this._domElement,{innerHTML:r,style:n.toCSS(a)}),this._styleElement.textContent=n.toGlobalCSS(),document.body.appendChild(this._svgRoot);const o=this._domElement.getBoundingClientRect();this._svgRoot.remove();const{width:h,height:l}=o,u=Math.min(this.maxWidth,Math.ceil(h)),c=Math.min(this.maxHeight,Math.ceil(l));return this._svgRoot.setAttribute("width",u.toString()),this._svgRoot.setAttribute("height",c.toString()),r!==this._text&&(this._domElement.innerHTML=this._text),n!==this._style&&(Object.assign(this._domElement,{style:(e=this._style)==null?void 0:e.toCSS(a)}),this._styleElement.textContent=(s=this._style)==null?void 0:s.toGlobalCSS()),{width:u+n.padding*2,height:c+n.padding*2}}async updateText(t=!0){const{style:e,_image:s,_loadImage:r}=this;if(this.localStyleID!==e.styleID&&(this.dirty=!0,this.localStyleID=e.styleID),!this.dirty&&t)return;const{width:n,height:a}=this.measureText();s.width=r.width=Math.ceil(Math.max(1,n)),s.height=r.height=Math.ceil(Math.max(1,a)),this._updateID++;const o=this._updateID;await new Promise(h=>{r.onload=async()=>{if(o/gi,"
").replace(/
/gi,"
").replace(/ /gi," ")}};ti.defaultDestroyOptions={texture:!0,children:!1,baseTexture:!0},ti.defaultMaxWidth=2024,ti.defaultMaxHeight=2024,ti.defaultAutoResolution=!0;let hg=ti;const Pe=new z;class ga{constructor(t){this.renderer=t}async image(t,e,s,r){const n=new Image;return n.src=await this.base64(t,e,s,r),n}async base64(t,e,s,r){const n=this.canvas(t,r);if(n.toBlob!==void 0)return new Promise((a,o)=>{n.toBlob(h=>{if(!h){o(new Error("ICanvas.toBlob failed!"));return}const l=new FileReader;l.onload=()=>a(l.result),l.onerror=o,l.readAsDataURL(h)},e,s)});if(n.toDataURL!==void 0)return n.toDataURL(e,s);if(n.convertToBlob!==void 0){const a=await n.convertToBlob({type:e,quality:s});return new Promise((o,h)=>{const l=new FileReader;l.onload=()=>o(l.result),l.onerror=h,l.readAsDataURL(a)})}throw new Error("CanvasExtract.base64() requires ICanvas.toDataURL, ICanvas.toBlob, or ICanvas.convertToBlob to be implemented")}canvas(t,e){const s=this.renderer;if(!s)throw new Error("The CanvasExtract has already been destroyed");let r,n,a;t&&(t instanceof Yt?a=t:(a=s.generateTexture(t,{region:e,resolution:s.resolution}),e&&(Pe.width=e.width,Pe.height=e.height,e=Pe))),a?(r=a.baseTexture._canvasRenderTarget.context,n=a.baseTexture._canvasRenderTarget.resolution,e=e!=null?e:a.frame):(r=s.canvasContext.rootContext,n=s._view.resolution,e||(e=Pe,e.width=s.width/n,e.height=s.height/n));const o=Math.round(e.x*n),h=Math.round(e.y*n),l=Math.max(Math.round(e.width*n),1),u=Math.max(Math.round(e.height*n),1),c=new ys(l,u,1),d=r.getImageData(o,h,l,u);return c.context.putImageData(d,0,0),c.canvas}pixels(t,e){const s=this.renderer;if(!s)throw new Error("The CanvasExtract has already been destroyed");let r,n,a;t&&(t instanceof Yt?a=t:(a=s.generateTexture(t,{region:e,resolution:s.resolution}),e&&(Pe.width=e.width,Pe.height=e.height,e=Pe))),a?(r=a.baseTexture._canvasRenderTarget.context,n=a.baseTexture._canvasRenderTarget.resolution,e=e!=null?e:a.frame):(r=s.canvasContext.rootContext,n=s.resolution,e||(e=Pe,e.width=s.width/n,e.height=s.height/n));const o=Math.round(e.x*n),h=Math.round(e.y*n),l=Math.max(Math.round(e.width*n),1),u=Math.max(Math.round(e.height*n),1);return r.getImageData(o,h,l,u).data}destroy(){this.renderer=null}}ga.extension={name:"extract",type:D.CanvasRendererSystem},U.add(ga);let _a;const ei=new tt;rs.prototype.generateCanvasTexture=function(i,t=1){const e=this.getLocalBounds(new z);e.width=Math.max(e.width,1/t),e.height=Math.max(e.height,1/t);const s=Yt.create({width:e.width,height:e.height,scaleMode:i,resolution:t});_a||(_a=new Bs),this.transform.updateLocalTransform(),this.transform.localTransform.copyTo(ei),ei.invert(),ei.tx-=e.x,ei.ty-=e.y,_a.render(this,{renderTexture:s,clear:!0,transform:ei});const r=L.from(s.baseTexture._canvasRenderTarget.canvas,{scaleMode:i});return r.baseTexture.setResolution(t),r},rs.prototype.cachedGraphicsData=[],rs.prototype._renderCanvas=function(i){this.isMask!==!0&&(this.finishPoly(),i.plugins.graphics.render(this))};class si{static offsetPolygon(t,e){const s=[],r=t.length;e=si.isPolygonClockwise(t)?e:-1*e;for(let n=0;n0}}class va{constructor(t){this._svgMatrix=null,this._tempMatrix=new tt,this.renderer=t}_calcCanvasStyle(t,e){let s;return t.texture&&t.texture.baseTexture!==L.WHITE.baseTexture?t.texture.valid?(s=gt.getTintedPattern(t.texture,e),this.setPatternTransform(s,t.matrix||tt.IDENTITY)):s="#808080":s=`#${`00000${(e|0).toString(16)}`.slice(-6)}`,s}render(t){const e=this.renderer,s=e.canvasContext.activeContext,r=t.worldAlpha,n=t.transform.worldTransform;e.canvasContext.setContextTransform(n),e.canvasContext.setBlendMode(t.blendMode);const a=t.geometry.graphicsData;let o,h;const l=Y.shared.setValue(t.tint).toArray();for(let u=0;u0){A=[],b=0,R=x[0],w=x[1];for(let S=2;S+2=0;I-=2)s.lineTo(x[I],x[I+1])}v[S].shape.closeStroke&&s.closePath(),A[S]=T*b<0}}f.visible&&(s.globalAlpha=f.alpha*r,s.fillStyle=o,s.fill()),p.visible&&this.paintPolygonStroke(_,p,h,v,A,r,s)}else if(c.type===it.RECT){const _=d;if(f.visible&&(s.globalAlpha=f.alpha*r,s.fillStyle=o,s.fillRect(_.x,_.y,_.width,_.height)),p.visible){const x=p.width*(.5-(1-p.alignment)),v=_.width+2*x,b=_.height+2*x;s.globalAlpha=p.alpha*r,s.strokeStyle=h,s.strokeRect(_.x-x,_.y-x,v,b)}}else if(c.type===it.CIRC){const _=d;if(s.beginPath(),s.arc(_.x,_.y,_.radius,0,2*Math.PI),s.closePath(),f.visible&&(s.globalAlpha=f.alpha*r,s.fillStyle=o,s.fill()),p.visible){if(p.alignment!==.5){const x=p.width*(.5-(1-p.alignment));s.beginPath(),s.arc(_.x,_.y,_.radius+x,0,2*Math.PI),s.closePath()}s.globalAlpha=p.alpha*r,s.strokeStyle=h,s.stroke()}}else if(c.type===it.ELIP){const _=d,x=p.alignment===1;if(x||this.paintEllipse(_,f,p,o,r,s),p.visible){if(p.alignment!==.5){const v=.5522848,b=p.width*(.5-(1-p.alignment)),T=(_.width+b)*2,R=(_.height+b)*2,w=_.x-T/2,A=_.y-R/2,S=T/2*v,I=R/2*v,H=w+T,B=A+R,E=w+T/2,P=A+R/2;s.beginPath(),s.moveTo(w,P),s.bezierCurveTo(w,P-I,E-S,A,E,A),s.bezierCurveTo(E+S,A,H,P-I,H,P),s.bezierCurveTo(H,P+I,E+S,B,E,B),s.bezierCurveTo(E-S,B,w,P+I,w,P),s.closePath()}s.globalAlpha=p.alpha*r,s.strokeStyle=h,s.stroke()}x&&this.paintEllipse(_,f,p,o,r,s)}else if(c.type===it.RREC){const _=d,x=p.alignment===1;if(x||this.paintRoundedRectangle(_,f,p,o,r,s),p.visible){if(p.alignment!==.5){const v=_.width,b=_.height,T=p.width*(.5-(1-p.alignment)),R=_.x-T,w=_.y-T,A=_.width+2*T,S=_.height+2*T,I=T*(p.alignment>=1?Math.min(A/v,S/b):Math.min(v/A,b/S));let H=_.radius+I;const B=Math.min(A,S)/2;H=H>B?B:H,s.beginPath(),s.moveTo(R,w+H),s.lineTo(R,w+S-H),s.quadraticCurveTo(R,w+S,R+H,w+S),s.lineTo(R+A-H,w+S),s.quadraticCurveTo(R+A,w+S,R+A,w+S-H),s.lineTo(R+A,w+H),s.quadraticCurveTo(R+A,w,R+A-H,w),s.lineTo(R+H,w),s.quadraticCurveTo(R,w,R,w+H),s.closePath()}s.globalAlpha=p.alpha*r,s.strokeStyle=h,s.stroke()}x&&this.paintRoundedRectangle(_,f,p,o,r,s)}}}paintPolygonStroke(t,e,s,r,n,a,o){if(e.alignment!==.5){const h=e.width*(.5-(1-e.alignment));let l=si.offsetPolygon(t.points,h),u;o.beginPath(),o.moveTo(l[0],l[1]);for(let c=2;c=0;d-=2)o.lineTo(l[d],l[d+1])}r[c].shape.closeStroke&&o.closePath()}}o.globalAlpha=e.alpha*a,o.strokeStyle=s,o.stroke()}paintEllipse(t,e,s,r,n,a){const o=t.width*2,h=t.height*2,l=t.x-o/2,u=t.y-h/2,c=.5522848,d=o/2*c,f=h/2*c,p=l+o,m=u+h,g=l+o/2,_=u+h/2;s.alignment===0&&a.save(),a.beginPath(),a.moveTo(l,_),a.bezierCurveTo(l,_-f,g-d,u,g,u),a.bezierCurveTo(g+d,u,p,_-f,p,_),a.bezierCurveTo(p,_+f,g+d,m,g,m),a.bezierCurveTo(g-d,m,l,_+f,l,_),a.closePath(),s.alignment===0&&a.clip(),e.visible&&(a.globalAlpha=e.alpha*n,a.fillStyle=r,a.fill()),s.alignment===0&&a.restore()}paintRoundedRectangle(t,e,s,r,n,a){const o=t.x,h=t.y,l=t.width,u=t.height;let c=t.radius;const d=Math.min(l,u)/2;c=c>d?d:c,s.alignment===0&&a.save(),a.beginPath(),a.moveTo(o,h+c),a.lineTo(o,h+u-c),a.quadraticCurveTo(o,h+u,o+c,h+u),a.lineTo(o+l-c,h+u),a.quadraticCurveTo(o+l,h+u,o+l,h+u-c),a.lineTo(o+l,h+c),a.quadraticCurveTo(o+l,h,o+l-c,h),a.lineTo(o+c,h),a.quadraticCurveTo(o,h,o,h+c),a.closePath(),s.alignment===0&&a.clip(),e.visible&&(a.globalAlpha=e.alpha*n,a.fillStyle=r,a.fill()),s.alignment===0&&a.restore()}setPatternTransform(t,e){if(this._svgMatrix!==!1){if(!this._svgMatrix){const s=document.createElementNS("http://www.w3.org/2000/svg","svg");if(s!=null&&s.createSVGMatrix&&(this._svgMatrix=s.createSVGMatrix()),!this._svgMatrix||!t.setTransform){this._svgMatrix=!1;return}}this._svgMatrix.a=e.a,this._svgMatrix.b=e.b,this._svgMatrix.c=e.c,this._svgMatrix.d=e.d,this._svgMatrix.e=e.tx,this._svgMatrix.f=e.ty,t.setTransform(this._svgMatrix.inverse())}}destroy(){this.renderer=null,this._svgMatrix=null,this._tempMatrix=null}}va.extension={name:"graphics",type:D.CanvasRendererPlugin},U.add(va),Object.defineProperties(N,{MESH_CANVAS_PADDING:{get(){return Et.defaultCanvasPadding},set(i){Et.defaultCanvasPadding=i}}}),Xe.prototype._renderCanvas=function(i,t){i.plugins.mesh.render(t)},Ks.prototype._cachedTint=16777215,Ks.prototype._tintedCanvas=null,Ks.prototype._canvasUvs=null,Ks.prototype._renderCanvas=function(i){const t=i.canvasContext.activeContext,e=this.worldTransform,s=this.tintValue!==16777215,r=this.texture;if(!r.valid)return;s&&this._cachedTint!==this.tintValue&&(this._cachedTint=this.tintValue,this._tintedCanvas=gt.getTintedCanvas(this,this.tintValue));const n=s?this._tintedCanvas:r.baseTexture.getDrawableSource();this._canvasUvs||(this._canvasUvs=[0,0,0,0,0,0,0,0]);const a=this.vertices,o=this._canvasUvs,h=s?0:r.frame.x,l=s?0:r.frame.y,u=h+r.frame.width,c=l+r.frame.height;o[0]=h,o[1]=h+this._leftWidth,o[2]=u-this._rightWidth,o[3]=u,o[4]=l,o[5]=l+this._topHeight,o[6]=c-this._bottomHeight,o[7]=c;for(let d=0;d<8;d++)o[d]*=r.baseTexture.resolution;t.globalAlpha=this.worldAlpha,i.canvasContext.setBlendMode(this.blendMode),i.canvasContext.setContextTransform(e,this.roundPixels);for(let d=0;d<3;d++)for(let f=0;f<3;f++){const p=f*2+d*8,m=Math.max(1,o[f+1]-o[f]),g=Math.max(1,o[d+5]-o[d+4]),_=Math.max(1,a[p+10]-a[p]),x=Math.max(1,a[p+11]-a[p+1]);t.drawImage(n,o[f],o[d+4],m,g,a[p],a[p+1],_,x)}};let Fu=!1;Et.prototype._cachedTint=16777215,Et.prototype._tintedCanvas=null,Et.prototype._cachedTexture=null,Et.prototype._renderCanvas=function(i){this.shader.uvMatrix&&(this.shader.uvMatrix.update(),this.calculateUvs()),this.material._renderCanvas?this.material._renderCanvas(i,this):Fu||(Fu=!0,globalThis.console.warn("Mesh with custom shaders are not supported in CanvasRenderer."))},Et.prototype._canvasPadding=null,Et.defaultCanvasPadding=0,Object.defineProperty(Et.prototype,"canvasPadding",{get(){var i;return(i=this._canvasPadding)!=null?i:Et.defaultCanvasPadding},set(i){this._canvasPadding=i}}),mu.prototype._renderCanvas=function(i){this.autoUpdate&&this.geometry.getBuffer("aVertexPosition").update(),this.shader.update&&this.shader.update(),this.calculateUvs(),this.material._renderCanvas(i,this)},gu.prototype._renderCanvas=function(i){(this.autoUpdate||this.geometry._width!==this.shader.texture.height)&&(this.geometry._width=this.shader.texture.height,this.geometry.update()),this.shader.update&&this.shader.update(),this.calculateUvs(),this.material._renderCanvas(i,this)};class ya{constructor(t){this.renderer=t}render(t){const e=this.renderer,s=t.worldTransform;e.canvasContext.activeContext.globalAlpha=t.worldAlpha,e.canvasContext.setBlendMode(t.blendMode),e.canvasContext.setContextTransform(s,t.roundPixels),t.drawMode!==Ot.TRIANGLES?this._renderTriangleMesh(t):this._renderTriangles(t)}_renderTriangleMesh(t){const e=t.geometry.buffers[0].data.length;for(let s=0;s0){const{a:ht,b:F,c:O,d:Z}=t.worldTransform,Q=(T+R+w)/3,J=(A+S+I)/3;let st=T-Q,et=A-J,rt=ht*st+O*et,lt=F*st+Z*et,_t=Math.sqrt(rt*rt+lt*lt),nt=1+H/_t;T=Q+st*nt,A=J+et*nt,st=R-Q,et=S-J,rt=ht*st+O*et,lt=F*st+Z*et,_t=Math.sqrt(rt*rt+lt*lt),nt=1+H/_t,R=Q+st*nt,S=J+et*nt,st=w-Q,et=I-J,rt=ht*st+O*et,lt=F*st+Z*et,_t=Math.sqrt(rt*rt+lt*lt),nt=1+H/_t,w=Q+st*nt,I=J+et*nt}a.save(),a.beginPath(),a.moveTo(T,A),a.lineTo(R,S),a.lineTo(w,I),a.closePath(),a.clip();const B=m*v+x*_+g*b-v*_-x*g-m*b,E=T*v+x*w+R*b-v*w-x*R-T*b,P=m*R+T*_+g*w-R*_-T*g-m*w,V=m*v*w+x*R*_+T*g*b-T*v*_-x*g*w-m*R*b,q=A*v+x*I+S*b-v*I-x*S-A*b,j=m*S+A*_+g*I-S*_-A*g-m*I,W=m*v*I+x*S*_+A*g*b-A*v*_-x*g*I-m*S*b;a.transform(E/B,q/B,P/B,j/B,V/B,W/B),a.drawImage(p,0,0,d*c.resolution,f*c.resolution,0,0,d,f),a.restore(),this.renderer.canvasContext.invalidateBlendMode()}renderMeshFlat(t){const e=this.renderer.canvasContext.activeContext,s=t.geometry.getBuffer("aVertexPosition").data,r=s.length/2;e.beginPath();for(let n=1;n Date: Wed, 22 Nov 2023 17:35:51 +0200 Subject: [PATCH 32/80] update install-spine script with shelljs and error logs --- GDJS/scripts/install-spine.js | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/GDJS/scripts/install-spine.js b/GDJS/scripts/install-spine.js index c7a362f0adb2..8025c3608a91 100644 --- a/GDJS/scripts/install-spine.js +++ b/GDJS/scripts/install-spine.js @@ -1,14 +1,27 @@ -const fs = require('fs'); const path = require('path'); +const shell = require('shelljs'); -const format = 'utf8'; +const readContent = (path, testErrorMessage) => { + if (!shell.test('-f', path)) { + shell.echo(`❌ ${testErrorMessage} Should exist in ${path} folder.`); + shell.exit(1); + } + + const readingResult = shell.cat(path); + + if (readingResult.stderr) { + shell.echo(`❌ Error during ${path} reading: ${readingResult.stderr}`); + shell.exit(1); + } + + return readingResult.toString(); +} const originalSpineDir = path.resolve('node_modules/pixi-spine'); -const originalSpinePackage = JSON.parse(fs.readFileSync(path.join(originalSpineDir, 'package.json'), format)); -const originalSpinePath = path.join(originalSpineDir, originalSpinePackage.extensionConfig.bundle); -const originalSpine = fs.readFileSync(originalSpinePath, format); +const originalSpinePackage = JSON.parse(readContent(path.join(originalSpineDir, 'package.json'), 'Cannot find pixi-spine package.json file.')); +const originalSpineContent = readContent(path.join(originalSpineDir, originalSpinePackage.extensionConfig.bundle), 'Cannot find pixi-spine bundle.'); const varSpineExport = '\nvar pixi_spine = this.PIXI.spine;\n'; const runtimeSpinePath = 'Runtime/pixi-renderers/pixi-spine.js'; +new shell.ShellString(originalSpineContent + varSpineExport).to(runtimeSpinePath); -fs.writeFileSync(runtimeSpinePath, originalSpine + varSpineExport, format); \ No newline at end of file From 8f373082bc799bfa0e78145490b2a2e8ea396292 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Thu, 23 Nov 2023 17:29:31 +0200 Subject: [PATCH 33/80] create SpineResource, restore JsonManager, update spine extension --- .../CodeGeneration/EventsCodeGenerator.cpp | 1 + .../Extensions/Metadata/ValueTypeMetadata.h | 3 +- .../IDE/Project/ArbitraryResourceWorker.cpp | 13 ++ .../IDE/Project/ArbitraryResourceWorker.h | 5 + .../Project/ObjectsUsingResourceCollector.h | 6 + .../GDCore/IDE/Project/ResourcesInUseHelper.h | 6 + Core/GDCore/IDE/Project/ResourcesRenamer.h | 3 + .../Project/CustomObjectConfiguration.cpp | 2 + Core/GDCore/Project/ResourcesManager.cpp | 2 + Core/GDCore/Project/ResourcesManager.h | 15 ++ Extensions/.gitignore | 1 + Extensions/Spine/JsExtension.js | 18 +-- Extensions/Spine/SpineObjectConfiguration.cpp | 20 +-- Extensions/Spine/SpineObjectConfiguration.h | 2 +- .../managers/pixi-spine-atlas-manager.ts | 27 ++-- .../Spine/managers/pixi-spine-manager.ts | 135 ++++++++++++++++ .../Spine/spineruntimeobject-pixi-renderer.ts | 20 ++- Extensions/Spine/spineruntimeobject.ts | 6 +- GDJS/.gitignore | 3 +- GDJS/GDJS/IDE/ExporterHelper.cpp | 5 +- .../pixi-json-manager.ts => jsonmanager.ts} | 144 +++++------------- .../pixi-renderers/pixi-spine-manager.ts | 42 ----- GDJS/Runtime/runtimegame.ts | 66 +++++--- GDJS/Runtime/types/project-data.d.ts | 3 +- GDJS/scripts/install-spine.js | 2 +- GDevelop.js/Bindings/Bindings.idl | 5 + .../Bindings/ObjectJsImplementation.cpp | 2 + GDevelop.js/scripts/copy-to-newIDE.js | 1 - GDevelop.js/scripts/generate-types.js | 4 +- GDevelop.js/types/gdresource.js | 4 +- GDevelop.js/types/gdspineresource.js | 6 + GDevelop.js/types/libgdevelop.js | 1 + newIDE/app/src/AssetStore/InstallAsset.js | 2 + .../AssetStore/ResourceStore/ResourceCard.js | 1 + .../ParameterFields/SpineResourceField.js | 48 ++++++ .../EventsSheet/ParameterRenderingService.js | 3 + .../src/ObjectEditor/Editors/SpineEditor.js | 30 ++-- .../ObjectsRendering/PixiResourcesLoader.js | 2 +- .../FileToCloudProjectResourceUploader.js | 1 + ...FileToCloudProjectResourceUploader.spec.js | 3 + .../ResourcesList/ResourcePreview/index.js | 1 + .../app/src/ResourcesList/ResourceSource.js | 15 +- newIDE/app/src/ResourcesList/index.js | 3 +- .../ParameterFields/ResourceFields.stories.js | 21 +++ 44 files changed, 460 insertions(+), 243 deletions(-) create mode 100644 Extensions/.gitignore rename GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts => Extensions/Spine/managers/pixi-spine-atlas-manager.ts (87%) create mode 100644 Extensions/Spine/managers/pixi-spine-manager.ts rename GDJS/Runtime/{pixi-renderers/pixi-json-manager.ts => jsonmanager.ts} (61%) delete mode 100644 GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts create mode 100644 GDevelop.js/types/gdspineresource.js create mode 100644 newIDE/app/src/EventsSheet/ParameterFields/SpineResourceField.js diff --git a/Core/GDCore/Events/CodeGeneration/EventsCodeGenerator.cpp b/Core/GDCore/Events/CodeGeneration/EventsCodeGenerator.cpp index dbbb76cd19fa..0203ae20252e 100644 --- a/Core/GDCore/Events/CodeGeneration/EventsCodeGenerator.cpp +++ b/Core/GDCore/Events/CodeGeneration/EventsCodeGenerator.cpp @@ -715,6 +715,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes( metadata.GetType() == "videoResource" || metadata.GetType() == "model3DResource" || metadata.GetType() == "atlasResource" || + metadata.GetType() == "spineResource" || // Deprecated, old parameter names: metadata.GetType() == "password" || metadata.GetType() == "musicfile" || metadata.GetType() == "soundfile" || metadata.GetType() == "police") { diff --git a/Core/GDCore/Extensions/Metadata/ValueTypeMetadata.h b/Core/GDCore/Extensions/Metadata/ValueTypeMetadata.h index 4ad2dcb350db..4f488d29d612 100644 --- a/Core/GDCore/Extensions/Metadata/ValueTypeMetadata.h +++ b/Core/GDCore/Extensions/Metadata/ValueTypeMetadata.h @@ -218,7 +218,8 @@ class GD_CORE_API ValueTypeMetadata { parameterType == "tilemapResource" || parameterType == "tilesetResource" || parameterType == "model3DResource" || - parameterType == "atlasResource"; + parameterType == "atlasResource" || + parameterType == "spineResource"; } return false; } diff --git a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp index c09c573890c6..01023f6aad88 100644 --- a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp +++ b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp @@ -57,6 +57,11 @@ void ArbitraryResourceWorker::ExposeAtlas(gd::String& resourceName){ // do. }; +void ArbitraryResourceWorker::ExposeSpine(gd::String& resourceName){ + // Nothing to do by default - each child class can define here the action to + // do. +}; + void ArbitraryResourceWorker::ExposeVideo(gd::String& videoName){ // Nothing to do by default - each child class can define here the action to // do. @@ -199,6 +204,10 @@ void ArbitraryResourceWorker::ExposeResourceWithType( ExposeAtlas(resourceName); return; } + if (resourceType == "spine") { + ExposeSpine(resourceName); + return; + } gd::LogError("Unexpected resource type: " + resourceType + " for: " + resourceName); return; } @@ -269,6 +278,10 @@ bool ResourceWorkerInEventsWorker::DoVisitInstruction(gd::Instruction& instructi gd::String updatedParameterValue = parameterValue; worker.ExposeAtlas(updatedParameterValue); instruction.SetParameter(parameterIndex, updatedParameterValue); + } else if (parameterMetadata.GetType() == "spineResource") { + gd::String updatedParameterValue = parameterValue; + worker.ExposeSpine(updatedParameterValue); + instruction.SetParameter(parameterIndex, updatedParameterValue); } }); diff --git a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.h b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.h index e4f701d9dfd4..ef5c313a8708 100644 --- a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.h +++ b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.h @@ -101,6 +101,11 @@ class GD_CORE_API ArbitraryResourceWorker { */ virtual void ExposeAtlas(gd::String &resourceName); + /** + * \brief Expose an spine, which is always a reference to a "spine" resource. + */ + virtual void ExposeSpine(gd::String &resourceName); + /** * \brief Expose a video, which is always a reference to a "video" resource. */ diff --git a/Core/GDCore/IDE/Project/ObjectsUsingResourceCollector.h b/Core/GDCore/IDE/Project/ObjectsUsingResourceCollector.h index dd7ee45c93cc..df3aaa5fb866 100644 --- a/Core/GDCore/IDE/Project/ObjectsUsingResourceCollector.h +++ b/Core/GDCore/IDE/Project/ObjectsUsingResourceCollector.h @@ -75,6 +75,12 @@ class GD_CORE_API ResourceNameMatcher : public ArbitraryResourceWorker { virtual void ExposeModel3D(gd::String& otherResourceName) override { MatchResourceName(otherResourceName); }; + virtual void ExposeAtlas(gd::String& otherResourceName) override { + MatchResourceName(otherResourceName); + }; + virtual void ExposeSpine(gd::String& otherResourceName) override { + MatchResourceName(otherResourceName); + }; void MatchResourceName(gd::String& otherResourceName) { if (otherResourceName == resourceName) matchesResourceName = true; diff --git a/Core/GDCore/IDE/Project/ResourcesInUseHelper.h b/Core/GDCore/IDE/Project/ResourcesInUseHelper.h index 02721b023fc8..cbc1ab3bf795 100644 --- a/Core/GDCore/IDE/Project/ResourcesInUseHelper.h +++ b/Core/GDCore/IDE/Project/ResourcesInUseHelper.h @@ -47,6 +47,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker { std::set& GetAllBitmapFonts() { return GetAll("bitmapFont"); }; std::set& GetAll3DModels() { return GetAll("model3D"); }; std::set& GetAllAtlases() { return GetAll("atlas"); }; + std::set& GetAllSpines() { return GetAll("spine"); }; std::set& GetAll(const gd::String& resourceType) { if (resourceType == "image") return allImages; if (resourceType == "audio") return allAudios; @@ -58,6 +59,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker { if (resourceType == "bitmapFont") return allBitmapFonts; if (resourceType == "model3D") return allModel3Ds; if (resourceType == "atlas") return allAtlases; + if (resourceType == "spine") return allSpines; return emptyResources; }; @@ -95,6 +97,9 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker { virtual void ExposeAtlas(gd::String& resourceName) override { allAtlases.insert(resourceName); }; + virtual void ExposeSpine(gd::String& resourceName) override { + allSpines.insert(resourceName); + }; protected: std::set allImages; @@ -107,6 +112,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker { std::set allBitmapFonts; std::set allModel3Ds; std::set allAtlases; + std::set allSpines; std::set emptyResources; }; diff --git a/Core/GDCore/IDE/Project/ResourcesRenamer.h b/Core/GDCore/IDE/Project/ResourcesRenamer.h index 9065517650ef..38951e5d320f 100644 --- a/Core/GDCore/IDE/Project/ResourcesRenamer.h +++ b/Core/GDCore/IDE/Project/ResourcesRenamer.h @@ -65,6 +65,9 @@ class ResourcesRenamer : public gd::ArbitraryResourceWorker { virtual void ExposeAtlas(gd::String& resourceName) override { RenameIfNeeded(resourceName); }; + virtual void ExposeSpine(gd::String& resourceName) override { + RenameIfNeeded(resourceName); + }; private: void RenameIfNeeded(gd::String& resourceName) { diff --git a/Core/GDCore/Project/CustomObjectConfiguration.cpp b/Core/GDCore/Project/CustomObjectConfiguration.cpp index 6118c662fe1a..8f76fd53903b 100644 --- a/Core/GDCore/Project/CustomObjectConfiguration.cpp +++ b/Core/GDCore/Project/CustomObjectConfiguration.cpp @@ -157,6 +157,8 @@ void CustomObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker& wor worker.ExposeModel3D(newPropertyValue); } else if (resourceType == "atlas") { worker.ExposeAtlas(newPropertyValue); + } else if (resourceType == "spine") { + worker.ExposeSpine(newPropertyValue); } if (newPropertyValue != oldPropertyValue) { diff --git a/Core/GDCore/Project/ResourcesManager.cpp b/Core/GDCore/Project/ResourcesManager.cpp index f4e5b6d61415..d08de73169e5 100644 --- a/Core/GDCore/Project/ResourcesManager.cpp +++ b/Core/GDCore/Project/ResourcesManager.cpp @@ -95,6 +95,8 @@ std::shared_ptr ResourcesManager::CreateResource( return std::make_shared(); else if (kind == "atlas") return std::make_shared(); + else if (kind == "spine") + return std::make_shared(); std::cout << "Bad resource created (type: " << kind << ")" << std::endl; return std::make_shared(); diff --git a/Core/GDCore/Project/ResourcesManager.h b/Core/GDCore/Project/ResourcesManager.h index 78a0a14e123b..39897bb145d3 100644 --- a/Core/GDCore/Project/ResourcesManager.h +++ b/Core/GDCore/Project/ResourcesManager.h @@ -373,6 +373,21 @@ class GD_CORE_API JsonResource : public Resource { gd::String file; }; +/** + * \brief Describe a spine json file used by a project. + * + * \see Resource + * \ingroup ResourcesManagement + */ +class GD_CORE_API SpineResource : public JsonResource { + public: + SpineResource() : JsonResource() { SetKind("spine"); }; + virtual ~SpineResource(){}; + virtual SpineResource* Clone() const override { + return new SpineResource(*this); + } +}; + /** * \brief Describe a tilemap file used by a project. * diff --git a/Extensions/.gitignore b/Extensions/.gitignore new file mode 100644 index 000000000000..68fef6ce5db2 --- /dev/null +++ b/Extensions/.gitignore @@ -0,0 +1 @@ +Spine/pixi-spine \ No newline at end of file diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 6ed32e49d892..fe3f67853028 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -53,6 +53,9 @@ module.exports = { ) .setIncludeFile('Extensions/Spine/spineruntimeobject.js') .addIncludeFile('Extensions/Spine/spineruntimeobject-pixi-renderer.js') + .addIncludeFile('Extensions/Spine/pixi-spine/pixi-spine.js') + .addIncludeFile('Extensions/Spine/managers/pixi-spine-atlas-manager.js') + .addIncludeFile('Extensions/Spine/managers/pixi-spine-manager.js') .setCategoryFullName(_('General')); object @@ -189,14 +192,7 @@ module.exports = { */ registerEditorConfigurations: function ( objectsEditorService /*: ObjectsEditorService */ - ) { - objectsEditorService.registerEditorConfiguration( - 'SpineObject::SpineObject', - objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({ - helpPagePath: '/objects/spine', - }) - ); - }, + ) { }, /** * Register renderers for instance of objects on the scene editor. * @@ -354,8 +350,8 @@ module.exports = { _loadSpine() { const properties = this._getProperties(); - const jsonResourceName = properties - .get('jsonResourceName') + const spineResourceName = properties + .get('spineResourceName') .getValue(); const imageResourceName = properties .get('imageResourceName') @@ -367,7 +363,7 @@ module.exports = { this._pixiResourcesLoader .getSpineData( this._project, - jsonResourceName, + spineResourceName, imageResourceName, atlasResourceName ) diff --git a/Extensions/Spine/SpineObjectConfiguration.cpp b/Extensions/Spine/SpineObjectConfiguration.cpp index 10dc25dc89ff..d6d73fb39a55 100644 --- a/Extensions/Spine/SpineObjectConfiguration.cpp +++ b/Extensions/Spine/SpineObjectConfiguration.cpp @@ -22,7 +22,7 @@ SpineAnimation SpineObjectConfiguration::badAnimation; SpineObjectConfiguration::SpineObjectConfiguration() : scale(1), opacity(255), timeScale(1), - jsonResourceName(""), imageResourceName(""), atlasResourceName("") {}; + spineResourceName(""), imageResourceName(""), atlasResourceName("") {}; bool SpineObjectConfiguration::UpdateProperty(const gd::String &propertyName, const gd::String &newValue) { if (propertyName == "scale") { @@ -37,8 +37,8 @@ bool SpineObjectConfiguration::UpdateProperty(const gd::String &propertyName, co timeScale = newValue.To(); return true; } - if (propertyName == "jsonResourceName") { - jsonResourceName = newValue; + if (propertyName == "spineResourceName") { + spineResourceName = newValue; return true; } if (propertyName == "imageResourceName") { @@ -75,11 +75,11 @@ SpineObjectConfiguration::GetProperties() const { .SetLabel(_("Time Scale")) .SetGroup(_("Play")); - objectProperties["jsonResourceName"] - .SetValue(jsonResourceName) + objectProperties["spineResourceName"] + .SetValue(spineResourceName) .SetType("resource") - .AddExtraInfo("json") - .SetLabel(_("Json")); + .AddExtraInfo("spine") + .SetLabel(_("Spine json")); objectProperties["imageResourceName"] .SetValue(imageResourceName) @@ -124,7 +124,7 @@ void SpineObjectConfiguration::DoUnserializeFrom(gd::Project &project, const gd: scale = content.GetDoubleAttribute("scale"); opacity = content.GetDoubleAttribute("opacity"); timeScale = content.GetDoubleAttribute("timeScale"); - jsonResourceName = content.GetStringAttribute("jsonResourceName"); + spineResourceName = content.GetStringAttribute("spineResourceName"); imageResourceName = content.GetStringAttribute("imageResourceName"); atlasResourceName = content.GetStringAttribute("atlasResourceName"); @@ -146,7 +146,7 @@ void SpineObjectConfiguration::DoSerializeTo(gd::SerializerElement &element) con content.SetAttribute("scale", scale); content.SetAttribute("opacity", opacity); content.SetAttribute("timeScale", timeScale); - content.SetAttribute("jsonResourceName", jsonResourceName); + content.SetAttribute("spineResourceName", spineResourceName); content.SetAttribute("imageResourceName", imageResourceName); content.SetAttribute("atlasResourceName", atlasResourceName); @@ -161,7 +161,7 @@ void SpineObjectConfiguration::DoSerializeTo(gd::SerializerElement &element) con } void SpineObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker &worker) { - worker.ExposeJson(jsonResourceName); + worker.ExposeSpine(spineResourceName); worker.ExposeImage(imageResourceName); worker.ExposeAtlas(atlasResourceName); } diff --git a/Extensions/Spine/SpineObjectConfiguration.h b/Extensions/Spine/SpineObjectConfiguration.h index 183784245f83..a6728b87b43a 100644 --- a/Extensions/Spine/SpineObjectConfiguration.h +++ b/Extensions/Spine/SpineObjectConfiguration.h @@ -156,7 +156,7 @@ class GD_EXTENSION_API SpineObjectConfiguration : public gd::ObjectConfiguration double opacity; double timeScale; - gd::String jsonResourceName; + gd::String spineResourceName; gd::String imageResourceName; gd::String atlasResourceName; diff --git a/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts similarity index 87% rename from GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts rename to Extensions/Spine/managers/pixi-spine-atlas-manager.ts index 4034f0d8dfcb..acedf4d58b08 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-atlas-manager.ts +++ b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts @@ -5,12 +5,12 @@ */ namespace gdjs { const logger = new gdjs.Logger('Atlas Manager'); - type AtlasManagerOnProgressCallback = ( + type SpineAtlasManagerOnProgressCallback = ( loadedCount: integer, totalCount: integer ) => void; /** The callback called when a text that was requested is loaded (or an error occurred). */ - export type AtlasManagerRequestCallback = ( + export type SpineAtlasManagerRequestCallback = ( error: Error | null, content?: pixi_spine.TextureAtlas ) => void; @@ -27,10 +27,12 @@ namespace gdjs { * You should properly handle errors, and give the developer/player a way to know * that loading failed. */ - export class AtlasManager { + export class SpineAtlasManager { private _resourcesLoader: RuntimeGameResourcesLoader; private _resources: ResourceData[]; - private _loadedAtlases: { [key: string]: pixi_spine.TextureAtlas } = {}; + private _loadedSpineAtlases: { + [key: string]: pixi_spine.TextureAtlas; + } = {}; /** * @param resources The resources data of the game. @@ -55,7 +57,7 @@ namespace gdjs { } /** - * Request all the text resources to be preloaded (unless they are marked as not preloaded). + * Request all the atlas resources to be preloaded (unless they are marked as not preloaded). * * Note that even if a atlas is already loaded, it will be reloaded (useful for hot-reloading, * as atlas files can have been modified without the editor knowing). @@ -64,7 +66,7 @@ namespace gdjs { * @param onComplete The function called when all atlases are loaded. */ async preloadAll( - onProgress: AtlasManagerOnProgressCallback + onProgress: SpineAtlasManagerOnProgressCallback ): Promise { const atlasResources = this._resources.filter( (resource) => isAtlasResource(resource) && !resource.disablePreload @@ -75,7 +77,7 @@ namespace gdjs { atlasResources.map( (resource, i) => new Promise((resolve) => { - const onLoad: AtlasManagerRequestCallback = (error) => { + const onLoad: SpineAtlasManagerRequestCallback = (error) => { if (error) { logger.error( 'Error while preloading a text resource:' + error @@ -99,7 +101,10 @@ namespace gdjs { * @param resources The data of resource to load. * @param callback The callback to pass atlas to it once it is loaded. */ - load(resource: ResourceData, callback: AtlasManagerRequestCallback): void { + load( + resource: ResourceData, + callback: SpineAtlasManagerRequestCallback + ): void { if (!isAtlasResource(resource)) callback(new Error(`${resource.name} is on atlas!`)); @@ -110,7 +115,7 @@ namespace gdjs { const image = this._imageManager.getPIXITexture(metadata.image); const onLoad = (atlas: pixi_spine.TextureAtlas) => { - this._loadedAtlases[resource.name] = atlas; + this._loadedSpineAtlases[resource.name] = atlas; callback(null, atlas); }; @@ -144,7 +149,7 @@ namespace gdjs { * @returns true if the content of the atlas resource is loaded, false otherwise. */ isLoaded(resourceName: string): boolean { - return resourceName in this._loadedAtlases; + return resourceName in this._loadedSpineAtlases; } /** @@ -154,7 +159,7 @@ namespace gdjs { * @returns the TextureAtlas of the atlas if loaded, `null` otherwise. */ getAtlasTexture(resourceName: string): pixi_spine.TextureAtlas | null { - return this._loadedAtlases[resourceName] || null; + return this._loadedSpineAtlases[resourceName] || null; } } } diff --git a/Extensions/Spine/managers/pixi-spine-manager.ts b/Extensions/Spine/managers/pixi-spine-manager.ts new file mode 100644 index 000000000000..2415135653ae --- /dev/null +++ b/Extensions/Spine/managers/pixi-spine-manager.ts @@ -0,0 +1,135 @@ +/* + * GDevelop JS Platform + * Copyright 2013-present Florian Rival (Florian.Rival@gmail.com). All rights reserved. + * This project is released under the MIT License. + */ +namespace gdjs { + const logger = new gdjs.Logger('Spine Manager'); + + /** + * SpineManager manages pixi spine skeleton data. + */ + export class SpineManager { + private _resourcesLoader: RuntimeGameResourcesLoader; + private _resources: Map; + private _spineData: { [key: string]: pixi_spine.ISkeletonData } = {}; + private _spineAtlasManager: SpineAtlasManager; + + /** + * @param resourceDataArray The resources data of the game. + * @param resourcesLoader The resources loader of the game. + */ + constructor( + resourceDataArray: ResourceData[], + resourcesLoader: RuntimeGameResourcesLoader, + spineAtlasManager: SpineAtlasManager + ) { + this._resources = new Map(); + this.setResources(resourceDataArray); + this._resourcesLoader = resourcesLoader; + this._spineAtlasManager = spineAtlasManager; + } + + /** + * Update the resources data of the game. Useful for hot-reloading, should not be used otherwise. + * + * @param resourceDataArray The resources data of the game. + */ + setResources(resourceDataArray: ResourceData[]): void { + this._resources.clear(); + for (const resourceData of resourceDataArray) { + if (resourceData.kind === 'spine') { + this._resources.set(resourceData.name, resourceData); + } + } + } + + /** + * Request all the json resources to be preloaded (unless they are marked as not preloaded). + * + * Note that even if a JSON is already loaded, it will be reloaded (useful for hot-reloading, + * as JSON files can have been modified without the editor knowing). + * + * @param onProgress The function called after each json is loaded. + * @returns the promise of loaded jsons count. + */ + async preloadAll( + onProgress: (loadingCount: integer, totalCount: integer) => void + ): Promise { + let loadedNumber = 0; + const getPreferences = (file: string) => + ({ + preferWorkers: false, + crossOrigin: this._resourcesLoader.checkIfCredentialsRequired(file) + ? 'use-credentials' + : 'anonymous', + } as Partial); + const jsonPromises = Array.from( + this._resources.values(), + async (resource) => { + try { + const metadata = resource.metadata + ? JSON.parse(resource.metadata) + : {}; + const atlasInDependencies = + !!metadata.atlas && + this._spineAtlasManager.isLoaded(metadata.atlas); + + PIXI.Assets.setPreferences(getPreferences(resource.file)); + PIXI.Assets.add( + resource.name, + resource.file, + atlasInDependencies + ? { + spineAtlas: this._spineAtlasManager.getAtlasTexture( + metadata.atlas + ), + } + : undefined + ); + const loadedJson = await PIXI.Assets.load(resource.name); + + if (loadedJson.spineData) { + this._spineData[resource.name] = loadedJson.spineData; + } else { + logger.error( + `Loader cannot process spine resource ${resource.name} correctly.` + ); + } + } catch (error) { + logger.error( + `Error while preloading spine resource ${resource.name}:`, + error + ); + } + + onProgress(loadedNumber++, this._resources.size); + } + ); + + await Promise.all(jsonPromises); + + return loadedNumber; + } + + /** + * Get the object for the given resource that is already loaded (preloaded or loaded with `loadJson`). + * If the resource is not loaded, `null` will be returned. + * + * @param resourceName The name of the spine skeleton. + * @returns the spine skeleton if loaded, `null` otherwise. + */ + getSpine(resourceName: string): pixi_spine.ISkeletonData { + return this._spineData[resourceName] || null; + } + + /** + * Check if the given spine skeleton was loaded. + * @param resourceName The name of the spine skeleton. + * @returns true if the content of the spine skeleton is loaded, false otherwise. + */ + isSpineLoaded(resourceName: string): boolean { + return !!this._spineData[resourceName]; + } + } +} diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index 9e4e2c20582e..75550b6217db 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -133,14 +133,18 @@ namespace gdjs { private constructRendererObject(): pixi_spine.Spine | PIXI.Container { const game = this.instanceContainer.getGame(); - const spineData = game - .getSpineManager() - .getSpine(this._object.jsonResourceName); - const rendererObject = spineData - ? new pixi_spine.Spine(spineData) - : new PIXI.Container(); - - return rendererObject; + const spineManager = game.getSpineManager(); + + if ( + !spineManager || + !spineManager.isSpineLoaded(this._object.spineResourceName) + ) { + return new PIXI.Container(); + } + + return new pixi_spine.Spine( + spineManager.getSpine(this._object.spineResourceName) + ); } private updateBounds(): void { diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 207fdc33133d..0fb0574b0a50 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -6,7 +6,7 @@ namespace gdjs { opacity: float; scale: float; timeScale: float; - jsonResourceName: string; + spineResourceName: string; atlasResourceName: string; imageResourceName: string; animations: SpineAnimation[]; @@ -22,7 +22,7 @@ namespace gdjs { private _currentAnimationIndex = 0; private _renderer: gdjs.SpineRuntimeObjectPixiRenderer; - readonly jsonResourceName: string; + readonly spineResourceName: string; readonly atlasResourceName: string; readonly imageResourceName: string; @@ -40,7 +40,7 @@ namespace gdjs { this._timeScale = objectData.content.timeScale; this._opacity = objectData.content.opacity; this._scale = objectData.content.scale; - this.jsonResourceName = objectData.content.jsonResourceName; + this.spineResourceName = objectData.content.spineResourceName; this.atlasResourceName = objectData.content.atlasResourceName; this.imageResourceName = objectData.content.imageResourceName; this._renderer = new gdjs.SpineRuntimeObjectRenderer( diff --git a/GDJS/.gitignore b/GDJS/.gitignore index b238e714d3d4..30bc1627986a 100644 --- a/GDJS/.gitignore +++ b/GDJS/.gitignore @@ -1,2 +1 @@ -/node_modules -Runtime/pixi-renderers/pixi-spine.js \ No newline at end of file +/node_modules \ No newline at end of file diff --git a/GDJS/GDJS/IDE/ExporterHelper.cpp b/GDJS/GDJS/IDE/ExporterHelper.cpp index 43d4875499c6..5b1bc6aaf7f4 100644 --- a/GDJS/GDJS/IDE/ExporterHelper.cpp +++ b/GDJS/GDJS/IDE/ExporterHelper.cpp @@ -619,6 +619,7 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers, InsertUnique(includesFiles, "libs/rbush.js"); InsertUnique(includesFiles, "AsyncTasksManager.js"); InsertUnique(includesFiles, "inputmanager.js"); + InsertUnique(includesFiles, "jsonmanager.js"); InsertUnique(includesFiles, "Model3DManager.js"); InsertUnique(includesFiles, "timemanager.js"); InsertUnique(includesFiles, "polygon.js"); @@ -687,15 +688,11 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers, } if (pixiRenderers) { InsertUnique(includesFiles, "pixi-renderers/pixi.js"); - InsertUnique(includesFiles, "pixi-renderers/pixi-spine.js"); InsertUnique(includesFiles, "pixi-renderers/pixi-filters-tools.js"); InsertUnique(includesFiles, "pixi-renderers/runtimegame-pixi-renderer.js"); InsertUnique(includesFiles, "pixi-renderers/runtimescene-pixi-renderer.js"); InsertUnique(includesFiles, "pixi-renderers/layer-pixi-renderer.js"); InsertUnique(includesFiles, "pixi-renderers/pixi-image-manager.js"); - InsertUnique(includesFiles, "pixi-renderers/pixi-spine-manager.js"); - InsertUnique(includesFiles, "pixi-renderers/pixi-json-manager.js"); - InsertUnique(includesFiles, "pixi-renderers/pixi-atlas-manager.js"); InsertUnique(includesFiles, "pixi-renderers/pixi-bitmapfont-manager.js"); InsertUnique(includesFiles, "pixi-renderers/spriteruntimeobject-pixi-renderer.js"); diff --git a/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts b/GDJS/Runtime/jsonmanager.ts similarity index 61% rename from GDJS/Runtime/pixi-renderers/pixi-json-manager.ts rename to GDJS/Runtime/jsonmanager.ts index aff68a32c4bc..f388306fb43a 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-json-manager.ts +++ b/GDJS/Runtime/jsonmanager.ts @@ -4,16 +4,14 @@ * This project is released under the MIT License. */ namespace gdjs { - const logger = new gdjs.Logger('Json Manager'); - + const logger = new gdjs.Logger('JSON Manager'); /** The callback called when a json that was requested is loaded (or an error occurred). */ export type JsonManagerRequestCallback = ( error: Error | null, content: Object | null ) => void; - /** - * JsonManager loads json files with pixi loader, using the "json" resources + * JsonManager loads json files (using `XMLHttpRequest`), using the "json" resources * registered in the game resources. * * Contrary to audio/fonts, json files are loaded asynchronously, when requested. @@ -21,32 +19,22 @@ namespace gdjs { * that loading failed. */ export class JsonManager { - private _resourcesLoader: RuntimeGameResourcesLoader; - private _resources: Map; - private _loadedJsons: { [key: string]: Object } = {}; - private _callbacks: { - [key: string]: Array; - } = {}; - private _spineManager: SpineManager; - private _atlasManager: AtlasManager; - + _resourcesLoader: RuntimeGameResourcesLoader; + _resources: Map; + _loadedJsons: { [key: string]: Object } = {}; + _callbacks: { [key: string]: Array } = {}; /** * @param resourceDataArray The resources data of the game. * @param resourcesLoader The resources loader of the game. */ constructor( resourceDataArray: ResourceData[], - resourcesLoader: RuntimeGameResourcesLoader, - spineManager: SpineManager, - atlasManager: AtlasManager + resourcesLoader: RuntimeGameResourcesLoader ) { this._resources = new Map(); this.setResources(resourceDataArray); this._resourcesLoader = resourcesLoader; - this._spineManager = spineManager; - this._atlasManager = atlasManager; } - /** * Update the resources data of the game. Useful for hot-reloading, should not be used otherwise. * @@ -64,7 +52,6 @@ namespace gdjs { } } } - /** * Request all the json resources to be preloaded (unless they are marked as not preloaded). * @@ -72,81 +59,34 @@ namespace gdjs { * as JSON files can have been modified without the editor knowing). * * @param onProgress The function called after each json is loaded. - * @returns the promise of loaded jsons count. */ - async preloadAll( - onProgress: (loadingCount: integer, totalCount: integer) => void + async preloadJsons( + onProgress: (loadedCount: integer, totalCount: integer) => void ): Promise { - let loadedNumber = 0; - const getPreferences = (file: string) => - ({ - preferWorkers: false, - crossOrigin: this._resourcesLoader.checkIfCredentialsRequired(file) - ? 'use-credentials' - : 'anonymous', - } as Partial); - const jsonPromises = Array.from( - this._resources.values(), - async (resource) => { + const preloadedResources = [...this._resources.values()].filter( + (resource) => !resource.disablePreload + ); + let loadedCount = 0; + await Promise.all( + preloadedResources.map(async (resource) => { try { - if (resource.kind === 'json') { - const metadata = resource.metadata - ? JSON.parse(resource.metadata) - : {}; - const atlasInDependencies = - !!metadata.atlas && this._atlasManager.isLoaded(metadata.atlas); - - PIXI.Assets.setPreferences(getPreferences(resource.file)); - PIXI.Assets.add( - resource.name, - resource.file, - atlasInDependencies - ? { - spineAtlas: this._atlasManager.getAtlasTexture( - metadata.atlas - ), - } - : undefined - ); - const loadedJson = await PIXI.Assets.load(resource.name); - - if (loadedJson.spineData) { - this._spineManager.setSpine( - resource.name, - loadedJson.spineData - ); - } else { - this._loadedJsons[resource.name] = loadedJson; - } - } else { - await this.loadJsonAsync(resource.name); - } + await this.loadJsonAsync(resource.name); } catch (error) { logger.error( `Error while preloading json resource ${resource.name}:`, error ); } - - onProgress(loadedNumber++, this._resources.size); - } + loadedCount++; + onProgress(loadedCount, this._resources.size); + }) ); - - await Promise.all(jsonPromises); - - return loadedNumber; + return loadedCount; } - - /** - * Request the json file from the given resource name. - * - * @param resourceName The resource pointing to the json file to load. - * @returns the promise of loaded json or promise of null if loading is failed. - */ loadJsonAsync(resourceName: string): Promise { const that = this; return new Promise((resolve, reject) => { - that.load(resourceName, (error, content) => { + that.loadJson(resourceName, (error, content) => { if (error) { reject(error.message); } @@ -154,7 +94,6 @@ namespace gdjs { }); }); } - /** * Request the json file from the given resource name. * This method is asynchronous. When loaded, the `callback` is called with the error @@ -163,31 +102,34 @@ namespace gdjs { * @param resourceName The resource pointing to the json file to load. * @param callback The callback function called when json is loaded (or an error occurred). */ - load(resourceName: string, callback: JsonManagerRequestCallback): void { + loadJson(resourceName: string, callback: JsonManagerRequestCallback): void { const resource = this._resources.get(resourceName); if (!resource) { - return callback( + callback( new Error( - `Can't find resource with name: "${resourceName}" (or is not a json resource).` + 'Can\'t find resource with name: "' + + resourceName + + '" (or is not a json resource).' ), null ); + return; } - // Don't fetch again an object that is already in memory if (this._loadedJsons[resourceName]) { - return callback(null, this._loadedJsons[resourceName]); + callback(null, this._loadedJsons[resourceName]); + return; } - // Don't fetch again an object that is already being fetched. - const resourceCallbacks = this._callbacks[resourceName]; - if (resourceCallbacks) { - resourceCallbacks.push(callback); - return; - } else { - this._callbacks[resourceName] = [callback]; + { + const callbacks = this._callbacks[resourceName]; + if (callbacks) { + callbacks.push(callback); + return; + } else { + this._callbacks[resourceName] = [callback]; + } } - const that = this; const xhr = new XMLHttpRequest(); xhr.responseType = 'json'; @@ -197,8 +139,9 @@ namespace gdjs { xhr.open('GET', this._resourcesLoader.getFullUrl(resource.file)); xhr.onload = function () { const callbacks = that._callbacks[resourceName]; - - if (!callbacks) return; + if (!callbacks) { + return; + } if (xhr.status !== 200) { for (const callback of callbacks) { callback( @@ -211,7 +154,6 @@ namespace gdjs { delete that._callbacks[resourceName]; return; } - // Cache the result that._loadedJsons[resourceName] = xhr.response; for (const callback of callbacks) { @@ -241,22 +183,20 @@ namespace gdjs { }; xhr.send(); } - /** * Check if the given json resource was loaded (preloaded or loaded with `loadJson`). * @param resourceName The name of the json resource. - * @returns true if the content of the json resource is loaded, false otherwise. + * @returns true if the content of the json resource is loaded. false otherwise. */ isJsonLoaded(resourceName: string): boolean { return !!this._loadedJsons[resourceName]; } - /** * Get the object for the given resource that is already loaded (preloaded or loaded with `loadJson`). * If the resource is not loaded, `null` will be returned. * * @param resourceName The name of the json resource. - * @returns the content of the json resource if loaded, `null` otherwise. + * @returns the content of the json resource, if loaded. `null` otherwise. */ getLoadedJson(resourceName: string): Object | null { return this._loadedJsons[resourceName] || null; diff --git a/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts deleted file mode 100644 index 89d49333aaf9..000000000000 --- a/GDJS/Runtime/pixi-renderers/pixi-spine-manager.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * GDevelop JS Platform - * Copyright 2013-present Florian Rival (Florian.Rival@gmail.com). All rights reserved. - * This project is released under the MIT License. - */ -namespace gdjs { - const logger = new gdjs.Logger('Spine Manager'); - - /** - * SpineManager manages pixi spine skeleton data. - * - * It doesn`t load data by itself but it is designed to store data that was loaded by some other managers. - * E.g. spine skeleton can be loaded in JsonManager as we don`t know real meaning of json file. - */ - export class SpineManager { - _spineData: { [key: string]: pixi_spine.ISkeletonData } = {}; - - setSpine(resourceName: string, spineData: pixi_spine.ISkeletonData) { - this._spineData[resourceName] = spineData; - } - - /** - * Get the object for the given resource that is already loaded (preloaded or loaded with `loadJson`). - * If the resource is not loaded, `null` will be returned. - * - * @param resourceName The name of the spine skeleton. - * @returns the spine skeleton if loaded, `null` otherwise. - */ - getSpine(resourceName: string): pixi_spine.ISkeletonData { - return this._spineData[resourceName] || null; - } - - /** - * Check if the given spine skeleton was loaded. - * @param resourceName The name of the spine skeleton. - * @returns true if the content of the spine skeleton is loaded, false otherwise. - */ - isSpineLoaded(resourceName: string): boolean { - return !!this._spineData[resourceName]; - } - } -} diff --git a/GDJS/Runtime/runtimegame.ts b/GDJS/Runtime/runtimegame.ts index 094e3154c6d1..102b19563f69 100644 --- a/GDJS/Runtime/runtimegame.ts +++ b/GDJS/Runtime/runtimegame.ts @@ -140,8 +140,8 @@ namespace gdjs { _soundManager: SoundManager; _fontManager: FontManager; _jsonManager: JsonManager; - _spineManager: SpineManager; - _atlasManager: AtlasManager; + _spineManager: SpineManager | null = null; + _spineAtlasManager: SpineAtlasManager | null = null; _model3DManager: Model3DManager; _effectsManager: EffectsManager; _bitmapFontManager: BitmapFontManager; @@ -227,17 +227,9 @@ namespace gdjs { resources, this._resourcesLoader ); - this._spineManager = new gdjs.SpineManager(); - this._atlasManager = new gdjs.AtlasManager( - this._data.resources.resources, - this._resourcesLoader, - this._imageManager - ); this._jsonManager = new gdjs.JsonManager( resources, - this._resourcesLoader, - this._spineManager, - this._atlasManager + this._resourcesLoader ); this._bitmapFontManager = new gdjs.BitmapFontManager( resources, @@ -248,6 +240,20 @@ namespace gdjs { resources, this._resourcesLoader ); + + if (pixi_spine) { + this._spineAtlasManager = new gdjs.SpineAtlasManager( + this._data.resources.resources, + this._resourcesLoader, + this._imageManager + ); + this._spineManager = new gdjs.SpineManager( + resources, + this._resourcesLoader, + this._spineAtlasManager + ); + } + this._effectsManager = new gdjs.EffectsManager(); this._maxFPS = this._data.properties.maxFPS; this._minFPS = this._data.properties.minFPS; @@ -324,18 +330,24 @@ namespace gdjs { * @param projectData The object (usually stored in data.json) containing the full project data */ setProjectData(projectData: ProjectData): void { - const { resources } = projectData.resources; - this._data = projectData; - [ + + const { resources } = projectData.resources; + const managers: { + setResources: InstanceType['setResources']; + }[] = [ this._imageManager, this._soundManager, this._fontManager, this._jsonManager, - this._atlasManager, this._bitmapFontManager, this._model3DManager, - ].forEach((manager) => manager.setResources(resources)); + ]; + + if (this._spineAtlasManager) managers.push(this._spineAtlasManager); + if (this._spineManager) managers.push(this._spineManager); + + managers.forEach((manager) => manager.setResources(resources)); } /** @@ -409,7 +421,12 @@ namespace gdjs { return this._jsonManager; } - getSpineManager(): gdjs.SpineManager { + /** + * Get the spine manager of the game, used to load and construct spine skeletons from game + * resources. + * @return The json manager for the game + */ + getSpineManager(): gdjs.SpineManager | null { return this._spineManager; } @@ -418,8 +435,8 @@ namespace gdjs { * resources. * @return The atlas manager for the game */ - getAtlasManager(): gdjs.AtlasManager { - return this._atlasManager; + getSpineAtlasManager(): gdjs.SpineAtlasManager | null { + return this._spineAtlasManager; } /** @@ -746,9 +763,16 @@ namespace gdjs { loadedAssets += await this._imageManager.loadTextures(onProgress); loadedAssets += await this._soundManager.preloadAudio(onProgress); loadedAssets += await this._fontManager.loadFonts(onProgress); - loadedAssets += await this._atlasManager.preloadAll(onProgress); - loadedAssets += await this._jsonManager.preloadAll(onProgress); + loadedAssets += await this._jsonManager.preloadJsons(onProgress); loadedAssets += await this._model3DManager.loadModels(onProgress); + + if (this._spineAtlasManager) { + loadedAssets += await this._spineAtlasManager.preloadAll(onProgress); + } + if (this._spineManager) { + loadedAssets += await this._spineManager.preloadAll(onProgress); + } + await this._bitmapFontManager.loadBitmapFontData(onProgress); await loadingScreen.unload(); await gdjs.getAllAsynchronouslyLoadingLibraryPromise(); diff --git a/GDJS/Runtime/types/project-data.d.ts b/GDJS/Runtime/types/project-data.d.ts index e2a4dc4d16cc..dd8b1f77cb64 100644 --- a/GDJS/Runtime/types/project-data.d.ts +++ b/GDJS/Runtime/types/project-data.d.ts @@ -274,4 +274,5 @@ declare type ResourceKind = | 'tileset' | 'bitmapFont' | 'model3D' - | 'atlas'; + | 'atlas' + | 'spine'; diff --git a/GDJS/scripts/install-spine.js b/GDJS/scripts/install-spine.js index 8025c3608a91..0c33c5e4966f 100644 --- a/GDJS/scripts/install-spine.js +++ b/GDJS/scripts/install-spine.js @@ -22,6 +22,6 @@ const originalSpinePackage = JSON.parse(readContent(path.join(originalSpineDir, const originalSpineContent = readContent(path.join(originalSpineDir, originalSpinePackage.extensionConfig.bundle), 'Cannot find pixi-spine bundle.'); const varSpineExport = '\nvar pixi_spine = this.PIXI.spine;\n'; -const runtimeSpinePath = 'Runtime/pixi-renderers/pixi-spine.js'; +const runtimeSpinePath = '../Extensions/Spine/pixi-spine/pixi-spine.js'; new shell.ShellString(originalSpineContent + varSpineExport).to(runtimeSpinePath); diff --git a/GDevelop.js/Bindings/Bindings.idl b/GDevelop.js/Bindings/Bindings.idl index feb42bb065d2..3647e656be90 100644 --- a/GDevelop.js/Bindings/Bindings.idl +++ b/GDevelop.js/Bindings/Bindings.idl @@ -1117,6 +1117,11 @@ interface JsonResource { }; JsonResource implements Resource; +interface SpineResource { + void SpineResource(); +}; +SpineResource implements JsonResource; + interface TilemapResource { void TilemapResource(); }; diff --git a/GDevelop.js/Bindings/ObjectJsImplementation.cpp b/GDevelop.js/Bindings/ObjectJsImplementation.cpp index 04711e80df25..fd5c1b90282a 100644 --- a/GDevelop.js/Bindings/ObjectJsImplementation.cpp +++ b/GDevelop.js/Bindings/ObjectJsImplementation.cpp @@ -197,6 +197,8 @@ void ObjectJsImplementation::ExposeResources(gd::ArbitraryResourceWorker& worker worker.ExposeModel3D(newPropertyValue); } else if (resourceType == "atlas") { worker.ExposeAtlas(newPropertyValue); + } else if (resourceType == "spine") { + worker.ExposeSpine(newPropertyValue); } if (newPropertyValue != oldPropertyValue) { diff --git a/GDevelop.js/scripts/copy-to-newIDE.js b/GDevelop.js/scripts/copy-to-newIDE.js index 1bf5e080fb60..1a4038678958 100644 --- a/GDevelop.js/scripts/copy-to-newIDE.js +++ b/GDevelop.js/scripts/copy-to-newIDE.js @@ -1,5 +1,4 @@ const shell = require('shelljs'); -const fs = require('fs'); const path = require('path'); const sourcePath = path.join(__dirname, '../../Binaries/embuild/GDevelop.js'); diff --git a/GDevelop.js/scripts/generate-types.js b/GDevelop.js/scripts/generate-types.js index a1a75958508e..f452bba9a612 100644 --- a/GDevelop.js/scripts/generate-types.js +++ b/GDevelop.js/scripts/generate-types.js @@ -339,13 +339,13 @@ type ParticleEmitterObject_RendererType = 0 | 1 | 2` shell.sed( '-i', /setKind\(kind: string\): void/, - "setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas'): void", + "setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas' | 'spine'): void", 'types/gdresource.js' ); shell.sed( '-i', /getKind\(\): string/, - "getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas'", + "getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas' | 'spine'", 'types/gdresource.js' ); diff --git a/GDevelop.js/types/gdresource.js b/GDevelop.js/types/gdresource.js index bb3bda31d152..e522807fea10 100644 --- a/GDevelop.js/types/gdresource.js +++ b/GDevelop.js/types/gdresource.js @@ -4,8 +4,8 @@ declare class gdResource { clone(): gdResource; setName(name: string): void; getName(): string; - setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas'): void; - getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas'; + setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas' | 'spine'): void; + getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset' | 'model3D' | 'atlas' | 'spine'; isUserAdded(): boolean; setUserAdded(yes: boolean): void; useFile(): boolean; diff --git a/GDevelop.js/types/gdspineresource.js b/GDevelop.js/types/gdspineresource.js new file mode 100644 index 000000000000..8105cf59f83e --- /dev/null +++ b/GDevelop.js/types/gdspineresource.js @@ -0,0 +1,6 @@ +// Automatically generated by GDevelop.js/scripts/generate-types.js +declare class gdSpineResource extends gdJsonResource { + constructor(): void; + delete(): void; + ptr: number; +}; \ No newline at end of file diff --git a/GDevelop.js/types/libgdevelop.js b/GDevelop.js/types/libgdevelop.js index e2e44694eec5..fdb603248d00 100644 --- a/GDevelop.js/types/libgdevelop.js +++ b/GDevelop.js/types/libgdevelop.js @@ -110,6 +110,7 @@ declare class libGDevelop { BitmapFontResource: Class; VideoResource: Class; JsonResource: Class; + SpineResource: Class; TilemapResource: Class; TilesetResource: Class; Model3DResource: Class; diff --git a/newIDE/app/src/AssetStore/InstallAsset.js b/newIDE/app/src/AssetStore/InstallAsset.js index 5858a0e98596..9ea2c227db57 100644 --- a/newIDE/app/src/AssetStore/InstallAsset.js +++ b/newIDE/app/src/AssetStore/InstallAsset.js @@ -123,6 +123,8 @@ export const installResource = ( newResource = new gd.Model3DResource(); } else if (serializedResource.kind === 'atlas') { newResource = new gd.AtlasResource(); + } else if (serializedResource.kind === 'spine') { + newResource = new gd.SpineResource(); } else { throw new Error( `Resource of kind "${serializedResource.kind}" is not supported.` diff --git a/newIDE/app/src/AssetStore/ResourceStore/ResourceCard.js b/newIDE/app/src/AssetStore/ResourceStore/ResourceCard.js index fa03afa345e3..c01cb981c595 100644 --- a/newIDE/app/src/AssetStore/ResourceStore/ResourceCard.js +++ b/newIDE/app/src/AssetStore/ResourceStore/ResourceCard.js @@ -178,6 +178,7 @@ export const ResourceCard = ({ resource, onChoose, size }: Props) => { case 'json': case 'tilemap': case 'tileset': + case 'spine': return ( diff --git a/newIDE/app/src/EventsSheet/ParameterFields/SpineResourceField.js b/newIDE/app/src/EventsSheet/ParameterFields/SpineResourceField.js new file mode 100644 index 000000000000..d50a335ac837 --- /dev/null +++ b/newIDE/app/src/EventsSheet/ParameterFields/SpineResourceField.js @@ -0,0 +1,48 @@ +// @flow +import * as React from 'react'; +import { Trans } from '@lingui/macro'; +import ResourceSelector, { + type ResourceSelectorInterface, +} from '../../ResourcesList/ResourceSelector'; +import ResourcesLoader from '../../ResourcesLoader'; +import { + type ParameterFieldProps, + type ParameterFieldInterface, + type FieldFocusFunction, +} from './ParameterFieldCommons'; + +export default React.forwardRef( + function SpineResourceField(props, ref) { + const field = React.useRef(null); + const focus: FieldFocusFunction = options => { + if (field.current) field.current.focus(options); + }; + React.useImperativeHandle(ref, () => ({ + focus, + })); + + if (!props.resourceManagementProps || !props.project) { + console.error( + 'Missing project or resourceManagementProps for SpineResourceField' + ); + return null; + } + + return ( + Choose the spine json file to use} + onRequestClose={props.onRequestClose} + onApply={props.onApply} + ref={field} + /> + ); + } +); diff --git a/newIDE/app/src/EventsSheet/ParameterRenderingService.js b/newIDE/app/src/EventsSheet/ParameterRenderingService.js index b5c6db75c119..6d4d390d5f72 100644 --- a/newIDE/app/src/EventsSheet/ParameterRenderingService.js +++ b/newIDE/app/src/EventsSheet/ParameterRenderingService.js @@ -41,6 +41,7 @@ import ImageResourceField from './ParameterFields/ImageResourceField'; import AudioResourceField from './ParameterFields/AudioResourceField'; import VideoResourceField from './ParameterFields/VideoResourceField'; import JsonResourceField from './ParameterFields/JsonResourceField'; +import SpineResourceField from './ParameterFields/SpineResourceField'; import BitmapFontResourceField from './ParameterFields/BitmapFontResourceField'; import FontResourceField from './ParameterFields/FontResourceField'; import ColorExpressionField from './ParameterFields/ColorExpressionField'; @@ -96,6 +97,7 @@ const components = { fontResource: FontResourceField, model3DResource: Model3DResourceField, atlasResource: AtlasResourceField, + spineResource: SpineResourceField, color: ColorExpressionField, police: DefaultField, //TODO forceMultiplier: ForceMultiplierField, @@ -154,6 +156,7 @@ const userFriendlyTypeName: { [string]: MessageDescriptor } = { jsonResource: t`JSON resource`, tilemapResource: t`Tile map resource`, atlasResource: t`Atlas resource`, + spineResource: t`Spine json resource`, color: t`Color`, forceMultiplier: t`Instant or permanent force`, sceneName: t`Scene name`, diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 5f4d067e2938..76b030dd44e3 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -115,12 +115,12 @@ const SpineEditor = ({ const [skeleton, setSkeleton] = React.useState(null); const getSkeleton = React.useCallback( ( - jsonResourceName: string, + spineResourceName: string, imageResourceName: string, atlasResourceName: string ) => { if ( - [jsonResourceName, imageResourceName, atlasResourceName].some( + [spineResourceName, imageResourceName, atlasResourceName].some( resName => !resName ) ) { @@ -129,7 +129,7 @@ const SpineEditor = ({ return PixiResourcesLoader.getSpineData( project, - jsonResourceName, + spineResourceName, imageResourceName, atlasResourceName ).then(newSkeleton => { @@ -141,21 +141,21 @@ const SpineEditor = ({ [project] ); getSkeleton( - properties.get('jsonResourceName').getValue(), + properties.get('spineResourceName').getValue(), properties.get('imageResourceName').getValue(), properties.get('atlasResourceName').getValue() ); - const onChangeJsonResourceName = React.useCallback( - (jsonResourceName: string) => { + const onChangeSpineResourceName = React.useCallback( + (spineResourceName: string) => { const atlasResourceName = properties.get('atlasResourceName').getValue(); if (atlasResourceName) { - extendMetadata(jsonResourceName, { atlas: atlasResourceName }); + extendMetadata(spineResourceName, { atlas: atlasResourceName }); } getSkeleton( - jsonResourceName, + spineResourceName, properties.get('imageResourceName').getValue(), atlasResourceName ).then(newSkeleton => { @@ -166,18 +166,18 @@ const SpineEditor = ({ ); const onChangeAtlasResourceName = React.useCallback( (atlasResourceName: string) => { - const jsonResourceName = properties.get('jsonResourceName').getValue(); + const spineResourceName = properties.get('spineResourceName').getValue(); const imageResourceName = properties.get('imageResourceName').getValue(); - if (jsonResourceName) { - extendMetadata(jsonResourceName, { atlas: atlasResourceName }); + if (spineResourceName) { + extendMetadata(spineResourceName, { atlas: atlasResourceName }); } if (imageResourceName) { extendMetadata(atlasResourceName, { image: imageResourceName }); } getSkeleton( - properties.get('jsonResourceName').getValue(), + properties.get('spineResourceName').getValue(), imageResourceName, atlasResourceName ).then(newSkeleton => { @@ -195,7 +195,7 @@ const SpineEditor = ({ } getSkeleton( - properties.get('jsonResourceName').getValue(), + properties.get('spineResourceName').getValue(), imageResourceName, atlasResourceName ).then(newSkeleton => { @@ -385,10 +385,10 @@ const SpineEditor = ({ { const resourceManager = project.getResourcesManager(); const resourcesData = [ - [spineName, 'json'], + [spineName, 'spine'], [atlasImageName, 'image'], [atlasTextName, 'atlas'], ]; diff --git a/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.js b/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.js index e6b87c74ec47..e29e64241ae9 100644 --- a/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.js +++ b/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.js @@ -47,6 +47,7 @@ const resourceKindToInputAcceptedMimes = { // 'model/gltf-binary' ], atlas: [], + spine: ['application/json'], }; const getAcceptedExtensions = ( diff --git a/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.spec.js b/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.spec.js index 2dfaf98cba6f..65830a156693 100644 --- a/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.spec.js +++ b/newIDE/app/src/ResourcesList/FileToCloudProjectResourceUploader.spec.js @@ -34,5 +34,8 @@ describe('FileToCloudProjectResourceUploader', () => { expect(getInputAcceptedMimesAndExtensions('atlas')).toMatchInlineSnapshot( `".atlas"` ); + expect(getInputAcceptedMimesAndExtensions('spine')).toMatchInlineSnapshot( + `"application/json,.json"` + ); }); }); diff --git a/newIDE/app/src/ResourcesList/ResourcePreview/index.js b/newIDE/app/src/ResourcesList/ResourcePreview/index.js index 008e887a4b38..526b18fff03e 100644 --- a/newIDE/app/src/ResourcesList/ResourcePreview/index.js +++ b/newIDE/app/src/ResourcesList/ResourcePreview/index.js @@ -49,6 +49,7 @@ const ResourcePreview = (props: Props) => { case 'tileset': case 'model3D': case 'atlas': + case 'spine': return } />; case 'video': return + + ( + + )} + /> + ); From 34172bfcff2044c2b3335b292326db30cccf34dd Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Mon, 27 Nov 2023 16:26:32 +0200 Subject: [PATCH 34/80] update install-spine script --- GDJS/scripts/install-spine.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/GDJS/scripts/install-spine.js b/GDJS/scripts/install-spine.js index 0c33c5e4966f..9bc5cdf385db 100644 --- a/GDJS/scripts/install-spine.js +++ b/GDJS/scripts/install-spine.js @@ -22,6 +22,13 @@ const originalSpinePackage = JSON.parse(readContent(path.join(originalSpineDir, const originalSpineContent = readContent(path.join(originalSpineDir, originalSpinePackage.extensionConfig.bundle), 'Cannot find pixi-spine bundle.'); const varSpineExport = '\nvar pixi_spine = this.PIXI.spine;\n'; -const runtimeSpinePath = '../Extensions/Spine/pixi-spine/pixi-spine.js'; +const runtimeSpineDir = '../Extensions/Spine/pixi-spine'; + +if (!shell.test('-d', runtimeSpineDir)) { + shell.echo(`Creating directory for pixi-spine bundle ${runtimeSpineDir}.`); + shell.mkdir(runtimeSpineDir); +} + +const runtimeSpinePath = path.join(runtimeSpineDir, 'pixi-spine.js'); new shell.ShellString(originalSpineContent + varSpineExport).to(runtimeSpinePath); From 4f65ee6c58321631f61b1b2aa7491db96068b0b0 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Mon, 27 Nov 2023 16:53:41 +0200 Subject: [PATCH 35/80] add try/catch block to install-spine --- GDJS/scripts/install-spine.js | 50 ++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/GDJS/scripts/install-spine.js b/GDJS/scripts/install-spine.js index 9bc5cdf385db..25dff10c05ec 100644 --- a/GDJS/scripts/install-spine.js +++ b/GDJS/scripts/install-spine.js @@ -2,33 +2,35 @@ const path = require('path'); const shell = require('shelljs'); const readContent = (path, testErrorMessage) => { - if (!shell.test('-f', path)) { - shell.echo(`❌ ${testErrorMessage} Should exist in ${path} folder.`); - shell.exit(1); - } + if (!shell.test('-f', path)) throw new Error(`${testErrorMessage} Should exist by ${path}.`); const readingResult = shell.cat(path); - if (readingResult.stderr) { - shell.echo(`❌ Error during ${path} reading: ${readingResult.stderr}`); - shell.exit(1); - } + if (readingResult.stderr) throw new Error(readingResult.stderr); return readingResult.toString(); +}; + +try { + shell.echo(`Start pixi-spine.js copying...`); + + const originalSpineDir = path.resolve('node_modules/pixi-spine'); + const originalSpinePackage = JSON.parse(readContent(path.join(originalSpineDir, 'package.json'), 'Cannot find pixi-spine package.json file.')); + const originalSpineContent = readContent(path.join(originalSpineDir, originalSpinePackage.extensionConfig.bundle), 'Cannot find pixi-spine.js.'); + + const varSpineExport = '\nvar pixi_spine = this.PIXI.spine;\n'; + const runtimeSpineDir = '../Extensions/Spine/pixi-spine'; + + if (!shell.test('-d', runtimeSpineDir)) { + shell.echo(`Creating directory for pixi-spine.js ${runtimeSpineDir}.`); + shell.mkdir(runtimeSpineDir); + } + + const runtimeSpinePath = path.join(runtimeSpineDir, 'pixi-spine.js'); + new shell.ShellString(originalSpineContent + varSpineExport).to(runtimeSpinePath); + + shell.echo(`✅ Properly copied pixi-spine.js from node_modules to ${runtimeSpinePath}.`); +} catch(error) { + shell.echo(`❌ Unable to copy pixi-spine.js from node_modules. Error is: ${error}`) + shell.exit(1); } - -const originalSpineDir = path.resolve('node_modules/pixi-spine'); -const originalSpinePackage = JSON.parse(readContent(path.join(originalSpineDir, 'package.json'), 'Cannot find pixi-spine package.json file.')); -const originalSpineContent = readContent(path.join(originalSpineDir, originalSpinePackage.extensionConfig.bundle), 'Cannot find pixi-spine bundle.'); - -const varSpineExport = '\nvar pixi_spine = this.PIXI.spine;\n'; -const runtimeSpineDir = '../Extensions/Spine/pixi-spine'; - -if (!shell.test('-d', runtimeSpineDir)) { - shell.echo(`Creating directory for pixi-spine bundle ${runtimeSpineDir}.`); - shell.mkdir(runtimeSpineDir); -} - -const runtimeSpinePath = path.join(runtimeSpineDir, 'pixi-spine.js'); -new shell.ShellString(originalSpineContent + varSpineExport).to(runtimeSpinePath); - From 7c9fefdf6d963e070f1e196d29029473bf1a1b32 Mon Sep 17 00:00:00 2001 From: Gleb Volkov Date: Mon, 27 Nov 2023 18:29:13 +0100 Subject: [PATCH 36/80] Remove unused logger in SpineAtlasManager --- Extensions/Spine/managers/pixi-spine-atlas-manager.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts index 164d0572fff2..a3e178dd57dd 100644 --- a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts +++ b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts @@ -4,8 +4,6 @@ * This project is released under the MIT License. */ namespace gdjs { - const logger = new gdjs.Logger('Atlas Manager'); - /** The callback called when a text that was requested is loaded (or an error occurred). */ export type SpineAtlasManagerRequestCallback = ( error: Error | null, From 5be090629317938e37210d34496704470885fb2d Mon Sep 17 00:00:00 2001 From: Gleb Volkov Date: Mon, 27 Nov 2023 19:04:05 +0100 Subject: [PATCH 37/80] Add missing `jsonmanger` dependency in tests --- GDJS/tests/karma.conf.js | 1 + 1 file changed, 1 insertion(+) diff --git a/GDJS/tests/karma.conf.js b/GDJS/tests/karma.conf.js index 4102a6bd36fb..dde037c56f6b 100644 --- a/GDJS/tests/karma.conf.js +++ b/GDJS/tests/karma.conf.js @@ -49,6 +49,7 @@ module.exports = function (config) { './newIDE/app/resources/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver.js', './newIDE/app/resources/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js', './newIDE/app/resources/GDJS/Runtime/Model3DManager.js', + './newIDE/app/resources/GDJS/Runtime/jsonmanager.js', './newIDE/app/resources/GDJS/Runtime/ResourceLoader.js', './newIDE/app/resources/GDJS/Runtime/ResourceCache.js', './newIDE/app/resources/GDJS/Runtime/timemanager.js', From 506487d20110d2b5d8172384d0c161b010650f62 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 28 Nov 2023 10:33:04 +0200 Subject: [PATCH 38/80] lock pixi-spine version --- newIDE/app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newIDE/app/package.json b/newIDE/app/package.json index 00762d13fa1d..5259115ba5df 100644 --- a/newIDE/app/package.json +++ b/newIDE/app/package.json @@ -62,7 +62,7 @@ "node-require-function": "^1.2.0", "path-browserify": "^1.0.1", "pixi-simple-gesture": "github:4ian/pixi-simple-gesture#v0.3.3", - "pixi-spine": "^4.0.4", + "pixi-spine": "4.0.4", "pixi.js-legacy": "^7.3.0", "posthog-js": "^1.57.2", "prop-types": "^15.5.10", From d8f580d89e1bb1fa537688a47dcdb8685c66518c Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 28 Nov 2023 10:41:29 +0200 Subject: [PATCH 39/80] remove pixi-simple-gesture dependency --- newIDE/app/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/newIDE/app/package.json b/newIDE/app/package.json index 5259115ba5df..98b0a86eafcc 100644 --- a/newIDE/app/package.json +++ b/newIDE/app/package.json @@ -61,7 +61,6 @@ "lodash": "4.17.4", "node-require-function": "^1.2.0", "path-browserify": "^1.0.1", - "pixi-simple-gesture": "github:4ian/pixi-simple-gesture#v0.3.3", "pixi-spine": "4.0.4", "pixi.js-legacy": "^7.3.0", "posthog-js": "^1.57.2", From 550b35852a8bdf6913ac7ea36b0bfe048b3d6a8f Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 28 Nov 2023 10:42:48 +0200 Subject: [PATCH 40/80] apply format --- .../managers/pixi-spine-atlas-manager.ts | 58 ++- .../Spine/managers/pixi-spine-manager.ts | 32 +- GDJS/Runtime/ResourceLoader.ts | 13 +- GDJS/Runtime/jsonmanager.ts | 362 +++++++++--------- 4 files changed, 245 insertions(+), 220 deletions(-) diff --git a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts index a3e178dd57dd..a18559ba96a6 100644 --- a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts +++ b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts @@ -23,8 +23,12 @@ namespace gdjs { export class SpineAtlasManager implements gdjs.ResourceManager { private _imageManager: ImageManager; private _resourceLoader: ResourceLoader; - private _loadedSpineAtlases = new gdjs.ResourceCache(); - private _loadingSpineAtlases = new gdjs.ResourceCache>(); + private _loadedSpineAtlases = new gdjs.ResourceCache< + pixi_spine.TextureAtlas + >(); + private _loadingSpineAtlases = new gdjs.ResourceCache< + Promise + >(); /** * @param resources The resources data of the game. @@ -59,28 +63,40 @@ namespace gdjs { const resource = this._getAtlasResource(resourceName); if (!resource) { - return Promise.reject(`Unable to find atlas for resource '${resourceName}'.`); + return Promise.reject( + `Unable to find atlas for resource '${resourceName}'.` + ); } if (!this._loadingSpineAtlases.get(resource)) { - this._loadingSpineAtlases.set(resource, new Promise((resolve, reject) => { - const onLoad: SpineAtlasManagerRequestCallback = (error, content) => { - if (error) { - return reject(`Error while preloading a spine atlas resource: ${error}`); - } - if (!content) { - return reject(`Cannot reach texture atlas for resource '${resourceName}'.`); - } - - resolve(content); - }; - - this.load(resource, onLoad); - })); + this._loadingSpineAtlases.set( + resource, + new Promise((resolve, reject) => { + const onLoad: SpineAtlasManagerRequestCallback = ( + error, + content + ) => { + if (error) { + return reject( + `Error while preloading a spine atlas resource: ${error}` + ); + } + if (!content) { + return reject( + `Cannot reach texture atlas for resource '${resourceName}'.` + ); + } + + resolve(content); + }; + + this.load(resource, onLoad); + }) + ); } return this._loadingSpineAtlases.get(resource)!; - } + } /** * Load specified atlas resource and pass it to callback once it is loaded. @@ -148,9 +164,9 @@ namespace gdjs { private _getAtlasResource(resourceName: string): ResourceData | null { const resource = this._resourceLoader.getResource(resourceName); - return (resource && this.getResourceKinds().includes(resource.kind) - ? resource - : null); + return resource && this.getResourceKinds().includes(resource.kind) + ? resource + : null; } } } diff --git a/Extensions/Spine/managers/pixi-spine-manager.ts b/Extensions/Spine/managers/pixi-spine-manager.ts index 3323bda1c04a..fa88604b1f0d 100644 --- a/Extensions/Spine/managers/pixi-spine-manager.ts +++ b/Extensions/Spine/managers/pixi-spine-manager.ts @@ -40,30 +40,32 @@ namespace gdjs { const resource = this._getSpineResource(resourceName); if (!resource) { - return logger.error(`Unable to find spine json for resource ${resourceName}.`); + return logger.error( + `Unable to find spine json for resource ${resourceName}.` + ); } try { - const metadata = resource.metadata - ? JSON.parse(resource.metadata) - : {}; + const metadata = resource.metadata ? JSON.parse(resource.metadata) : {}; if (!metadata.atlas) { - return logger.error(`Unable to find atlas metadata for resource spine json ${resourceName}.`); + return logger.error( + `Unable to find atlas metadata for resource spine json ${resourceName}.` + ); } - const spineAtlas = await this._spineAtlasManager.getOrLoad(metadata.atlas); + const spineAtlas = await this._spineAtlasManager.getOrLoad( + metadata.atlas + ); PIXI.Assets.setPreferences({ preferWorkers: false, - crossOrigin: this._resourceLoader.checkIfCredentialsRequired(resource.file) + crossOrigin: this._resourceLoader.checkIfCredentialsRequired( + resource.file + ) ? 'use-credentials' : 'anonymous', }); - PIXI.Assets.add( - resource.name, - resource.file, - { spineAtlas } - ); + PIXI.Assets.add(resource.name, resource.file, { spineAtlas }); const loadedJson = await PIXI.Assets.load(resource.name); if (loadedJson.spineData) { @@ -102,9 +104,9 @@ namespace gdjs { private _getSpineResource(resourceName: string): ResourceData | null { const resource = this._resourceLoader.getResource(resourceName); - return (resource && this.getResourceKinds().includes(resource.kind) + return resource && this.getResourceKinds().includes(resource.kind) ? resource - : null); - }; + : null; + } } } diff --git a/GDJS/Runtime/ResourceLoader.ts b/GDJS/Runtime/ResourceLoader.ts index f2c5d1bd5e23..a74fce908e67 100644 --- a/GDJS/Runtime/ResourceLoader.ts +++ b/GDJS/Runtime/ResourceLoader.ts @@ -166,8 +166,14 @@ namespace gdjs { // add spine related managers only if spine extension is used if (gdjs.SpineAtlasManager && gdjs.SpineManager) { - this._spineAtlasManager = new gdjs.SpineAtlasManager(this, this._imageManager); - this._spineManager = new gdjs.SpineManager(this, this._spineAtlasManager); + this._spineAtlasManager = new gdjs.SpineAtlasManager( + this, + this._imageManager + ); + this._spineManager = new gdjs.SpineManager( + this, + this._spineAtlasManager + ); } const resourceManagers: Array = [ @@ -179,7 +185,8 @@ namespace gdjs { this._model3DManager, ]; - if (this._spineAtlasManager) resourceManagers.push(this._spineAtlasManager); + if (this._spineAtlasManager) + resourceManagers.push(this._spineAtlasManager); if (this._spineManager) resourceManagers.push(this._spineManager); this._resourceManagersMap = new Map(); diff --git a/GDJS/Runtime/jsonmanager.ts b/GDJS/Runtime/jsonmanager.ts index 6a9d94dd6f82..8c8151820cff 100644 --- a/GDJS/Runtime/jsonmanager.ts +++ b/GDJS/Runtime/jsonmanager.ts @@ -4,201 +4,201 @@ * This project is released under the MIT License. */ namespace gdjs { - const logger = new gdjs.Logger('JSON Manager'); - - /** The callback called when a json that was requested is loaded (or an error occurred). */ - export type JsonManagerRequestCallback = ( - error: Error | null, - content: Object | null - ) => void; - - const resourceKinds: Array = ['json', 'tilemap', 'tileset']; + const logger = new gdjs.Logger('JSON Manager'); + + /** The callback called when a json that was requested is loaded (or an error occurred). */ + export type JsonManagerRequestCallback = ( + error: Error | null, + content: Object | null + ) => void; + + const resourceKinds: Array = ['json', 'tilemap', 'tileset']; + /** + * JsonManager loads json files (using `XMLHttpRequest`), using the "json" resources + * registered in the game resources. + * + * Contrary to audio/fonts, json files are loaded asynchronously, when requested. + * You should properly handle errors, and give the developer/player a way to know + * that loading failed. + */ + export class JsonManager implements gdjs.ResourceManager { + _resourceLoader: ResourceLoader; + + _loadedJsons = new gdjs.ResourceCache(); + _callbacks = new gdjs.ResourceCache>(); + /** - * JsonManager loads json files (using `XMLHttpRequest`), using the "json" resources - * registered in the game resources. + * @param resourceDataArray The resources data of the game. + * @param resourceLoader The resources loader of the game. + */ + constructor(resourceLoader: gdjs.ResourceLoader) { + this._resourceLoader = resourceLoader; + } + + getResourceKinds(): ResourceKind[] { + return resourceKinds; + } + + /** + * Request all the json resources to be preloaded (unless they are marked as not preloaded). * - * Contrary to audio/fonts, json files are loaded asynchronously, when requested. - * You should properly handle errors, and give the developer/player a way to know - * that loading failed. + * Note that even if a JSON is already loaded, it will be reloaded (useful for hot-reloading, + * as JSON files can have been modified without the editor knowing). */ - export class JsonManager implements gdjs.ResourceManager { - _resourceLoader: ResourceLoader; - - _loadedJsons = new gdjs.ResourceCache(); - _callbacks = new gdjs.ResourceCache>(); - - /** - * @param resourceDataArray The resources data of the game. - * @param resourceLoader The resources loader of the game. - */ - constructor(resourceLoader: gdjs.ResourceLoader) { - this._resourceLoader = resourceLoader; + async loadResource(resourceName: string): Promise { + const resource = this._resourceLoader.getResource(resourceName); + if (!resource) { + logger.warn('Unable to find json for resource "' + resourceName + '".'); + return; } - - getResourceKinds(): ResourceKind[] { - return resourceKinds; + if (resource.disablePreload) { + return; } - - /** - * Request all the json resources to be preloaded (unless they are marked as not preloaded). - * - * Note that even if a JSON is already loaded, it will be reloaded (useful for hot-reloading, - * as JSON files can have been modified without the editor knowing). - */ - async loadResource(resourceName: string): Promise { - const resource = this._resourceLoader.getResource(resourceName); - if (!resource) { - logger.warn('Unable to find json for resource "' + resourceName + '".'); - return; - } - if (resource.disablePreload) { - return; - } - - try { - await this.loadJsonAsync(resource.name); - } catch (error) { - logger.error( - `Error while preloading json resource ${resource.name}:`, - error - ); - } + + try { + await this.loadJsonAsync(resource.name); + } catch (error) { + logger.error( + `Error while preloading json resource ${resource.name}:`, + error + ); } - - loadJsonAsync(resourceName: string): Promise { - const that = this; - return new Promise((resolve, reject) => { - that.loadJson(resourceName, (error, content) => { - if (error) { - reject(error.message); - } - resolve(content); - }); + } + + loadJsonAsync(resourceName: string): Promise { + const that = this; + return new Promise((resolve, reject) => { + that.loadJson(resourceName, (error, content) => { + if (error) { + reject(error.message); + } + resolve(content); }); + }); + } + + private _getJsonResource = (resourceName: string): ResourceData | null => { + const resource = this._resourceLoader.getResource(resourceName); + return resource && this.getResourceKinds().includes(resource.kind) + ? resource + : null; + }; + + async processResource(resourceName: string): Promise { + // Do nothing because json are light enough to be parsed in background. + } + + /** + * Request the json file from the given resource name. + * This method is asynchronous. When loaded, the `callback` is called with the error + * (null if none) and the loaded json (a JS Object). + * + * @param resourceName The resource pointing to the json file to load. + * @param callback The callback function called when json is loaded (or an error occurred). + */ + loadJson(resourceName: string, callback: JsonManagerRequestCallback): void { + const resource = this._getJsonResource(resourceName); + if (!resource) { + callback( + new Error( + 'Can\'t find resource with name: "' + + resourceName + + '" (or is not a json resource).' + ), + null + ); + return; } - - private _getJsonResource = (resourceName: string): ResourceData | null => { - const resource = this._resourceLoader.getResource(resourceName); - return resource && this.getResourceKinds().includes(resource.kind) - ? resource - : null; - }; - - async processResource(resourceName: string): Promise { - // Do nothing because json are light enough to be parsed in background. + + // Don't fetch again an object that is already in memory + if (this._loadedJsons.get(resource)) { + callback(null, this._loadedJsons.get(resource)); + return; } - - /** - * Request the json file from the given resource name. - * This method is asynchronous. When loaded, the `callback` is called with the error - * (null if none) and the loaded json (a JS Object). - * - * @param resourceName The resource pointing to the json file to load. - * @param callback The callback function called when json is loaded (or an error occurred). - */ - loadJson(resourceName: string, callback: JsonManagerRequestCallback): void { - const resource = this._getJsonResource(resourceName); - if (!resource) { - callback( - new Error( - 'Can\'t find resource with name: "' + - resourceName + - '" (or is not a json resource).' - ), - null - ); + // Don't fetch again an object that is already being fetched. + { + const callbacks = this._callbacks.get(resource); + if (callbacks) { + callbacks.push(callback); return; + } else { + this._callbacks.set(resource, [callback]); } - - // Don't fetch again an object that is already in memory - if (this._loadedJsons.get(resource)) { - callback(null, this._loadedJsons.get(resource)); + } + + const that = this; + const xhr = new XMLHttpRequest(); + xhr.responseType = 'json'; + xhr.withCredentials = this._resourceLoader.checkIfCredentialsRequired( + resource.file + ); + xhr.open('GET', this._resourceLoader.getFullUrl(resource.file)); + xhr.onload = function () { + const callbacks = that._callbacks.get(resource); + if (!callbacks) { return; } - // Don't fetch again an object that is already being fetched. - { - const callbacks = this._callbacks.get(resource); - if (callbacks) { - callbacks.push(callback); - return; - } else { - this._callbacks.set(resource, [callback]); - } - } - - const that = this; - const xhr = new XMLHttpRequest(); - xhr.responseType = 'json'; - xhr.withCredentials = this._resourceLoader.checkIfCredentialsRequired( - resource.file - ); - xhr.open('GET', this._resourceLoader.getFullUrl(resource.file)); - xhr.onload = function () { - const callbacks = that._callbacks.get(resource); - if (!callbacks) { - return; - } - if (xhr.status !== 200) { - for (const callback of callbacks) { - callback( - new Error( - 'HTTP error: ' + xhr.status + '(' + xhr.statusText + ')' - ), - null - ); - } - that._callbacks.delete(resource); - return; - } - - // Cache the result - that._loadedJsons.set(resource, xhr.response); + if (xhr.status !== 200) { for (const callback of callbacks) { - callback(null, xhr.response); + callback( + new Error( + 'HTTP error: ' + xhr.status + '(' + xhr.statusText + ')' + ), + null + ); } that._callbacks.delete(resource); - }; - xhr.onerror = function () { - const callbacks = that._callbacks.get(resource); - if (!callbacks) { - return; - } - for (const callback of callbacks) { - callback(new Error('Network error'), null); - } - that._callbacks.delete(resource); - }; - xhr.onabort = function () { - const callbacks = that._callbacks.get(resource); - if (!callbacks) { - return; - } - for (const callback of callbacks) { - callback(new Error('Request aborted'), null); - } - that._callbacks.delete(resource); - }; - xhr.send(); - } - - /** - * Check if the given json resource was loaded (preloaded or loaded with `loadJson`). - * @param resourceName The name of the json resource. - * @returns true if the content of the json resource is loaded. false otherwise. - */ - isJsonLoaded(resourceName: string): boolean { - return !!this._loadedJsons.getFromName(resourceName); - } - - /** - * Get the object for the given resource that is already loaded (preloaded or loaded with `loadJson`). - * If the resource is not loaded, `null` will be returned. - * - * @param resourceName The name of the json resource. - * @returns the content of the json resource, if loaded. `null` otherwise. - */ - getLoadedJson(resourceName: string): Object | null { - return this._loadedJsons.getFromName(resourceName) || null; - } + return; + } + + // Cache the result + that._loadedJsons.set(resource, xhr.response); + for (const callback of callbacks) { + callback(null, xhr.response); + } + that._callbacks.delete(resource); + }; + xhr.onerror = function () { + const callbacks = that._callbacks.get(resource); + if (!callbacks) { + return; + } + for (const callback of callbacks) { + callback(new Error('Network error'), null); + } + that._callbacks.delete(resource); + }; + xhr.onabort = function () { + const callbacks = that._callbacks.get(resource); + if (!callbacks) { + return; + } + for (const callback of callbacks) { + callback(new Error('Request aborted'), null); + } + that._callbacks.delete(resource); + }; + xhr.send(); + } + + /** + * Check if the given json resource was loaded (preloaded or loaded with `loadJson`). + * @param resourceName The name of the json resource. + * @returns true if the content of the json resource is loaded. false otherwise. + */ + isJsonLoaded(resourceName: string): boolean { + return !!this._loadedJsons.getFromName(resourceName); + } + + /** + * Get the object for the given resource that is already loaded (preloaded or loaded with `loadJson`). + * If the resource is not loaded, `null` will be returned. + * + * @param resourceName The name of the json resource. + * @returns the content of the json resource, if loaded. `null` otherwise. + */ + getLoadedJson(resourceName: string): Object | null { + return this._loadedJsons.getFromName(resourceName) || null; } - } \ No newline at end of file + } +} From 8b948ae50ab0340210e249dcd05c376f61ea60d6 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 28 Nov 2023 16:35:00 +0200 Subject: [PATCH 41/80] use spine root bone centration --- Extensions/Spine/JsExtension.js | 36 +++++++++++++------ .../Spine/spineruntimeobject-pixi-renderer.ts | 28 +++------------ 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index fe3f67853028..ecc5bbcb5fcb 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -209,6 +209,8 @@ module.exports = { _initialWidth = null; _initialHeight = null; _animationIndex = -1; + _spineOriginOffsetX = 0; + _spineOriginOffsetY = 0; constructor( project, @@ -251,25 +253,37 @@ module.exports = { const width = this.getWidth(); const height = this.getHeight(); - - this._rect.clear(); - this._rect.beginFill(0xffffff); - this._rect.lineStyle(0, 0xffffff); - this._rect.drawRect(0, 0, width, height); - const { _spine: spine } = this; + if (spine) { spine.width = width; spine.height = height; spine.alpha = this._getProperties().get('opacity').getValue() / 255; const localBounds = spine.getLocalBounds(undefined, true); - spine.position.set( - -localBounds.x * spine.scale.x, - -localBounds.y * spine.scale.y - ); + + this._spineOriginOffsetX = localBounds.x * spine.scale.x; + this._spineOriginOffsetY = localBounds.y * spine.scale.y; + this._rect.position.set(this._spineOriginOffsetX, this._spineOriginOffsetY); } - this._pixiObject.calculateBounds(); + this._rect.clear(); + this._rect.beginFill(0xffffff); + this._rect.lineStyle(1, 0xff0000); + this._rect.drawRect(0, 0, width, height); + } + + /** + * @returns x coordinate of this spine origin offset + */ + getOriginX() { + return -this._spineOriginOffsetX; + } + + /** + * @returns y coordinate of this spine origin offset + */ + getOriginY() { + return -this._spineOriginOffsetY; } /** diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index 072433b35a1c..e906cd28fbfa 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -47,11 +47,11 @@ namespace gdjs { updateScale(): void { this._rendererObject.scale.set(Math.max(this._object.getScale(), 0)); - this.updateBounds(); } updatePosition(): void { - this.updateBounds(); + this._rendererObject.position.x = this._object.x; + this._rendererObject.position.y = this._object.y; } updateAngle(): void { @@ -72,18 +72,15 @@ namespace gdjs { setWidth(width: float): void { this._rendererObject.width = width; - this.updateBounds(); } setHeight(height: float): void { this._rendererObject.height = height; - this.updateBounds(); } setSize(width: float, height: float): void { this._rendererObject.width = width; this._rendererObject.height = height; - this.updateBounds(); } setAnimation(animation: string, loop: boolean): void { @@ -91,12 +88,8 @@ namespace gdjs { const onCompleteListener: pixi_spine.IAnimationStateListener = { complete: () => { this._isAnimationComplete = true; - setTimeout( - () => - (this._rendererObject as pixi_spine.Spine).state.removeListener( - onCompleteListener - ), - 0 + (this._rendererObject as pixi_spine.Spine).state.removeListener( + onCompleteListener ); }, }; @@ -105,7 +98,6 @@ namespace gdjs { this._rendererObject.state.addListener(onCompleteListener); this._rendererObject.state.setAnimation(0, animation, loop); this._rendererObject.update(0); - this.updateBounds(); } else { this._isAnimationComplete = true; } @@ -146,18 +138,6 @@ namespace gdjs { spineManager.getSpine(this._object.spineResourceName)! ); } - - private updateBounds(): void { - this._rendererObject.position.x = this._object.x; - this._rendererObject.position.y = this._object.y; - - const localBounds = this._rendererObject.getLocalBounds(undefined, true); - - this._rendererObject.position.x -= - localBounds.x * this._rendererObject.scale.x; - this._rendererObject.position.y -= - localBounds.y * this._rendererObject.scale.y; - } } export const SpineRuntimeObjectRenderer = SpineRuntimeObjectPixiRenderer; } From f42cd38b83e069a75ed9622aa3a2f34cfd1c893f Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 28 Nov 2023 18:02:51 +0200 Subject: [PATCH 42/80] add mixing parameter for animations --- Extensions/Spine/JsExtension.js | 2 ++ .../Spine/spineruntimeobject-pixi-renderer.ts | 6 ++++ Extensions/Spine/spineruntimeobject.ts | 35 ++++++++++++++++--- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index ecc5bbcb5fcb..06411a84ef6e 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -143,6 +143,7 @@ module.exports = { ) .addParameter('object', _('Spine'), 'SpineObject') .useStandardParameters('number', gd.ParameterOptions.makeNewOptions()) + .addParameter('number', _('Mixing duration'), '', false) .markAsSimple() .setFunctionName('setAnimationIndex') .setGetter('getCurrentAnimationIndex'); @@ -162,6 +163,7 @@ module.exports = { 'objectAnimationName', gd.ParameterOptions.makeNewOptions().setDescription(_('Animation name')) ) + .addParameter('number', _('Mixing duration'), '', false) .markAsAdvanced() .setFunctionName('setAnimationName') .setGetter('getAnimationName'); diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index e906cd28fbfa..1e1e20d188a8 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -83,6 +83,12 @@ namespace gdjs { this._rendererObject.height = height; } + setMixing(from: string, to: string, duration: number): void { + if (!isSpine(this._rendererObject)) return; + + this._rendererObject.stateData.setMix(from, to, duration); + } + setAnimation(animation: string, loop: boolean): void { if (isSpine(this._rendererObject)) { const onCompleteListener: pixi_spine.IAnimationStateListener = { diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 0fb0574b0a50..95e298b5396c 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -19,7 +19,7 @@ namespace gdjs { private _scale: number; private _timeScale: number; private _animations: SpineAnimation[]; - private _currentAnimationIndex = 0; + private _currentAnimationIndex = -1; private _renderer: gdjs.SpineRuntimeObjectPixiRenderer; readonly spineResourceName: string; @@ -85,7 +85,7 @@ namespace gdjs { ? animationData.value : this._currentAnimationIndex; - this.setAnimationIndex(animationIndex); + this.setAnimationIndex(animationIndex, 0); if (initialInstanceData.customSize) { this.setScale(1); @@ -163,18 +163,39 @@ namespace gdjs { this.invalidateHitboxes(); } - setAnimationIndex(animationIndex: number): void { + setAnimationIndex(animationIndex: number, mixingDuration: number): void { if (!this.isAnimationIndex(animationIndex)) { return; } + const previousAnimationName = this.getAnimationSource( + this._currentAnimationIndex + ); + const newAnimationName = this.getAnimationSource(animationIndex); + + if ( + previousAnimationName && + newAnimationName && + newAnimationName !== previousAnimationName + ) { + this._renderer.setMixing( + previousAnimationName, + newAnimationName, + mixingDuration + ); + } + const animation = this._animations[animationIndex]; this._currentAnimationIndex = animationIndex; + this._renderer.setAnimation(animation.source, animation.loop); } - setAnimationName(animationName: string): void { - this.setAnimationIndex(this.getAnimationIndex(animationName)); + setAnimationName(animationName: string, mixingDuration: number): void { + this.setAnimationIndex( + this.getAnimationIndex(animationName), + mixingDuration + ); } getCurrentAnimationIndex(): number { @@ -187,6 +208,10 @@ namespace gdjs { : ''; } + getAnimationSource(index: number): string { + return this.isAnimationIndex(index) ? this._animations[index].source : ''; + } + getAnimationIndex(animationName: string): number { return this._animations.findIndex( (animation) => animation.name === animationName From ee780f8ae137c02fc2c8d1435634db00c4de8437 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 5 Dec 2023 16:35:32 +0200 Subject: [PATCH 43/80] use correct spine help page path --- newIDE/app/src/ObjectEditor/ObjectsEditorService.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/newIDE/app/src/ObjectEditor/ObjectsEditorService.js b/newIDE/app/src/ObjectEditor/ObjectsEditorService.js index 0e0808ed3a08..236b90014b29 100644 --- a/newIDE/app/src/ObjectEditor/ObjectsEditorService.js +++ b/newIDE/app/src/ObjectEditor/ObjectsEditorService.js @@ -1,3 +1,4 @@ + // @flow import TextEditor from './Editors/TextEditor'; import TiledSpriteEditor from './Editors/TiledSpriteEditor'; @@ -179,7 +180,7 @@ const ObjectsEditorService = { objectConfiguration: gdObjectConfiguration ): gdObjectJsImplementation => gd.asObjectJsImplementation(objectConfiguration), - helpPagePath: '/objects/3d-model', + helpPagePath: '/objects/spine', }, 'TiledSpriteObject::TiledSprite': { component: TiledSpriteEditor, From dc35f5df96714358cfee743191215119143b9130 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 5 Dec 2023 17:48:39 +0200 Subject: [PATCH 44/80] fix formatting issue --- newIDE/app/src/ObjectEditor/ObjectsEditorService.js | 1 - 1 file changed, 1 deletion(-) diff --git a/newIDE/app/src/ObjectEditor/ObjectsEditorService.js b/newIDE/app/src/ObjectEditor/ObjectsEditorService.js index 236b90014b29..97e688f29376 100644 --- a/newIDE/app/src/ObjectEditor/ObjectsEditorService.js +++ b/newIDE/app/src/ObjectEditor/ObjectsEditorService.js @@ -1,4 +1,3 @@ - // @flow import TextEditor from './Editors/TextEditor'; import TiledSpriteEditor from './Editors/TiledSpriteEditor'; From 4b9e78054ae6c161592947e5fb38a83882bece72 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Mon, 11 Dec 2023 19:23:08 +0200 Subject: [PATCH 45/80] use embedded resources mechanis for spine loading --- Extensions/Spine/JsExtension.js | 8 - Extensions/Spine/SpineObjectConfiguration.cpp | 30 +-- Extensions/Spine/SpineObjectConfiguration.h | 2 - .../managers/pixi-spine-atlas-manager.ts | 30 ++- .../Spine/managers/pixi-spine-manager.ts | 14 +- Extensions/Spine/spineruntimeobject.ts | 8 +- GDJS/Runtime/ResourceLoader.ts | 7 + GDJS/Runtime/runtimegame.ts | 11 + GDevelop.js/types.d.ts | 31 +++ .../src/ObjectEditor/Editors/SpineEditor.js | 142 ++++--------- .../ObjectsRendering/PixiResourcesLoader.js | 196 +++++++++++------- .../LocalEmbeddedResourceSources.js | 87 ++++++++ .../src/ResourcesList/LocalResourceSources.js | 24 +++ 13 files changed, 362 insertions(+), 228 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 06411a84ef6e..f70db0776a8d 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -369,19 +369,11 @@ module.exports = { const spineResourceName = properties .get('spineResourceName') .getValue(); - const imageResourceName = properties - .get('imageResourceName') - .getValue(); - const atlasResourceName = properties - .get('atlasResourceName') - .getValue(); this._pixiResourcesLoader .getSpineData( this._project, spineResourceName, - imageResourceName, - atlasResourceName ) .then((spineData) => { if (!spineData) return; diff --git a/Extensions/Spine/SpineObjectConfiguration.cpp b/Extensions/Spine/SpineObjectConfiguration.cpp index d6d73fb39a55..89c5f00fbe19 100644 --- a/Extensions/Spine/SpineObjectConfiguration.cpp +++ b/Extensions/Spine/SpineObjectConfiguration.cpp @@ -21,8 +21,7 @@ using namespace std; SpineAnimation SpineObjectConfiguration::badAnimation; SpineObjectConfiguration::SpineObjectConfiguration() - : scale(1), opacity(255), timeScale(1), - spineResourceName(""), imageResourceName(""), atlasResourceName("") {}; + : scale(1), opacity(255), timeScale(1), spineResourceName("") {}; bool SpineObjectConfiguration::UpdateProperty(const gd::String &propertyName, const gd::String &newValue) { if (propertyName == "scale") { @@ -41,14 +40,6 @@ bool SpineObjectConfiguration::UpdateProperty(const gd::String &propertyName, co spineResourceName = newValue; return true; } - if (propertyName == "imageResourceName") { - imageResourceName = newValue; - return true; - } - if (propertyName == "atlasResourceName") { - atlasResourceName = newValue; - return true; - } return false; } @@ -81,18 +72,6 @@ SpineObjectConfiguration::GetProperties() const { .AddExtraInfo("spine") .SetLabel(_("Spine json")); - objectProperties["imageResourceName"] - .SetValue(imageResourceName) - .SetType("resource") - .AddExtraInfo("image") - .SetLabel(_("Atlas image")); - - objectProperties["atlasResourceName"] - .SetValue(atlasResourceName) - .SetType("resource") - .AddExtraInfo("atlas") - .SetLabel(_("Atlas text")); - return objectProperties; } @@ -125,8 +104,6 @@ void SpineObjectConfiguration::DoUnserializeFrom(gd::Project &project, const gd: opacity = content.GetDoubleAttribute("opacity"); timeScale = content.GetDoubleAttribute("timeScale"); spineResourceName = content.GetStringAttribute("spineResourceName"); - imageResourceName = content.GetStringAttribute("imageResourceName"); - atlasResourceName = content.GetStringAttribute("atlasResourceName"); RemoveAllAnimations(); auto &animationsElement = content.GetChild("animations"); @@ -147,8 +124,6 @@ void SpineObjectConfiguration::DoSerializeTo(gd::SerializerElement &element) con content.SetAttribute("opacity", opacity); content.SetAttribute("timeScale", timeScale); content.SetAttribute("spineResourceName", spineResourceName); - content.SetAttribute("imageResourceName", imageResourceName); - content.SetAttribute("atlasResourceName", atlasResourceName); auto &animationsElement = content.AddChild("animations"); animationsElement.ConsiderAsArrayOf("animation"); @@ -162,8 +137,7 @@ void SpineObjectConfiguration::DoSerializeTo(gd::SerializerElement &element) con void SpineObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker &worker) { worker.ExposeSpine(spineResourceName); - worker.ExposeImage(imageResourceName); - worker.ExposeAtlas(atlasResourceName); + worker.ExposeEmbeddeds(spineResourceName); } const SpineAnimation & diff --git a/Extensions/Spine/SpineObjectConfiguration.h b/Extensions/Spine/SpineObjectConfiguration.h index a6728b87b43a..261dc2066357 100644 --- a/Extensions/Spine/SpineObjectConfiguration.h +++ b/Extensions/Spine/SpineObjectConfiguration.h @@ -157,8 +157,6 @@ class GD_EXTENSION_API SpineObjectConfiguration : public gd::ObjectConfiguration double timeScale; gd::String spineResourceName; - gd::String imageResourceName; - gd::String atlasResourceName; std::vector animations; diff --git a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts index a18559ba96a6..7c5c103df586 100644 --- a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts +++ b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts @@ -108,12 +108,29 @@ namespace gdjs { resource: ResourceData, callback: SpineAtlasManagerRequestCallback ): void { - const metadata = resource.metadata ? JSON.parse(resource.metadata) : {}; + const game = this._resourceLoader.getRuntimeGame(); + const embeddedResourcesMapping = game.getEmbeddedResourcesNames( + resource.name + ); + + if (!embeddedResourcesMapping.length) + return callback( + new Error(`${resource.name} do not have image metadata!`) + ); - if (!metadata.image) - callback(new Error(`${resource.name} do not have image metadata!`)); + const images = embeddedResourcesMapping.reduce<{ + [key: string]: PIXI.Texture; + }>((imagesMap, embeddedResourceName) => { + const mappedResourceName = game.resolveEmbeddedResource( + resource.name, + embeddedResourceName + ); + imagesMap[ + embeddedResourceName + ] = this._imageManager.getOrLoadPIXITexture(mappedResourceName); - const image = this._imageManager.getOrLoadPIXITexture(metadata.image); + return imagesMap; + }, {}); const onLoad = (atlas: pixi_spine.TextureAtlas) => { this._loadedSpineAtlases.set(resource, atlas); callback(null, atlas); @@ -127,13 +144,14 @@ namespace gdjs { ? 'use-credentials' : 'anonymous', }); - PIXI.Assets.add(resource.name, resource.file, { image }); + PIXI.Assets.add(resource.name, resource.file, { images }); PIXI.Assets.load(resource.name).then( (atlas) => { if (typeof atlas === 'string') { new pixi_spine.TextureAtlas( atlas, - (_, textureCb) => textureCb(image.baseTexture), + (textureName, textureCb) => + textureCb(images[textureName].baseTexture), onLoad ); } else { diff --git a/Extensions/Spine/managers/pixi-spine-manager.ts b/Extensions/Spine/managers/pixi-spine-manager.ts index fa88604b1f0d..21a11160f58d 100644 --- a/Extensions/Spine/managers/pixi-spine-manager.ts +++ b/Extensions/Spine/managers/pixi-spine-manager.ts @@ -46,16 +46,24 @@ namespace gdjs { } try { - const metadata = resource.metadata ? JSON.parse(resource.metadata) : {}; + const game = this._resourceLoader.getRuntimeGame(); + const embeddedResourcesMapping = game.getEmbeddedResourcesNames( + resource.name + ); - if (!metadata.atlas) { + // there should be exactly one file which is pointing to atlas + if (embeddedResourcesMapping.length !== 1) { return logger.error( `Unable to find atlas metadata for resource spine json ${resourceName}.` ); } + const atlasResourceName = game.resolveEmbeddedResource( + resource.name, + embeddedResourcesMapping[0] + ); const spineAtlas = await this._spineAtlasManager.getOrLoad( - metadata.atlas + atlasResourceName ); PIXI.Assets.setPreferences({ preferWorkers: false, diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 95e298b5396c..20de7b8696f0 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -7,8 +7,6 @@ namespace gdjs { scale: float; timeScale: float; spineResourceName: string; - atlasResourceName: string; - imageResourceName: string; animations: SpineAnimation[]; }; }; @@ -19,12 +17,10 @@ namespace gdjs { private _scale: number; private _timeScale: number; private _animations: SpineAnimation[]; - private _currentAnimationIndex = -1; + private _currentAnimationIndex = 0; private _renderer: gdjs.SpineRuntimeObjectPixiRenderer; readonly spineResourceName: string; - readonly atlasResourceName: string; - readonly imageResourceName: string; /** * @param instanceContainer The container the object belongs to. @@ -41,8 +37,6 @@ namespace gdjs { this._opacity = objectData.content.opacity; this._scale = objectData.content.scale; this.spineResourceName = objectData.content.spineResourceName; - this.atlasResourceName = objectData.content.atlasResourceName; - this.imageResourceName = objectData.content.imageResourceName; this._renderer = new gdjs.SpineRuntimeObjectRenderer( this, instanceContainer diff --git a/GDJS/Runtime/ResourceLoader.ts b/GDJS/Runtime/ResourceLoader.ts index 395cd0c7543e..e47b8edbcb2b 100644 --- a/GDJS/Runtime/ResourceLoader.ts +++ b/GDJS/Runtime/ResourceLoader.ts @@ -207,6 +207,13 @@ namespace gdjs { } } + /** + * @returns the runtime game instance. + */ + getRuntimeGame(): RuntimeGame { + return this._runtimeGame; + } + /** * Update the resources data of the game. Useful for hot-reloading, should * not be used otherwise. diff --git a/GDJS/Runtime/runtimegame.ts b/GDJS/Runtime/runtimegame.ts index 493f7b5b6bc7..1fd14bc1f265 100644 --- a/GDJS/Runtime/runtimegame.ts +++ b/GDJS/Runtime/runtimegame.ts @@ -1171,5 +1171,16 @@ namespace gdjs { ? mapping[embeddedResourceName] : embeddedResourceName; } + + /** + * Returns the array of resources that are embedded to passed one. + * @param resourceName The name of resource to find embedded resources of. + * @returns The array of related resources names. + */ + getEmbeddedResourcesNames(resourceName: string): string[] { + return this._embeddedResourcesMappings.has(resourceName) + ? Object.keys(this._embeddedResourcesMappings.get(resourceName)!) + : []; + } } } diff --git a/GDevelop.js/types.d.ts b/GDevelop.js/types.d.ts index 7f7604f8b300..3e597b7b48ed 100644 --- a/GDevelop.js/types.d.ts +++ b/GDevelop.js/types.d.ts @@ -974,6 +974,10 @@ export class JsonResource extends EmscriptenObject { constructor(): void; } +export class SpineResource extends EmscriptenObject { + constructor(): void; +} + export class TilemapResource extends EmscriptenObject { constructor(): void; } @@ -982,6 +986,10 @@ export class TilesetResource extends EmscriptenObject { constructor(): void; } +export class AtlasResource extends EmscriptenObject { + constructor(): void; +} + export class InitialInstance extends EmscriptenObject { constructor(): void; setObjectName(name: string): void; @@ -2422,6 +2430,29 @@ export class SpriteObject extends EmscriptenObject { setAdaptCollisionMaskAutomatically(adaptCollisionMaskAutomatically: boolean): void; } +export class SpineAnimation extends EmscriptenObject { + constructor(): void; + setName(name: string): void; + getName(): string; + setSource(name: string): void; + getSource(): string; + setShouldLoop(shouldLoop: boolean): void; + shouldLoop(): boolean; +} + +export class SpineObjectConfiguration extends EmscriptenObject { + constructor(): void; + addAnimation(animation: SpineAnimation): void; + getAnimation(index: number): SpineAnimation; + hasAnimationNamed(name: string): boolean; + getAnimationsCount(): number; + removeAnimation(index: number): void; + removeAllAnimations(): void; + hasNoAnimations(): boolean; + swapAnimations(first: number, second: number): void; + moveAnimation(oldIndex: number, newIndex: number): void; +} + export class TextObject extends EmscriptenObject { constructor(): void; setString(string: string): void; diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 76b030dd44e3..80b114b33ab8 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -51,7 +51,7 @@ const SpineEditor = ({ const scrollView = React.useRef(null); const getResource = React.useCallback( - name => { + (name: string) => { const resourcesManager = project.getResourcesManager(); return resourcesManager.hasResource(name) @@ -65,19 +65,6 @@ const SpineEditor = ({ return !!metadataString ? JSON.parse(metadataString) : {}; }; - const setMetadata = (resource, metadata) => { - if (resource) { - resource.setMetadata(JSON.stringify(metadata)); - } - }; - const extendMetadata = React.useCallback( - (resourceName, metadata) => { - const resource = getResource(resourceName); - - setMetadata(resource, Object.assign(getMetadata(resource), metadata)); - }, - [getResource] - ); const [ justAddedAnimationName, setJustAddedAnimationName, @@ -113,96 +100,57 @@ const SpineEditor = ({ ); const [skeleton, setSkeleton] = React.useState(null); - const getSkeleton = React.useCallback( - ( - spineResourceName: string, - imageResourceName: string, - atlasResourceName: string - ) => { - if ( - [spineResourceName, imageResourceName, atlasResourceName].some( - resName => !resName - ) - ) { - return Promise.resolve(undefined); - } - - return PixiResourcesLoader.getSpineData( - project, - spineResourceName, - imageResourceName, - atlasResourceName - ).then(newSkeleton => { - setSkeleton(newSkeleton); + const getEmbeddedResourcesMapping = React.useCallback( + (resourceName: string): { [string]: string } => { + const resource = getResource(resourceName); - return newSkeleton; - }); + return getMetadata(resource).embeddedResourcesMapping; }, - [project] - ); - getSkeleton( - properties.get('spineResourceName').getValue(), - properties.get('imageResourceName').getValue(), - properties.get('atlasResourceName').getValue() + [getResource] ); - - const onChangeSpineResourceName = React.useCallback( + const getSkeleton = React.useCallback( (spineResourceName: string) => { - const atlasResourceName = properties.get('atlasResourceName').getValue(); + const jsonResourcesMapping = getEmbeddedResourcesMapping( + spineResourceName + ); + if (!jsonResourcesMapping) return Promise.resolve(undefined); - if (atlasResourceName) { - extendMetadata(spineResourceName, { atlas: atlasResourceName }); - } + const jsonResourcesMappingValues = Object.values(jsonResourcesMapping); + const textureAtlasName = jsonResourcesMappingValues[0]; - getSkeleton( - spineResourceName, - properties.get('imageResourceName').getValue(), - atlasResourceName - ).then(newSkeleton => { - spineConfiguration.removeAllAnimations(); - }); - }, - [getSkeleton, extendMetadata, properties, spineConfiguration] - ); - const onChangeAtlasResourceName = React.useCallback( - (atlasResourceName: string) => { - const spineResourceName = properties.get('spineResourceName').getValue(); - const imageResourceName = properties.get('imageResourceName').getValue(); + // flow check + if (typeof textureAtlasName !== 'string') + return Promise.resolve(undefined); - if (spineResourceName) { - extendMetadata(spineResourceName, { atlas: atlasResourceName }); - } - if (imageResourceName) { - extendMetadata(atlasResourceName, { image: imageResourceName }); - } + const atlasResourcesMapping = getEmbeddedResourcesMapping( + textureAtlasName + ); - getSkeleton( - properties.get('spineResourceName').getValue(), - imageResourceName, - atlasResourceName - ).then(newSkeleton => { - spineConfiguration.removeAllAnimations(); - }); + if ( + !atlasResourcesMapping || + !Object.values(atlasResourcesMapping).length + ) + return Promise.resolve(undefined); + + return PixiResourcesLoader.getSpineData(project, spineResourceName).then( + newSkeleton => { + setSkeleton(newSkeleton); + + return newSkeleton; + } + ); }, - [getSkeleton, extendMetadata, properties, spineConfiguration] + [project, getEmbeddedResourcesMapping] ); - const onChangeImageResourceName = React.useCallback( - (imageResourceName: string) => { - const atlasResourceName = properties.get('atlasResourceName').getValue(); - - if (atlasResourceName) { - extendMetadata(atlasResourceName, { image: imageResourceName }); - } + getSkeleton(properties.get('spineResourceName').getValue()); - getSkeleton( - properties.get('spineResourceName').getValue(), - imageResourceName, - atlasResourceName - ).then(newSkeleton => { + const onChangeSpineResourceName = React.useCallback( + (spineResourceName: string) => { + getSkeleton(spineResourceName).then(newSkeleton => { spineConfiguration.removeAllAnimations(); }); }, - [getSkeleton, extendMetadata, properties, spineConfiguration] + [getSkeleton, spineConfiguration] ); const scanNewAnimations = React.useCallback( @@ -390,20 +338,6 @@ const SpineEditor = ({ resourceManagementProps={resourceManagementProps} onChange={onChangeSpineResourceName} /> - - Appearance diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index bb27cd62b56e..a45b59203f3d 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -4,7 +4,7 @@ import slugs from 'slugs'; import axios from 'axios'; import * as PIXI from 'pixi.js-legacy'; import * as PIXI_SPINE from 'pixi-spine'; -import { ISkeleton } from 'pixi-spine'; +import { ISkeleton, TextureAtlas } from 'pixi-spine'; import * as THREE from 'three'; import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; @@ -457,43 +457,57 @@ export default class PixiResourcesLoader { } /** - * Return the Pixi spine data to the specified resource names. + * Return the Pixi spine texture atlas of the specified resource names. * @param project The project - * @param spineName The name of the spine json resource - * @param atlasImageName The name of the atlas image resource * @param atlasTextName The name of the atlas text resource - * @returns The requested material. + * @returns The requested texture atlas. */ - static async getSpineData( + static async getSpineTextureAtlas( project: gdProject, - spineName: string, - atlasImageName: string, - atlasTextName: string - ): Promise { + spineTextureAtlasName: string + ): Promise { const resourceManager = project.getResourcesManager(); - const resourcesData = [ - [spineName, 'spine'], - [atlasImageName, 'image'], - [atlasTextName, 'atlas'], - ]; - - for (const [resName, resKind] of resourcesData) { - if (!resourceManager.hasResource(resName)) { - return Promise.reject(`Unknown ${resKind} file ${resName}.`); - } - if (resourceManager.getResource(resName).getKind() !== resKind) { + if (!resourceManager.hasResource(spineTextureAtlasName)) { + return Promise.reject(`Unknown atlas file ${spineTextureAtlasName}.`); + } + + const resource = resourceManager.getResource(spineTextureAtlasName); + if (resource.getKind() !== 'atlas') { + return Promise.reject( + `The resource called ${spineTextureAtlasName} is not of appropriate file type atlas.` + ); + } + + if (!atlasPromises[spineTextureAtlasName]) { + const metadataString = resource.getMetadata(); + const textureAtlasMapping = metadataString + ? JSON.parse(metadataString).embeddedResourcesMapping + : {}; + const textureAtlasMappingEntries = Object.entries(textureAtlasMapping); + if (!textureAtlasMappingEntries.length) { return Promise.reject( - `The resource called ${resName} is not of appropriate file type ${resKind}.` + `Unable to find embedded resources mapping for ${spineTextureAtlasName} atlas.` ); } - } - // https://github.com/pixijs/spine/blob/master/examples/preload_atlas_text.md - if (!atlasPromises[atlasTextName]) { - atlasPromises[atlasTextName] = new Promise(resolve => { + const images = textureAtlasMappingEntries.reduce( + (imagesMapping, [relatedPath, resourceName]) => { + // flow check + if (typeof resourceName === 'string') { + imagesMapping[relatedPath] = this.getPIXITexture( + project, + resourceName + ); + } + + return imagesMapping; + }, + {} + ); + atlasPromises[spineTextureAtlasName] = new Promise(resolve => { const onError = err => { console.error( - `Error during ${atlasTextName} atlas loading: ${err}.\nCheck if you selected correct pair of atlas and image files.` + `Error during ${spineTextureAtlasName} atlas loading: ${err}.\nCheck if you selected correct pair of atlas and image files.` ); resolve(undefined); }; @@ -501,25 +515,25 @@ export default class PixiResourcesLoader { try { const atlasUrl = ResourcesLoader.getResourceFullUrl( project, - atlasTextName, + spineTextureAtlasName, { isResourceForPixi: true, } ); - const atlasImage = this.getPIXITexture(project, atlasImageName); PIXI.Assets.setPreferences({ preferWorkers: false, crossOrigin: checkIfCredentialsRequired(atlasUrl) ? 'use-credentials' : 'anonymous', }); - PIXI.Assets.add(atlasTextName, atlasUrl, { image: atlasImage }); - PIXI.Assets.load(atlasTextName) + PIXI.Assets.add(spineTextureAtlasName, atlasUrl, { images }); + PIXI.Assets.load(spineTextureAtlasName) .then(atlas => { if (typeof atlas === 'string') { new PIXI_SPINE.TextureAtlas( atlas, - (_, textureCb) => textureCb(atlasImage.baseTexture), + (textureName, textureCb) => + textureCb(images[textureName].baseTexture), resolve ); } else { @@ -533,48 +547,90 @@ export default class PixiResourcesLoader { }); } + return atlasPromises[spineTextureAtlasName]; + } + + /** + * Return the Pixi spine data of the specified resource names. + * @param project The project + * @param spineName The name of the spine json resource + * @returns The requested spine skeleton. + */ + static async getSpineData( + project: gdProject, + spineName: string + ): Promise { + const resourceManager = project.getResourcesManager(); + if (!resourceManager.hasResource(spineName)) { + return Promise.reject(`Unknown spine file ${spineName}.`); + } + + const resource = resourceManager.getResource(spineName); + if (resource.getKind() !== 'spine') { + return Promise.reject( + `The resource called ${spineName} is not of appropriate file type spine.` + ); + } + if (!spineDataPromises[spineName]) { + const metadataString = resource.getMetadata(); + const textureAtlasMapping = metadataString + ? JSON.parse(metadataString).embeddedResourcesMapping + : {}; + const spineTextureAtlasName = Object.values(textureAtlasMapping)[0]; + + // flow check + if (typeof spineTextureAtlasName !== 'string') { + return Promise.reject( + `Unable to find embedded resources mapping for ${spineName} spine.` + ); + } + spineDataPromises[spineName] = new Promise(resolve => { - atlasPromises[atlasTextName].then(spineAtlas => { - if (!spineAtlas) { - console.error( - `Cannot load ${spineName} spine. Atlas ${atlasTextName} is undefined. Check if you selected correct files.` - ); - return resolve(undefined); - } + this.getSpineTextureAtlas(project, spineTextureAtlasName) + .then(spineAtlas => { + if (!spineAtlas) { + console.error( + `Cannot load ${spineName} spine. Atlas ${spineTextureAtlasName} is undefined. Check if you selected correct files.` + ); + return resolve(undefined); + } - const onError = err => { - console.error( - `Error during ${spineName} spine loading: ${err}.\nCheck if you selected correct files.` - ); + const onError = err => { + console.error( + `Error during ${spineName} spine loading: ${err}.\nCheck if you selected correct files.` + ); + resolve(undefined); + }; + + try { + const jsonUrl = ResourcesLoader.getResourceFullUrl( + project, + spineName, + { + isResourceForPixi: true, + } + ); + PIXI.Assets.setPreferences({ + preferWorkers: false, + crossOrigin: checkIfCredentialsRequired(jsonUrl) + ? 'use-credentials' + : 'anonymous', + }); + PIXI.Assets.add(spineName, jsonUrl, { spineAtlas }); + PIXI.Assets.load(spineName) + .then(jsonData => { + resolve(jsonData.spineData); + }) + .catch(onError); + } catch (err) { + onError(err); + } + }) + .catch(err => { + console.error('Errot during spine atlas loading.\n', err); resolve(undefined); - }; - - try { - const jsonUrl = ResourcesLoader.getResourceFullUrl( - project, - spineName, - { - isResourceForPixi: true, - } - ); - PIXI.Assets.setPreferences({ - preferWorkers: false, - crossOrigin: checkIfCredentialsRequired(jsonUrl) - ? 'use-credentials' - : 'anonymous', - }); - PIXI.Assets.add(spineName, jsonUrl, { spineAtlas }); - - PIXI.Assets.load(spineName) - .then(jsonData => { - resolve(jsonData.spineData); - }) - .catch(onError); - } catch (err) { - onError(err); - } - }); + }); }); } diff --git a/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js b/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js index 57ffde6ec955..9e351167f038 100644 --- a/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js +++ b/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js @@ -117,6 +117,21 @@ export function createAndMapEmbeddedResources( mapping[relPath] = resourceName; + // embedded resources can have mappings too + if (filesWithMappedResources.has(fullPath)) { + const mappedResources = filesWithMappedResources.get(fullPath); + + if (mappedResources && mappedResources.mapping) { + theEmbeddedResource.setMetadata( + JSON.stringify({ + embeddedResourcesMapping: mappedResources.mapping, + }) + ); + + filesWithMappedResources.delete(fullPath); + } + } + project.getResourcesManager().addResource(theEmbeddedResource); } } @@ -212,7 +227,79 @@ export async function listTileMapEmbeddedResources( } } +export async function listSpineEmbeddedResources( + project: gdProject, + filePath: string +): Promise { + if (!fs || !path) return null; + + const atlasPath = filePath.replace('.json', '.atlas'); + const isSameNamedAtlasExists = await new Promise(resolve => { + fs.promises + .access(atlasPath, fs.constants.F_OK) + .then(() => resolve(true)) + .catch(() => resolve(false)); + }); + + // Spine resources usualy have the same names. E.g. skeleton.json, skeleton.atlas, skeleton.png + if (!isSameNamedAtlasExists) return null; + + const atlasFileName = path.basename(atlasPath); + const embeddedResources = new Map(); + const isOutsideProjectFolder = !isPathInProjectFolder(project, atlasPath); + const resource: EmbeddedResource = { + resourceKind: 'atlas', + relPath: atlasFileName, + fullPath: atlasPath, + isOutsideProjectFolder, + }; + + embeddedResources.set(atlasFileName, resource); + + return { + embeddedResources, + hasAnyEmbeddedResourceOutsideProjectFolder: isOutsideProjectFolder, + }; +} + +export async function listSpineTextureAtlasEmbeddedResources( + project: gdProject, + filePath: string +): Promise { + if (!fs || !path) return null; + + const atlasContent = await fs.promises.readFile(filePath, 'utf8'); + const atlasImageRegex = /.*\.(png|jpeg|jpg)$/gm; + const imageDependencies = atlasContent.match(atlasImageRegex); + const dir = path.dirname(filePath); + const embeddedResources = new Map(); + let hasAnyEmbeddedResourceOutsideProjectFolder = false; + + for (const relatedImagePath of imageDependencies) { + const fullPath = path.resolve(dir, relatedImagePath); + const isOutsideProjectFolder = !isPathInProjectFolder(project, fullPath); + const resource: EmbeddedResource = { + resourceKind: 'image', + relPath: relatedImagePath, + fullPath, + isOutsideProjectFolder, + }; + + embeddedResources.set(relatedImagePath, resource); + + if (isOutsideProjectFolder) + hasAnyEmbeddedResourceOutsideProjectFolder = true; + } + + return { + embeddedResources, + hasAnyEmbeddedResourceOutsideProjectFolder, + }; +} + export const embeddedResourcesParsers: { [string]: ParseEmbeddedFiles } = { tilemap: listTileMapEmbeddedResources, json: listTileMapEmbeddedResources, + spine: listSpineEmbeddedResources, + atlas: listSpineTextureAtlasEmbeddedResources, }; diff --git a/newIDE/app/src/ResourcesList/LocalResourceSources.js b/newIDE/app/src/ResourcesList/LocalResourceSources.js index e8bb4550f27c..682250caa358 100644 --- a/newIDE/app/src/ResourcesList/LocalResourceSources.js +++ b/newIDE/app/src/ResourcesList/LocalResourceSources.js @@ -98,6 +98,28 @@ const localResourceSources: Array = [ // as written inside the tilemap to the name of the resource that is representing this file. const filesWithEmbeddedResources = new Map(); const parseEmbeddedResources = embeddedResourcesParsers[kind]; + const recursivelyParseEmbeddedResources = async ( + initialEmbeddedResources: EmbeddedResources + ) => { + for (const initialEmbeddedResource of initialEmbeddedResources.embeddedResources.values()) { + const embeddedResourseParser = + embeddedResourcesParsers[initialEmbeddedResource.resourceKind]; + + if (!embeddedResourseParser) continue; + + const { fullPath } = initialEmbeddedResource; + const newDependentResources = await embeddedResourseParser( + project, + fullPath + ); + + if (newDependentResources) { + filesWithEmbeddedResources.set(fullPath, newDependentResources); + + await recursivelyParseEmbeddedResources(newDependentResources); + } + } + }; if (parseEmbeddedResources) { for (const filePath of filePaths) { const embeddedResources = await parseEmbeddedResources( @@ -106,6 +128,8 @@ const localResourceSources: Array = [ ); if (embeddedResources) { + await recursivelyParseEmbeddedResources(embeddedResources); + filesWithEmbeddedResources.set(filePath, embeddedResources); if (embeddedResources.hasAnyEmbeddedResourceOutsideProjectFolder) From 109fc71ef52ca40285acce4c65d001609e830913 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 12 Dec 2023 17:52:41 +0200 Subject: [PATCH 46/80] recursively expose embedded resources --- Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp index ea4ecd74bba0..03c5efb5dec0 100644 --- a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp +++ b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp @@ -130,6 +130,7 @@ void ArbitraryResourceWorker::ExposeEmbeddeds(gd::String& resourceName) { gd::String potentiallyUpdatedTargetResourceName = targetResourceName; ExposeResourceWithType(targetResource.GetKind(), potentiallyUpdatedTargetResourceName); + ExposeEmbeddeds(potentiallyUpdatedTargetResourceName); if (potentiallyUpdatedTargetResourceName != targetResourceName) { // The resource name was renamed. Also update the mapping. From 298268f051621fa7f3474e7cf6bf0b5a6e403374 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Tue, 12 Dec 2023 18:23:42 +0200 Subject: [PATCH 47/80] use scaled initial width/height --- Extensions/Spine/JsExtension.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index f70db0776a8d..04a84793142f 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -313,6 +313,7 @@ module.exports = { const animation = configuration.getAnimation(index); const source = animation.getSource(); const shouldLoop = animation.shouldLoop(); + const scale = this.getScale(); // reset scale to track new animation range // if custom size is set it will be reinitialized in update method @@ -321,8 +322,8 @@ module.exports = { spine.state.tracks[0].trackTime = 0; spine.update(0); spine.autoUpdate = false; - this._initialWidth = spine.width; - this._initialHeight = spine.height; + this._initialWidth = spine.width * this.getScale(); + this._initialHeight = spine.height * this.getScale(); } /** @@ -330,7 +331,7 @@ module.exports = { */ getDefaultWidth() { return (this._initialWidth !== null - ? this._initialWidth * this.getScale() + ? this._initialWidth : 256); } @@ -339,7 +340,7 @@ module.exports = { */ getDefaultHeight() { return (this._initialHeight !== null - ? this._initialHeight * this.getScale() + ? this._initialHeight : 256); } @@ -350,6 +351,11 @@ module.exports = { return Number(this._getProperties().get('scale').getValue()) || 1; } + onRemovedFromScene() { + super.onRemovedFromScene(); + this._pixiObject.destroy(true); + } + /** * @returns this spine object configuration */ From 2f58de69b1d2e0251472f6f6fc2a6a3fc6860694 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Thu, 21 Dec 2023 10:55:46 +0200 Subject: [PATCH 48/80] add explanation comment for TextureAtlas issue, format code --- Extensions/Spine/managers/pixi-spine-atlas-manager.ts | 6 ++++++ newIDE/app/package-lock.json | 8 +------- newIDE/app/package.json | 2 +- newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js | 6 ++++++ 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts index 7c5c103df586..db6c6d6fb53e 100644 --- a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts +++ b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts @@ -147,6 +147,12 @@ namespace gdjs { PIXI.Assets.add(resource.name, resource.file, { images }); PIXI.Assets.load(resource.name).then( (atlas) => { + /** + * Ideally atlas of TextureAtlas should be passed here + * but there is known issue in case of preloaded images (see https://github.com/pixijs/spine/issues/537) + * + * Here covered all possible ways to make it work fine if issue is fixed in pixi-spine or after migration to spine-pixi + */ if (typeof atlas === 'string') { new pixi_spine.TextureAtlas( atlas, diff --git a/newIDE/app/package-lock.json b/newIDE/app/package-lock.json index dd5225cb51aa..4b832341ddcc 100644 --- a/newIDE/app/package-lock.json +++ b/newIDE/app/package-lock.json @@ -31,8 +31,7 @@ "lodash": "4.17.4", "node-require-function": "^1.2.0", "path-browserify": "^1.0.1", - "pixi-simple-gesture": "github:4ian/pixi-simple-gesture#v0.3.3", - "pixi-spine": "^4.0.4", + "pixi-spine": "4.0.4", "pixi.js-legacy": "^7.3.0", "posthog-js": "^1.57.2", "prop-types": "^15.5.10", @@ -26154,11 +26153,6 @@ "node": ">= 6" } }, - "node_modules/pixi-simple-gesture": { - "version": "0.3.3", - "resolved": "git+ssh://git@github.com/4ian/pixi-simple-gesture.git#c84e0cc3c62edeca019e708d9897ef6b97a0d18a", - "license": "MIT" - }, "node_modules/pixi-spine": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/pixi-spine/-/pixi-spine-4.0.4.tgz", diff --git a/newIDE/app/package.json b/newIDE/app/package.json index 98b0a86eafcc..0b06703fb559 100644 --- a/newIDE/app/package.json +++ b/newIDE/app/package.json @@ -62,7 +62,7 @@ "node-require-function": "^1.2.0", "path-browserify": "^1.0.1", "pixi-spine": "4.0.4", - "pixi.js-legacy": "^7.3.0", + "pixi.js-legacy": "7.3.0", "posthog-js": "^1.57.2", "prop-types": "^15.5.10", "qr-creator": "^1.0.0", diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index a45b59203f3d..1fb56763c8f5 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -529,6 +529,12 @@ export default class PixiResourcesLoader { PIXI.Assets.add(spineTextureAtlasName, atlasUrl, { images }); PIXI.Assets.load(spineTextureAtlasName) .then(atlas => { + /** + * Ideally atlas of TextureAtlas should be passed here + * but there is known issue in case of preloaded images (see https://github.com/pixijs/spine/issues/537) + * + * Here covered all possible ways to make it work fine if issue is fixed in pixi-spine or after migration to spine-pixi + */ if (typeof atlas === 'string') { new PIXI_SPINE.TextureAtlas( atlas, From b34c136c97f357d039a3d69a6dae2256b74b88b5 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 13 Dec 2023 14:38:19 +0200 Subject: [PATCH 49/80] use custom clamp instead of PixiFiltersTools --- Extensions/Spine/spineruntimeobject.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 20de7b8696f0..d305940db5cb 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -131,7 +131,7 @@ namespace gdjs { } setOpacity(opacity: float): void { - this._opacity = gdjs.PixiFiltersTools.clampValue(opacity, 0, 255); + this._opacity = Math.max(0, Math.min(255, opacity)); this._renderer.updateOpacity(); } From 969daf35133c5252f94a5f7df2a6439c7ba18f0e Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 13 Dec 2023 14:45:58 +0200 Subject: [PATCH 50/80] lock pixi.js-legacy From ed6193f14ea11f442582fc1732610fde12185b96 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 13 Dec 2023 14:46:58 +0200 Subject: [PATCH 51/80] fix typos --- GDJS/Runtime/ResourceLoader.ts | 8 ++++---- GDJS/Runtime/runtimegame.ts | 8 ++++---- newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/GDJS/Runtime/ResourceLoader.ts b/GDJS/Runtime/ResourceLoader.ts index e47b8edbcb2b..19e0e86bfde5 100644 --- a/GDJS/Runtime/ResourceLoader.ts +++ b/GDJS/Runtime/ResourceLoader.ts @@ -604,18 +604,18 @@ namespace gdjs { } /** - * Get the spine manager of the game, used to load and construct spine skeletons from game + * Get the Spine manager of the game, used to load and construct spine skeletons from game * resources. - * @return The json manager for the game + * @return The Spine manager for the game */ getSpineManager(): gdjs.SpineManager | null { return this._spineManager; } /** - * Get the atlas manager of the game, used to load atlases from game + * Get the Spine Atlas manager of the game, used to load atlases from game * resources. - * @return The atlas manager for the game + * @return The Spine Atlas manager for the game */ getSpineAtlasManager(): gdjs.SpineAtlasManager | null { return this._spineAtlasManager; diff --git a/GDJS/Runtime/runtimegame.ts b/GDJS/Runtime/runtimegame.ts index 1fd14bc1f265..9e247567e462 100644 --- a/GDJS/Runtime/runtimegame.ts +++ b/GDJS/Runtime/runtimegame.ts @@ -308,18 +308,18 @@ namespace gdjs { } /** - * Get the spine manager of the game, used to load and construct spine skeletons from game + * Get the Spine manager of the game, used to load and construct spine skeletons from game * resources. - * @return The json manager for the game + * @return The Spine manager for the game */ getSpineManager(): gdjs.SpineManager | null { return this._resourcesLoader.getSpineManager(); } /** - * Get the atlas manager of the game, used to load atlases from game + * Get the Spine Atlas manager of the game, used to load atlases from game * resources. - * @return The atlas manager for the game + * @return The Spine Atlas manager for the game */ getSpineAtlasManager(): gdjs.SpineAtlasManager | null { return this._resourcesLoader.getSpineAtlasManager(); diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 1fb56763c8f5..962c4c77c510 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -634,7 +634,7 @@ export default class PixiResourcesLoader { } }) .catch(err => { - console.error('Errot during spine atlas loading.\n', err); + console.error('Error during Spine atlas loading:', err); resolve(undefined); }); }); From 4f68cc8a8ac63981aaa82036e32ac70f26455aad Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 13 Dec 2023 14:59:30 +0200 Subject: [PATCH 52/80] stop imitate spine behavior if spine skeleton is not loaded --- Extensions/Spine/spineruntimeobject-pixi-renderer.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index 1e1e20d188a8..7ed861db8304 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -6,7 +6,6 @@ namespace gdjs { private _object: gdjs.SpineRuntimeObject; private _rendererObject: pixi_spine.Spine | PIXI.Container; private _isAnimationComplete = true; - private _autoUpdateReplacer: boolean = true; /** * @param runtimeObject The object to render @@ -104,8 +103,6 @@ namespace gdjs { this._rendererObject.state.addListener(onCompleteListener); this._rendererObject.state.setAnimation(0, animation, loop); this._rendererObject.update(0); - } else { - this._isAnimationComplete = true; } } @@ -118,14 +115,12 @@ namespace gdjs { return this._rendererObject.autoUpdate; } - return !!this._autoUpdateReplacer; + return true; } setIsUpdatable(isUpdatable: boolean): void { if (isSpine(this._rendererObject)) { this._rendererObject.autoUpdate = isUpdatable; - } else { - this._autoUpdateReplacer = isUpdatable; } } From 7bf1a81271096c2f76e1e614dbf47b064f0e0e37 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 13 Dec 2023 17:44:57 +0200 Subject: [PATCH 53/80] update spine atlas manager --- .../managers/pixi-spine-atlas-manager.ts | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts index db6c6d6fb53e..02a5464ade1c 100644 --- a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts +++ b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts @@ -68,34 +68,35 @@ namespace gdjs { ); } - if (!this._loadingSpineAtlases.get(resource)) { - this._loadingSpineAtlases.set( - resource, - new Promise((resolve, reject) => { - const onLoad: SpineAtlasManagerRequestCallback = ( - error, - content - ) => { - if (error) { - return reject( - `Error while preloading a spine atlas resource: ${error}` - ); - } - if (!content) { - return reject( - `Cannot reach texture atlas for resource '${resourceName}'.` - ); - } - - resolve(content); - }; - - this.load(resource, onLoad); - }) - ); + let loadingPromise = this._loadingSpineAtlases.get(resource); + + if (!loadingPromise) { + loadingPromise = new Promise((resolve, reject) => { + const onLoad: SpineAtlasManagerRequestCallback = ( + error, + content + ) => { + if (error) { + return reject( + `Error while preloading a spine atlas resource: ${error}` + ); + } + if (!content) { + return reject( + `Cannot reach texture atlas for resource '${resourceName}'.` + ); + } + + resolve(content); + }; + + this.load(resource, onLoad); + }); + + this._loadingSpineAtlases.set(resource, loadingPromise); } - return this._loadingSpineAtlases.get(resource)!; + return loadingPromise; } /** @@ -109,16 +110,16 @@ namespace gdjs { callback: SpineAtlasManagerRequestCallback ): void { const game = this._resourceLoader.getRuntimeGame(); - const embeddedResourcesMapping = game.getEmbeddedResourcesNames( + const embeddedResourcesNames = game.getEmbeddedResourcesNames( resource.name ); - if (!embeddedResourcesMapping.length) + if (!embeddedResourcesNames.length) return callback( new Error(`${resource.name} do not have image metadata!`) ); - const images = embeddedResourcesMapping.reduce<{ + const images = embeddedResourcesNames.reduce<{ [key: string]: PIXI.Texture; }>((imagesMap, embeddedResourceName) => { const mappedResourceName = game.resolveEmbeddedResource( From c5f78e4961c0068d4c5a2d4da63f2d7e6ce09467 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 13 Dec 2023 20:12:13 +0200 Subject: [PATCH 54/80] stop spine skeleton loading at every render call --- .../Spine/managers/pixi-spine-manager.ts | 6 +- .../src/ObjectEditor/Editors/SpineEditor.js | 57 ++++++++++--------- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/Extensions/Spine/managers/pixi-spine-manager.ts b/Extensions/Spine/managers/pixi-spine-manager.ts index 21a11160f58d..ec1499804b4a 100644 --- a/Extensions/Spine/managers/pixi-spine-manager.ts +++ b/Extensions/Spine/managers/pixi-spine-manager.ts @@ -47,12 +47,12 @@ namespace gdjs { try { const game = this._resourceLoader.getRuntimeGame(); - const embeddedResourcesMapping = game.getEmbeddedResourcesNames( + const embeddedResourcesNames = game.getEmbeddedResourcesNames( resource.name ); // there should be exactly one file which is pointing to atlas - if (embeddedResourcesMapping.length !== 1) { + if (embeddedResourcesNames.length !== 1) { return logger.error( `Unable to find atlas metadata for resource spine json ${resourceName}.` ); @@ -60,7 +60,7 @@ namespace gdjs { const atlasResourceName = game.resolveEmbeddedResource( resource.name, - embeddedResourcesMapping[0] + embeddedResourcesNames[0] ); const spineAtlas = await this._spineAtlasManager.getOrLoad( atlasResourceName diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 80b114b33ab8..508377638092 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -108,7 +108,7 @@ const SpineEditor = ({ }, [getResource] ); - const getSkeleton = React.useCallback( + const loadSkeleton = React.useCallback( (spineResourceName: string) => { const jsonResourcesMapping = getEmbeddedResourcesMapping( spineResourceName @@ -132,25 +132,43 @@ const SpineEditor = ({ ) return Promise.resolve(undefined); - return PixiResourcesLoader.getSpineData(project, spineResourceName).then( - newSkeleton => { - setSkeleton(newSkeleton); + return PixiResourcesLoader.getSpineData(project, spineResourceName); + }, + [project, getEmbeddedResourcesMapping] + ); + const [sourceSelectOptions, setSourceSelectOptions] = React.useState>([]); + const spineResourceName = properties.get('spineResourceName').getValue(); - return newSkeleton; + React.useEffect( + () => { + (async () => { + const skeleton = await loadSkeleton(spineResourceName); + + setSkeleton(skeleton); + + if (skeleton) { + setSourceSelectOptions( + skeleton.animations.map(animation => ( + + )) + ); } - ); + })(); }, - [project, getEmbeddedResourcesMapping] + [loadSkeleton, setSourceSelectOptions, spineResourceName] ); - getSkeleton(properties.get('spineResourceName').getValue()); const onChangeSpineResourceName = React.useCallback( - (spineResourceName: string) => { - getSkeleton(spineResourceName).then(newSkeleton => { - spineConfiguration.removeAllAnimations(); - }); + () => { + spineConfiguration.removeAllAnimations(); + forceUpdate(); }, - [getSkeleton, spineConfiguration] + [forceUpdate, spineConfiguration] ); const scanNewAnimations = React.useCallback( @@ -314,19 +332,6 @@ const SpineEditor = ({ ] ); - const sourceSelectOptions = skeleton - ? skeleton.animations.map(animation => { - return ( - - ); - }) - : []; - return ( <> From 138804ae4ded45e9c4af6d57bfe0e86fdc550899 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Thu, 21 Dec 2023 11:30:33 +0200 Subject: [PATCH 55/80] apply format --- .../managers/pixi-spine-atlas-manager.ts | 44 ++++++++++--------- .../src/ObjectEditor/Editors/SpineEditor.js | 4 +- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts index 02a5464ade1c..a8a85679518e 100644 --- a/Extensions/Spine/managers/pixi-spine-atlas-manager.ts +++ b/Extensions/Spine/managers/pixi-spine-atlas-manager.ts @@ -71,27 +71,29 @@ namespace gdjs { let loadingPromise = this._loadingSpineAtlases.get(resource); if (!loadingPromise) { - loadingPromise = new Promise((resolve, reject) => { - const onLoad: SpineAtlasManagerRequestCallback = ( - error, - content - ) => { - if (error) { - return reject( - `Error while preloading a spine atlas resource: ${error}` - ); - } - if (!content) { - return reject( - `Cannot reach texture atlas for resource '${resourceName}'.` - ); - } - - resolve(content); - }; - - this.load(resource, onLoad); - }); + loadingPromise = new Promise( + (resolve, reject) => { + const onLoad: SpineAtlasManagerRequestCallback = ( + error, + content + ) => { + if (error) { + return reject( + `Error while preloading a spine atlas resource: ${error}` + ); + } + if (!content) { + return reject( + `Cannot reach texture atlas for resource '${resourceName}'.` + ); + } + + resolve(content); + }; + + this.load(resource, onLoad); + } + ); this._loadingSpineAtlases.set(resource, loadingPromise); } diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 508377638092..47f144eb878f 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -136,7 +136,9 @@ const SpineEditor = ({ }, [project, getEmbeddedResourcesMapping] ); - const [sourceSelectOptions, setSourceSelectOptions] = React.useState>([]); + const [sourceSelectOptions, setSourceSelectOptions] = React.useState< + Array + >([]); const spineResourceName = properties.get('spineResourceName').getValue(); React.useEffect( From 2e38c5102a1f24a904843f1c5a14af01af5510c0 Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Sat, 23 Dec 2023 15:23:18 +0100 Subject: [PATCH 56/80] Improve various error handling --- Extensions/Spine/JsExtension.js | 5 +- GDevelop.js/Gruntfile.js | 2 +- newIDE/app/package-lock.json | 2 +- .../ObjectsRendering/PixiResourcesLoader.js | 291 +++++++++--------- .../LocalEmbeddedResourceSources.js | 23 +- 5 files changed, 175 insertions(+), 148 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 04a84793142f..a9566d22aca0 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -262,7 +262,7 @@ module.exports = { spine.height = height; spine.alpha = this._getProperties().get('opacity').getValue() / 255; const localBounds = spine.getLocalBounds(undefined, true); - + this._spineOriginOffsetX = localBounds.x * spine.scale.x; this._spineOriginOffsetY = localBounds.y * spine.scale.y; this._rect.position.set(this._spineOriginOffsetX, this._spineOriginOffsetY); @@ -387,6 +387,9 @@ module.exports = { this._spine = new PIXI.Spine(spineData); this._pixiObject.addChild(this._spine); this.update(); + }, (err) => { + console.error("Unable to load Spine:", err); + this._spine = null; }); } } diff --git a/GDevelop.js/Gruntfile.js b/GDevelop.js/Gruntfile.js index 3a6f6bc30e64..06d37d658440 100644 --- a/GDevelop.js/Gruntfile.js +++ b/GDevelop.js/Gruntfile.js @@ -13,7 +13,7 @@ module.exports = function (grunt) { let cmakeBinary = 'emcmake cmake'; let cmakeGeneratorArgs = []; let makeBinary = 'emmake make'; - let makeArgs = ['-j 4']; + let makeArgs = ['-j 8']; // Use more specific paths on Windows if (isWin) { diff --git a/newIDE/app/package-lock.json b/newIDE/app/package-lock.json index 4b832341ddcc..04f3f6e551be 100644 --- a/newIDE/app/package-lock.json +++ b/newIDE/app/package-lock.json @@ -32,7 +32,7 @@ "node-require-function": "^1.2.0", "path-browserify": "^1.0.1", "pixi-spine": "4.0.4", - "pixi.js-legacy": "^7.3.0", + "pixi.js-legacy": "7.3.0", "posthog-js": "^1.57.2", "prop-types": "^15.5.10", "qr-creator": "^1.0.0", diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 962c4c77c510..f8936ec17f1b 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -22,7 +22,7 @@ const invalidTexture = PIXI.Texture.from('res/error48.png'); let loadedThreeTextures = {}; let loadedThreeMaterials = {}; let loadedOrLoading3DModelPromises: ResourcePromise = {}; -let atlasPromises: ResourcePromise< +let spineAtlasPromises: ResourcePromise< PIXI_SPINE.TextureAtlas | typeof undefined > = {}; let spineDataPromises: ResourcePromise = {}; @@ -150,6 +150,23 @@ const traverseToRemoveMetalnessFromMeshes = ( node: THREE.Object3D ) => node.traverse(removeMetalnessFromMesh); +const readEmbeddedResourcesMapping = (resource: gdResource): {} | null => { + const metadataString = resource.getMetadata(); + try { + const metadata = JSON.parse(metadataString); + if ( + !metadata.embeddedResourcesMapping || + typeof metadata.embeddedResourcesMapping !== 'object' + ) { + return null; + } + + return metadata.embeddedResourcesMapping; + } catch (err) { + return null; + } +}; + /** * Expose functions to load PIXI textures or fonts, given the names of * resources and a gd.Project. @@ -164,7 +181,7 @@ export default class PixiResourcesLoader { loadedThreeTextures = {}; loadedThreeMaterials = {}; loadedOrLoading3DModelPromises = {}; - atlasPromises = {}; + spineAtlasPromises = {}; spineDataPromises = {}; } @@ -459,105 +476,103 @@ export default class PixiResourcesLoader { /** * Return the Pixi spine texture atlas of the specified resource names. * @param project The project - * @param atlasTextName The name of the atlas text resource - * @returns The requested texture atlas. + * @param spineTextureAtlasName The name of the atlas texture resource. + * @returns The requested texture atlas, or null if it could not be loaded. */ - static async getSpineTextureAtlas( + static async _getSpineTextureAtlas( project: gdProject, spineTextureAtlasName: string - ): Promise { + ): Promise { + const promise = spineAtlasPromises[spineTextureAtlasName]; + if (promise) return promise; + + if (!spineTextureAtlasName) + throw new Error('No resource name was specified.'); + const resourceManager = project.getResourcesManager(); if (!resourceManager.hasResource(spineTextureAtlasName)) { - return Promise.reject(`Unknown atlas file ${spineTextureAtlasName}.`); + throw new Error( + `Can't find resource with name ${spineTextureAtlasName}.` + ); } const resource = resourceManager.getResource(spineTextureAtlasName); if (resource.getKind() !== 'atlas') { - return Promise.reject( - `The resource called ${spineTextureAtlasName} is not of appropriate file type atlas.` + throw new Error( + `Resource "${spineTextureAtlasName}" is not of appropriate type "atlas".` ); } - if (!atlasPromises[spineTextureAtlasName]) { - const metadataString = resource.getMetadata(); - const textureAtlasMapping = metadataString - ? JSON.parse(metadataString).embeddedResourcesMapping - : {}; - const textureAtlasMappingEntries = Object.entries(textureAtlasMapping); - if (!textureAtlasMappingEntries.length) { - return Promise.reject( - `Unable to find embedded resources mapping for ${spineTextureAtlasName} atlas.` - ); - } + const embeddedResourcesMapping = readEmbeddedResourcesMapping(resource); + const textureAtlasMappingEntries = embeddedResourcesMapping + ? Object.entries(embeddedResourcesMapping) + : []; + if (!textureAtlasMappingEntries.length) { + throw new Error( + `Unable to find embedded resources mapping for ${spineTextureAtlasName} atlas.` + ); + } - const images = textureAtlasMappingEntries.reduce( - (imagesMapping, [relatedPath, resourceName]) => { - // flow check - if (typeof resourceName === 'string') { - imagesMapping[relatedPath] = this.getPIXITexture( - project, - resourceName + const images = textureAtlasMappingEntries.reduce( + (imagesMapping, [relatedPath, resourceName]) => { + // flow check + if (typeof resourceName === 'string') { + imagesMapping[relatedPath] = this.getPIXITexture( + project, + resourceName + ); + } + + return imagesMapping; + }, + {} + ); + + return (spineAtlasPromises[spineTextureAtlasName] = new Promise(resolve => { + const atlasUrl = ResourcesLoader.getResourceFullUrl( + project, + spineTextureAtlasName, + { + isResourceForPixi: true, + } + ); + PIXI.Assets.setPreferences({ + preferWorkers: false, + crossOrigin: checkIfCredentialsRequired(atlasUrl) + ? 'use-credentials' + : 'anonymous', + }); + PIXI.Assets.add(spineTextureAtlasName, atlasUrl, { images }); + PIXI.Assets.load(spineTextureAtlasName).then( + atlas => { + // Ideally atlas of type `TextureAtlas` should be passed here. + // But there is a known issue in case of preloaded images (see https://github.com/pixijs/spine/issues/537). + // + // This branching covers all possible ways to make it work fine, + // if issue is fixed in pixi-spine or after migration to spine-pixi. + if (typeof atlas === 'string') { + new PIXI_SPINE.TextureAtlas( + atlas, + (textureName, textureCb) => + textureCb(images[textureName].baseTexture), + resolve ); + } else { + resolve(atlas); } - - return imagesMapping; }, - {} - ); - atlasPromises[spineTextureAtlasName] = new Promise(resolve => { - const onError = err => { + err => { console.error( - `Error during ${spineTextureAtlasName} atlas loading: ${err}.\nCheck if you selected correct pair of atlas and image files.` - ); - resolve(undefined); - }; - - try { - const atlasUrl = ResourcesLoader.getResourceFullUrl( - project, - spineTextureAtlasName, - { - isResourceForPixi: true, - } + `Error while loading Spine atlas "${spineTextureAtlasName}": ${err}.\nCheck if you selected the correct pair of atlas and image files.` ); - PIXI.Assets.setPreferences({ - preferWorkers: false, - crossOrigin: checkIfCredentialsRequired(atlasUrl) - ? 'use-credentials' - : 'anonymous', - }); - PIXI.Assets.add(spineTextureAtlasName, atlasUrl, { images }); - PIXI.Assets.load(spineTextureAtlasName) - .then(atlas => { - /** - * Ideally atlas of TextureAtlas should be passed here - * but there is known issue in case of preloaded images (see https://github.com/pixijs/spine/issues/537) - * - * Here covered all possible ways to make it work fine if issue is fixed in pixi-spine or after migration to spine-pixi - */ - if (typeof atlas === 'string') { - new PIXI_SPINE.TextureAtlas( - atlas, - (textureName, textureCb) => - textureCb(images[textureName].baseTexture), - resolve - ); - } else { - resolve(atlas); - } - }) - .catch(onError); - } catch (err) { - onError(err); + resolve(null); } - }); - } - - return atlasPromises[spineTextureAtlasName]; + ); + })); } /** - * Return the Pixi spine data of the specified resource names. + * Return the Pixi spine data for the specified resource name. * @param project The project * @param spineName The name of the spine json resource * @returns The requested spine skeleton. @@ -565,82 +580,76 @@ export default class PixiResourcesLoader { static async getSpineData( project: gdProject, spineName: string - ): Promise { + ): Promise { + const promise = spineDataPromises[spineName]; + if (promise) return promise; + + if (!spineName) throw new Error('No resource name was specified.'); + const resourceManager = project.getResourcesManager(); if (!resourceManager.hasResource(spineName)) { - return Promise.reject(`Unknown spine file ${spineName}.`); + throw new Error(`Can't find resource with name ${spineName}.`); } const resource = resourceManager.getResource(spineName); if (resource.getKind() !== 'spine') { - return Promise.reject( - `The resource called ${spineName} is not of appropriate file type spine.` + throw new Error( + `Resource "${spineName}" is not of appropriate type "spine".` ); } - if (!spineDataPromises[spineName]) { - const metadataString = resource.getMetadata(); - const textureAtlasMapping = metadataString - ? JSON.parse(metadataString).embeddedResourcesMapping - : {}; - const spineTextureAtlasName = Object.values(textureAtlasMapping)[0]; - - // flow check - if (typeof spineTextureAtlasName !== 'string') { - return Promise.reject( - `Unable to find embedded resources mapping for ${spineName} spine.` - ); - } + const embeddedResourcesMapping = readEmbeddedResourcesMapping(resource); + const spineTextureAtlasName = embeddedResourcesMapping + ? Object.values(embeddedResourcesMapping)[0] + : null; + if (typeof spineTextureAtlasName !== 'string') { + throw new Error( + `Unable to find embedded resources mapping for ${spineName} spine.` + ); + } - spineDataPromises[spineName] = new Promise(resolve => { - this.getSpineTextureAtlas(project, spineTextureAtlasName) - .then(spineAtlas => { - if (!spineAtlas) { - console.error( - `Cannot load ${spineName} spine. Atlas ${spineTextureAtlasName} is undefined. Check if you selected correct files.` - ); - return resolve(undefined); - } + return (spineDataPromises[spineName] = new Promise(resolve => { + this._getSpineTextureAtlas(project, spineTextureAtlasName).then( + spineAtlas => { + if (!spineAtlas) { + console.error( + `Cannot load ${spineName} spine. Atlas ${spineTextureAtlasName} is undefined. Check if you selected correct files.` + ); + return resolve(null); + } - const onError = err => { + const spineUrl = ResourcesLoader.getResourceFullUrl( + project, + spineName, + { + isResourceForPixi: true, + } + ); + PIXI.Assets.setPreferences({ + preferWorkers: false, + crossOrigin: checkIfCredentialsRequired(spineUrl) + ? 'use-credentials' + : 'anonymous', + }); + PIXI.Assets.add(spineName, spineUrl, { spineAtlas }); + PIXI.Assets.load(spineName).then( + jsonData => { + resolve(jsonData.spineData); + }, + err => { console.error( - `Error during ${spineName} spine loading: ${err}.\nCheck if you selected correct files.` - ); - resolve(undefined); - }; - - try { - const jsonUrl = ResourcesLoader.getResourceFullUrl( - project, - spineName, - { - isResourceForPixi: true, - } + `Error while loading Spine data "${spineName}": ${err}.\nCheck if you selected correct files.` ); - PIXI.Assets.setPreferences({ - preferWorkers: false, - crossOrigin: checkIfCredentialsRequired(jsonUrl) - ? 'use-credentials' - : 'anonymous', - }); - PIXI.Assets.add(spineName, jsonUrl, { spineAtlas }); - PIXI.Assets.load(spineName) - .then(jsonData => { - resolve(jsonData.spineData); - }) - .catch(onError); - } catch (err) { - onError(err); + resolve(null); } - }) - .catch(err => { - console.error('Error during Spine atlas loading:', err); - resolve(undefined); - }); - }); - } - - return spineDataPromises[spineName]; + ); + }, + err => { + console.error('Error while loading Spine atlas:', err); + resolve(null); + } + ); + })); } /** diff --git a/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js b/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js index 9e351167f038..947e174aeef0 100644 --- a/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js +++ b/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js @@ -234,15 +234,19 @@ export async function listSpineEmbeddedResources( if (!fs || !path) return null; const atlasPath = filePath.replace('.json', '.atlas'); - const isSameNamedAtlasExists = await new Promise(resolve => { + const hasAtlasWithSameBasename = await new Promise(resolve => { fs.promises .access(atlasPath, fs.constants.F_OK) .then(() => resolve(true)) .catch(() => resolve(false)); }); - // Spine resources usualy have the same names. E.g. skeleton.json, skeleton.atlas, skeleton.png - if (!isSameNamedAtlasExists) return null; + // Spine resources usually have the same base names: + // e.g. skeleton.json, skeleton.atlas and skeleton.png. + if (!hasAtlasWithSameBasename) { + console.error(`Could not find an atlas file for Spine file ${filePath}.`); + return null; + } const atlasFileName = path.basename(atlasPath); const embeddedResources = new Map(); @@ -268,7 +272,18 @@ export async function listSpineTextureAtlasEmbeddedResources( ): Promise { if (!fs || !path) return null; - const atlasContent = await fs.promises.readFile(filePath, 'utf8'); + let atlasContent: ?string = null; + try { + atlasContent = await fs.promises.readFile(filePath, 'utf8'); + } catch (error) { + console.error( + `Unable to read Spine Atlas file at path ${filePath}:`, + error + ); + } + + if (!atlasContent) return null; + const atlasImageRegex = /.*\.(png|jpeg|jpg)$/gm; const imageDependencies = atlasContent.match(atlasImageRegex); const dir = path.dirname(filePath); From 1d17ff5a17faafadffd9130a0e0a07f7070dae0d Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Sat, 23 Dec 2023 16:00:39 +0100 Subject: [PATCH 57/80] Add a table showing embedded resources in the resource editor --- .../ObjectsRendering/PixiResourcesLoader.js | 4 +- .../EmbeddedResourcesMappingTable.js | 67 +++++++++++++++++++ .../ResourcePropertiesEditor/index.js | 32 +++++---- .../LocalEmbeddedResourceSources.js | 2 + 4 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/EmbeddedResourcesMappingTable.js diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index f8936ec17f1b..9c6cc968d64c 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -150,7 +150,9 @@ const traverseToRemoveMetalnessFromMeshes = ( node: THREE.Object3D ) => node.traverse(removeMetalnessFromMesh); -const readEmbeddedResourcesMapping = (resource: gdResource): {} | null => { +export const readEmbeddedResourcesMapping = ( + resource: gdResource +): {} | null => { const metadataString = resource.getMetadata(); try { const metadata = JSON.parse(metadataString); diff --git a/newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/EmbeddedResourcesMappingTable.js b/newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/EmbeddedResourcesMappingTable.js new file mode 100644 index 000000000000..84877371052f --- /dev/null +++ b/newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/EmbeddedResourcesMappingTable.js @@ -0,0 +1,67 @@ +// @flow +import * as React from 'react'; +import { Trans } from '@lingui/macro'; +import { + Table, + TableBody, + TableHeader, + TableHeaderColumn, + TableRow, + TableRowColumn, +} from '../../UI/Table'; +import { readEmbeddedResourcesMapping } from '../../ObjectsRendering/PixiResourcesLoader'; + +type Props = {| + resources: Array, +|}; + +const styles = { + tableCell: { + // Avoid long filenames breaking the design. + wordBreak: 'break-word', + }, +}; + +export const EmbeddedResourcesMappingTable = ({ resources }: Props) => { + if (resources.length !== 1) return null; + + const resource = resources[0]; + const embeddedResourcesMapping = readEmbeddedResourcesMapping(resource); + if (!embeddedResourcesMapping) return null; + + return ( + + + + + Embedded file name + + + Associated resource name + + + + + {Object.entries(embeddedResourcesMapping).map( + ([embeddedFilePath, associatedResourceNameRaw]) => { + const associatedResourceName = + typeof associatedResourceNameRaw === 'string' + ? associatedResourceNameRaw + : 'Unrecognized value.'; + + return ( + + + {embeddedFilePath} + + + {associatedResourceName} + + + ); + } + )} + +
+ ); +}; diff --git a/newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/index.js b/newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/index.js index 1d385fc2c629..5ed443485a87 100644 --- a/newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/index.js +++ b/newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/index.js @@ -16,6 +16,10 @@ import { type ResourceManagementProps, } from '../../ResourcesList/ResourceSource'; import useForceUpdate from '../../Utils/UseForceUpdate'; +import { EmbeddedResourcesMappingTable } from './EmbeddedResourcesMappingTable'; +import { Column, Spacer } from '../../UI/Grid'; +import ScrollView from '../../UI/ScrollView'; +import { ColumnStackLayout } from '../../UI/Layout'; const styles = { propertiesContainer: { @@ -152,15 +156,10 @@ const ResourcePropertiesEditor = React.forwardRef< ); return ( -
'' + resource.ptr).join(';')} - > - -
+ ); }, [resources, schema, forceUpdate] @@ -181,9 +180,18 @@ const ResourcePropertiesEditor = React.forwardRef< return ( {renderPreview()} - {!resources || !resources.length - ? renderEmpty() - : renderResourcesProperties()} + + + '' + resource.ptr).join(';')} + > + {!resources || !resources.length + ? renderEmpty() + : renderResourcesProperties()} + + + ); } diff --git a/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js b/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js index 947e174aeef0..50b3c97b42d6 100644 --- a/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js +++ b/newIDE/app/src/ResourcesList/LocalEmbeddedResourceSources.js @@ -286,6 +286,8 @@ export async function listSpineTextureAtlasEmbeddedResources( const atlasImageRegex = /.*\.(png|jpeg|jpg)$/gm; const imageDependencies = atlasContent.match(atlasImageRegex); + if (!imageDependencies) return null; + const dir = path.dirname(filePath); const embeddedResources = new Map(); let hasAnyEmbeddedResourceOutsideProjectFolder = false; From 804918e3a4839393d32d01961a9d016a963e240e Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Sat, 23 Dec 2023 16:11:40 +0100 Subject: [PATCH 58/80] Improve some wordings --- Extensions/Spine/JsExtension.js | 2 +- .../app/src/EventsSheet/ParameterFields/SpineResourceField.js | 2 +- newIDE/app/src/ObjectEditor/Editors/SpineEditor.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index a9566d22aca0..cf1b2fd2eda9 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -35,7 +35,7 @@ module.exports = { 'Open source (MIT License)' ) .setExtensionHelpPath('/objects/spine') - .setCategory('General'); + .setCategory('Advanced'); extension .addInstructionOrExpressionGroupMetadata(_('Spine')) diff --git a/newIDE/app/src/EventsSheet/ParameterFields/SpineResourceField.js b/newIDE/app/src/EventsSheet/ParameterFields/SpineResourceField.js index d50a335ac837..0fb83d3c0177 100644 --- a/newIDE/app/src/EventsSheet/ParameterFields/SpineResourceField.js +++ b/newIDE/app/src/EventsSheet/ParameterFields/SpineResourceField.js @@ -34,7 +34,7 @@ export default React.forwardRef( project={props.project} resourceManagementProps={props.resourceManagementProps} resourcesLoader={ResourcesLoader} - resourceKind="json" + resourceKind="spine" fullWidth initialResourceName={props.value} onChange={props.onChange} diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 47f144eb878f..2ada9b08dc32 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -373,8 +373,8 @@ const SpineEditor = ({ title={Add your first animation} description={ - Import one or more animations that available in spine - file. + Import one or more animations that are available in + this Spine file. } actionLabel={Add an animation} From 6727d016db02d4ea5150557c977daade58c13d12 Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Sat, 23 Dec 2023 16:12:29 +0100 Subject: [PATCH 59/80] Properly factor property fields between Spine and 3D model editors --- .../src/ObjectEditor/Editors/Model3DEditor.js | 157 +---------------- .../ObjectEditor/Editors/PropertyFields.js | 158 ++++++++++++++++++ .../src/ObjectEditor/Editors/SpineEditor.js | 19 ++- 3 files changed, 178 insertions(+), 156 deletions(-) create mode 100644 newIDE/app/src/ObjectEditor/Editors/PropertyFields.js diff --git a/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js b/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js index 154536244c22..b6b3de568eb0 100644 --- a/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/Model3DEditor.js @@ -8,20 +8,11 @@ import { ColumnStackLayout, ResponsiveLineStackLayout } from '../../UI/Layout'; import Text from '../../UI/Text'; import SemiControlledTextField from '../../UI/SemiControlledTextField'; import useForceUpdate from '../../Utils/UseForceUpdate'; -import ResourceSelector from '../../ResourcesList/ResourceSelector'; import Checkbox from '../../UI/Checkbox'; import { Column, Line, Spacer } from '../../UI/Grid'; -import FormHelperText from '@material-ui/core/FormHelperText'; -import InputAdornment from '@material-ui/core/InputAdornment'; -import Tooltip from '@material-ui/core/Tooltip'; -import { MarkdownText } from '../../UI/MarkdownText'; import SelectField from '../../UI/SelectField'; import SelectOption from '../../UI/SelectOption'; -import MeasurementUnitDocumentation from '../../PropertiesEditor/MeasurementUnitDocumentation'; -import { getMeasurementUnitShortLabel } from '../../PropertiesEditor/PropertiesMapToSchema'; import AlertMessage from '../../UI/AlertMessage'; -import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource'; -import ResourcesLoader from '../../ResourcesLoader'; import IconButton from '../../UI/IconButton'; import RaisedButton from '../../UI/RaisedButton'; import FlatButton from '../../UI/FlatButton'; @@ -39,6 +30,11 @@ import useAlertDialog from '../../UI/Alert/useAlertDialog'; import { type GLTF } from 'three/examples/jsm/loaders/GLTFLoader'; import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils'; import * as THREE from 'three'; +import { + PropertyCheckbox, + PropertyField, + PropertyResourceSelector, +} from './PropertyFields'; const gd: libGDevelop = global.gd; @@ -46,7 +42,7 @@ const DragSourceAndDropTarget = makeDragSourceAndDropTarget( 'model3d-animations-list' ); -export const styles = { +const styles = { rowContainer: { display: 'flex', flexDirection: 'column', @@ -100,147 +96,6 @@ export const hasLight = (layout: ?gd.Layout) => { return false; }; -type PropertyFieldProps = {| - objectConfiguration: gdObjectConfiguration, - propertyName: string, - onChange?: () => void, -|}; - -export const PropertyField = ({ - objectConfiguration, - propertyName, - onChange, -}: PropertyFieldProps) => { - const forceUpdate = useForceUpdate(); - const properties = objectConfiguration.getProperties(); - - const updateProperty = React.useCallback( - (value: string) => { - const oldValue = objectConfiguration - .getProperties() - .get(propertyName) - .getValue(); - objectConfiguration.updateProperty(propertyName, value); - const newValue = objectConfiguration - .getProperties() - .get(propertyName) - .getValue(); - if (onChange && newValue !== oldValue) { - onChange(); - } - forceUpdate(); - }, - [objectConfiguration, propertyName, onChange, forceUpdate] - ); - - const property = properties.get(propertyName); - const measurementUnit = property.getMeasurementUnit(); - const endAdornment = { - label: getMeasurementUnitShortLabel(measurementUnit), - tooltipContent: ( - - ), - }; - return ( - - - {endAdornment.label} - - } - /> - - ); -}; - -export const PropertyCheckbox = ({ - objectConfiguration, - propertyName, -}: PropertyFieldProps) => { - const forceUpdate = useForceUpdate(); - const properties = objectConfiguration.getProperties(); - - const onChangeProperty = React.useCallback( - (property: string, value: string) => { - objectConfiguration.updateProperty(property, value); - forceUpdate(); - }, - [objectConfiguration, forceUpdate] - ); - - const property = properties.get(propertyName); - return ( - - {property.getLabel()} - - - - - } - onCheck={(_, value) => { - onChangeProperty(propertyName, value ? '1' : '0'); - }} - /> - ); -}; - -type PropertyResourceSelectorProps = {| - objectConfiguration: gdObjectConfiguration, - propertyName: string, - project: gd.Project, - resourceManagementProps: ResourceManagementProps, - onChange: (value: string) => void, -|}; - -export const PropertyResourceSelector = ({ - objectConfiguration, - propertyName, - project, - resourceManagementProps, - onChange, -}: PropertyResourceSelectorProps) => { - const forceUpdate = useForceUpdate(); - const { current: resourcesLoader } = React.useRef(ResourcesLoader); - const properties = objectConfiguration.getProperties(); - - const onChangeProperty = React.useCallback( - (property: string, value: string) => { - objectConfiguration.updateProperty(property, value); - onChange(value); - forceUpdate(); - }, - [objectConfiguration, onChange, forceUpdate] - ); - - const property = properties.get(propertyName); - const extraInfos = property.getExtraInfo(); - return ( - 0 ? extraInfos.at(0) : ''} - floatingLabelText={property.getLabel()} - resourceManagementProps={resourceManagementProps} - initialResourceName={property.getValue()} - onChange={value => onChangeProperty(propertyName, value)} - resourcesLoader={resourcesLoader} - fullWidth - /> - ); -}; - const Model3DEditor = ({ objectConfiguration, project, diff --git a/newIDE/app/src/ObjectEditor/Editors/PropertyFields.js b/newIDE/app/src/ObjectEditor/Editors/PropertyFields.js new file mode 100644 index 000000000000..94f70ce1954d --- /dev/null +++ b/newIDE/app/src/ObjectEditor/Editors/PropertyFields.js @@ -0,0 +1,158 @@ +// @flow +import * as React from 'react'; +import SemiControlledTextField from '../../UI/SemiControlledTextField'; +import useForceUpdate from '../../Utils/UseForceUpdate'; +import Checkbox from '../../UI/Checkbox'; +import ResourceSelector from '../../ResourcesList/ResourceSelector'; +import FormHelperText from '@material-ui/core/FormHelperText'; +import InputAdornment from '@material-ui/core/InputAdornment'; +import Tooltip from '@material-ui/core/Tooltip'; +import { MarkdownText } from '../../UI/MarkdownText'; +import MeasurementUnitDocumentation from '../../PropertiesEditor/MeasurementUnitDocumentation'; +import { getMeasurementUnitShortLabel } from '../../PropertiesEditor/PropertiesMapToSchema'; +import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource'; +import ResourcesLoader from '../../ResourcesLoader'; +import { Column, Line } from '../../UI/Grid'; + +const gd: libGDevelop = global.gd; + +type PropertyFieldProps = {| + objectConfiguration: gdObjectConfiguration, + propertyName: string, + onChange?: () => void, +|}; + +export const PropertyField = ({ + objectConfiguration, + propertyName, + onChange, +}: PropertyFieldProps) => { + const forceUpdate = useForceUpdate(); + const properties = objectConfiguration.getProperties(); + + const updateProperty = React.useCallback( + (value: string) => { + const oldValue = objectConfiguration + .getProperties() + .get(propertyName) + .getValue(); + objectConfiguration.updateProperty(propertyName, value); + const newValue = objectConfiguration + .getProperties() + .get(propertyName) + .getValue(); + if (onChange && newValue !== oldValue) { + onChange(); + } + forceUpdate(); + }, + [objectConfiguration, propertyName, onChange, forceUpdate] + ); + + const property = properties.get(propertyName); + const measurementUnit = property.getMeasurementUnit(); + const endAdornment = { + label: getMeasurementUnitShortLabel(measurementUnit), + tooltipContent: ( + + ), + }; + return ( + + + {endAdornment.label} + + } + /> + + ); +}; + +export const PropertyCheckbox = ({ + objectConfiguration, + propertyName, +}: PropertyFieldProps) => { + const forceUpdate = useForceUpdate(); + const properties = objectConfiguration.getProperties(); + + const onChangeProperty = React.useCallback( + (property: string, value: string) => { + objectConfiguration.updateProperty(property, value); + forceUpdate(); + }, + [objectConfiguration, forceUpdate] + ); + + const property = properties.get(propertyName); + return ( + + {property.getLabel()} + + + + + } + onCheck={(_, value) => { + onChangeProperty(propertyName, value ? '1' : '0'); + }} + /> + ); +}; + +type PropertyResourceSelectorProps = {| + objectConfiguration: gdObjectConfiguration, + propertyName: string, + project: gd.Project, + resourceManagementProps: ResourceManagementProps, + onChange: (value: string) => void, +|}; + +export const PropertyResourceSelector = ({ + objectConfiguration, + propertyName, + project, + resourceManagementProps, + onChange, +}: PropertyResourceSelectorProps) => { + const forceUpdate = useForceUpdate(); + const { current: resourcesLoader } = React.useRef(ResourcesLoader); + const properties = objectConfiguration.getProperties(); + + const onChangeProperty = React.useCallback( + (property: string, value: string) => { + objectConfiguration.updateProperty(property, value); + onChange(value); + forceUpdate(); + }, + [objectConfiguration, onChange, forceUpdate] + ); + + const property = properties.get(propertyName); + const extraInfos = property.getExtraInfo(); + return ( + 0 ? extraInfos.at(0) : ''} + floatingLabelText={property.getLabel()} + resourceManagementProps={resourceManagementProps} + initialResourceName={property.getValue()} + onChange={value => onChangeProperty(propertyName, value)} + resourcesLoader={resourcesLoader} + fullWidth + /> + ); +}; diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 2ada9b08dc32..2748ab9c12f1 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -26,11 +26,7 @@ import DropIndicator from '../../UI/SortableVirtualizedItemList/DropIndicator'; import GDevelopThemeContext from '../../UI/Theme/GDevelopThemeContext'; import PixiResourcesLoader from '../../ObjectsRendering/PixiResourcesLoader'; import useAlertDialog from '../../UI/Alert/useAlertDialog'; -import { - PropertyResourceSelector, - PropertyField, - styles, -} from './Model3DEditor'; +import { PropertyResourceSelector, PropertyField } from './PropertyFields'; import { ISkeletonData } from 'pixi-spine'; const gd: libGDevelop = global.gd; @@ -39,6 +35,19 @@ const DragSourceAndDropTarget = makeDragSourceAndDropTarget( 'spine-animations-list' ); +const styles = { + rowContainer: { + display: 'flex', + flexDirection: 'column', + marginTop: 5, + }, + rowContent: { + display: 'flex', + flex: 1, + alignItems: 'center', + }, +}; + const SpineEditor = ({ objectConfiguration, project, From 9bbbef96d5eeffa36044a90874def1dfe15bf01b Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Sat, 23 Dec 2023 16:35:08 +0100 Subject: [PATCH 60/80] Refactor some logic out of React components and fix animations cleared when blurring out the spine file property field --- .../ObjectEditor/Editors/PropertyFields.js | 19 ++++-- .../src/ObjectEditor/Editors/SpineEditor.js | 64 ++++++++----------- 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/newIDE/app/src/ObjectEditor/Editors/PropertyFields.js b/newIDE/app/src/ObjectEditor/Editors/PropertyFields.js index 94f70ce1954d..e045758dd640 100644 --- a/newIDE/app/src/ObjectEditor/Editors/PropertyFields.js +++ b/newIDE/app/src/ObjectEditor/Editors/PropertyFields.js @@ -132,25 +132,32 @@ export const PropertyResourceSelector = ({ const properties = objectConfiguration.getProperties(); const onChangeProperty = React.useCallback( - (property: string, value: string) => { - objectConfiguration.updateProperty(property, value); - onChange(value); + (propertyName: string, newValue: string) => { + objectConfiguration.updateProperty(propertyName, newValue); + onChange(newValue); forceUpdate(); }, [objectConfiguration, onChange, forceUpdate] ); + // Note that property is a temporary - don't access it in callbacks. const property = properties.get(propertyName); const extraInfos = property.getExtraInfo(); + const value = property.getValue(); + const label = property.getLabel(); + return ( 0 ? extraInfos.at(0) : ''} - floatingLabelText={property.getLabel()} + floatingLabelText={label} resourceManagementProps={resourceManagementProps} - initialResourceName={property.getValue()} - onChange={value => onChangeProperty(propertyName, value)} + initialResourceName={value} + onChange={newValue => { + if (newValue !== value) + onChangeProperty(propertyName, newValue); + }} resourcesLoader={resourcesLoader} fullWidth /> diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 2748ab9c12f1..f40ba5a2f351 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -24,7 +24,9 @@ import { makeDragSourceAndDropTarget } from '../../UI/DragAndDrop/DragSourceAndD import { DragHandleIcon } from '../../UI/DragHandle'; import DropIndicator from '../../UI/SortableVirtualizedItemList/DropIndicator'; import GDevelopThemeContext from '../../UI/Theme/GDevelopThemeContext'; -import PixiResourcesLoader from '../../ObjectsRendering/PixiResourcesLoader'; +import PixiResourcesLoader, { + readEmbeddedResourcesMapping, +} from '../../ObjectsRendering/PixiResourcesLoader'; import useAlertDialog from '../../UI/Alert/useAlertDialog'; import { PropertyResourceSelector, PropertyField } from './PropertyFields'; import { ISkeletonData } from 'pixi-spine'; @@ -48,6 +50,18 @@ const styles = { }, }; +const getAndReadEmbeddedResourcesMapping = ( + project: gdProject, + resourceName: string +) => { + const resourcesManager = project.getResourcesManager(); + if (!resourcesManager.hasResource(resourceName)) return null; + + return readEmbeddedResourcesMapping( + resourcesManager.getResource(resourceName) + ); +}; + const SpineEditor = ({ objectConfiguration, project, @@ -58,22 +72,6 @@ const SpineEditor = ({ resourceManagementProps, }: EditorProps) => { const scrollView = React.useRef(null); - - const getResource = React.useCallback( - (name: string) => { - const resourcesManager = project.getResourcesManager(); - - return resourcesManager.hasResource(name) - ? resourcesManager.getResource(name) - : null; - }, - [project] - ); - const getMetadata = resource => { - const metadataString = resource ? resource.getMetadata() : ''; - - return !!metadataString ? JSON.parse(metadataString) : {}; - }; const [ justAddedAnimationName, setJustAddedAnimationName, @@ -109,29 +107,23 @@ const SpineEditor = ({ ); const [skeleton, setSkeleton] = React.useState(null); - const getEmbeddedResourcesMapping = React.useCallback( - (resourceName: string): { [string]: string } => { - const resource = getResource(resourceName); - return getMetadata(resource).embeddedResourcesMapping; - }, - [getResource] - ); const loadSkeleton = React.useCallback( - (spineResourceName: string) => { - const jsonResourcesMapping = getEmbeddedResourcesMapping( + async (spineResourceName: string) => { + const embeddedResourcesMapping = getAndReadEmbeddedResourcesMapping( + project, spineResourceName ); - if (!jsonResourcesMapping) return Promise.resolve(undefined); + if (!embeddedResourcesMapping) return null; - const jsonResourcesMappingValues = Object.values(jsonResourcesMapping); - const textureAtlasName = jsonResourcesMappingValues[0]; - - // flow check - if (typeof textureAtlasName !== 'string') - return Promise.resolve(undefined); + const embeddedResourcesMappingValues = Object.values( + embeddedResourcesMapping + ); + const textureAtlasName = embeddedResourcesMappingValues[0]; + if (typeof textureAtlasName !== 'string') return null; - const atlasResourcesMapping = getEmbeddedResourcesMapping( + const atlasResourcesMapping = getAndReadEmbeddedResourcesMapping( + project, textureAtlasName ); @@ -139,11 +131,11 @@ const SpineEditor = ({ !atlasResourcesMapping || !Object.values(atlasResourcesMapping).length ) - return Promise.resolve(undefined); + return null; return PixiResourcesLoader.getSpineData(project, spineResourceName); }, - [project, getEmbeddedResourcesMapping] + [project] ); const [sourceSelectOptions, setSourceSelectOptions] = React.useState< Array From e08f8a13d36d9d291ee97fd106d46f19c1eee56c Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Sat, 23 Dec 2023 19:45:12 +0200 Subject: [PATCH 61/80] clear and format code --- .../app/src/ObjectEditor/Editors/PropertyFields.js | 3 +-- .../ResourcePropertiesEditor/index.js | 12 +----------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/newIDE/app/src/ObjectEditor/Editors/PropertyFields.js b/newIDE/app/src/ObjectEditor/Editors/PropertyFields.js index e045758dd640..7ea7da2aeca0 100644 --- a/newIDE/app/src/ObjectEditor/Editors/PropertyFields.js +++ b/newIDE/app/src/ObjectEditor/Editors/PropertyFields.js @@ -155,8 +155,7 @@ export const PropertyResourceSelector = ({ resourceManagementProps={resourceManagementProps} initialResourceName={value} onChange={newValue => { - if (newValue !== value) - onChangeProperty(propertyName, newValue); + if (newValue !== value) onChangeProperty(propertyName, newValue); }} resourcesLoader={resourcesLoader} fullWidth diff --git a/newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/index.js b/newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/index.js index 5ed443485a87..aafbc58fce3a 100644 --- a/newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/index.js +++ b/newIDE/app/src/ResourcesEditor/ResourcePropertiesEditor/index.js @@ -17,20 +17,10 @@ import { } from '../../ResourcesList/ResourceSource'; import useForceUpdate from '../../Utils/UseForceUpdate'; import { EmbeddedResourcesMappingTable } from './EmbeddedResourcesMappingTable'; -import { Column, Spacer } from '../../UI/Grid'; +import { Spacer } from '../../UI/Grid'; import ScrollView from '../../UI/ScrollView'; import { ColumnStackLayout } from '../../UI/Layout'; -const styles = { - propertiesContainer: { - padding: 8, - overflowY: 'scroll', - scrollbarWidth: 'thin', // For Firefox, to avoid having a very large scrollbar. - overflowX: 'hidden', - flex: 1, - }, -}; - type Props = {| project: gdProject, resourcesLoader: typeof ResourcesLoader, From 7bf0848d61a41ca8bb821496aeabeb574b82ea85 Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Sun, 24 Dec 2023 18:26:01 +0100 Subject: [PATCH 62/80] Add display of the loading error of a Spine in the Spine editor --- Extensions/Spine/JsExtension.js | 43 +++--- .../src/ObjectEditor/Editors/SpineEditor.js | 100 +++++++------ .../ObjectsRendering/PixiResourcesLoader.js | 132 ++++++++++++------ 3 files changed, 162 insertions(+), 113 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index cf1b2fd2eda9..b26a3892a5e2 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -194,7 +194,7 @@ module.exports = { */ registerEditorConfigurations: function ( objectsEditorService /*: ObjectsEditorService */ - ) { }, + ) {}, /** * Register renderers for instance of objects on the scene editor. * @@ -265,7 +265,10 @@ module.exports = { this._spineOriginOffsetX = localBounds.x * spine.scale.x; this._spineOriginOffsetY = localBounds.y * spine.scale.y; - this._rect.position.set(this._spineOriginOffsetX, this._spineOriginOffsetY); + this._rect.position.set( + this._spineOriginOffsetX, + this._spineOriginOffsetY + ); } this._rect.clear(); @@ -330,18 +333,14 @@ module.exports = { * @returns {number} default width */ getDefaultWidth() { - return (this._initialWidth !== null - ? this._initialWidth - : 256); + return this._initialWidth !== null ? this._initialWidth : 256; } /** * @returns {number} default height */ getDefaultHeight() { - return (this._initialHeight !== null - ? this._initialHeight - : 256); + return this._initialHeight !== null ? this._initialHeight : 256; } /** @@ -377,19 +376,25 @@ module.exports = { .getValue(); this._pixiResourcesLoader - .getSpineData( - this._project, - spineResourceName, - ) - .then((spineData) => { - if (!spineData) return; - - this._spine = new PIXI.Spine(spineData); + .getSpineData(this._project, spineResourceName) + .then((spineDataOrLoadingError) => { + if (!spineDataOrLoadingError.skeleton) { + const loadingError = + spineDataOrLoadingError.loadingError || + (spineDataOrLoadingError.textureAtlasOrLoadingError + ? spineDataOrLoadingError.textureAtlasOrLoadingError + .loadingError + : null); + console.error( + 'Unable to load Spine: ' + (loadingError || 'Unknown reason.') + ); + this._spine = null; + return; + } + + this._spine = new PIXI.Spine(spineDataOrLoadingError.skeleton); this._pixiObject.addChild(this._spine); this.update(); - }, (err) => { - console.error("Unable to load Spine:", err); - this._spine = null; }); } } diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index f40ba5a2f351..f85ae50817cc 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -25,11 +25,11 @@ import { DragHandleIcon } from '../../UI/DragHandle'; import DropIndicator from '../../UI/SortableVirtualizedItemList/DropIndicator'; import GDevelopThemeContext from '../../UI/Theme/GDevelopThemeContext'; import PixiResourcesLoader, { - readEmbeddedResourcesMapping, + type SpineDataOrLoadingError, } from '../../ObjectsRendering/PixiResourcesLoader'; import useAlertDialog from '../../UI/Alert/useAlertDialog'; import { PropertyResourceSelector, PropertyField } from './PropertyFields'; -import { ISkeletonData } from 'pixi-spine'; +import AlertMessage from '../../UI/AlertMessage'; const gd: libGDevelop = global.gd; @@ -50,18 +50,6 @@ const styles = { }, }; -const getAndReadEmbeddedResourcesMapping = ( - project: gdProject, - resourceName: string -) => { - const resourcesManager = project.getResourcesManager(); - if (!resourcesManager.hasResource(resourceName)) return null; - - return readEmbeddedResourcesMapping( - resourcesManager.getResource(resourceName) - ); -}; - const SpineEditor = ({ objectConfiguration, project, @@ -106,37 +94,11 @@ const SpineEditor = ({ {} ); - const [skeleton, setSkeleton] = React.useState(null); - - const loadSkeleton = React.useCallback( - async (spineResourceName: string) => { - const embeddedResourcesMapping = getAndReadEmbeddedResourcesMapping( - project, - spineResourceName - ); - if (!embeddedResourcesMapping) return null; - - const embeddedResourcesMappingValues = Object.values( - embeddedResourcesMapping - ); - const textureAtlasName = embeddedResourcesMappingValues[0]; - if (typeof textureAtlasName !== 'string') return null; - - const atlasResourcesMapping = getAndReadEmbeddedResourcesMapping( - project, - textureAtlasName - ); + const [spineData, setSpineData] = React.useState({ + skeleton: null, + loadingError: null, + }); - if ( - !atlasResourcesMapping || - !Object.values(atlasResourcesMapping).length - ) - return null; - - return PixiResourcesLoader.getSpineData(project, spineResourceName); - }, - [project] - ); const [sourceSelectOptions, setSourceSelectOptions] = React.useState< Array >([]); @@ -145,13 +107,16 @@ const SpineEditor = ({ React.useEffect( () => { (async () => { - const skeleton = await loadSkeleton(spineResourceName); + const spineData = await PixiResourcesLoader.getSpineData( + project, + spineResourceName + ); - setSkeleton(skeleton); + setSpineData(spineData); - if (skeleton) { + if (spineData.skeleton) { setSourceSelectOptions( - skeleton.animations.map(animation => ( + spineData.skeleton.animations.map(animation => ( { - if (!skeleton) { - return; - } + const { skeleton } = spineData; + if (!skeleton) return; + setNameErrors({}); const animationSources = mapFor( @@ -229,7 +194,7 @@ const SpineEditor = ({ }, [ forceUpdate, - skeleton, + spineData, spineConfiguration, onObjectUpdated, onSizeUpdated, @@ -346,6 +311,35 @@ const SpineEditor = ({ resourceManagementProps={resourceManagementProps} onChange={onChangeSpineResourceName} /> + {!spineData.skeleton && + (spineData.loadingError || spineData.textureAtlasOrLoadingError) ? ( + + {spineData.loadingError === 'invalid-spine-resource' ? ( + + The selected resource is not a proper Spine resource. + + ) : spineData.loadingError === 'missing-texture-atlas-name' ? ( + Missing texture atlas name in the Spine file. + ) : spineData.loadingError === 'spine-resource-loading-error' ? ( + Error while loading the Spine resource. + ) : spineData.textureAtlasOrLoadingError ? ( + spineData.textureAtlasOrLoadingError.loadingError === + 'invalid-atlas-resource' ? ( + + The Atlas embed in the Spine fine ca'n't be located. + + ) : spineData.textureAtlasOrLoadingError.loadingError === + 'missing-texture-resources' ? ( + Missing texture for an atlas in the Spine file. + ) : spineData.textureAtlasOrLoadingError.loadingError === + 'atlas-resource-loading-error' ? ( + + Error while loading the Spine Texture Atlas resource. + + ) : null + ) : null} + + ) : null} Appearance diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 9c6cc968d64c..5a61d52ce180 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -13,6 +13,25 @@ import { loadFontFace } from '../Utils/FontFaceLoader'; import { checkIfCredentialsRequired } from '../Utils/CrossOrigin'; const gd: libGDevelop = global.gd; +type SpineTextureAtlasOrLoadingError = {| + textureAtlas: ?TextureAtlas, + loadingError: + | null + | 'invalid-atlas-resource' + | 'missing-texture-resources' + | 'atlas-resource-loading-error', +|}; + +export type SpineDataOrLoadingError = {| + skeleton: ?ISkeleton, + loadingError: + | null + | 'invalid-spine-resource' + | 'missing-texture-atlas-name' + | 'spine-resource-loading-error', + textureAtlasOrLoadingError?: SpineTextureAtlasOrLoadingError, +|}; + type ResourcePromise = { [resourceName: string]: Promise }; let loadedBitmapFonts = {}; @@ -22,10 +41,8 @@ const invalidTexture = PIXI.Texture.from('res/error48.png'); let loadedThreeTextures = {}; let loadedThreeMaterials = {}; let loadedOrLoading3DModelPromises: ResourcePromise = {}; -let spineAtlasPromises: ResourcePromise< - PIXI_SPINE.TextureAtlas | typeof undefined -> = {}; -let spineDataPromises: ResourcePromise = {}; +let spineAtlasPromises: ResourcePromise = {}; +let spineDataPromises: ResourcePromise = {}; const createInvalidModel = (): GLTF => { /** @@ -484,25 +501,31 @@ export default class PixiResourcesLoader { static async _getSpineTextureAtlas( project: gdProject, spineTextureAtlasName: string - ): Promise { + ): Promise { const promise = spineAtlasPromises[spineTextureAtlasName]; if (promise) return promise; - if (!spineTextureAtlasName) - throw new Error('No resource name was specified.'); + if (!spineTextureAtlasName) { + return { + textureAtlas: null, + loadingError: 'invalid-atlas-resource', + }; + } const resourceManager = project.getResourcesManager(); if (!resourceManager.hasResource(spineTextureAtlasName)) { - throw new Error( - `Can't find resource with name ${spineTextureAtlasName}.` - ); + return { + textureAtlas: null, + loadingError: 'invalid-atlas-resource', + }; } const resource = resourceManager.getResource(spineTextureAtlasName); if (resource.getKind() !== 'atlas') { - throw new Error( - `Resource "${spineTextureAtlasName}" is not of appropriate type "atlas".` - ); + return { + textureAtlas: null, + loadingError: 'invalid-atlas-resource', + }; } const embeddedResourcesMapping = readEmbeddedResourcesMapping(resource); @@ -510,9 +533,10 @@ export default class PixiResourcesLoader { ? Object.entries(embeddedResourcesMapping) : []; if (!textureAtlasMappingEntries.length) { - throw new Error( - `Unable to find embedded resources mapping for ${spineTextureAtlasName} atlas.` - ); + return { + textureAtlas: null, + loadingError: 'missing-texture-resources', + }; } const images = textureAtlasMappingEntries.reduce( @@ -557,17 +581,27 @@ export default class PixiResourcesLoader { atlas, (textureName, textureCb) => textureCb(images[textureName].baseTexture), - resolve + textureAtlas => + resolve({ + textureAtlas, + loadingError: null, + }) ); } else { - resolve(atlas); + resolve({ + textureAtlas: atlas, + loadingError: null, + }); } }, err => { console.error( `Error while loading Spine atlas "${spineTextureAtlasName}": ${err}.\nCheck if you selected the correct pair of atlas and image files.` ); - resolve(null); + resolve({ + textureAtlas: null, + loadingError: 'atlas-resource-loading-error', + }); } ); })); @@ -582,22 +616,32 @@ export default class PixiResourcesLoader { static async getSpineData( project: gdProject, spineName: string - ): Promise { + ): Promise { const promise = spineDataPromises[spineName]; if (promise) return promise; - if (!spineName) throw new Error('No resource name was specified.'); + if (!spineName) { + // Nothing is even tried to be loaded. + return { + skeleton: null, + loadingError: null, + }; + } const resourceManager = project.getResourcesManager(); if (!resourceManager.hasResource(spineName)) { - throw new Error(`Can't find resource with name ${spineName}.`); + return { + skeleton: null, + loadingError: 'invalid-spine-resource', + }; } const resource = resourceManager.getResource(spineName); if (resource.getKind() !== 'spine') { - throw new Error( - `Resource "${spineName}" is not of appropriate type "spine".` - ); + return { + skeleton: null, + loadingError: 'invalid-spine-resource', + }; } const embeddedResourcesMapping = readEmbeddedResourcesMapping(resource); @@ -605,19 +649,21 @@ export default class PixiResourcesLoader { ? Object.values(embeddedResourcesMapping)[0] : null; if (typeof spineTextureAtlasName !== 'string') { - throw new Error( - `Unable to find embedded resources mapping for ${spineName} spine.` - ); + return { + skeleton: null, + loadingError: 'missing-texture-atlas-name', + }; } return (spineDataPromises[spineName] = new Promise(resolve => { this._getSpineTextureAtlas(project, spineTextureAtlasName).then( - spineAtlas => { - if (!spineAtlas) { - console.error( - `Cannot load ${spineName} spine. Atlas ${spineTextureAtlasName} is undefined. Check if you selected correct files.` - ); - return resolve(null); + textureAtlasOrLoadingError => { + if (!textureAtlasOrLoadingError.textureAtlas) { + return resolve({ + skeleton: null, + loadingError: null, + textureAtlasOrLoadingError, + }); } const spineUrl = ResourcesLoader.getResourceFullUrl( @@ -633,22 +679,26 @@ export default class PixiResourcesLoader { ? 'use-credentials' : 'anonymous', }); - PIXI.Assets.add(spineName, spineUrl, { spineAtlas }); + PIXI.Assets.add(spineName, spineUrl, { + spineAtlas: textureAtlasOrLoadingError.textureAtlas, + }); PIXI.Assets.load(spineName).then( jsonData => { - resolve(jsonData.spineData); + resolve({ + skeleton: jsonData.spineData, + loadingError: null, + }); }, err => { console.error( `Error while loading Spine data "${spineName}": ${err}.\nCheck if you selected correct files.` ); - resolve(null); + resolve({ + skeleton: null, + loadingError: 'spine-resource-loading-error', + }); } ); - }, - err => { - console.error('Error while loading Spine atlas:', err); - resolve(null); } ); })); From a5411387e9b8d7b2664e8dd04ee4b27509cbf6cd Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Sun, 24 Dec 2023 18:44:44 +0100 Subject: [PATCH 63/80] Robustify against crashes when loading a Spine in the editor --- Extensions/Spine/JsExtension.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index b26a3892a5e2..cae83feff3bd 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -392,7 +392,13 @@ module.exports = { return; } - this._spine = new PIXI.Spine(spineDataOrLoadingError.skeleton); + try { + this._spine = new PIXI.Spine(spineDataOrLoadingError.skeleton); + } catch (error) { + console.error('Exception while loading Spine.', error); + this._spine = null; + return; + } this._pixiObject.addChild(this._spine); this.update(); }); From a974c743129ee73d4bdf67c1ce3a594e2136279d Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Thu, 28 Dec 2023 13:58:03 +0200 Subject: [PATCH 64/80] stop destroy children textures on spine destroy --- Extensions/Spine/JsExtension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index cae83feff3bd..4733dac1942d 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -352,7 +352,7 @@ module.exports = { onRemovedFromScene() { super.onRemovedFromScene(); - this._pixiObject.destroy(true); + this._pixiObject.destroy({ children: true }); } /** From 6e6b13d8f1ba8e4ac2c9a01f293d06b0c4c82947 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Fri, 5 Jan 2024 16:47:39 +0200 Subject: [PATCH 65/80] implement reloading for spine resources --- .../ObjectsRendering/PixiResourcesLoader.js | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 5a61d52ce180..5bd96e4cf9d4 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -186,6 +186,38 @@ export const readEmbeddedResourcesMapping = ( } }; +const getEmbeddedOwnerResource = ( + project: gdProject, + resourceName: string +): null | gdResource => { + const resourcesManager = project.getResourcesManager(); + + for (const supposedOwnerResourceName of resourcesManager + .getAllResourceNames() + .toJSArray()) { + if (resourceName === supposedOwnerResourceName) { + continue; + } + + const supposedOwnerResource = resourcesManager.getResource( + supposedOwnerResourceName + ); + const embeddedResourcesMapping = readEmbeddedResourcesMapping( + supposedOwnerResource + ); + if (!embeddedResourcesMapping) { + continue; + } + + const mappedResources = Object.values(embeddedResourcesMapping); + if (mappedResources.includes(resourceName)) { + return supposedOwnerResource; + } + } + + return null; +}; + /** * Expose functions to load PIXI textures or fonts, given the names of * resources and a gd.Project. @@ -219,6 +251,17 @@ export default class PixiResourcesLoader { // been added and detected by file watcher. When reloading the texture, the cache must // be cleaned too. delete loadedTextures[resourceName]; + + const supposedAtlasOwner = getEmbeddedOwnerResource( + project, + resourceName + ); + if (supposedAtlasOwner && supposedAtlasOwner.getKind() === 'atlas') { + await this.reloadTextureForResource( + project, + supposedAtlasOwner.getName() + ); + } } await PixiResourcesLoader.loadTextures(project, [resourceName]); @@ -236,6 +279,43 @@ export default class PixiResourcesLoader { loadedThreeTextures[resourceName].dispose(); delete loadedThreeTextures[resourceName]; } + if (spineAtlasPromises[resourceName]) { + /** + * Expected error due to https://github.com/pixijs/spine/issues/537 issue (read comments). + * String is stored as loaded atlas resource but pixi-spine considers it as TextureAtlas and tries to call dispose on it that causes TypeError. + */ + await PIXI.Assets.unload(resourceName).catch(async () => { + const { textureAtlas } = await spineAtlasPromises[resourceName]; + if (textureAtlas) textureAtlas.dispose(); + }); + delete spineAtlasPromises[resourceName]; + + const supposedSpineResourceOwner = getEmbeddedOwnerResource( + project, + resourceName + ); + if ( + supposedSpineResourceOwner && + supposedSpineResourceOwner.getKind() === 'spine' + ) { + await this.reloadTextureForResource( + project, + supposedSpineResourceOwner.getName() + ); + } + } + if (spineDataPromises[resourceName]) { + await PIXI.Assets.unload(resourceName); + delete spineDataPromises[resourceName]; + + /** + * This line allows us to omit issue https://github.com/pixijs/pixijs/issues/10069. + * PIXI.Assets.resolver caches data that was passed to PIXI.Assets.add even if resource was unloaded. + * So every time we unload spine resources we need to call it to clean resolver cash + * and pick up fresh data next time we load it. + */ + PIXI.Assets.resolver.prefer(); + } const matchingMaterials = Object.keys(loadedThreeMaterials).filter(key => key.startsWith(resourceName) ); From 962a1ea519abbfc475704fecda30b8398352eeda Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Fri, 5 Jan 2024 17:00:12 +0200 Subject: [PATCH 66/80] make up code --- .../app/src/ObjectsRendering/PixiResourcesLoader.js | 12 +++++++----- newIDE/app/src/SceneEditor/index.js | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 5bd96e4cf9d4..bf183157ca3e 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -189,7 +189,7 @@ export const readEmbeddedResourcesMapping = ( const getEmbeddedOwnerResource = ( project: gdProject, resourceName: string -): null | gdResource => { +): gdResource | null => { const resourcesManager = project.getResourcesManager(); for (const supposedOwnerResourceName of resourcesManager @@ -236,7 +236,7 @@ export default class PixiResourcesLoader { spineDataPromises = {}; } - static async reloadTextureForResource( + static async reloadResource( project: gdProject, resourceName: string ) { @@ -257,7 +257,7 @@ export default class PixiResourcesLoader { resourceName ); if (supposedAtlasOwner && supposedAtlasOwner.getKind() === 'atlas') { - await this.reloadTextureForResource( + await this.reloadResource( project, supposedAtlasOwner.getName() ); @@ -286,7 +286,9 @@ export default class PixiResourcesLoader { */ await PIXI.Assets.unload(resourceName).catch(async () => { const { textureAtlas } = await spineAtlasPromises[resourceName]; - if (textureAtlas) textureAtlas.dispose(); + if (textureAtlas) { + textureAtlas.dispose(); + } }); delete spineAtlasPromises[resourceName]; @@ -298,7 +300,7 @@ export default class PixiResourcesLoader { supposedSpineResourceOwner && supposedSpineResourceOwner.getKind() === 'spine' ) { - await this.reloadTextureForResource( + await this.reloadResource( project, supposedSpineResourceOwner.getName() ); diff --git a/newIDE/app/src/SceneEditor/index.js b/newIDE/app/src/SceneEditor/index.js index 7f3867510d4c..fd84370fa0e5 100644 --- a/newIDE/app/src/SceneEditor/index.js +++ b/newIDE/app/src/SceneEditor/index.js @@ -236,7 +236,7 @@ export default class SceneEditor extends React.Component { // through the RenderedInstance's, triggering crashes. So the scene rendering // is paused during this period. editorDisplay.startSceneRendering(false); - await PixiResourcesLoader.reloadTextureForResource( + await PixiResourcesLoader.reloadResource( project, resourceName ); From db85cde75421814efdb887f404e0a0c49c5d7514 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Fri, 5 Jan 2024 17:10:25 +0200 Subject: [PATCH 67/80] make up code --- .../ObjectsRendering/PixiResourcesLoader.js | 40 ++++++------------- newIDE/app/src/SceneEditor/index.js | 5 +-- 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index bf183157ca3e..d1d2e3d8cdb6 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -11,6 +11,7 @@ import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; import ResourcesLoader from '../ResourcesLoader'; import { loadFontFace } from '../Utils/FontFaceLoader'; import { checkIfCredentialsRequired } from '../Utils/CrossOrigin'; +import { type ResourceKind } from '../ResourcesList/ResourceSource'; const gd: libGDevelop = global.gd; type SpineTextureAtlasOrLoadingError = {| @@ -236,10 +237,18 @@ export default class PixiResourcesLoader { spineDataPromises = {}; } - static async reloadResource( + static async _reloadResourceOwner( project: gdProject, - resourceName: string + resourceName: string, + ownerKind: ResourceKind ) { + const supposedOwner = getEmbeddedOwnerResource(project, resourceName); + if (supposedOwner && supposedOwner.getKind() === ownerKind) { + await this.reloadResource(project, supposedOwner.getName()); + } + } + + static async reloadResource(project: gdProject, resourceName: string) { const loadedTexture = loadedTextures[resourceName]; if (loadedTexture && loadedTexture.textureCacheIds) { // The property textureCacheIds indicates that the PIXI.Texture object has some @@ -251,17 +260,7 @@ export default class PixiResourcesLoader { // been added and detected by file watcher. When reloading the texture, the cache must // be cleaned too. delete loadedTextures[resourceName]; - - const supposedAtlasOwner = getEmbeddedOwnerResource( - project, - resourceName - ); - if (supposedAtlasOwner && supposedAtlasOwner.getKind() === 'atlas') { - await this.reloadResource( - project, - supposedAtlasOwner.getName() - ); - } + await this._reloadResourceOwner(project, resourceName, 'atlas'); } await PixiResourcesLoader.loadTextures(project, [resourceName]); @@ -291,20 +290,7 @@ export default class PixiResourcesLoader { } }); delete spineAtlasPromises[resourceName]; - - const supposedSpineResourceOwner = getEmbeddedOwnerResource( - project, - resourceName - ); - if ( - supposedSpineResourceOwner && - supposedSpineResourceOwner.getKind() === 'spine' - ) { - await this.reloadResource( - project, - supposedSpineResourceOwner.getName() - ); - } + await this._reloadResourceOwner(project, resourceName, 'spine'); } if (spineDataPromises[resourceName]) { await PIXI.Assets.unload(resourceName); diff --git a/newIDE/app/src/SceneEditor/index.js b/newIDE/app/src/SceneEditor/index.js index fd84370fa0e5..7c5260a4f9d9 100644 --- a/newIDE/app/src/SceneEditor/index.js +++ b/newIDE/app/src/SceneEditor/index.js @@ -236,10 +236,7 @@ export default class SceneEditor extends React.Component { // through the RenderedInstance's, triggering crashes. So the scene rendering // is paused during this period. editorDisplay.startSceneRendering(false); - await PixiResourcesLoader.reloadResource( - project, - resourceName - ); + await PixiResourcesLoader.reloadResource(project, resourceName); editorDisplay.forceUpdateObjectsList(); From 7201ce704a065fe2db17092034ed2f545eb80477 Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Sun, 7 Jan 2024 17:25:44 +0100 Subject: [PATCH 68/80] Slight refactoring and support for multiple embedder resources reloading --- .../src/ObjectEditor/Editors/SpineEditor.js | 2 +- .../ObjectsRendering/PixiResourcesLoader.js | 81 +++++++++++-------- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index f85ae50817cc..8e4b67b5b6cb 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -326,7 +326,7 @@ const SpineEditor = ({ spineData.textureAtlasOrLoadingError.loadingError === 'invalid-atlas-resource' ? ( - The Atlas embed in the Spine fine ca'n't be located. + The Atlas embedded in the Spine fine can't be located. ) : spineData.textureAtlasOrLoadingError.loadingError === 'missing-texture-resources' ? ( diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index d1d2e3d8cdb6..9893b046df51 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -187,36 +187,40 @@ export const readEmbeddedResourcesMapping = ( } }; -const getEmbeddedOwnerResource = ( +const getEmbedderResources = ( project: gdProject, - resourceName: string -): gdResource | null => { + embeddedResourceName: string, + embedderResourceKind: ResourceKind +): Array => { const resourcesManager = project.getResourcesManager(); + const embedderResources: Array = []; - for (const supposedOwnerResourceName of resourcesManager + for (const resourceName of resourcesManager .getAllResourceNames() .toJSArray()) { - if (resourceName === supposedOwnerResourceName) { + if (embeddedResourceName === resourceName) { + continue; + } + + const possibleEmbedderResource = resourcesManager.getResource(resourceName); + if (possibleEmbedderResource.getKind() !== embedderResourceKind) { continue; } - const supposedOwnerResource = resourcesManager.getResource( - supposedOwnerResourceName - ); const embeddedResourcesMapping = readEmbeddedResourcesMapping( - supposedOwnerResource + possibleEmbedderResource ); if (!embeddedResourcesMapping) { continue; } const mappedResources = Object.values(embeddedResourcesMapping); - if (mappedResources.includes(resourceName)) { - return supposedOwnerResource; + if (mappedResources.includes(embeddedResourceName)) { + embedderResources.push(possibleEmbedderResource); } } - return null; + return embedderResources; }; /** @@ -237,15 +241,21 @@ export default class PixiResourcesLoader { spineDataPromises = {}; } - static async _reloadResourceOwner( + static async _reloadEmbedderResources( project: gdProject, - resourceName: string, - ownerKind: ResourceKind + embeddedResourceName: string, + embedderResourceKind: ResourceKind ) { - const supposedOwner = getEmbeddedOwnerResource(project, resourceName); - if (supposedOwner && supposedOwner.getKind() === ownerKind) { - await this.reloadResource(project, supposedOwner.getName()); - } + const embeddedResources = getEmbedderResources( + project, + embeddedResourceName, + embedderResourceKind + ); + await Promise.all( + embeddedResources.map(embeddedResource => + this.reloadResource(project, embeddedResource.getName()) + ) + ); } static async reloadResource(project: gdProject, resourceName: string) { @@ -260,7 +270,9 @@ export default class PixiResourcesLoader { // been added and detected by file watcher. When reloading the texture, the cache must // be cleaned too. delete loadedTextures[resourceName]; - await this._reloadResourceOwner(project, resourceName, 'atlas'); + + // Also reload any resource embedding this resource: + await this._reloadEmbedderResources(project, resourceName, 'atlas'); } await PixiResourcesLoader.loadTextures(project, [resourceName]); @@ -279,31 +291,33 @@ export default class PixiResourcesLoader { delete loadedThreeTextures[resourceName]; } if (spineAtlasPromises[resourceName]) { - /** - * Expected error due to https://github.com/pixijs/spine/issues/537 issue (read comments). - * String is stored as loaded atlas resource but pixi-spine considers it as TextureAtlas and tries to call dispose on it that causes TypeError. - */ await PIXI.Assets.unload(resourceName).catch(async () => { + // Workaround: + // This is an expected error due to https://github.com/pixijs/spine/issues/537 issue (read comments + // and search the other mentions to this issue in the codebase): + // A string, instead of a TextureAtlas, is stored as the loaded atlas resource (which is the root cause of this exception). + // pixi-spine considers it acts on a TextureAtlas and tries to call dispose on it that causes a TypeError. const { textureAtlas } = await spineAtlasPromises[resourceName]; if (textureAtlas) { - textureAtlas.dispose(); + textureAtlas.dispose(); // Workaround by doing `dispose` ourselves. } }); delete spineAtlasPromises[resourceName]; - await this._reloadResourceOwner(project, resourceName, 'spine'); + + // Also reload any resource embedding this resource: + await this._reloadEmbedderResources(project, resourceName, 'spine'); } if (spineDataPromises[resourceName]) { await PIXI.Assets.unload(resourceName); delete spineDataPromises[resourceName]; - /** - * This line allows us to omit issue https://github.com/pixijs/pixijs/issues/10069. - * PIXI.Assets.resolver caches data that was passed to PIXI.Assets.add even if resource was unloaded. - * So every time we unload spine resources we need to call it to clean resolver cash - * and pick up fresh data next time we load it. - */ + // This line allows us to avoid issue https://github.com/pixijs/pixijs/issues/10069. + // PIXI.Assets.resolver caches data that was passed to `PIXI.Assets.add`, even if resource was unloaded. + // So every time we unload spine resources, we need to call it to clean the resolver cache + // and pick up fresh data next time we call `getSpineData`. PIXI.Assets.resolver.prefer(); } + const matchingMaterials = Object.keys(loadedThreeMaterials).filter(key => key.startsWith(resourceName) ); @@ -640,7 +654,8 @@ export default class PixiResourcesLoader { PIXI.Assets.load(spineTextureAtlasName).then( atlas => { // Ideally atlas of type `TextureAtlas` should be passed here. - // But there is a known issue in case of preloaded images (see https://github.com/pixijs/spine/issues/537). + // But there is a known issue in case of preloaded images (see https://github.com/pixijs/spine/issues/537 + // and search the other mentions to this issue in the codebase). // // This branching covers all possible ways to make it work fine, // if issue is fixed in pixi-spine or after migration to spine-pixi. From 25241a9a212faf35608e8093bf9a23248930a2c9 Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Sun, 7 Jan 2024 17:41:43 +0100 Subject: [PATCH 69/80] Simplify a bit error reporting + indicate this is experimental feature --- Extensions/Spine/JsExtension.js | 18 +++---- .../src/ObjectEditor/Editors/SpineEditor.js | 49 +++++++++++-------- .../ObjectsRendering/PixiResourcesLoader.js | 48 ++++++++++++------ 3 files changed, 69 insertions(+), 46 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 4733dac1942d..120047285e00 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -29,7 +29,7 @@ module.exports = { extension .setExtensionInformation( 'SpineObject', - _('Spine'), + _('Spine (experimental)'), _('Displays a Spine animation.'), 'Vladyslav Pohorielov', 'Open source (MIT License)' @@ -44,7 +44,7 @@ module.exports = { const object = extension .addObject( 'SpineObject', - _('Spine'), + _('Spine (experimental)'), _( 'Display and animate Spine skeleton. Select Spine files (json, atlas, image).' ), @@ -56,7 +56,7 @@ module.exports = { .addIncludeFile('Extensions/Spine/pixi-spine/pixi-spine.js') .addIncludeFile('Extensions/Spine/managers/pixi-spine-atlas-manager.js') .addIncludeFile('Extensions/Spine/managers/pixi-spine-manager.js') - .setCategoryFullName(_('General')); + .setCategoryFullName(_('Advanced')); object .addExpressionAndConditionAndAction( @@ -379,14 +379,12 @@ module.exports = { .getSpineData(this._project, spineResourceName) .then((spineDataOrLoadingError) => { if (!spineDataOrLoadingError.skeleton) { - const loadingError = - spineDataOrLoadingError.loadingError || - (spineDataOrLoadingError.textureAtlasOrLoadingError - ? spineDataOrLoadingError.textureAtlasOrLoadingError - .loadingError - : null); console.error( - 'Unable to load Spine: ' + (loadingError || 'Unknown reason.') + 'Unable to load Spine (' + + (spineDataOrLoadingError.loadingErrorReason || + 'Unknown reason') + + ')', + spineDataOrLoadingError.loadingError ); this._spine = null; return; diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 8e4b67b5b6cb..ee4cc9ad9a1d 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -97,6 +97,7 @@ const SpineEditor = ({ const [spineData, setSpineData] = React.useState({ skeleton: null, loadingError: null, + loadingErrorReason: null, }); const [sourceSelectOptions, setSourceSelectOptions] = React.useState< @@ -311,32 +312,38 @@ const SpineEditor = ({ resourceManagementProps={resourceManagementProps} onChange={onChangeSpineResourceName} /> - {!spineData.skeleton && - (spineData.loadingError || spineData.textureAtlasOrLoadingError) ? ( + {!spineData.skeleton && spineData.loadingErrorReason ? ( - {spineData.loadingError === 'invalid-spine-resource' ? ( + {spineData.loadingErrorReason === 'invalid-spine-resource' ? ( The selected resource is not a proper Spine resource. - ) : spineData.loadingError === 'missing-texture-atlas-name' ? ( + ) : spineData.loadingErrorReason === + 'missing-texture-atlas-name' ? ( Missing texture atlas name in the Spine file. - ) : spineData.loadingError === 'spine-resource-loading-error' ? ( - Error while loading the Spine resource. - ) : spineData.textureAtlasOrLoadingError ? ( - spineData.textureAtlasOrLoadingError.loadingError === - 'invalid-atlas-resource' ? ( - - The Atlas embedded in the Spine fine can't be located. - - ) : spineData.textureAtlasOrLoadingError.loadingError === - 'missing-texture-resources' ? ( - Missing texture for an atlas in the Spine file. - ) : spineData.textureAtlasOrLoadingError.loadingError === - 'atlas-resource-loading-error' ? ( - - Error while loading the Spine Texture Atlas resource. - - ) : null + ) : spineData.loadingErrorReason === + 'spine-resource-loading-error' ? ( + Error while loading the Spine resource ( + {spineData.loadingError + ? spineData.loadingError.message + : 'Unknown error'} + ). + ) : spineData.loadingErrorReason === 'invalid-atlas-resource' ? ( + + The Atlas embedded in the Spine fine can't be located. + + ) : spineData.loadingErrorReason === + 'missing-texture-resources' ? ( + Missing texture for an atlas in the Spine file. + ) : spineData.loadingErrorReason === + 'atlas-resource-loading-error' ? ( + + Error while loading the Spine Texture Atlas resource ( + {spineData.loadingError + ? spineData.loadingError.message + : 'Unknown error'} + ). + ) : null} ) : null} diff --git a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js index 9893b046df51..6277aeefc6c1 100644 --- a/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js +++ b/newIDE/app/src/ObjectsRendering/PixiResourcesLoader.js @@ -16,7 +16,8 @@ const gd: libGDevelop = global.gd; type SpineTextureAtlasOrLoadingError = {| textureAtlas: ?TextureAtlas, - loadingError: + loadingError: ?Error, + loadingErrorReason: | null | 'invalid-atlas-resource' | 'missing-texture-resources' @@ -25,12 +26,16 @@ type SpineTextureAtlasOrLoadingError = {| export type SpineDataOrLoadingError = {| skeleton: ?ISkeleton, - loadingError: + loadingError: ?Error, + loadingErrorReason: | null | 'invalid-spine-resource' | 'missing-texture-atlas-name' - | 'spine-resource-loading-error', - textureAtlasOrLoadingError?: SpineTextureAtlasOrLoadingError, + | 'spine-resource-loading-error' + // Atlas loading error reasons: + | 'invalid-atlas-resource' + | 'missing-texture-resources' + | 'atlas-resource-loading-error', |}; type ResourcePromise = { [resourceName: string]: Promise }; @@ -590,7 +595,8 @@ export default class PixiResourcesLoader { if (!spineTextureAtlasName) { return { textureAtlas: null, - loadingError: 'invalid-atlas-resource', + loadingError: null, + loadingErrorReason: 'invalid-atlas-resource', }; } @@ -598,7 +604,8 @@ export default class PixiResourcesLoader { if (!resourceManager.hasResource(spineTextureAtlasName)) { return { textureAtlas: null, - loadingError: 'invalid-atlas-resource', + loadingError: null, + loadingErrorReason: 'invalid-atlas-resource', }; } @@ -606,7 +613,8 @@ export default class PixiResourcesLoader { if (resource.getKind() !== 'atlas') { return { textureAtlas: null, - loadingError: 'invalid-atlas-resource', + loadingError: null, + loadingErrorReason: 'invalid-atlas-resource', }; } @@ -617,7 +625,8 @@ export default class PixiResourcesLoader { if (!textureAtlasMappingEntries.length) { return { textureAtlas: null, - loadingError: 'missing-texture-resources', + loadingError: null, + loadingErrorReason: 'missing-texture-resources', }; } @@ -668,12 +677,14 @@ export default class PixiResourcesLoader { resolve({ textureAtlas, loadingError: null, + loadingErrorReason: null, }) ); } else { resolve({ textureAtlas: atlas, loadingError: null, + loadingErrorReason: null, }); } }, @@ -683,7 +694,8 @@ export default class PixiResourcesLoader { ); resolve({ textureAtlas: null, - loadingError: 'atlas-resource-loading-error', + loadingError: err, + loadingErrorReason: 'atlas-resource-loading-error', }); } ); @@ -708,6 +720,7 @@ export default class PixiResourcesLoader { return { skeleton: null, loadingError: null, + loadingErrorReason: null, }; } @@ -715,7 +728,8 @@ export default class PixiResourcesLoader { if (!resourceManager.hasResource(spineName)) { return { skeleton: null, - loadingError: 'invalid-spine-resource', + loadingError: null, + loadingErrorReason: 'invalid-spine-resource', }; } @@ -723,7 +737,8 @@ export default class PixiResourcesLoader { if (resource.getKind() !== 'spine') { return { skeleton: null, - loadingError: 'invalid-spine-resource', + loadingError: null, + loadingErrorReason: 'invalid-spine-resource', }; } @@ -734,7 +749,8 @@ export default class PixiResourcesLoader { if (typeof spineTextureAtlasName !== 'string') { return { skeleton: null, - loadingError: 'missing-texture-atlas-name', + loadingError: null, + loadingErrorReason: 'missing-texture-atlas-name', }; } @@ -744,8 +760,8 @@ export default class PixiResourcesLoader { if (!textureAtlasOrLoadingError.textureAtlas) { return resolve({ skeleton: null, - loadingError: null, - textureAtlasOrLoadingError, + loadingError: textureAtlasOrLoadingError.loadingError, + loadingErrorReason: textureAtlasOrLoadingError.loadingErrorReason, }); } @@ -770,6 +786,7 @@ export default class PixiResourcesLoader { resolve({ skeleton: jsonData.spineData, loadingError: null, + loadingErrorReason: null, }); }, err => { @@ -778,7 +795,8 @@ export default class PixiResourcesLoader { ); resolve({ skeleton: null, - loadingError: 'spine-resource-loading-error', + loadingError: err, + loadingErrorReason: 'spine-resource-loading-error', }); } ); From aa03f271a178308887b1058be4f94ccfbaaf2c48 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Mon, 8 Jan 2024 12:31:34 +0200 Subject: [PATCH 70/80] format code --- newIDE/app/src/ObjectEditor/Editors/SpineEditor.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index ee4cc9ad9a1d..9794b8ff7cb0 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -323,11 +323,13 @@ const SpineEditor = ({ Missing texture atlas name in the Spine file. ) : spineData.loadingErrorReason === 'spine-resource-loading-error' ? ( - Error while loading the Spine resource ( + + Error while loading the Spine resource ( {spineData.loadingError ? spineData.loadingError.message : 'Unknown error'} - ). + ). + ) : spineData.loadingErrorReason === 'invalid-atlas-resource' ? ( The Atlas embedded in the Spine fine can't be located. From 0a4e3376962820485e3fe823e928fc9442a7edf8 Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Tue, 9 Jan 2024 17:17:42 +0100 Subject: [PATCH 71/80] Add icon for Spine based object --- Extensions/Spine/JsExtension.js | 16 ++++++++-------- .../app/public/JsPlatform/Extensions/spine.svg | 9 +++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 newIDE/app/public/JsPlatform/Extensions/spine.svg diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 120047285e00..0ecbb3dd2ba9 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -39,7 +39,7 @@ module.exports = { extension .addInstructionOrExpressionGroupMetadata(_('Spine')) - .setIcon('CppPlatform/Extensions/spriteicon.png'); + .setIcon('JsPlatform/Extensions/spine.svg'); const object = extension .addObject( @@ -48,7 +48,7 @@ module.exports = { _( 'Display and animate Spine skeleton. Select Spine files (json, atlas, image).' ), - 'CppPlatform/Extensions/spriteicon.png', + 'JsPlatform/Extensions/spine.svg', new gd.SpineObjectConfiguration() ) .setIncludeFile('Extensions/Spine/spineruntimeobject.js') @@ -107,8 +107,8 @@ module.exports = { ), _('The animation of _PARAM0_ is complete'), _('Animations and images'), - 'res/conditions/animation24.png', - 'res/conditions/animation.png' + 'JsPlatform/Extensions/spine.svg', + 'JsPlatform/Extensions/spine.svg' ) .addParameter('object', _('Spine'), 'SpineObject') .markAsSimple() @@ -122,7 +122,7 @@ module.exports = { _('an animation is updatable'), _('Updatable'), '', - 'res/conditions/animation.png' + 'JsPlatform/Extensions/spine.svg' ) .addParameter('object', _('Spine'), 'SpineObject') .useStandardParameters('boolean', gd.ParameterOptions.makeNewOptions()) @@ -139,7 +139,7 @@ module.exports = { ), _('the number of the animation'), _('Animations and images'), - 'res/actions/animation24.png' + 'JsPlatform/Extensions/spine.svg' ) .addParameter('object', _('Spine'), 'SpineObject') .useStandardParameters('number', gd.ParameterOptions.makeNewOptions()) @@ -156,7 +156,7 @@ module.exports = { _('the animation played by the object'), _('the animation'), _('Animations and images'), - 'res/actions/animation24.png' + 'JsPlatform/Extensions/spine.svg' ) .addParameter('object', _('Spine'), 'SpineObject') .useStandardParameters( @@ -242,7 +242,7 @@ module.exports = { } static getThumbnail(project, resourcesLoader, objectConfiguration) { - return 'CppPlatform/Extensions/spriteicon.png'; + return 'JsPlatform/Extensions/spine.svg'; } update() { diff --git a/newIDE/app/public/JsPlatform/Extensions/spine.svg b/newIDE/app/public/JsPlatform/Extensions/spine.svg new file mode 100644 index 000000000000..b40854993bff --- /dev/null +++ b/newIDE/app/public/JsPlatform/Extensions/spine.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file From 1f295f406377ea66f5dddfba4928a18451e43df6 Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Tue, 9 Jan 2024 17:19:50 +0100 Subject: [PATCH 72/80] Update the description --- Extensions/Spine/JsExtension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 0ecbb3dd2ba9..81c894c28c6e 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -46,7 +46,7 @@ module.exports = { 'SpineObject', _('Spine (experimental)'), _( - 'Display and animate Spine skeleton. Select Spine files (json, atlas, image).' + 'Display and smoothly animate a 2D object with skeletal animations made with Spine. Use files exported from Spine (json, atlas and image).' ), 'JsPlatform/Extensions/spine.svg', new gd.SpineObjectConfiguration() From 93bc488bf0ad33e8772a73179dbbe8e21364bbf6 Mon Sep 17 00:00:00 2001 From: Vladyslav Pohorielov Date: Wed, 10 Jan 2024 16:10:51 +0200 Subject: [PATCH 73/80] implement geDrawableX/Y methods for spine runtime object to correctly calculate hit boxes --- Extensions/Spine/spineruntimeobject-pixi-renderer.ts | 11 +++++++++++ Extensions/Spine/spineruntimeobject.ts | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index 7ed861db8304..59199ea5c618 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -34,6 +34,17 @@ namespace gdjs { return this._rendererObject; } + getOriginOffset(): PIXI.Point { + if (!isSpine(this._rendererObject)) return new PIXI.Point(0, 0); + + const localBounds = this._rendererObject.getLocalBounds(undefined, true); + + return new PIXI.Point( + localBounds.x * this._rendererObject.scale.x, + localBounds.y * this._rendererObject.scale.y + ); + } + onDestroy(): void { this._rendererObject.destroy(); } diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index d305940db5cb..41453a8a9e38 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -91,6 +91,18 @@ namespace gdjs { } } + getDrawableX(): number { + const originOffset = this._renderer.getOriginOffset(); + + return this.getX() + originOffset.x; + } + + getDrawableY(): number { + const originOffset = this._renderer.getOriginOffset(); + + return this.getY() + originOffset.y; + } + onDestroyed(): void { super.onDestroyed(); this._renderer.onDestroy(); From 234cbb08cee50450f02cc8e21b52b2c5728fbe98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davy=20H=C3=A9lard?= Date: Mon, 15 Jan 2024 12:13:24 +0100 Subject: [PATCH 74/80] Add capabilities for size, scale, flip, opacity and effects. --- Extensions/Spine/JsExtension.js | 11 ++ .../Spine/spineruntimeobject-pixi-renderer.ts | 9 +- Extensions/Spine/spineruntimeobject.ts | 103 +++++++++++++++++- 3 files changed, 116 insertions(+), 7 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index 81c894c28c6e..ad3f040ffafa 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -51,6 +51,13 @@ module.exports = { 'JsPlatform/Extensions/spine.svg', new gd.SpineObjectConfiguration() ) + .addDefaultBehavior('EffectCapability::EffectBehavior') + .addDefaultBehavior('ResizableCapability::ResizableBehavior') + .addDefaultBehavior('ScalableCapability::ScalableBehavior') + .addDefaultBehavior('FlippableCapability::FlippableBehavior') + .addDefaultBehavior('OpacityCapability::OpacityBehavior') + // TODO implement AnimatableBehavior + //.addDefaultBehavior('AnimatableCapability::AnimatableBehavior') .setIncludeFile('Extensions/Spine/spineruntimeobject.js') .addIncludeFile('Extensions/Spine/spineruntimeobject-pixi-renderer.js') .addIncludeFile('Extensions/Spine/pixi-spine/pixi-spine.js') @@ -58,6 +65,7 @@ module.exports = { .addIncludeFile('Extensions/Spine/managers/pixi-spine-manager.js') .setCategoryFullName(_('Advanced')); + // TODO Remove before the release. object .addExpressionAndConditionAndAction( 'number', @@ -68,6 +76,7 @@ module.exports = { '', 'res/conditions/opacity24.png' ) + .setHidden() .addParameter('object', _('Spine'), 'SpineObject', false) .useStandardParameters( 'number', @@ -78,6 +87,7 @@ module.exports = { .setFunctionName('setOpacity') .setGetter('getOpacity'); + // TODO Remove before the release. object .addExpressionAndConditionAndAction( 'number', @@ -88,6 +98,7 @@ module.exports = { '', 'res/actions/scale24_black.png' ) + .setHidden() .addParameter('object', _('Spine'), 'SpineObject', false) .useStandardParameters( 'number', diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index 59199ea5c618..ad4526bb4460 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -56,7 +56,14 @@ namespace gdjs { } updateScale(): void { - this._rendererObject.scale.set(Math.max(this._object.getScale(), 0)); + const scaleX = Math.max(this._object._originalScale * this._object.getScaleX(), 0); + const scaleY = Math.max(this._object._originalScale * this._object.getScaleY(), 0); + this._rendererObject.scale.x = this._object.isFlippedX() + ? -scaleX + : scaleX; + this._rendererObject.scale.y = this._object.isFlippedY() + ? -scaleY + : scaleY; } updatePosition(): void { diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 41453a8a9e38..995852c108c9 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -12,9 +12,20 @@ namespace gdjs { }; export type SpineObjectData = ObjectData & SpineObjectDataType; - export class SpineRuntimeObject extends gdjs.RuntimeObject { + export class SpineRuntimeObject + extends gdjs.RuntimeObject + implements + gdjs.Resizable, + gdjs.Scalable, + // TODO implement Animatable + // gdjs.Animatable, + gdjs.OpacityHandler { private _opacity: float; - private _scale: number; + private _scaleX: number = 1; + private _scaleY: number = 1; + _originalScale: number; + private _flippedX: boolean = false; + private _flippedY: boolean = false; private _timeScale: number; private _animations: SpineAnimation[]; private _currentAnimationIndex = 0; @@ -35,7 +46,7 @@ namespace gdjs { this._animations = objectData.content.animations; this._timeScale = objectData.content.timeScale; this._opacity = objectData.content.opacity; - this._scale = objectData.content.scale; + this._originalScale = objectData.content.scale; this.spineResourceName = objectData.content.spineResourceName; this._renderer = new gdjs.SpineRuntimeObjectRenderer( this, @@ -117,14 +128,89 @@ namespace gdjs { return this._timeScale; } - setScale(scale: float): void { - this._scale = scale; + flipX(enable: boolean) { + if (enable !== this._flippedX) { + this._scaleX *= -1; + this._flippedX = enable; + this.invalidateHitboxes(); + this._renderer.updateScale(); + } + } + + flipY(enable: boolean) { + if (enable !== this._flippedY) { + this._scaleY *= -1; + this._flippedY = enable; + this.invalidateHitboxes(); + this._renderer.updateScale(); + } + } + + isFlippedX(): boolean { + return this._flippedX; + } + + isFlippedY(): boolean { + return this._flippedY; + } + + setScale(newScale: float): void { + if (newScale < 0) { + newScale = 0; + } + if ( + newScale === Math.abs(this._scaleX) && + newScale === Math.abs(this._scaleY) + ) { + return; + } + this._scaleX = newScale * (this._flippedX ? -1 : 1); + this._scaleY = newScale * (this._flippedY ? -1 : 1); this._renderer.updateScale(); this.invalidateHitboxes(); } + setScaleX(newScale: float): void { + if (newScale < 0) { + newScale = 0; + } + if (newScale === Math.abs(this._scaleX)) { + return; + } + this._scaleX = newScale * (this._flippedX ? -1 : 1); + this._renderer.updateScale(); + this.invalidateHitboxes(); + } + + setScaleY(newScale: float): void { + if (newScale < 0) { + newScale = 0; + } + if (newScale === Math.abs(this._scaleY)) { + return; + } + this._scaleY = newScale * (this._flippedY ? -1 : 1); + this._renderer.updateScale(); + this.invalidateHitboxes(); + } + + /** + * Get the scale of the object (or the geometric mean of the X and Y scale in case they are different). + * + * @return the scale of the object (or the geometric mean of the X and Y scale in case they are different). + */ getScale(): float { - return this._scale; + const scaleX = Math.abs(this._scaleX); + const scaleY = Math.abs(this._scaleY); + return scaleX === scaleY ? scaleX : Math.sqrt(scaleX * scaleY); + } + + getScaleY(): float { + return Math.abs(this._scaleY); + } + + getScaleX(): float { + return Math.abs(this._scaleX); } setX(x: float): void { @@ -169,6 +255,11 @@ namespace gdjs { this.invalidateHitboxes(); } + setSize(newWidth: number, newHeight: number): void { + this.setWidth(newWidth); + this.setHeight(newHeight); + } + setAnimationIndex(animationIndex: number, mixingDuration: number): void { if (!this.isAnimationIndex(animationIndex)) { return; From a12bcab11a0bdfbd1bbfa6913830a6f0b1674ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davy=20H=C3=A9lard?= Date: Mon, 15 Jan 2024 19:55:02 +0100 Subject: [PATCH 75/80] Add capability for animation. --- Extensions/Spine/JsExtension.js | 45 +- Extensions/Spine/SpineObjectConfiguration.cpp | 14 +- Extensions/Spine/SpineObjectConfiguration.h | 1 - .../Spine/spineruntimeobject-pixi-renderer.ts | 84 +- Extensions/Spine/spineruntimeobject.ts | 288 +- .../object-capabilities/AnimatableBehavior.ts | 6 - .../games/capabilities/assets/spineboy.atlas | 101 + .../games/capabilities/assets/spineboy.json | 3672 +++++++++++++++++ .../games/capabilities/assets/spineboy.png | Bin 0 -> 244631 bytes .../games/capabilities/capabilities.json | 636 ++- .../src/ObjectEditor/Editors/SpineEditor.js | 7 - 11 files changed, 4591 insertions(+), 263 deletions(-) create mode 100644 GDJS/tests/games/capabilities/assets/spineboy.atlas create mode 100644 GDJS/tests/games/capabilities/assets/spineboy.json create mode 100644 GDJS/tests/games/capabilities/assets/spineboy.png diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index ad3f040ffafa..deab1cab66f7 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -56,8 +56,7 @@ module.exports = { .addDefaultBehavior('ScalableCapability::ScalableBehavior') .addDefaultBehavior('FlippableCapability::FlippableBehavior') .addDefaultBehavior('OpacityCapability::OpacityBehavior') - // TODO implement AnimatableBehavior - //.addDefaultBehavior('AnimatableCapability::AnimatableBehavior') + .addDefaultBehavior('AnimatableCapability::AnimatableBehavior') .setIncludeFile('Extensions/Spine/spineruntimeobject.js') .addIncludeFile('Extensions/Spine/spineruntimeobject-pixi-renderer.js') .addIncludeFile('Extensions/Spine/pixi-spine/pixi-spine.js') @@ -109,6 +108,7 @@ module.exports = { .setFunctionName('setScale') .setGetter('getScale'); + // TODO Remove before the release. object .addCondition( 'isAnimationComplete', @@ -121,25 +121,12 @@ module.exports = { 'JsPlatform/Extensions/spine.svg', 'JsPlatform/Extensions/spine.svg' ) + .setHidden() .addParameter('object', _('Spine'), 'SpineObject') .markAsSimple() - .setFunctionName('isAnimationComplete'); - - object - .addExpressionAndConditionAndAction( - 'boolean', - 'Updatable', - _('Updatable'), - _('an animation is updatable'), - _('Updatable'), - '', - 'JsPlatform/Extensions/spine.svg' - ) - .addParameter('object', _('Spine'), 'SpineObject') - .useStandardParameters('boolean', gd.ParameterOptions.makeNewOptions()) - .setFunctionName('setIsUpdatable') - .setGetter('isUpdatable'); + .setFunctionName('hasAnimationEnded'); + // TODO Remove before the release. object .addExpressionAndConditionAndAction( 'number', @@ -152,13 +139,15 @@ module.exports = { _('Animations and images'), 'JsPlatform/Extensions/spine.svg' ) + .setHidden() .addParameter('object', _('Spine'), 'SpineObject') .useStandardParameters('number', gd.ParameterOptions.makeNewOptions()) .addParameter('number', _('Mixing duration'), '', false) .markAsSimple() .setFunctionName('setAnimationIndex') - .setGetter('getCurrentAnimationIndex'); + .setGetter('getAnimationIndex'); + // TODO Remove before the release. object .addExpressionAndConditionAndAction( 'string', @@ -169,6 +158,7 @@ module.exports = { _('Animations and images'), 'JsPlatform/Extensions/spine.svg' ) + .setHidden() .addParameter('object', _('Spine'), 'SpineObject') .useStandardParameters( 'objectAnimationName', @@ -179,6 +169,23 @@ module.exports = { .setFunctionName('setAnimationName') .setGetter('getAnimationName'); + object + .addExpressionAndConditionAndAction( + 'number', + 'Animation', + _('Animation mixing duration'), + _( + 'the duration of the smooth transition between 2 animations (in second)' + ), + _('the animation mixing duration'), + _('Animations and images'), + 'JsPlatform/Extensions/spine.svg' + ) + .addParameter('object', _('Spine'), 'SpineObject') + .useStandardParameters('number', gd.ParameterOptions.makeNewOptions()) + .setFunctionName('setAnimationMixingDuration') + .setGetter('getAnimationMixingDuration'); + return extension; }, diff --git a/Extensions/Spine/SpineObjectConfiguration.cpp b/Extensions/Spine/SpineObjectConfiguration.cpp index 89c5f00fbe19..cc4288c64aa8 100644 --- a/Extensions/Spine/SpineObjectConfiguration.cpp +++ b/Extensions/Spine/SpineObjectConfiguration.cpp @@ -21,7 +21,7 @@ using namespace std; SpineAnimation SpineObjectConfiguration::badAnimation; SpineObjectConfiguration::SpineObjectConfiguration() - : scale(1), opacity(255), timeScale(1), spineResourceName("") {}; + : scale(1), opacity(255), spineResourceName("") {}; bool SpineObjectConfiguration::UpdateProperty(const gd::String &propertyName, const gd::String &newValue) { if (propertyName == "scale") { @@ -32,10 +32,6 @@ bool SpineObjectConfiguration::UpdateProperty(const gd::String &propertyName, co opacity = newValue.To(); return true; } - if (propertyName == "timeScale") { - timeScale = newValue.To(); - return true; - } if (propertyName == "spineResourceName") { spineResourceName = newValue; return true; @@ -59,12 +55,6 @@ SpineObjectConfiguration::GetProperties() const { .SetType("number") .SetLabel(_("Opacity")) .SetGroup(_("Appearance")); - - objectProperties["timeScale"] - .SetValue(gd::String::From(timeScale)) - .SetType("number") - .SetLabel(_("Time Scale")) - .SetGroup(_("Play")); objectProperties["spineResourceName"] .SetValue(spineResourceName) @@ -102,7 +92,6 @@ void SpineObjectConfiguration::DoUnserializeFrom(gd::Project &project, const gd: scale = content.GetDoubleAttribute("scale"); opacity = content.GetDoubleAttribute("opacity"); - timeScale = content.GetDoubleAttribute("timeScale"); spineResourceName = content.GetStringAttribute("spineResourceName"); RemoveAllAnimations(); @@ -122,7 +111,6 @@ void SpineObjectConfiguration::DoSerializeTo(gd::SerializerElement &element) con auto &content = element.AddChild("content"); content.SetAttribute("scale", scale); content.SetAttribute("opacity", opacity); - content.SetAttribute("timeScale", timeScale); content.SetAttribute("spineResourceName", spineResourceName); auto &animationsElement = content.AddChild("animations"); diff --git a/Extensions/Spine/SpineObjectConfiguration.h b/Extensions/Spine/SpineObjectConfiguration.h index 261dc2066357..1bf5179a1bbe 100644 --- a/Extensions/Spine/SpineObjectConfiguration.h +++ b/Extensions/Spine/SpineObjectConfiguration.h @@ -154,7 +154,6 @@ class GD_EXTENSION_API SpineObjectConfiguration : public gd::ObjectConfiguration private: double scale; double opacity; - double timeScale; gd::String spineResourceName; diff --git a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts index ad4526bb4460..d0d42956f414 100644 --- a/Extensions/Spine/spineruntimeobject-pixi-renderer.ts +++ b/Extensions/Spine/spineruntimeobject-pixi-renderer.ts @@ -17,8 +17,10 @@ namespace gdjs { ) { this._object = runtimeObject; this._rendererObject = this.constructRendererObject(); + if (isSpine(this._rendererObject)) { + this._rendererObject.autoUpdate = false; + } - this.updateTimeScale(); this.updatePosition(); this.updateAngle(); this.updateOpacity(); @@ -30,6 +32,13 @@ namespace gdjs { .addRendererObject(this._rendererObject, runtimeObject.getZOrder()); } + updateAnimation(timeDelta: float) { + if (!isSpine(this._rendererObject)) { + return; + } + this._rendererObject.update(timeDelta); + } + getRendererObject(): pixi_spine.Spine | PIXI.Container { return this._rendererObject; } @@ -49,15 +58,15 @@ namespace gdjs { this._rendererObject.destroy(); } - updateTimeScale(): void { - if (!isSpine(this._rendererObject)) return; - - this._rendererObject.state.timeScale = this._object.getTimeScale(); - } - updateScale(): void { - const scaleX = Math.max(this._object._originalScale * this._object.getScaleX(), 0); - const scaleY = Math.max(this._object._originalScale * this._object.getScaleY(), 0); + const scaleX = Math.max( + this._object._originalScale * this._object.getScaleX(), + 0 + ); + const scaleY = Math.max( + this._object._originalScale * this._object.getScaleY(), + 0 + ); this._rendererObject.scale.x = this._object.isFlippedX() ? -scaleX : scaleX; @@ -95,9 +104,18 @@ namespace gdjs { this._rendererObject.height = height; } - setSize(width: float, height: float): void { - this._rendererObject.width = width; - this._rendererObject.height = height; + getUnscaledWidth(): float { + return Math.abs( + (this._rendererObject.width * this._object._originalScale) / + this._rendererObject.scale.x + ); + } + + getUnscaledHeight(): float { + return Math.abs( + (this._rendererObject.height * this._object._originalScale) / + this._rendererObject.scale.y + ); } setMixing(from: string, to: string, duration: number): void { @@ -124,22 +142,44 @@ namespace gdjs { } } - isAnimationComplete(): boolean { - return this._isAnimationComplete; + getAnimationDuration(sourceAnimationName: string) { + if (!isSpine(this._rendererObject)) { + return 0; + } + const animation = this._rendererObject.spineData.findAnimation( + sourceAnimationName + ); + return animation ? animation.duration : 0; } - isUpdatable(): boolean { - if (isSpine(this._rendererObject)) { - return this._rendererObject.autoUpdate; + getAnimationElapsedTime(): number { + if (!isSpine(this._rendererObject)) { + return 0; } - - return true; + const tracks = this._rendererObject.state.tracks; + if (tracks.length === 0) { + return 0; + } + // This should be fine because only 1 track is used. + const track = tracks[0]; + // @ts-ignore TrackEntry.getAnimationTime is not exposed. + return track.getAnimationTime(); } - setIsUpdatable(isUpdatable: boolean): void { - if (isSpine(this._rendererObject)) { - this._rendererObject.autoUpdate = isUpdatable; + setAnimationElapsedTime(time: number): void { + if (!isSpine(this._rendererObject)) { + return; } + const tracks = this._rendererObject.state.tracks; + if (tracks.length === 0) { + return; + } + const track = tracks[0]; + track.trackTime = time; + } + + isAnimationComplete(): boolean { + return this._isAnimationComplete; } private constructRendererObject(): pixi_spine.Spine | PIXI.Container { diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 995852c108c9..ba54d4dfe309 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -17,8 +17,7 @@ namespace gdjs { implements gdjs.Resizable, gdjs.Scalable, - // TODO implement Animatable - // gdjs.Animatable, + gdjs.Animatable, gdjs.OpacityHandler { private _opacity: float; private _scaleX: number = 1; @@ -26,9 +25,13 @@ namespace gdjs { _originalScale: number; private _flippedX: boolean = false; private _flippedY: boolean = false; - private _timeScale: number; private _animations: SpineAnimation[]; - private _currentAnimationIndex = 0; + private _currentAnimationIndex = -1; + private _animationSpeedScale: float = 1; + private _animationPaused: boolean = false; + private _isPausedFrameDirty = false; + /** The duration in second for the smooth transition between 2 animations */ + private _animationMixingDuration: number; private _renderer: gdjs.SpineRuntimeObjectPixiRenderer; readonly spineResourceName: string; @@ -44,19 +47,33 @@ namespace gdjs { super(instanceContainer, objectData); this._animations = objectData.content.animations; - this._timeScale = objectData.content.timeScale; this._opacity = objectData.content.opacity; this._originalScale = objectData.content.scale; this.spineResourceName = objectData.content.spineResourceName; + this._animationMixingDuration = 0.1; this._renderer = new gdjs.SpineRuntimeObjectRenderer( this, instanceContainer ); + this.setAnimationIndex(0); + this._renderer.updateAnimation(0); // *ALWAYS* call `this.onCreated()` at the very end of your object constructor. this.onCreated(); } + update(instanceContainer: gdjs.RuntimeInstanceContainer): void { + if (this._animationPaused) { + if (this._isPausedFrameDirty) { + this._renderer.updateAnimation(0); + this._isPausedFrameDirty = false; + } + return; + } + const elapsedTime = this.getElapsedTime() / 1000; + this._renderer.updateAnimation(elapsedTime * this._animationSpeedScale); + } + getRendererObject(): pixi_spine.Spine | PIXI.Container { return this._renderer.getRendererObject(); } @@ -71,10 +88,7 @@ namespace gdjs { this.setOpacity(newObjectData.content.opacity); } if (oldObjectData.content.scale !== newObjectData.content.scale) { - this.setScale(newObjectData.content.scale); - } - if (oldObjectData.content.timeScale !== newObjectData.content.timeScale) { - this.setTimeScale(newObjectData.content.timeScale); + this._originalScale = newObjectData.content.scale; } return true; @@ -90,14 +104,10 @@ namespace gdjs { ? animationData.value : this._currentAnimationIndex; - this.setAnimationIndex(animationIndex, 0); + this.setAnimationIndexWithMixing(animationIndex, 0); if (initialInstanceData.customSize) { - this.setScale(1); - this._renderer.setSize( - initialInstanceData.width, - initialInstanceData.height - ); + this.setSize(initialInstanceData.width, initialInstanceData.height); this.invalidateHitboxes(); } } @@ -119,39 +129,55 @@ namespace gdjs { this._renderer.onDestroy(); } - setTimeScale(timeScale: float): void { - this._timeScale = timeScale; - this._renderer.updateTimeScale(); + setX(x: float): void { + super.setX(x); + this._renderer.updatePosition(); } - getTimeScale(): float { - return this._timeScale; + setY(y: float): void { + super.setY(y); + this._renderer.updatePosition(); } - flipX(enable: boolean) { - if (enable !== this._flippedX) { - this._scaleX *= -1; - this._flippedX = enable; - this.invalidateHitboxes(); - this._renderer.updateScale(); - } + setAngle(angle: float): void { + super.setAngle(angle); + this._renderer.updateAngle(); } - flipY(enable: boolean) { - if (enable !== this._flippedY) { - this._scaleY *= -1; - this._flippedY = enable; - this.invalidateHitboxes(); - this._renderer.updateScale(); + setOpacity(opacity: float): void { + this._opacity = Math.max(0, Math.min(255, opacity)); + this._renderer.updateOpacity(); + } + + getOpacity(): float { + return this._opacity; + } + + getWidth(): float { + return this._renderer.getWidth(); + } + + getHeight(): float { + return this._renderer.getHeight(); + } + + setWidth(newWidth: float): void { + const unscaledWidth = this._renderer.getUnscaledWidth(); + if (unscaledWidth !== 0) { + this.setScaleX(newWidth / unscaledWidth); } } - isFlippedX(): boolean { - return this._flippedX; + setHeight(newHeight: float): void { + const unscaledHeight = this._renderer.getUnscaledHeight(); + if (unscaledHeight !== 0) { + this.setScaleY(newHeight / unscaledHeight); + } } - isFlippedY(): boolean { - return this._flippedY; + setSize(newWidth: number, newHeight: number): void { + this.setWidth(newWidth); + this.setHeight(newHeight); } setScale(newScale: float): void { @@ -213,89 +239,103 @@ namespace gdjs { return Math.abs(this._scaleX); } - setX(x: float): void { - super.setX(x); - this._renderer.updatePosition(); - } - - setY(y: float): void { - super.setY(y); - this._renderer.updatePosition(); - } - - setAngle(angle: float): void { - super.setAngle(angle); - this._renderer.updateAngle(); - } - - setOpacity(opacity: float): void { - this._opacity = Math.max(0, Math.min(255, opacity)); - this._renderer.updateOpacity(); - } - - getOpacity(): float { - return this._opacity; - } - - getWidth(): float { - return this._renderer.getWidth(); + isFlippedX(): boolean { + return this._flippedX; } - getHeight(): float { - return this._renderer.getHeight(); + isFlippedY(): boolean { + return this._flippedY; } - setWidth(width: float): void { - this._renderer.setWidth(width); - this.invalidateHitboxes(); + flipX(enable: boolean) { + if (enable !== this._flippedX) { + this._scaleX *= -1; + this._flippedX = enable; + this.invalidateHitboxes(); + this._renderer.updateScale(); + } } - setHeight(height: float): void { - this._renderer.setHeight(height); - this.invalidateHitboxes(); + flipY(enable: boolean) { + if (enable !== this._flippedY) { + this._scaleY *= -1; + this._flippedY = enable; + this.invalidateHitboxes(); + this._renderer.updateScale(); + } } - setSize(newWidth: number, newHeight: number): void { - this.setWidth(newWidth); - this.setHeight(newHeight); + setAnimationIndex(animationIndex: number): void { + this.setAnimationIndexWithMixing( + animationIndex, + this._animationMixingDuration + ); } - setAnimationIndex(animationIndex: number, mixingDuration: number): void { - if (!this.isAnimationIndex(animationIndex)) { + setAnimationIndexWithMixing( + animationIndex: number, + mixingDuration: number + ): void { + if ( + this._animations.length === 0 || + this._currentAnimationIndex === animationIndex || + !this.isAnimationIndex(animationIndex) + ) { return; } + const previousAnimation = this._animations[this._currentAnimationIndex]; + const newAnimation = this._animations[animationIndex]; + this._currentAnimationIndex = animationIndex; - const previousAnimationName = this.getAnimationSource( - this._currentAnimationIndex - ); - const newAnimationName = this.getAnimationSource(animationIndex); - - if ( - previousAnimationName && - newAnimationName && - newAnimationName !== previousAnimationName - ) { + if (previousAnimation) { this._renderer.setMixing( - previousAnimationName, - newAnimationName, + previousAnimation.source, + newAnimation.source, mixingDuration ); } + this._renderer.setAnimation(newAnimation.source, newAnimation.loop); + this._isPausedFrameDirty = true; + } - const animation = this._animations[animationIndex]; - this._currentAnimationIndex = animationIndex; - - this._renderer.setAnimation(animation.source, animation.loop); + setAnimationName(animationName: string): void { + this.setAnimationNameWithMixing( + animationName, + this._animationMixingDuration + ); } - setAnimationName(animationName: string, mixingDuration: number): void { - this.setAnimationIndex( - this.getAnimationIndex(animationName), + setAnimationNameWithMixing( + animationName: string, + mixingDuration: number + ): void { + this.setAnimationIndexWithMixing( + this.getAnimationIndexFor(animationName), mixingDuration ); } - getCurrentAnimationIndex(): number { + getAnimationIndexFor(animationName: string): number { + return this._animations.findIndex( + (animation) => animation.name === animationName + ); + } + + /** + * Return the duration in second for the smooth transition between 2 animations. + */ + getAnimationMixingDuration(): number { + return this._animationMixingDuration; + } + + /** + * Change the duration in second for the smooth transition between 2 animations. + */ + setAnimationMixingDuration(animationMixingDuration: number): void { + this._animationMixingDuration = animationMixingDuration; + } + + getAnimationIndex(): number { return this._currentAnimationIndex; } @@ -305,16 +345,6 @@ namespace gdjs { : ''; } - getAnimationSource(index: number): string { - return this.isAnimationIndex(index) ? this._animations[index].source : ''; - } - - getAnimationIndex(animationName: string): number { - return this._animations.findIndex( - (animation) => animation.name === animationName - ); - } - isAnimationIndex(animationIndex: number): boolean { return ( Number.isInteger(animationIndex) && @@ -323,20 +353,52 @@ namespace gdjs { ); } - isAnimationComplete(): boolean { + hasAnimationEnded(): boolean { return this._renderer.isAnimationComplete(); } - isCurrentAnimationName(name: string): boolean { - return this.getAnimationName() === name; + isAnimationPaused() { + return this._animationPaused; + } + + pauseAnimation() { + this._animationPaused = true; + } + + resumeAnimation() { + this._animationPaused = false; + } + + getAnimationSpeedScale() { + return this._animationSpeedScale; } - setIsUpdatable(isUpdatable: boolean): void { - this._renderer.setIsUpdatable(isUpdatable); + setAnimationSpeedScale(ratio: float): void { + this._animationSpeedScale = ratio; } - isUpdatable(): boolean { - return this._renderer.isUpdatable(); + getAnimationElapsedTime(): number { + if (this._animations.length === 0) { + return 0; + } + return this._renderer.getAnimationElapsedTime(); + } + + setAnimationElapsedTime(time: number): void { + if (this._animations.length === 0) { + return; + } + this._renderer.setAnimationElapsedTime(time); + this._isPausedFrameDirty = true; + } + + getAnimationDuration(): number { + if (this._animations.length === 0) { + return 0; + } + return this._renderer.getAnimationDuration( + this._animations[this._currentAnimationIndex].source + ); } } diff --git a/GDJS/Runtime/object-capabilities/AnimatableBehavior.ts b/GDJS/Runtime/object-capabilities/AnimatableBehavior.ts index 21250a1e5f0c..87444d0b0655 100644 --- a/GDJS/Runtime/object-capabilities/AnimatableBehavior.ts +++ b/GDJS/Runtime/object-capabilities/AnimatableBehavior.ts @@ -29,8 +29,6 @@ namespace gdjs { */ setAnimationName(newAnimationName: string): void; - isCurrentAnimationName(name: string): boolean; - /** * Return true if animation has ended. * The animation had ended if: @@ -117,10 +115,6 @@ namespace gdjs { this.object.setAnimationName(newAnimationName); } - isCurrentAnimationName(name: string): boolean { - return this.object.isCurrentAnimationName(name); - } - hasAnimationEnded(): boolean { return this.object.hasAnimationEnded(); } diff --git a/GDJS/tests/games/capabilities/assets/spineboy.atlas b/GDJS/tests/games/capabilities/assets/spineboy.atlas new file mode 100644 index 000000000000..b07ccc3bf7be --- /dev/null +++ b/GDJS/tests/games/capabilities/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/GDJS/tests/games/capabilities/assets/spineboy.json b/GDJS/tests/games/capabilities/assets/spineboy.json new file mode 100644 index 000000000000..81688ebccc02 --- /dev/null +++ b/GDJS/tests/games/capabilities/assets/spineboy.json @@ -0,0 +1,3672 @@ +{ +"skeleton": { + "hash": "SmUDxzck41o", + "spine": "4.1.17", + "x": -221.27, + "y": -8.57, + "width": 470.72, + "height": 731.57, + "images": "./images/", + "audio": "" +}, +"bones": [ + { "name": "root" }, + { "name": "hip", "parent": "root", "y": 247.47 }, + { + "name": "torso", + "parent": "hip", + "length": 127.56, + "rotation": 103.82, + "x": -1.62, + "y": 4.9, + "color": "e0da19ff" + }, + { + "name": "front-upper-arm", + "parent": "torso", + "length": 69.45, + "rotation": 168.38, + "x": 103.76, + "y": 19.33, + "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-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": 91.34, + "rotation": 77.91, + "x": 128.76, + "y": -0.34, + "color": "00ff04ff" + }, + { + "name": "rear-upper-arm", + "parent": "torso", + "length": 51.94, + "rotation": -169.56, + "x": 92.36, + "y": -19.22, + "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.35, + "x": 34.42, + "y": -0.45, + "color": "ff000dff" + }, + { "name": "gun-tip", "parent": "gun", "rotation": 6.83, "x": 201.05, "y": 52.14, "color": "ff000dff" }, + { + "name": "neck", + "parent": "torso", + "length": 25.45, + "rotation": -31.54, + "x": 127.5, + "y": -0.31, + "color": "e0da19ff" + }, + { + "name": "head", + "parent": "neck", + "length": 263.58, + "rotation": 23.18, + "x": 27.66, + "y": -0.26, + "color": "e0da19ff" + }, + { + "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": 82.57, + "rotation": 69.3, + "x": 121.46, + "y": -0.76, + "color": "ff000dff" + } +], +"slots": [ + { "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": "gun-tip", "blend": "additive" }, + { "name": "head-bb", "bone": "head" } +], +"skins": [ + { + "name": "default", + "attachments": { + "eye": { + "eye-indifferent": { "x": 85.72, "y": -28.18, "rotation": -70.63, "width": 93, "height": 89 }, + "eye-surprised": { "x": 85.72, "y": -28.18, "rotation": -70.63, "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": { "x": 29.52, "y": 7.84, "rotation": 18.69, "width": 126, "height": 69 } + }, + "front-shin": { + "front-shin": { "x": 55.12, "y": -3.54, "rotation": 96.59, "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": 25.2, "y": 1.17, "rotation": 97.9, "width": 46, "height": 97 } + }, + "goggles": { + "goggles": { "x": 97.08, "y": 6.54, "rotation": -70.63, "width": 261, "height": 166 } + }, + "gun": { + "gun": { "x": 77.3, "y": 16.4, "rotation": 60.83, "width": 210, "height": 203 } + }, + "head": { + "head": { "x": 128.96, "y": 0.3, "rotation": -70.63, "width": 271, "height": 298 } + }, + "head-bb": { + "head": { + "type": "boundingbox", + "vertexCount": 6, + "vertices": [ -19.14, -70.3, 40.8, -118.07, 257.77, -115.62, 285.16, 57.18, 120.77, 164.95, -5.07, 76.95 ] + } + }, + "mouth": { + "mouth-grind": { "x": 23.69, "y": -32.24, "rotation": -70.63, "width": 93, "height": 59 }, + "mouth-oooo": { "x": 23.69, "y": -32.24, "rotation": -70.63, "width": 93, "height": 59 }, + "mouth-smile": { "x": 23.69, "y": -32.24, "rotation": -70.63, "width": 93, "height": 59 } + }, + "muzzle": { + "muzzle01": { + "x": 159.26, + "y": 5.83, + "scaleX": 4, + "scaleY": 4, + "rotation": 0.15, + "width": 133, + "height": 79 + }, + "muzzle02": { + "x": 191.23, + "y": 5.91, + "scaleX": 4, + "scaleY": 4, + "rotation": 0.15, + "width": 135, + "height": 84 + }, + "muzzle03": { + "x": 230.67, + "y": 6.02, + "scaleX": 4, + "scaleY": 4, + "rotation": 0.15, + "width": 166, + "height": 106 + }, + "muzzle04": { + "x": 218.54, + "y": 5.99, + "scaleX": 4, + "scaleY": 4, + "rotation": 0.15, + "width": 149, + "height": 90 + } + }, + "neck": { + "neck": { "x": 9.77, "y": -3.01, "rotation": -55.22, "width": 36, "height": 41 } + }, + "rear-bracer": { + "rear-bracer": { "x": 11.15, "y": -2.2, "rotation": 66.17, "width": 56, "height": 72 } + }, + "rear-foot": { + "rear-foot": { "x": 31.51, "y": 3.58, "rotation": 23.07, "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 } + }, + "torso": { + "torso": { "x": 63.61, "y": 7.12, "rotation": -94.54, "width": 98, "height": 180 } + } + } + } +], +"events": { + "footstep": {} +}, +"animations": { + "aim": { + "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 } + ] + } + } + }, + "death": { + "slots": { + "eye": { + "attachment": [ + { "name": "eye-surprised" }, + { "time": 0.4667, "name": "eye-indifferent" }, + { "time": 2.2333, "name": "eye-surprised" }, + { "time": 4.5333, "name": "eye-indifferent" } + ] + }, + "front-fist": { + "attachment": [ + { "name": "front-fist-open" } + ] + }, + "mouth": { + "attachment": [ + { "name": "mouth-oooo" }, + { "time": 2.2333, "name": "mouth-grind" }, + { "time": 4.5333, "name": "mouth-oooo" } + ] + } + }, + "bones": { + "head": { + "rotate": [ + { + "value": -2.83, + "curve": [ 0.044, -2.83, 0.105, -14.97 ] + }, + { + "time": 0.1333, + "value": -21.89, + "curve": [ 0.158, -28.04, 0.2, -34.87 ] + }, + { + "time": 0.2333, + "value": -34.87, + "curve": [ 0.267, -34.87, 0.3, -34.22 ] + }, + { + "time": 0.3333, + "value": -33.33, + "curve": [ 0.356, -32.74, 0.374, -30.69 ] + }, + { + "time": 0.4, + "value": -27.7, + "curve": [ 0.433, -23.82, 0.467, -10.64 ] + }, + { + "time": 0.5, + "value": -10.64, + "curve": [ 0.522, -10.64, 0.544, -16.82 ] + }, + { + "time": 0.5667, + "value": -23.05, + "curve": [ 0.589, -29.28, 0.611, -49.33 ] + }, + { + "time": 0.6333, + "value": -55.92, + "curve": [ 0.678, -69.1, 0.722, -82.35 ] + }, + { + "time": 0.7667, + "value": -82.35, + "curve": [ 0.787, -78.36, 0.912, -75.47 ] + }, + { "time": 1, "value": -78.9 }, + { + "time": 2.2333, + "value": -78.72, + "curve": [ 2.289, -78.72, 2.345, -66.24 ] + }, + { + "time": 2.4, + "value": -58.4, + "curve": [ 2.434, -53.72, 2.468, -52.12 ] + }, + { + "time": 2.5, + "value": -51.96, + "curve": [ 2.683, -51.05, 2.856, -50.86 ] + }, + { + "time": 3.0333, + "value": -50.86, + "curve": [ 3.343, -50.86, 3.712, -53.09 ] + }, + { + "time": 3.9333, + "value": -55.94, + "curve": [ 4.2, -59.38, 4.463, -65.17 ] + }, + { + "time": 4.5333, + "value": -69.07, + "curve": [ 4.598, -72.69, 4.635, -81.74 ] + }, + { "time": 4.6667, "value": -85.29 } + ], + "scale": [ + { + "time": 0.5, + "curve": [ 0.511, 1, 0.522, 1.041, 0.511, 1, 0.522, 0.953 ] + }, + { + "time": 0.5333, + "x": 1.041, + "y": 0.953, + "curve": [ 0.556, 1.041, 0.589, 1.038, 0.544, 0.953, 0.589, 0.959 ] + }, + { + "time": 0.6, + "x": 1.033, + "y": 0.966, + "curve": [ 0.633, 1.018, 0.667, 0.989, 0.633, 0.989, 0.667, 1.014 ] + }, + { + "time": 0.7, + "x": 0.989, + "y": 1.014, + "curve": [ 0.733, 0.989, 0.8, 1, 0.733, 1.014, 0.8, 1 ] + }, + { "time": 0.8333 } + ] + }, + "neck": { + "rotate": [ + { + "value": -2.83, + "curve": [ 0.033, -2.83, 0.1, 12.35 ] + }, + { + "time": 0.1333, + "value": 12.35, + "curve": [ 0.158, 12.35, 0.267, 2.18 ] + }, + { + "time": 0.3333, + "value": -8.48, + "curve": [ 0.389, -17.37, 0.444, -46.28 ] + }, + { + "time": 0.5, + "value": -46.28, + "curve": [ 0.522, -46.28, 0.551, -12.18 ] + }, + { + "time": 0.5667, + "value": -2.91, + "curve": [ 0.591, 11.16, 0.611, 20.82 ] + }, + { + "time": 0.6333, + "value": 23.43, + "curve": [ 0.756, 37.76, 0.878, 47.9 ] + }, + { + "time": 1, + "value": 47.91, + "curve": [ 1.411, 47.95, 1.935, 47.95 ] + }, + { + "time": 2.2333, + "value": 47.95, + "curve": [ 2.322, 47.95, 2.432, 19.53 ] + }, + { + "time": 2.5, + "value": 18.51, + "curve": [ 2.666, 16, 2.767, 14.59 ] + }, + { + "time": 2.9, + "value": 14.59, + "curve": [ 3.156, 14.59, 3.425, 14.72 ] + }, + { + "time": 3.6667, + "value": 15.23, + "curve": [ 4.026, 16, 4.28, 17.21 ] + }, + { + "time": 4.4667, + "value": 18.51, + "curve": [ 4.527, 18.71, 4.61, 45.05 ] + }, + { "time": 4.6667, "value": 47.95 } + ] + }, + "torso": { + "rotate": [ + { + "value": -8.62, + "curve": [ 0.031, -16.41, 0.1, -26.52 ] + }, + { + "time": 0.1333, + "value": -26.52, + "curve": [ 0.167, -26.52, 0.233, 3.45 ] + }, + { + "time": 0.2667, + "value": 21.92, + "curve": [ 0.326, 54.76, 0.422, 108.54 ] + }, + { + "time": 0.5, + "value": 108.54, + "curve": [ 0.522, 108.54, 0.559, 79.42 ] + }, + { + "time": 0.5667, + "value": 76.67, + "curve": [ 0.577, 72.83, 0.633, 68.68 ] + }, + { + "time": 0.6667, + "value": 68.68, + "curve": [ 0.733, 68.68, 0.8, 74.71 ] + }, + { "time": 0.8667, "value": 74.71, "curve": "stepped" }, + { + "time": 2.3333, + "value": 74.71, + "curve": [ 2.58, 74.71, 2.79, 72.33 ] + }, + { + "time": 2.9667, + "value": 72, + "curve": [ 3.439, 71.12, 3.668, 70.89 ] + }, + { + "time": 4, + "value": 71.29, + "curve": [ 4.189, 71.52, 4.286, 72.55 ] + }, + { "time": 4.6667, "value": 74.71 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": -35.85, + "curve": [ 0.024, -41.49, 0.089, -48.72 ] + }, + { + "time": 0.1333, + "value": -48.72, + "curve": [ 0.178, -48.72, 0.225, -18.52 ] + }, + { + "time": 0.2667, + "value": -2.77, + "curve": [ 0.313, 14.63, 0.356, 29.38 ] + }, + { + "time": 0.4, + "value": 42.91, + "curve": [ 0.411, 46.3, 0.422, 47.99 ] + }, + { + "time": 0.4333, + "value": 47.99, + "curve": [ 0.456, 47.99, 0.482, 40.58 ] + }, + { + "time": 0.5, + "value": 35.07, + "curve": [ 0.533, 24.91, 0.567, 12.21 ] + }, + { + "time": 0.6, + "value": 12.36, + "curve": [ 0.633, 12.52, 0.667, 35.68 ] + }, + { + "time": 0.7, + "value": 35.68, + "curve": [ 0.789, 35.68, 0.878, 20.08 ] + }, + { "time": 0.9667, "value": 12.28, "curve": "stepped" }, + { "time": 2.2333, "value": 12.28 }, + { + "time": 2.5667, + "value": 64.63, + "curve": [ 2.589, 66.48, 2.611, 69.77 ] + }, + { + "time": 2.6333, + "value": 70.2, + "curve": [ 2.756, 72.57, 2.878, 73.08 ] + }, + { + "time": 3, + "value": 73.04, + "curve": [ 3.189, 72.97, 3.378, 69.18 ] + }, + { + "time": 3.5667, + "value": 68.76, + "curve": [ 3.735, 68.38, 3.902, 72.6 ] + }, + { + "time": 4.0667, + "value": 72.12, + "curve": [ 4.224, 71.68, 4.378, 72.12 ] + }, + { + "time": 4.5333, + "value": 64.63, + "curve": [ 4.622, 60.34, 4.711, 42.63 ] + }, + { "time": 4.8, "value": 31.63 }, + { "time": 4.9333, "value": 10.72 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": -44.7, + "curve": [ 0.044, -44.7, 0.089, 52.3 ] + }, + { + "time": 0.1333, + "value": 52.3, + "curve": [ 0.178, 52.3, 0.227, 48.52 ] + }, + { + "time": 0.2667, + "value": 41.27, + "curve": [ 0.332, 29.13, 0.356, 21.33 ] + }, + { + "time": 0.4, + "value": 21.33, + "curve": [ 0.511, 21.33, 0.577, 177.32 ] + }, + { + "time": 0.6667, + "value": 178.37, + "curve": [ 0.703, 178.79, 0.822, 158.2 ] + }, + { "time": 0.9, "value": 158.2 } + ], + "translate": [ + { "time": 0.4 }, + { "time": 0.9, "x": -32.41, "y": 0.65 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": 21.88, + "curve": [ 0.048, 21.49, 0.089, 20.61 ] + }, + { + "time": 0.1333, + "value": 11.49, + "curve": [ 0.156, 6.92, 0.178, -12.78 ] + }, + { + "time": 0.2, + "value": -19.19, + "curve": [ 0.222, -25.6, 0.244, -26.96 ] + }, + { + "time": 0.2667, + "value": -26.96, + "curve": [ 0.311, -26.96, 0.356, -25.04 ] + }, + { + "time": 0.4, + "value": -15.9, + "curve": [ 0.433, -9.05, 0.467, 21.01 ] + }, + { + "time": 0.5, + "value": 21.01, + "curve": [ 0.533, 21.01, 0.567, -6.78 ] + }, + { + "time": 0.6, + "value": -18.23, + "curve": [ 0.622, -25.86, 0.644, -36.22 ] + }, + { + "time": 0.6667, + "value": -36.22, + "curve": [ 0.689, -36.22, 0.72, 1.23 ] + }, + { + "time": 0.7333, + "value": 10.31, + "curve": [ 0.761, 28.71, 0.822, 44.2 ] + }, + { + "time": 0.8667, + "value": 44.2, + "curve": [ 0.911, 44.2, 1, -14.97 ] + }, + { "time": 1, "value": -18.88, "curve": "stepped" }, + { + "time": 2.2333, + "value": -18.88, + "curve": [ 2.389, -18.88, 2.544, -1.96 ] + }, + { + "time": 2.7, + "value": -1.96, + "curve": [ 2.811, -1.96, 2.923, -10.35 ] + }, + { + "time": 3.0333, + "value": -10.35, + "curve": [ 3.224, -10.35, 3.411, -1.76 ] + }, + { + "time": 3.6, + "value": -1.76, + "curve": [ 3.922, -1.76, 4.244, -1.96 ] + }, + { + "time": 4.5667, + "value": -1.96, + "curve": [ 4.644, -1.96, 4.722, 34.31 ] + }, + { + "time": 4.8, + "value": 34.31, + "curve": [ 4.844, 34.31, 4.889, -1.06 ] + }, + { "time": 4.9333, "value": -18.75 } + ] + }, + "front-fist": { + "rotate": [ + { + "value": -2.33, + "curve": [ 0.044, -1.82, 0.089, -0.79 ] + }, + { + "time": 0.1333, + "value": -0.79, + "curve": [ 0.178, -0.79, 0.222, -12.86 ] + }, + { + "time": 0.2667, + "value": -12.86, + "curve": [ 0.322, -12.86, 0.378, -5.51 ] + }, + { + "time": 0.4333, + "value": -5.51, + "curve": [ 0.522, -5.51, 0.611, -23.93 ] + }, + { + "time": 0.7, + "value": -23.93, + "curve": [ 0.767, -23.93, 0.833, 6.31 ] + }, + { + "time": 0.9, + "value": 6.31, + "curve": [ 0.978, 6.31, 1.114, -2.63 ] + }, + { "time": 1.1333, "value": -5.63, "curve": "stepped" }, + { "time": 2.2333, "value": -5.63 }, + { "time": 2.4333, "value": -17.37 }, + { "time": 2.7, "value": 5.73, "curve": "stepped" }, + { + "time": 3.3667, + "value": 5.73, + "curve": [ 3.5, 5.73, 3.633, 1.93 ] + }, + { + "time": 3.7667, + "value": 1.93, + "curve": [ 3.867, 1.93, 3.967, 7.13 ] + }, + { + "time": 4.0667, + "value": 7.13, + "curve": [ 4.267, 7.13, 4.467, 5.73 ] + }, + { + "time": 4.6667, + "value": 5.73, + "curve": [ 4.678, 5.73, 4.732, 13.73 ] + }, + { + "time": 4.7667, + "value": 13.89, + "curve": [ 4.833, 14.19, 4.933, 4.95 ] + }, + { "time": 4.9333, "value": 3.65 } + ] + }, + "rear-bracer": { + "rotate": [ + { "value": 10.36 }, + { "time": 0.1333, "value": -23.12 }, + { "time": 0.2667, "value": -23.12 }, + { "time": 0.4, "value": -23.16, "curve": "stepped" }, + { "time": 0.4333, "value": -23.16 }, + { "time": 0.5667, "value": -23.2 } + ] + }, + "gun": { + "rotate": [ + { "value": -2.79 }, + { "time": 0.1333, "value": -24.58 } + ] + }, + "front-thigh": { + "rotate": [ + { + "curve": [ 0.052, 4.38, 0.089, 28.31 ] + }, + { + "time": 0.1333, + "value": 48.45, + "curve": [ 0.178, 68.6, 0.222, 99.39 ] + }, + { + "time": 0.2667, + "value": 120.87, + "curve": [ 0.311, 142.34, 0.356, 169.02 ] + }, + { + "time": 0.4, + "value": 177.3, + "curve": [ 0.433, 183.51, 0.467, 183.51 ] + }, + { + "time": 0.5, + "value": 183.51, + "curve": [ 0.544, 183.51, 0.589, 176.55 ] + }, + { + "time": 0.6333, + "value": 162.29, + "curve": [ 0.678, 148.03, 0.752, 108.37 ] + }, + { + "time": 0.7667, + "value": 97.94, + "curve": [ 0.819, 105.34, 0.856, 110.74 ] + }, + { + "time": 0.9, + "value": 110.74, + "curve": [ 0.944, 110.74, 1.016, 102.2 ] + }, + { "time": 1.0333, "value": 97.93 } + ] + }, + "front-shin": { + "rotate": [ + { + "curve": [ 0.044, 0.09, 0.1, -7.14 ] + }, + { + "time": 0.1333, + "value": -14.67, + "curve": [ 0.169, -22.83, 0.222, -43.77 ] + }, + { + "time": 0.2667, + "value": -43.77, + "curve": [ 0.311, -43.77, 0.344, -43.27 ] + }, + { + "time": 0.4, + "value": -33.94, + "curve": [ 0.433, -28.34, 0.467, 4.15 ] + }, + { + "time": 0.5, + "value": 9.2, + "curve": [ 0.533, 14.25, 0.567, 14.25 ] + }, + { + "time": 0.6, + "value": 14.25, + "curve": [ 0.733, 14.25, 0.867, 4.73 ] + }, + { "time": 1, "value": -0.03 } + ] + }, + "rear-thigh": { + "rotate": [ + { + "curve": [ 0.044, 21.88, 0.089, 41.01 ] + }, + { + "time": 0.1333, + "value": 65.64, + "curve": [ 0.178, 90.28, 0.222, 127.15 ] + }, + { + "time": 0.2667, + "value": 147.79, + "curve": [ 0.311, 168.43, 0.356, 189.48 ] + }, + { + "time": 0.4, + "value": 189.48, + "curve": [ 0.433, 189.48, 0.473, 161.8 ] + }, + { + "time": 0.5, + "value": 142.56, + "curve": [ 0.542, 113.14, 0.589, 83.04 ] + }, + { + "time": 0.6, + "value": 78.15, + "curve": [ 0.613, 83.04, 0.733, 108.16 ] + }, + { + "time": 0.8, + "value": 108.16, + "curve": [ 0.878, 108.16, 1.009, 88.71 ] + }, + { "time": 1.0333, "value": 82.7 } + ] + }, + "rear-shin": { + "rotate": [ + { + "curve": [ 0.044, -19.59, 0.089, -58.76 ] + }, + { + "time": 0.1333, + "value": -58.76, + "curve": [ 0.178, -58.76, 0.222, -54.53 ] + }, + { + "time": 0.2667, + "value": -47.85, + "curve": [ 0.311, -41.16, 0.356, -33.24 ] + }, + { + "time": 0.4, + "value": -18.63, + "curve": [ 0.433, -7.68, 0.467, 28.83 ] + }, + { + "time": 0.5, + "value": 28.83, + "curve": [ 0.533, 28.83, 0.567, 15.17 ] + }, + { + "time": 0.6, + "value": 15.17, + "curve": [ 0.633, 15.17, 0.667, 16.17 ] + }, + { + "time": 0.7, + "value": 18.37, + "curve": [ 0.744, 21.32, 0.789, 27.27 ] + }, + { + "time": 0.8333, + "value": 30.61, + "curve": [ 0.878, 33.95, 0.922, 38.42 ] + }, + { + "time": 0.9667, + "value": 38.42, + "curve": [ 1.011, 38.42, 1.079, 17.39 ] + }, + { "time": 1.1, "value": 9.11 } + ] + }, + "rear-foot": { + "rotate": [ + { + "curve": [ 0.044, 0, 0.114, -5.44 ] + }, + { + "time": 0.1333, + "value": -11.63, + "curve": [ 0.158, -19.61, 0.222, -57.59 ] + }, + { + "time": 0.2667, + "value": -57.59, + "curve": [ 0.311, -57.59, 0.356, -45.6 ] + }, + { + "time": 0.4, + "value": -45.6, + "curve": [ 0.433, -45.6, 0.467, -65.99 ] + }, + { + "time": 0.5, + "value": -65.99, + "curve": [ 0.522, -65.99, 0.544, -21.7 ] + }, + { + "time": 0.5667, + "value": -21.7, + "curve": [ 0.6, -21.7, 0.633, -47.61 ] + }, + { + "time": 0.6667, + "value": -47.61, + "curve": [ 0.722, -47.61, 0.778, -25.68 ] + }, + { + "time": 0.8333, + "value": -15.6, + "curve": [ 0.878, -7.54, 0.922, 6.79 ] + }, + { + "time": 0.9667, + "value": 6.79, + "curve": [ 1.022, 6.79, 1.093, 2.23 ] + }, + { + "time": 1.1333, + "value": -6.82, + "curve": [ 1.165, -13.89, 1.178, -28.53 ] + }, + { + "time": 1.2, + "value": -28.53, + "curve": [ 1.267, -28.53, 1.333, -23.77 ] + }, + { "time": 1.4, "value": -23.77 } + ] + }, + "front-foot": { + "rotate": [ + { + "curve": [ 0.022, -21.9, 0.044, -65.7 ] + }, + { + "time": 0.0667, + "value": -65.7, + "curve": [ 0.089, -65.7, 0.111, -65.7 ] + }, + { + "time": 0.1333, + "value": -64.65, + "curve": [ 0.222, -60.43, 0.311, -52.48 ] + }, + { + "time": 0.4, + "value": -42.68, + "curve": [ 0.433, -39, 0.467, -33.17 ] + }, + { + "time": 0.5, + "value": -24.22, + "curve": [ 0.544, -12.29, 0.589, 19.98 ] + }, + { + "time": 0.6333, + "value": 19.98, + "curve": [ 0.656, 19.98, 0.678, 13.2 ] + }, + { + "time": 0.7, + "value": 2.45, + "curve": [ 0.733, -13.69, 0.767, -60.68 ] + }, + { + "time": 0.8, + "value": -60.68, + "curve": [ 0.878, -60.68, 0.956, 0.38 ] + }, + { + "time": 1.0333, + "value": 0.38, + "curve": [ 1.078, 0.38, 1.122, -31.77 ] + }, + { + "time": 1.1667, + "value": -31.77, + "curve": [ 1.211, -31.77, 1.256, -26.74 ] + }, + { "time": 1.3, "value": -24.22 } + ] + }, + "hip": { + "translate": [ + { + "curve": [ 0.081, -41.14, 0.178, -93.27, 0.038, 78.73, 0.156, 168.49 ] + }, + { + "time": 0.2667, + "x": -137.74, + "y": 169.66, + "curve": [ 0.333, -171.09, 0.4, -202.84, 0.377, 170.82, 0.467, 29.16 ] + }, + { + "time": 0.4667, + "x": -233.47, + "y": -76.63, + "curve": [ 0.5, -248.79, 0.533, -265.16, 0.521, -158.34, 0.516, -167.9 ] + }, + { + "time": 0.5667, + "x": -275.61, + "y": -209.28, + "curve": [ 0.589, -282.57, 0.608, -285.14, 0.572, -213.87, 0.611, -216.23 ] + }, + { + "time": 0.6333, + "x": -285.69, + "y": -216.23, + "curve": [ 0.713, -287.45, 0.789, -288.08, 0.711, -216.23, 0.812, -213.49 ] + }, + { + "time": 0.8667, + "x": -288.44, + "y": -209.28, + "curve": [ 0.911, -288.65, 0.965, -288.65, 0.919, -209.28, 0.967, -209.28 ] + }, + { "time": 1, "x": -288.65, "y": -209.28 } + ] + } + } + }, + "hit": { + "slots": { + "front-fist": { + "attachment": [ + { "time": 0.1667, "name": "front-fist-open" } + ] + }, + "mouth": { + "attachment": [ + { "name": "mouth-grind" }, + { "time": 0.3333, "name": "mouth-smile" } + ] + } + }, + "bones": { + "torso": { + "rotate": [ + { "value": 56.42 }, + { "time": 0.3333, "value": 8.89 } + ] + }, + "neck": { + "rotate": [ + { "value": 35.39 }, + { "time": 0.2333, "value": 24.95 } + ] + }, + "head": { + "rotate": [ + { "value": 10.22 }, + { "time": 0.3333, "value": -41.3 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": -310.93, + "curve": [ 0.127, -397.15, 0.248, -472.6 ] + }, + { "time": 0.3333, "value": -472.6 } + ], + "translate": [ + { "x": 7.23, "y": -13.13 } + ] + }, + "front-bracer": { + "rotate": [ + { "value": 36.99 }, + { "time": 0.3333, "value": -28.65 } + ] + }, + "front-fist": { + "rotate": [ + { "value": 13.59 }, + { "time": 0.3333, "value": 7.56 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": 271.02, + "curve": [ 0.114, 297.63, 0.227, 322.97 ] + }, + { "time": 0.3333, "value": 344.16 } + ], + "translate": [ + { "time": 0.3333, "x": -0.1, "y": -0.46 } + ] + }, + "rear-bracer": { + "rotate": [ + {}, + { "time": 0.3333, "value": 40.03 } + ] + }, + "gun": { + "rotate": [ + { "value": 14.98 }, + { "time": 0.3333, "value": 39.76 } + ] + }, + "front-thigh": { + "rotate": [ + { + "value": 90.94, + "curve": [ 0.076, 75.29, 0.144, 32.03 ] + }, + { "time": 0.3333, "value": 32.03 } + ], + "translate": [ + { "x": 7.21, "y": -4 } + ] + }, + "rear-thigh": { + "rotate": [ + { + "value": 40.52, + "curve": [ 0.099, 55.81, 0.197, 90.52 ] + }, + { "time": 0.3333, "value": 90.77 } + ], + "translate": [ + { "x": -1.96, "y": -0.32 } + ] + }, + "front-shin": { + "rotate": [ + { "value": -96.63 }, + { "time": 0.3333, "value": -15.13 } + ] + }, + "rear-shin": { + "rotate": [ + { "value": 8 }, + { "time": 0.3333, "value": -67.54 } + ] + }, + "front-foot": { + "rotate": [ + { "value": 5.4 }, + { "time": 0.3333, "value": -16.27 } + ] + }, + "rear-foot": { + "rotate": [ + { "value": 2.67 }, + { "time": 0.3333, "value": -10.31 } + ] + }, + "hip": { + "translate": [ + { "x": -75.55, "y": -78.04 }, + { "time": 0.2333, "x": -36.48, "y": 12.42 }, + { "time": 0.3333, "x": -36.48, "y": -3 } + ] + } + } + }, + "idle": { + "slots": { + "front-fist": { + "attachment": [ + { "name": "front-fist-open" } + ] + } + }, + "bones": { + "torso": { + "rotate": [ + { + "value": -16.11, + "curve": [ 0.057, -15.7, 0.268, -14.61 ] + }, + { + "time": 0.4333, + "value": -14.6, + "curve": [ 0.591, -14.59, 0.73, -15.81 ] + }, + { + "time": 0.8333, + "value": -16.63, + "curve": [ 0.915, -17.27, 1.074, -18.04 ] + }, + { + "time": 1.2333, + "value": -18.02, + "curve": [ 1.385, -18, 1.619, -16.57 ] + }, + { "time": 1.6667, "value": -16.11 } + ], + "translate": [ + { "x": -6.5 } + ], + "scale": [ + { + "curve": [ 0.156, 0.996, 0.525, 0.994, 0.106, 1.002, 0.525, 1.01 ] + }, + { + "time": 0.8333, + "x": 0.994, + "y": 1.01, + "curve": [ 1.15, 0.994, 1.52, 0.997, 1.15, 1.01, 1.519, 1.004 ] + }, + { "time": 1.6667 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": -59.85, + "curve": [ 0.329, -59.85, 0.447, -64.99 ] + }, + { + "time": 0.6667, + "value": -64.99, + "curve": [ 0.997, -64.99, 1.417, -59.85 ] + }, + { "time": 1.6667, "value": -59.85 } + ], + "translate": [ + { + "x": -7.12, + "y": -8.24, + "curve": [ 0.167, -7.12, 0.5, -3.66, 0.167, -8.24, 0.5, -5.93 ] + }, + { + "time": 0.6667, + "x": -3.66, + "y": -5.93, + "curve": [ 0.917, -3.66, 1.417, -7.12, 0.917, -5.93, 1.417, -8.24 ] + }, + { "time": 1.6667, "x": -7.12, "y": -8.24 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": 39.08, + "curve": [ 0.37, 38.67, 0.55, 32.29 ] + }, + { + "time": 0.7333, + "value": 32.29, + "curve": [ 0.967, 32.29, 1.433, 39.08 ] + }, + { "time": 1.6667, "value": 39.08 } + ], + "translate": [ + { + "x": -1.83, + "y": -6.48, + "curve": [ 0.167, -1.83, 0.5, 0.35, 0.167, -6.48, 0.447, -4.92 ] + }, + { + "time": 0.6667, + "x": 0.35, + "y": -4.92, + "curve": [ 0.917, 0.35, 1.417, -1.83, 0.917, -4.92, 1.417, -6.48 ] + }, + { "time": 1.6667, "x": -1.83, "y": -6.48 } + ] + }, + "neck": { + "rotate": [ + { + "curve": [ 0.167, 0, 0.5, 2.39 ] + }, + { + "time": 0.6667, + "value": 2.39, + "curve": [ 0.917, 2.39, 1.417, 0 ] + }, + { "time": 1.6667 } + ], + "translate": [ + { "x": -1.89, "y": -4.76 } + ] + }, + "front-thigh": { + "rotate": [ + { + "value": 0.65, + "curve": [ 0.157, 0.6, 0.372, -4.31 ] + }, + { + "time": 0.6667, + "value": -4.34, + "curve": [ 1.262, -4.34, 1.32, 0.65 ] + }, + { "time": 1.6667, "value": 0.65 } + ], + "translate": [ + { "x": -13.4, "y": 6.7 } + ], + "scale": [ + { + "x": 0.945, + "curve": [ 0.157, 0.945, 0.372, 0.917, 0.157, 1, 0.372, 1 ] + }, + { + "time": 0.6667, + "x": 0.917, + "curve": [ 1.262, 0.917, 1.32, 0.945, 1.262, 1, 1.32, 1 ] + }, + { "time": 1.6667, "x": 0.945 } + ] + }, + "front-shin": { + "rotate": [ + { "value": -19.59 } + ], + "scale": [ + { + "curve": [ 0.157, 1, 0.372, 0.994, 0.157, 1, 0.372, 1 ] + }, + { + "time": 0.6667, + "x": 0.994, + "curve": [ 1.262, 0.994, 1.32, 1, 1.262, 1, 1.32, 1 ] + }, + { "time": 1.6667 } + ] + }, + "rear-thigh": { + "rotate": [ + { + "value": 30.51, + "curve": [ 0.157, 30.6, 0.372, 40.09 ] + }, + { + "time": 0.6667, + "value": 40.15, + "curve": [ 1.262, 40.14, 1.32, 30.51 ] + }, + { "time": 1.6667, "value": 30.51 } + ] + }, + "rear-shin": { + "rotate": [ + { + "value": -24.14, + "curve": [ 0.157, -24.33, 0.372, -43.64 ] + }, + { + "time": 0.6667, + "value": -43.77, + "curve": [ 1.262, -43.76, 1.32, -23.83 ] + }, + { "time": 1.6667, "value": -23.83 } + ] + }, + "front-foot": { + "rotate": [ + { + "value": 4.83, + "curve": [ 0.157, 4.88, 0.372, 10.02 ] + }, + { + "time": 0.6667, + "value": 10.05, + "curve": [ 1.262, 10.05, 1.32, 5.14 ] + }, + { "time": 1.6667, "value": 5.14 } + ], + "scale": [ + { "x": 0.755, "y": 1.31 } + ] + }, + "rear-foot": { + "rotate": [ + { + "value": -7.65, + "curve": [ 0.157, -7.54, 0.372, 3.78 ] + }, + { + "time": 0.6667, + "value": 3.85, + "curve": [ 1.262, 3.84, 1.32, -7.34 ] + }, + { "time": 1.6667, "value": -7.34 } + ] + }, + "rear-bracer": { + "rotate": [ + { + "value": -17.16, + "curve": [ 0.167, -17.16, 0.447, -4.1 ] + }, + { + "time": 0.6667, + "value": -4.1, + "curve": [ 0.997, -4.1, 1.417, -17.16 ] + }, + { "time": 1.6667, "value": -17.16 } + ] + }, + "head": { + "rotate": [ + { + "value": -5.51, + "curve": [ 0.167, -5.51, 0.7, -3.12 ] + }, + { + "time": 0.8667, + "value": -3.12, + "curve": [ 1.117, -3.12, 1.417, -5.51 ] + }, + { "time": 1.6667, "value": -5.51 } + ], + "scale": [ + { + "curve": [ 0.217, 1, 0.546, 0.996, 0.217, 1, 0.546, 1.007 ] + }, + { + "time": 0.8667, + "x": 0.996, + "y": 1.007, + "curve": [ 1.171, 0.996, 1.467, 1, 1.171, 1.007, 1.467, 1 ] + }, + { "time": 1.6667 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": 35.2, + "curve": [ 0.086, 36.03, 0.514, 40.31 ] + }, + { + "time": 0.6667, + "value": 40.3, + "curve": [ 0.859, 40.29, 0.969, 32.24 ] + }, + { + "time": 1.2, + "value": 32.31, + "curve": [ 1.401, 32.37, 1.561, 34.14 ] + }, + { "time": 1.6667, "value": 35.2 } + ] + }, + "gun": { + "rotate": [ + { + "curve": [ 0.167, 0, 0.581, -12.7 ] + }, + { + "time": 0.8667, + "value": -12.7, + "curve": [ 1.131, -12.7, 1.437, -0.11 ] + }, + { "time": 1.6667 } + ] + }, + "front-fist": { + "rotate": [ + { + "value": -6.85, + "curve": [ 0.181, -5.23, 0.5, -3.97 ] + }, + { + "time": 0.6667, + "value": -3.89, + "curve": [ 0.84, -3.81, 1.042, -9.89 ] + }, + { + "time": 1.2667, + "value": -9.76, + "curve": [ 1.428, -9.66, 1.537, -8.3 ] + }, + { "time": 1.6667, "value": -6.85 } + ], + "scale": [ + { + "curve": [ 0.167, 1, 0.5, 0.886, 0.167, 1, 0.5, 1.101 ] + }, + { + "time": 0.6667, + "x": 0.886, + "y": 1.101, + "curve": [ 0.917, 0.886, 1.417, 1, 0.917, 1.101, 1.417, 1 ] + }, + { "time": 1.6667 } + ] + }, + "hip": { + "translate": [ + { + "x": -6.64, + "y": -23.02, + "curve": [ 0.157, -6.51, 0.372, 6.19, 0.157, -23.13, 0.372, -34.93 ] + }, + { + "time": 0.6667, + "x": 6.28, + "y": -35.01, + "curve": [ 1.262, 6.27, 1.32, -6.64, 1.262, -35, 1.32, -23.02 ] + }, + { "time": 1.6667, "x": -6.64, "y": -23.02 } + ] + } + } + }, + "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.411, 36.56 ] + }, + { + "time": 0.5, + "value": 36.56, + "curve": [ 0.656, 36.56, 0.811, 33.41 ] + }, + { + "time": 0.9667, + "value": 26.43, + "curve": [ 1.011, 24.43, 1.056, 9.63 ] + }, + { + "time": 1.1, + "value": 9.63, + "curve": [ 1.122, 9.63, 1.144, 9.63 ] + }, + { + "time": 1.1667, + "value": 12.33, + "curve": [ 1.178, 13.68, 1.189, 47.62 ] + }, + { + "time": 1.2, + "value": 56.85, + "curve": [ 1.211, 66.08, 1.222, 67.7 ] + }, + { + "time": 1.2333, + "value": 67.72, + "curve": [ 1.261, 67.77, 1.322, 58.12 ] + }, + { "time": 1.3333, "value": 55.08 } + ], + "translate": [ + { + "x": -5.13, + "y": 11.55, + "curve": [ 0.422, -5.13, 0.733, -5.25, 0.422, 11.55, 0.733, 11.55 ] + }, + { + "time": 1.1, + "x": -5.25, + "y": 11.55, + "curve": [ 1.133, -5.25, 1.167, -4.54, 1.133, 11.55, 1.167, -1.07 ] + }, + { + "time": 1.2, + "x": -3.98, + "y": -1.07, + "curve": [ 1.211, -3.79, 1.222, -3.62, 1.211, -1.07, 1.222, 5.22 ] + }, + { + "time": 1.2333, + "x": -3.5, + "y": 5.73, + "curve": [ 1.245, -3.37, 1.289, -3.68, 1.245, 6.24, 1.283, 5.14 ] + }, + { + "time": 1.3, + "x": -4.1, + "y": 5.23, + "curve": [ 1.311, -4.52, 1.322, -4.99, 1.32, 5.32, 1.322, 9.78 ] + }, + { "time": 1.3333, "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.289, 44.58 ] + }, + { "time": 1.3333, "value": 40.5 } + ] + }, + "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.011, 10.6 ] + }, + { + "time": 1.1, + "value": 15.01, + "curve": [ 1.178, 18.87, 1.279, 20.64 ] + }, + { "time": 1.3333, "value": 20.73 } + ] + }, + "head": { + "rotate": [ + { + "value": 13.14, + "curve": [ 0.063, 13.1, 0.222, -20.78 ] + }, + { + "time": 0.3333, + "value": -20.78, + "curve": [ 0.467, -20.78, 0.6, 7.26 ] + }, + { + "time": 0.7333, + "value": 11.44, + "curve": [ 0.811, 13.88, 0.889, 13.88 ] + }, + { + "time": 0.9667, + "value": 13.88, + "curve": [ 1.044, 13.88, 1.122, 7.56 ] + }, + { + "time": 1.2, + "value": 7.56, + "curve": [ 1.244, 7.56, 1.289, 11.28 ] + }, + { "time": 1.3333, "value": 13.14 } + ], + "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.173, 1.092, 1, 1.128, 0.975 ] + }, + { + "time": 1.1667, + "x": 1.174, + "y": 0.973, + "curve": [ 1.204, 1.175, 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.311, 1, 1.288, 1.063, 1.311, 1 ] + }, + { "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, 753.87 ] + }, + { + "time": 0.7667, + "x": -34.52, + "y": 754.96, + "curve": [ 0.888, -34.52, 1.057, -21.95, 1.049, 754.54, 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.389, -51.96 ] + }, + { + "time": 0.5, + "value": -51.96, + "curve": [ 0.633, -51.96, 0.767, -40.17 ] + }, + { + "time": 0.9, + "value": -30.59, + "curve": [ 0.967, -25.8, 1.033, -16.01 ] + }, + { + "time": 1.1, + "value": -8.85, + "curve": [ 1.122, -6.46, 1.144, -1.91 ] + }, + { + "time": 1.1667, + "value": -1.91, + "curve": [ 1.178, -1.91, 1.189, -58.19 ] + }, + { + "time": 1.2, + "value": -72.71, + "curve": [ 1.211, -87.23, 1.222, -89.05 ] + }, + { + "time": 1.2333, + "value": -89.05, + "curve": [ 1.273, -89.05, 1.308, -79.55 ] + }, + { "time": 1.3333, "value": -74.19 } + ] + }, + "front-foot": { + "rotate": [ + { + "value": 15.88, + "curve": [ 0, 13.33, 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.089, -19.36, 1.127, -67.74 ] + }, + { + "time": 1.1667, + "value": -63.62, + "curve": [ 1.178, -62.51, 1.189, 5.83 ] + }, + { + "time": 1.2, + "value": 11.39, + "curve": [ 1.222, 22.51, 1.244, 22.51 ] + }, + { + "time": 1.2667, + "value": 22.51, + "curve": [ 1.289, 22.51, 1.333, 16.45 ] + }, + { "time": 1.3333, "value": 15.88 } + ] + }, + "rear-foot": { + "rotate": [ + { + "value": -7.14, + "curve": [ 0.044, -17.32, 0.089, -37.67 ] + }, + { + "time": 0.1333, + "value": -37.67, + "curve": [ 0.311, -37.67, 0.521, -26.72 ] + }, + { + "time": 0.6667, + "value": -15.71, + "curve": [ 0.776, -7.49, 0.911, 14.92 ] + }, + { + "time": 1.0333, + "value": 14.92, + "curve": [ 1.133, 14.92, 1.233, 0.21 ] + }, + { "time": 1.3333, "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 } + ] + } + }, + "events": [ + { "time": 1.2, "name": "footstep" } + ] + }, + "run": { + "slots": { + "mouth": { + "attachment": [ + { "name": "mouth-grind" } + ] + } + }, + "bones": { + "front-thigh": { + "rotate": [ + { + "value": 49.77, + "curve": [ 0.007, 49.71, 0.022, 41.99 ] + }, + { + "time": 0.0333, + "value": 32.26, + "curve": [ 0.044, 22.54, 0.056, 0.1 ] + }, + { + "time": 0.0667, + "value": -8.56, + "curve": [ 0.078, -17.22, 0.089, -19.05 ] + }, + { + "time": 0.1, + "value": -19.71, + "curve": [ 0.144, -22.38, 0.189, -22.38 ] + }, + { + "time": 0.2333, + "value": -22.38, + "curve": [ 0.267, -22.38, 0.3, 36.57 ] + }, + { + "time": 0.3333, + "value": 54.69, + "curve": [ 0.367, 72.82, 0.4, 86.37 ] + }, + { + "time": 0.4333, + "value": 86.37, + "curve": [ 0.478, 86.37, 0.522, 46.94 ] + }, + { + "time": 0.5667, + "value": 46.94, + "curve": [ 0.589, 46.94, 0.652, 49.34 ] + }, + { "time": 0.6667, "value": 49.77 } + ], + "translate": [ + { + "x": -7.86, + "y": 10.34, + "curve": [ 0.036, -7.85, 0.123, -6.71, 0.056, 10.34, 0.108, 9.74 ] + }, + { + "time": 0.1667, + "x": -5.7, + "y": 7.99, + "curve": [ 0.22, -4.49, 0.295, -0.78, 0.236, 5.93, 0.28, 3.22 ] + }, + { + "time": 0.3333, + "x": 1.68, + "y": 3.19, + "curve": [ 0.358, 3.28, 0.449, 9.99, 0.384, 3.16, 0.449, 4.98 ] + }, + { + "time": 0.5, + "x": 9.99, + "y": 6.76, + "curve": [ 0.556, 10, 0.611, -7.86, 0.556, 8.69, 0.611, 10.34 ] + }, + { "time": 0.6667, "x": -7.86, "y": 10.34 } + ] + }, + "torso": { + "rotate": [ + { + "value": -38.65, + "curve": [ 0.022, -39.16, 0.067, -41.4 ] + }, + { + "time": 0.1, + "value": -41.4, + "curve": [ 0.156, -41.4, 0.211, -37.6 ] + }, + { + "time": 0.2667, + "value": -37.6, + "curve": [ 0.289, -37.6, 0.315, -38.2 ] + }, + { + "time": 0.3333, + "value": -38.63, + "curve": [ 0.369, -39.48, 0.434, -41.38 ] + }, + { + "time": 0.4667, + "value": -41.39, + "curve": [ 0.512, -41.39, 0.556, -37.69 ] + }, + { + "time": 0.6, + "value": -37.69, + "curve": [ 0.622, -37.69, 0.652, -38.3 ] + }, + { "time": 0.6667, "value": -38.65 } + ] + }, + "rear-thigh": { + "rotate": [ + { + "value": 17.72, + "curve": [ 0.025, 28.51, 0.067, 54.38 ] + }, + { + "time": 0.1, + "value": 54.38, + "curve": [ 0.144, 54.38, 0.189, 19.31 ] + }, + { + "time": 0.2333, + "value": 19.31, + "curve": [ 0.254, 19.31, 0.278, 32.87 ] + }, + { + "time": 0.3, + "value": 32.87, + "curve": [ 0.311, 32.87, 0.322, 32.87 ] + }, + { + "time": 0.3333, + "value": 28.23, + "curve": [ 0.344, 23.6, 0.356, 4.08 ] + }, + { + "time": 0.3667, + "value": -3.6, + "curve": [ 0.389, -18.95, 0.411, -38.43 ] + }, + { + "time": 0.4333, + "value": -40.85, + "curve": [ 0.478, -45.69, 0.522, -45.69 ] + }, + { + "time": 0.5667, + "value": -45.69, + "curve": [ 0.6, -45.69, 0.633, -7.24 ] + }, + { "time": 0.6667, "value": 17.72 } + ], + "translate": [ + { + "x": -13.59, + "y": 3.21, + "curve": [ 0.013, -12.85, 0.183, -8.55, 0.03, 4.05, 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.633, -15.46, 0.592, 0.61, 0.633, 2.28 ] + }, + { "time": 0.6667, "x": -13.59, "y": 3.21 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": 324.21, + "curve": [ 0.051, 363.15, 0.145, 449.66 ] + }, + { + "time": 0.2333, + "value": 449.66, + "curve": [ 0.28, 450.07, 0.324, 419.51 ] + }, + { + "time": 0.3333, + "value": 411.11, + "curve": [ 0.358, 390.19, 0.445, 293.13 ] + }, + { + "time": 0.5667, + "value": 292.23, + "curve": [ 0.599, 291.99, 0.633, 298.54 ] + }, + { "time": 0.6667, "value": 324.21 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": 7.49, + "curve": [ 0.032, 2.15, 0.089, -2.82 ] + }, + { + "time": 0.1333, + "value": -2.8, + "curve": [ 0.186, -2.78, 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, + "curve": [ 0.533, 40.96, 0.643, 13.39 ] + }, + { "time": 0.6667, "value": 7.49 } + ] + }, + "front-fist": { + "rotate": [ + { + "value": -10.96, + "curve": [ 0.014, -13.6, 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.489, -21.29 ] + }, + { + "time": 0.5667, + "value": -21.29, + "curve": [ 0.6, -21.29, 0.633, -10.96 ] + }, + { "time": 0.6667, "value": -10.96 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": 35.32, + "curve": [ 0.028, 18.56, 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.633, 55.07 ] + }, + { "time": 0.6667, "value": 35.32 } + ], + "translate": [ + { + "x": -4.58, + "y": 0.93, + "curve": [ 0.044, -5.37, 0.169, -5.48, 0.044, 2.63, 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.633, -3.98, 0.611, -3.13, 0.633, -0.35 ] + }, + { "time": 0.6667, "x": -4.58, "y": 0.93 } + ] + }, + "rear-bracer": { + "rotate": [ + { "value": 17.03 }, + { + "time": 0.2333, + "value": -13.07, + "curve": [ 0.252, -16.08, 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.625, 24.64 ] + }, + { "time": 0.6667, "value": 17.03 } + ] + }, + "neck": { + "rotate": [ + { + "value": 10.23, + "curve": [ 0.024, 9.75, 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.3, 10.88 ] + }, + { + "time": 0.3333, + "value": 10.3, + "curve": [ 0.367, 9.72, 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.633, 10.91 ] + }, + { "time": 0.6667, "value": 10.23 } + ] + }, + "head": { + "rotate": [ + { + "value": 8.93, + "curve": [ 0.033, 7.96, 0.065, 6.03 ] + }, + { + "time": 0.1, + "value": 6.03, + "curve": [ 0.146, 6.03, 0.189, 10.78 ] + }, + { + "time": 0.2333, + "value": 10.78, + "curve": [ 0.267, 10.78, 0.309, 9.94 ] + }, + { + "time": 0.3333, + "value": 8.93, + "curve": [ 0.358, 7.93, 0.388, 6.1 ] + }, + { + "time": 0.4333, + "value": 6.1, + "curve": [ 0.486, 6.1, 0.544, 10.76 ] + }, + { + "time": 0.6, + "value": 10.76, + "curve": [ 0.622, 10.76, 0.652, 9.58 ] + }, + { "time": 0.6667, "value": 8.93 } + ], + "scale": [ + { + "x": 0.992, + "y": 1.01, + "curve": [ 0.036, 0.991, 0.068, 0.991, 0.014, 1.013, 0.083, 1.026 ] + }, + { + "time": 0.1, + "x": 0.991, + "y": 1.026, + "curve": [ 0.128, 0.991, 0.205, 1.038, 0.128, 1.026, 0.197, 0.982 ] + }, + { + "time": 0.2333, + "x": 1.038, + "y": 0.982, + "curve": [ 0.272, 1.038, 0.305, 1.008, 0.262, 0.982, 0.311, 0.995 ] + }, + { + "time": 0.3333, + "curve": [ 0.351, 0.995, 0.417, 0.981, 0.359, 1.006, 0.417, 1.026 ] + }, + { + "time": 0.4333, + "x": 0.981, + "y": 1.026, + "curve": [ 0.467, 0.981, 0.533, 1.037, 0.467, 1.026, 0.533, 0.982 ] + }, + { + "time": 0.5667, + "x": 1.037, + "y": 0.982, + "curve": [ 0.592, 1.037, 0.636, 0.993, 0.592, 0.982, 0.64, 1.004 ] + }, + { "time": 0.6667, "x": 0.992, "y": 1.01 } + ] + }, + "gun": { + "rotate": [ + { + "value": 18.25, + "curve": [ 0.033, 19.24, 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": 18.25 } + ] + }, + "hip": { + "translate": [ + { + "x": 0.63, + "y": -34.19, + "curve": [ 0.042, 0.39, 0.118, 7.62, 0.042, -33.83, 0.084, 20.04 ] + }, + { + "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.416, 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.633, 0.82, 0.584, -28.58, 0.633, -34.48 ] + }, + { "time": 0.6667, "x": 0.63, "y": -34.19 } + ] + }, + "rear-foot": { + "rotate": [ + { + "value": -27.81, + "curve": [ 0.078, -27.81, 0.156, 17.7 ] + }, + { + "time": 0.2333, + "value": 17.7, + "curve": [ 0.256, 17.7, 0.278, 12.8 ] + }, + { + "time": 0.3, + "value": 12.8, + "curve": [ 0.311, 12.8, 0.322, 17.93 ] + }, + { + "time": 0.3333, + "value": 20.49, + "curve": [ 0.344, 20.49, 0.356, 36.91 ] + }, + { + "time": 0.3667, + "value": 33.49, + "curve": [ 0.378, 30.04, 0.389, 28.84 ] + }, + { + "time": 0.4, + "value": 19.93, + "curve": [ 0.411, 10.9, 0.422, -5.84 ] + }, + { + "time": 0.4333, + "value": -8.18, + "curve": [ 0.478, -17.39, 0.523, 4.88 ] + }, + { + "time": 0.5667, + "value": 2.21, + "curve": [ 0.6, 0.19, 0.633, -27.81 ] + }, + { "time": 0.6667, "value": -27.81 } + ] + }, + "front-foot": { + "rotate": [ + { + "value": 11.76, + "curve": [ 0.008, 11.76, 0.02, 19.97 ] + }, + { + "time": 0.0333, + "value": 20.38, + "curve": [ 0.044, 20.72, 0.056, 17.21 ] + }, + { + "time": 0.0667, + "value": 11.96, + "curve": [ 0.079, 6.01, 0.089, -24.56 ] + }, + { + "time": 0.1, + "value": -25.8, + "curve": [ 0.144, -30.78, 0.189, -30.78 ] + }, + { + "time": 0.2333, + "value": -30.78, + "curve": [ 0.267, -30.78, 0.3, -29.2 ] + }, + { + "time": 0.3333, + "value": -24.64, + "curve": [ 0.389, -17.03, 0.444, -0.27 ] + }, + { + "time": 0.5, + "value": 5.74, + "curve": [ 0.556, 11.76, 0.633, 11.76 ] + }, + { "time": 0.6667, "value": 11.76 } + ] + }, + "front-shin": { + "rotate": [ + { + "value": -66.44, + "curve": [ 0.011, -66.44, 0.022, -65.11 ] + }, + { + "time": 0.0333, + "value": -58, + "curve": [ 0.044, -50.9, 0.056, -28.78 ] + }, + { + "time": 0.0667, + "value": -23.84, + "curve": [ 0.078, -18.9, 0.089, -18.9 ] + }, + { + "time": 0.1, + "value": -18.9, + "curve": [ 0.144, -18.9, 0.189, -66.55 ] + }, + { + "time": 0.2333, + "value": -85.8, + "curve": [ 0.267, -100.25, 0.3, -120 ] + }, + { + "time": 0.3333, + "value": -120, + "curve": [ 0.367, -120, 0.4, -116.77 ] + }, + { + "time": 0.4333, + "value": -103.62, + "curve": [ 0.456, -94.85, 0.478, -73.54 ] + }, + { + "time": 0.5, + "value": -54.26, + "curve": [ 0.522, -34.99, 0.544, -5.08 ] + }, + { + "time": 0.5667, + "value": -5.08, + "curve": [ 0.589, -5.08, 0.611, -31.56 ] + }, + { + "time": 0.6333, + "value": -45.19, + "curve": [ 0.644, -52.01, 0.656, -66.44 ] + }, + { "time": 0.6667, "value": -66.44 } + ] + }, + "rear-shin": { + "rotate": [ + { + "value": -99.91, + "curve": [ 0.048, -99.45, 0.067, -87.25 ] + }, + { + "time": 0.1, + "value": -72.41, + "curve": [ 0.144, -52.61, 0.189, 4.01 ] + }, + { + "time": 0.2333, + "value": 4.01, + "curve": [ 0.256, 4.01, 0.278, -32.4 ] + }, + { + "time": 0.3, + "value": -46.27, + "curve": [ 0.311, -53.2, 0.322, -58.41 ] + }, + { + "time": 0.3333, + "value": -58.41, + "curve": [ 0.367, -58.41, 0.4, -2.86 ] + }, + { + "time": 0.4333, + "value": -2.86, + "curve": [ 0.478, -2.86, 0.522, -61.56 ] + }, + { + "time": 0.5667, + "value": -80.05, + "curve": [ 0.6, -93.91, 0.632, -99.87 ] + }, + { "time": 0.6667, "value": -99.91 } + ] + }, + "gun-tip": { + "rotate": [ + { "time": 0.4333, "value": 12.93 } + ] + } + }, + "drawOrder": [ + { + "offsets": [ + { "slot": "head", "offset": -2 } + ] + } + ], + "events": [ + { "time": 0.2667, "name": "footstep" }, + { "time": 0.6, "name": "footstep" } + ] + }, + "shoot": { + "slots": { + "muzzle": { + "rgba": [ + { "time": 0.3667, "color": "ffffff00" } + ], + "attachment": [ + { "time": 0.1333, "name": "muzzle01" }, + { "time": 0.2, "name": "muzzle02" }, + { "time": 0.2667, "name": "muzzle03" }, + { "time": 0.3333, "name": "muzzle04" }, + { "time": 0.3667 } + ] + } + }, + "bones": { + "gun-tip": { + "translate": [ + { "time": 0.1333 }, + { "time": 0.2333, "x": 32.31, "y": 2.94 } + ] + }, + "gun": { + "rotate": [ + { "value": 1.91, "curve": "stepped" }, + { + "time": 0.1, + "value": 1.91, + "curve": [ 0.113, 4.95, 0.122, 6.56 ] + }, + { + "time": 0.1333, + "value": 6.56, + "curve": [ 0.167, 6.56, 0.2, -0.97 ] + }, + { + "time": 0.2333, + "value": -0.97, + "curve": [ 0.289, -0.97, 0.344, 0.95 ] + }, + { "time": 0.4, "value": 1.91 } + ], + "translate": [ + { "x": 7.95, "y": 5.85, "curve": "stepped" }, + { + "time": 0.1, + "x": 7.95, + "y": 5.85, + "curve": [ 0.167, 7.95, 0.204, -9.3, 0.167, 5.85, 0.204, -1.41 ] + }, + { + "time": 0.3, + "x": -9.3, + "y": -1.41, + "curve": [ 0.333, -9.3, 0.367, 7.95, 0.333, -1.41, 0.367, 5.85 ] + }, + { "time": 0.4, "x": 7.95, "y": 5.85 } + ] + }, + "rear-bracer": { + "rotate": [ + { "value": -30.47 } + ], + "translate": [ + { + "time": 0.1, + "curve": [ 0.156, -4.39, 0.204, -6, 0.167, -3.38, 0.204, -3.72 ] + }, + { "time": 0.3, "x": -6, "y": -3.72 }, + { "time": 0.4 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { "value": 62.31 } + ], + "translate": [ + { + "time": 0.1, + "curve": [ 0.167, 0, 0.204, 2.81, 0.16, 11.74, 0.23, 11.7 ] + }, + { "time": 0.3, "x": 2.81, "y": 11.53 }, + { "time": 0.4 } + ] + } + } + }, + "walk": { + "bones": { + "hip": { + "rotate": [ + { "value": 0.94 } + ], + "translate": [ + { + "x": -2.86, + "y": -13.86, + "curve": [ 0.025, -2.84, 0.067, -2.82, 0.028, -19.14, 0.054, -31.19 ] + }, + { + "time": 0.1, + "x": -2.61, + "y": -31.36, + "curve": [ 0.143, -2.34, 0.202, -1.79, 0.152, -31.16, 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, -31.74 ] + }, + { + "time": 0.6, + "x": -0.17, + "y": -31.56, + "curve": [ 0.632, -0.45, 0.683, -0.94, 0.646, -31.41, 0.688, -17.46 ] + }, + { + "time": 0.7333, + "x": -1.4, + "y": -8.62, + "curve": [ 0.783, -1.85, 0.833, -2.28, 0.77, -1.61, 0.831, 3.51 ] + }, + { + "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 } + ] + }, + "torso": { + "rotate": [ + { + "value": -20.72, + "curve": [ 0.013, -20.49, 0.071, -19.12 ] + }, + { + "time": 0.1333, + "value": -19.12, + "curve": [ 0.187, -19.12, 0.285, -22.22 ] + }, + { + "time": 0.3667, + "value": -22.22, + "curve": [ 0.405, -22.22, 0.491, -20.92 ] + }, + { + "time": 0.5, + "value": -20.71, + "curve": [ 0.51, -20.48, 0.582, -19.06 ] + }, + { + "time": 0.6333, + "value": -19.06, + "curve": [ 0.709, -19.07, 0.815, -22.22 ] + }, + { + "time": 0.8667, + "value": -22.22, + "curve": [ 0.908, -22.22, 0.981, -21.1 ] + }, + { "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 } + ] + }, + "front-thigh": { + "rotate": [ + { + "value": 41.41, + "curve": [ 0.033, 41.52, 0.075, 57.36 ] + }, + { + "time": 0.1, + "value": 57.36, + "curve": [ 0.142, 57.36, 0.249, 30.8 ] + }, + { + "time": 0.2667, + "value": 26.81, + "curve": [ 0.314, 16.08, 0.378, 5.4 ] + }, + { + "time": 0.4, + "value": 2.75, + "curve": [ 0.455, -3.75, 0.54, -12.39 ] + }, + { + "time": 0.6, + "value": -12.39, + "curve": [ 0.633, -12.39, 0.722, 21.07 ] + }, + { + "time": 0.7333, + "value": 25.71, + "curve": [ 0.751, 32.81, 0.824, 63.52 ] + }, + { + "time": 0.8667, + "value": 63.79, + "curve": [ 0.913, 64.09, 0.948, 41.49 ] + }, + { "time": 1, "value": 41.41 } + ], + "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.875, 17.16, 0.525, 0.02, 0.875, -0.09 ] + }, + { "time": 1, "x": 17.15, "y": -0.09 } + ] + }, + "rear-thigh": { + "rotate": [ + { + "value": -40.72, + "curve": [ 0.026, -42.96, 0.075, -43 ] + }, + { + "time": 0.1, + "value": -43, + "curve": [ 0.142, -43, 0.239, 8.23 ] + }, + { + "time": 0.2667, + "value": 18.99, + "curve": [ 0.284, 25.64, 0.367, 38.72 ] + }, + { + "time": 0.4, + "value": 38.72, + "curve": [ 0.425, 38.72, 0.475, 18.7 ] + }, + { + "time": 0.5, + "value": 18.7, + "curve": [ 0.525, 18.7, 0.575, 31.73 ] + }, + { + "time": 0.6, + "value": 31.73, + "curve": [ 0.633, 31.73, 0.719, 15.2 ] + }, + { + "time": 0.7333, + "value": 11.21, + "curve": [ 0.767, 2.12, 0.851, -15.29 ] + }, + { + "time": 0.8667, + "value": -18.46, + "curve": [ 0.905, -26.32, 0.951, -35.33 ] + }, + { "time": 1, "value": -40.72 } + ], + "translate": [ + { + "x": -17.71, + "y": -4.63, + "curve": [ 0.028, -19.31, 0.04, -20.22, 0.027, -4.63, 0.036, 1.71 ] + }, + { + "time": 0.0667, + "x": -20.72, + "y": 1.6, + "curve": [ 0.082, -21, 0.087, -20.93, 0.082, 1.54, 0.091, 0.29 ] + }, + { + "time": 0.1, + "x": -20.95, + "y": 0.06, + "curve": [ 0.162, -21.05, 0.4, 7.79, 0.194, -2.43, 0.4, -1.9 ] + }, + { + "time": 0.5, + "x": 7.79, + "y": -1.94, + "curve": [ 0.519, 7.78, 0.542, 7.33, 0.517, -1.94, 0.54, 5.55 ] + }, + { + "time": 0.5667, + "x": 6.45, + "y": 5.4, + "curve": [ 0.587, 5.74, 0.721, -0.95, 0.587, 5.28, 0.732, -3.74 ] + }, + { + "time": 0.7667, + "x": -3.61, + "y": -4.14, + "curve": [ 0.855, -8.76, 0.942, -14.37, 0.814, -4.69, 0.944, -4.63 ] + }, + { "time": 1, "x": -17.71, "y": -4.63 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": -14.27, + "curve": [ 0.021, -18.08, 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.967, -8.36 ] + }, + { "time": 1, "value": -14.27 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": 13.57, + "curve": [ 0.022, 9.71, 0.147, -15.4 ] + }, + { + "time": 0.3667, + "value": -15.3, + "curve": [ 0.457, -15.28, 0.635, 30.8 ] + }, + { + "time": 0.8, + "value": 30.92, + "curve": [ 0.894, 30.82, 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 } + ] + }, + "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 } + ] + }, + "gun-tip": { + "rotate": [ + { "time": 0.2333, "value": 0.11 } + ] + }, + "rear-foot": { + "rotate": [ + { "value": 26.22 }, + { + "time": 0.0333, + "value": 28.94, + "curve": [ 0.05, 28.94, 0.081, 17.62 ] + }, + { + "time": 0.1, + "value": 12.68, + "curve": [ 0.121, 7.25, 0.239, -22.96 ] + }, + { + "time": 0.2667, + "value": -26.31, + "curve": [ 0.299, -30.12, 0.364, -35.52 ] + }, + { + "time": 0.4, + "value": -35.38, + "curve": [ 0.418, -35.31, 0.485, 1.14 ] + }, + { + "time": 0.5, + "value": 6.17, + "curve": [ 0.503, 7.08, 0.519, 11.27 ] + }, + { + "time": 0.5333, + "value": 11.15, + "curve": [ 0.545, 11.06, 0.552, 11.27 ] + }, + { "time": 0.5667, "value": 3.69 }, + { "time": 0.6, "value": 3.55 }, + { "time": 0.7, "value": 10.77 }, + { "time": 1, "value": 26.22 } + ] + }, + "front-shin": { + "rotate": [ + { + "value": -6.79, + "curve": [ 0.028, -6.79, 0.087, -49.32 ] + }, + { + "time": 0.1, + "value": -51.42, + "curve": [ 0.109, -52.92, 0.137, -55.37 ] + }, + { + "time": 0.1667, + "value": -55.35, + "curve": [ 0.188, -55.34, 0.238, -44.96 ] + }, + { + "time": 0.2667, + "value": -40.55, + "curve": [ 0.284, -37.93, 0.365, -23.14 ] + }, + { + "time": 0.4333, + "value": -22.85, + "curve": [ 0.524, -22.46, 0.585, -48.24 ] + }, + { + "time": 0.6, + "value": -54.5, + "curve": [ 0.618, -61.64, 0.714, -97.51 ] + }, + { + "time": 0.7333, + "value": -102.65, + "curve": [ 0.749, -106.84, 0.768, -109.78 ] + }, + { + "time": 0.8, + "value": -109.78, + "curve": [ 0.818, -109.78, 0.859, -94.44 ] + }, + { + "time": 0.8667, + "value": -87.74, + "curve": [ 0.874, -81.52, 0.969, -6.79 ] + }, + { "time": 1, "value": -6.79 } + ], + "scale": [ + {}, + { "time": 0.0333, "x": 0.983 }, + { "time": 0.1, "x": 0.967, "y": 0.981 }, + { "time": 0.4333 }, + { "time": 0.5333, "x": 0.958, "y": 0.951 }, + { "time": 0.6333 } + ] + }, + "rear-shin": { + "rotate": [ + { + "value": 6.84, + "curve": [ 0.025, 6.84, 0.093, -24.57 ] + }, + { + "time": 0.1, + "value": -28.08, + "curve": [ 0.121, -38.52, 0.204, -92.35 ] + }, + { + "time": 0.2667, + "value": -91.68, + "curve": [ 0.309, -91.22, 0.379, -77.62 ] + }, + { + "time": 0.4, + "value": -68.91, + "curve": [ 0.43, -56.58, 0.474, 2.28 ] + }, + { + "time": 0.5, + "value": 2.63, + "curve": [ 0.538, 3.15, 0.567, -35.43 ] + }, + { + "time": 0.6, + "value": -35.18, + "curve": [ 0.634, -34.93, 0.665, -34.17 ] + }, + { + "time": 0.7, + "value": -30.64, + "curve": [ 0.718, -28.79, 0.857, -8.34 ] + }, + { + "time": 0.8667, + "value": -6.83, + "curve": [ 0.915, 0.75, 0.967, 6.84 ] + }, + { "time": 1, "value": 6.84 } + ] + }, + "front-foot": { + "rotate": [ + { + "value": 2.73, + "curve": [ 0.013, 4.28, 0.019, 5.27 ] + }, + { + "time": 0.0333, + "value": 5.15, + "curve": [ 0.045, 5.05, 0.063, -4.11 ] + }, + { + "time": 0.0667, + "value": -6.67, + "curve": [ 0.111, -6.72, 0.148, 3.78 ] + }, + { "time": 0.1667, "value": 4.67 }, + { "time": 0.2667, "value": 7.06 }, + { "time": 0.3333, "value": 8.97 }, + { "time": 0.4, "value": 11.15 }, + { + "time": 0.5333, + "value": 21.62, + "curve": [ 0.572, 21.62, 0.587, 17.19 ] + }, + { + "time": 0.6, + "value": 13.77, + "curve": [ 0.639, 3.33, 0.713, -20.85 ] + }, + { + "time": 0.7333, + "value": -27.3, + "curve": [ 0.757, -34.54, 0.766, -37.13 ] + }, + { + "time": 0.8, + "value": -38.01, + "curve": [ 0.828, -38.72, 0.976, -2.16 ] + }, + { "time": 1, "value": 2.73 } + ] + } + }, + "events": [ + { "name": "footstep" }, + { "time": 0.5333, "name": "footstep" } + ] + } +} +} \ No newline at end of file diff --git a/GDJS/tests/games/capabilities/assets/spineboy.png b/GDJS/tests/games/capabilities/assets/spineboy.png new file mode 100644 index 0000000000000000000000000000000000000000..1f322d0bd681d54957141e198dd01070e3771d82 GIT binary patch literal 244631 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℘n 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%0Di-OoY!n3pkz&hwamUJ) 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%0Dck$_!+rJHydHG` z;Mt0kG5~5PyV?maqW#as5U9sj6j{w>SaNMXQAegu>Ky+}8=Bh}oFrX{QJ@(+IcWjlX*6OSAYPH<2knNIhHN{3m%^5I&P5syFv9o0+Z%@`~jEqV>(s;bX)%LZMN@r zT-SMC06(2!994W?!KsMzK$-2&1mv$7b5`DbeCs7wwyvfxYuf-q6?maUC9eS%<^mi} zb&zTSfISBe@44uL^DaVIyg_L+{Bv0OXJL1W00sOA0H~?_lL#o_sG8O4%|HM3%?mw` zW3l9auUUI>PSxTt%qpJVyA^BJUkuB#u=$cJapMnujsD|3QuMZ|r2`k9y8`ch_q)*C zajslrUU1R5Si5csetzrskY2tCEtkIzF-^x3s$qDr2T$(06Bl0gcEsW;UiR{(VAtnEF0RXcx0_q7#J?c@9-&MFIx{J#)a8O4yj=?`fpeRh%5`D*)s`pX# z`=piSnk*v_>l2?*1xkViz@Fl#tWs&3F9denlh6yzqTa=uE+Un|YS1Xqu*}nr11Q zrYfpP{1ufdqWT{VaiF=unP34(KLP0};0yN+VZkAPdcNyOw*fz}|HEnC8y)67s#Ep# zyQhwRC2yB6cBLV}W zQ#Jw(q74(D`snWcj|v9B0*C6-wvH7WMDj1%M;CRj#mMk6Y&!2MWOEs~LeU?<;-#yD zS%7gACPq*wl(B4e4th*SOKTIBtyqjTYd?+Ke)Me|Kl})aB^U7+$J^ifN(>JyL1SYZ zT3VW5+cvIy)$4KTC7W^6H@<@HTc5_N6EbPRs`@}2YNhtTK8uX>I&rhdSp95BHM&mDvQFxs{9W~P??s9P1R#J|&cg}p_yUc9h^8N85(~NRqQ!zx`46h+ zo-hCi83)r_2%h2EBmx0s+J%6_7PvA*B4}YkU%Paf;jX}I{xTzLnqxh*&;XDH%YGWh zXYWJ#ZpPg;gkxFg1aPYJSF8&SpRpUk`J^m{2Mhth9`IuziBBQ+nOnea*$?}vg$-iV zJT96aJP&@5{mZ5rrn;Wus*Xn$#ZeT65=s?9Md6>&aFQmGm8EQ6XX3%1bee+>w*lK`(cRvrDD8+-5j=v$Utn(az9!DarLxEN$>0ppywoF(RZ zoj4vG_-mnvKW3M|cyr&@RZEl2^oq7MSe@>a&MqFGotwZLsJg%L|ioPAf8C#uRipT@Z1VqtAwRXm*TEp+zL%N zO%Q_SR$+z9q-AbPYX|=2-@b~5bPV78`d94RZu`kk>XUap>HxrV1p?Ie|3_56c?uoZ zS7*<60Iq2adXCl4e7{`@ZDW}4N#Q;cx>-?0eMZMhe2%aM%pdPT%d*uV3YFAL=WO(TL>N;H*FRV9MPEBZ=6Nob@Vnt%s%Rrz49D<53g zyoujEkIO1nv~aK8-ji-WpYOiR#ph~pF3|A^8&lhzqRLDTc7 zPlF)A|4G_^sQ)~j0l;~L18^<@04b&*i2*G9M4!q1=6s>L4|8n1sQ!MT;8u^{e00l~ zE^Axgae2#nx&C-2+5jXN1E^FLx1RZY&@TWy0O0+7#>C(D9e=E|C6=L^8kS;H!!qQw zz%8J*RpE5j%N4_{eDW*b{Ny)3`}f~eHBAjb041#YhqV9cSY53#SNJHFtHr z>r+o}UFi4#I6IljLf3R85-IF`q6g<+_zJ9Cy-dPywUJH7FnYXzcp@!9k&Z=eQsmGN zJ5WU1Kqi$$Q$r5AN^sA;4`A`qv!LrLve`_?6AB0qrePzS0DgMgZF>OJ1pw<&2LPU* z1zALFs`Ua`*s87`&-IZ66;eoZ<)q>uDVi<`p@f|75eq;7<~f)=aRkjv*GQ3=M6MCB zv|t1Dp)hb9ypti-(1OKhU!)RB|M=i$zcM~o`*IH9^uB?zEt;y^R)>-Kiy;c zLQVE-ZVzPol~?l&Xb|#Yl>EptIA5cQfN5-E1*1ket^A)Wdus+v~xT49V zJ5cGLecBFDQX>Eq4Ym$o; z4TYi*jExTC@y8#35cQ}>9RPT4RtM45I(!l6Hp01<*WLr=)mYn55#9Bo`(M;z z5oNgGXEyPl@#Qx2enx=B^=C?MO7DJ>Gzhcmotdp;J{R*CP3Jxd+?# zBsh>(V$5PL3QpCpdKN8uhLX2RaD4BWO4TFoyd)K(kZl>?X5az{xX@+(yN*@IUURHE zwnR|gn)D3X;#qVin$aA~AfqNEP$578j|oVCiS0mtHID%!kC5$A%R;~hKl2|SY|dqx z-*ENiZxBm1kZ1~>?eq_xb6nTC`;qN;f9$I_ee6)*z%!|yAF*wN$MiUvni{}`7r!3e zOBT%m_3=RQe{uqeWERO}0_jvLIwb;DMA#;wDFjdV90F)YG6g!jIwYW=D#0CJ>|Hvg z)f+XR?~_Z9uhWvr z6;#z`ZEqCff3o1pIULIf0Dxz>(zl9Ja2lGS#gbtMsEM%b=VmnuIOXj;k6}=uJ zp;y#YO3~73MNOrtno24`wO>~GCA~kO_$yJhzxF$Vwd8cFXjF9yT2I4{8lj7ez z`nOE6?X^W}$2jU$i(VTloN3r1Rxw`hHF1u z^zC2&p-)}^_wRe>-+$!2@BBz6oyo|1Ba1p-LNiXzcz&{&|M`~R{`|(D-F@S({fBq) zXL?M42Pg9<{_oh>pn%|!NMw-9W#{Uwfu>N5kBuUmZ9*a$2UX|{)&mQ-SFi*2@86H6 zrbY5BYi!B|!j41oV;q9y;8Y-nkotJ5)-%E)8nc@CKCKGQZ$#4%_p`9sl;b3Id?k z4zPyqe==dfg)SuKw`e=voBFA$+9#!|2LydZ)2W(HsaiIxXt|uKWiqnbFB5**+ph+F z{)!s){sWO4x1jcidH^J-@Yg1F(RfDh36~8lfL27`zpw%KTv6R;j5vWKn9v3Y#mk6L z6bJwTt~WL^-?k+qz%7*mhCtO|%yT26)Q?MpZXCZttZGjhJGFp@1les{EDB-WI z_)ljVlezE!%ynm}5qXcgoukA*x`joQ_nGHC=XEgP1#*%RRaMleg($GEi2y-qZ|4hE zkN^rjuRdP$ntvi7fY;JNYSshf`AGCn6##m}$G5`dy%WG10F9x>P)h1C28sU!fW9#C zp9n#KGrdeTMbaETL}WOyQXzB&=e(JL=NPzfg3!Zp90MSF^PfD~hYDMT&wk_kpZ(eo zZvWbAue$WLS6+DTmCF{jF4Gl7pDdOq_w^jx_u$T_9^CrmzOAP1m}hEdgze;szP$UB-e&aLE zOIPon=<9i2d%egUfw>p}wePP52Tr#=V6Mg1nbHSX80DNpR@vhTMbBkbt)W4SH8v_T z@lT~B&7Wvma0d^Y0;2>!{26KjNMJzNQBb*Xmwo;;BK*nPfLtwzF2D##Aqd(^nIA0h zB>><^>c3(;#J6qk+csm4%_QC5^Q3No5Dk=4$O5p4#RO;}fC|YBkgR}mS%Lw+9kBwQ zNy5HR;lAIA3fi-r_(v6fTAT3KB>OX&0CQ;rENnbOJ@^@keh3Og&wY;4C)$7HwJyx)#C6O9!B8eu z=!Hq0>-wH)x=yv~IhBg%nx-dPg)Hj~i4y)k0Rd;~b{C^RxFf}&Lp8}nluj0rsJ3x z?Z;%1VR1uD-oI5!;3prFyx_YS868I|vk{%$9dH~+>Wn4gX?eR4?HiPEj0-x! zLKzwLs7DK4kyfu{}?$#6esejjJ7>N(c&+4{du7F5+5^h9d08jE*m@#JdHwlVGtk=8*WLsn#VWioO#D{e(ZDZj>x?6vfiuGP$iKk;#KAJ^5wmG@408K zz4ltrT$+RW;#nBZ>`0OXP@di_V*`Uu2XxB<-LPQyZEsE=x&NR4wy|(-uit5|Tn+@l zT90=F{G=&hQW0>m=inM3C|NDO5J~y@`p@aUP}R0f#<0s}(;gbqWz|2MMewg1>5Qh? zcCt#Zz`ib>{#BLEww2?*Yz06Cfa>yN2~|K$2qfN*Q)N#j0U!Z@m4DwCk?*Pge`NrO z3w=or2$c>%sR7CZ0G)+2O^C z$!=NPHQb{FVCPc?BwGM_U(>HOCE030CCj+d-|Gdyl7s*wR+I@+1|*087!Uz3)}Xcy zyol*~t~fheEN$76D{a|gr^{uWM}khR)@d&;dYzS(R{iW*9w&Yvk*LWZQUFjYJy!pH zUjcki5`szzfEo0XlhjP7P;fMSf1F*296%${PDfnW`9Bzg@zXSx1K+*<%&CK)c=W;V zzAu%sjoFP;QUTyN4w!}p)8knfA4a{(g)Dv@DbCI>GZj zsMYF_D_M{)4s531ApTmBAM<7y|;}rCr#q+5(Uq(mE!l1`JB?Mj$AAoL=eJ zUoI*ptyK1QE0ep8fyipQIc{Zg+cX0W(M(e}%`Cd?qxl`@5wV{Vl#>CkkYPDd6or0G zM3LKCS$HxE!e-#LpXFh28W^+E#o=q1rloL=qUrjimCbMA$^|w90wrz|-$14`0#3dJ zPOgyjRaj~e_;X!6%wo`(?IK`M)~>Yr2~3~$&9?OFxQR9gN{ zadIQ%$7aUUrDGrPJIzmCD)68DpUnPNQv~z__uXW`#i{_->ecUaLcUNf2eRUC7}>1h z3=dnW@p02E7BwT4(hUUvNCKoY%E%87u(($rfjxqLW?4+PEEVmis{iu2r2L;zBp|-d z#27%luM;Fx?3Akh$Cdv8fxmS8=bp={`i};HQUQPqe@p~uxA8F~15_%2A_A0u0OyPu z8VVYue}S3JQhPuYG@AX0fPUT#7aH-L{9a$C=6@_%?eD4N6Y!52o>lw*Sx@CZK?tx5 zRRMHY@>k=k6`&Wa$NZ0xT|Bi55cw)6tL_#7QUw5q!FXO5OS);8>2zsi@7|H|tFFrC zCMJTQ(`mPtmO8D)#a8{y8JtHfC!fz2XJ>~euD;r|b2-z_=S?${(GAH% ztedF%d!0(fbE{Ray|mPB&Chq53k#jr{Jig0t6|V?tGNJ4LCZ4jY!;1MqF5ck<$N(1 zFOvg{mY#U74%$9mq#=Y@_B`)bfBeI*efQMKgP(fGyFa`sm(Rngljk6x&q5);4IX{? z`_W?u=Ctw29SnQ=Z-3*h;Cnu_nk{IzI`WE;c1)Rg5QRPj0f*7?QK;AI5C)-aCtxxI zh{5PkT6zE!i-p0wI~W53;H4U@j{<-t-~vmow336p(yXm<4WmyOmVKj{%Dg_6E563b z7k4<>f+?l%mLnbYfvV_Yb)43xoQ2LOWqhVQvvrck9tuj;7|I{|PSCku;VliAZXh9` z3a2V94a8c&KmKy?eNg(3l6=HtRw@I}&(NL$=UlY`ST;m~5ABsj8U2^sVBC&$u}rt6 z9Bk{2uVV{GpZ>M#+2fyzd-pC036KQ(G7UND1(5h1GXCo(4(R^HUT-h(@%4btez)m= zl?!2{(}q1XWTz)4OlM?NH*#53_0Q(eY>#^T<4V8ISRCgkP5vbDWf3U=Wd6rw)h<>6 zU>g8a6=O*T7^)=zUrT_HQLcAfpv4nHN_!=k4;8qV&i^t7Fbdl(S;-GuO_cdlETH;v zJ6sY4DEC)YM8#a{0@(;8Ds&^2j*M(G46rqz(cobRCBl4-{eGb)a-ut@>|(#q%LDiW z$@|$_pq~u6Vp1ph9xNFgLp}f$Pqx+(OA~E;En3a#KPI)Hx4N$g0m0}o89)_hgi(t? zuPT84;9x;|Av0=RrPr8Ylt=gO9htiR`c!6g6hU|txo*d;)ezhlhj;8Stz6EqG8vo? zWG}z0;^Y58;I)^RBeT;%VjT$tUA6X@f-ZKrn9^;VS=lU)G8x0nWGtsxbkf7asqFZ; zU#M1nuU11+z-=uow43wufmg4Gq3Z^2y&iGjmxiK-;}|TRmTCeyXYj%IeYp-`Xfm5) znwiy@o(86;&;kbM93di42;LSVa)C!3j{l3OGdO>r?|^TdJpS}ufAsMW{POh7rgx^( zxhtk;Hs><={DJR%`>Ve;Il1XCZn=GI4@&=ka?gV>Ju?YIBW1|u6i;K@28<17pt4ej zrR8P$SUQshx8p&fn5RpLY#sRAfB&ra$RiJbez4OAV?Y4BR7_v@x~eAzaCPKL4^h7A z^MWdu+vP>mEjyFFQMa7i>`eAw+u6dNOmWz>GI`JqBMG*t%HOm3t7U)n+cktO>3_sZ zvCmPz5vvI!&TR8OO`$FIS%%uSS{fL0`wFRsu|0fTC=h+It)*1EJ?{T*3X_^G2@&B6c z*a-Zc^z<}V{iV!bn*3#RSp7$EFRS+w?8`_$8PSb70t45KKMjr@8o3hE8c1HWIda6eL|&+PYd zmy#!|{@UumpV|Oa8)p*aci(17)j)E(gnp04lMPE!)AX`rf4^$}r~OZ_jrjuJO9sg5 zzaYPWM0)^L8A<3iXbb2!@MMm`c`7|TJUa8LSCxi$?LsmDtM>@Z?Nqsp)qIU<8usW1 zezS>yyjeSW63GGItJe{*2X3wAc2-vKd8+oK{9h>nY#Ye}-Att{=@XF6;`>^t7Qi1X zo5dd_9FVL;Q1837S_cV$#<_E?#+ftt_uTf<5|Rw~JxiZ}pxKmWqMB(+=?5wT21LN6 zo_~__D#Q}8kfBG6W*{N$Xw1j~(^8sd8@ZsaIvONFa|G)p|HQvISQWF4F z?eDJopRfAgod7^pe`*`R+t1SoP^{JGzXnOLE<-x3fE!k!V5MiKoy>*}hFvP*ecj0A zu`;eI_z3(F%wxo#ts?%U=^vN9Cko)3ri=iT#(=gXfxnJKfN6n>|BC@VM^%3$o&0%3 zeK9O<4WL{~@>Wo)3JKUbCz*?k4J1!tj^qGV2|Z6Ub9s{wjUdnueMtmVL%&jqf<_(V z0I|Z)rB{IGs`dapXrqX67OMCFRk6hF2#s_)@~bse7sQU@=Su-t3*d`&&b#6=^9M+R z_gJ~n1N;f-Yb5VafPOmRi6kJve?AkyHQE4JzkS;c?x}jORBbVkPmlqO)B!+IXru~& zIAp7r2#DJQgq9=}1_NRRk!|BSn#s@1jBmK@emo;XVHN&1U?ZQ4_Iv$^X z6f_U}-pWrxul6M8{>tDyzSse^_(!da1^@VcKmLauOUrY&ZrOINRxFLc#MBgwjE+FZ z4WQFl6d(UDpI!LuXaC#xs@2Nx2Z4Y3zI*=u5AVC@@2{~P=ZajeuxWW|;U_|f?*hQm zUXU(zf@c1VtcVGRkOli~(ybh87B*pL9Cz@f(+lXZ%9)T<* zBqFHAs_S{R_C!TB%I}>_9*lymR;u`3Q7FlPz;i)HmGZaL$yC(8-SGp!?NVQ@LNr(yhfRS<;*b{n%&l~m?F1n`)l4fbN1;+ z-Wz)Er!UFsB;oqs4e(ccZMPBNYJmR&NdUHn>;L)8`}+M3Tm5(O*mY8tGd|{IH*K=h zlaturZ&<|=O8!x@kBeTcwrM(==iv{6f72vC!l07?Q>5&)OYG(z?E0-5{8M1V{Nz!OX-l|>W^X$pw`0IsX+>5OS3 z8Q^vl5m2p!UZoNSwHlHGN)h0?A_{z=;Q=b!3w#if^eHekvyAN!frkV_ttMLtUYOag zpXuVoq&>XY3v~kUbUUu>_elM_fxotTrJsI}#aE0T>Hq2^0PBqjOa#&<`>GO>|76r3 z0eL3kM|qMA=xGyBJ^(C91jPMaJYg32)2;@Pv!h|9(>SrGGUMYD8*jM8Ud>1iYb%41hvIT5tm zs03(Kj~}lsJ^L(@0hPsr2k{WV-$zqHBm+q6H6Q^lbV!m=FwM;CMrN~V7p^kx(zS+> z-O4l_WBNkDqc)HH3Ku~QMA(-1c~}=BYybp!W`+!m6mTA5r60Hm1QP*>FkWzB9Bk-| zD6I3yJx6m3V>%K7IG4{FR(`i>6|dCv)RdmeZnaXQuZ==?F7Q_F_uYlNL%(?h-)HcJ zJ+Cq62i_e|9r*FCrw;u1YE9ENYnqW}418T@ORno-Lc>o0;2gR80{{{*-}77-e+K(- zFa`v`B}MzNS_?q(nio5E(mm)G;{0+M=-Qw94^w-u|3C9%(`5wV=#C$wK`@;Z*eLx+ zupC#c(daJ3_!8-1u3DS14Il~w8F8lyq;Z#Nx4EJoq;kMc=fFy5 z!7y!%^ON^`z5!AYplZN(We-1+1Q$vM$Vz=CC*}Va3;rekiU|y_S*Ps>otY{PV0m7? zH*O!krnRyNt>t;h42`Wy0wAUNR9cJBX;Q;*;GIRI!~3c#OK1gzEukOcLl07$<6 z`9=b+b)H@z*o+_5HPb4U?97G@PHxjC(=L|{3xD!OP0IKUCF$24N4ov%nG9CNrKCk} zk0#~*m=K^D>8w%;pelfAYCAcXA-<|WEENL4OicqFEq-)r2asUDyWgKSi*=(w%VruE zu_>TT1OOH%1aLo)z@I>Yuv5a2F<`#nvI5wa$^bo+HLdbcWH%dOP^tLt;zH3i6|l`n zr2%M?K#ZMj#KmZNc}TR)oRgb*+Ksd`#DLt87|@D@|wQHKvunN;gtd zI420;fjXBpA$ZV=B5yGY+b4P0IT1yzQ#|rlI1lPr^Q*3e z5K$uv+xTMaV;k};v^?XFwknub%A-$Nq7lcYhrwhZms ziZs(hfNrHT64>|RN9B`dI%%*{S$S>5_i!6E2z(dTh^v?Hg@i`BI0VlZm&%j_EDFc_ z0Ji~b2kdM?5&+Z&kSUMI?Px5`ftATg)5O(27p~JbUVHQO=>reEUhwD}FUeA+U(bIZ zV?an&_DKQIXRH_eU!XfYyTG_Vh3s_4u~L(h2>k8z)RbWs3RY@-LN_y6a_t9M^|u`z zfxnr{p%n%JH`(8Bq%-(>O?Ohb7#Gq7F~GW*f z;4LmHBA`}_FvC(R0(2eQ1LSf=M3JO`ta2HNfY4jP*Vd&{V6E>Y$&L2=Zdd;vFBOnX zO7~gJDs}^ZMGCM4LC_2QlS%-3jRgEGnII5TJ}jvMSRbEE`-%igPxbmEooL&-Q7Gu9A|Pd?s7e*lXlABl5i-nCiY4?1z!oIKV6iz3k6JAewOTxE zHj(thM1Xd4Zf<%0z=1Q?KmT(oJ2sZiO->euwr$H7H*U4J%$J8lgc3>qL!RnV9ZO&F0_{u#r{ZDY(VVQ&@A-+~9r2=>FEb|CPokA*?& z1P?oB5vWsjBRM}N=F;bLesRJ5W#3);vF|S3*U{`D(MSj&vHjmeXaUD~(OH<*H#Tit}iC>c-K0~Si6_4V!r9*#n zWf7pVB&+n;S8tdWbw|^mBDJan^s*A)Zb$+F<@Bo&0k|zzDlOyrUXUxkX@YLrwE89= z0NDb7?E$zif=&yfph&+0wR5Loc;ogYp%U*W=>=fsM<@SnZSK@dO#t)&d@UZ3Gz#qV z9&5elMGU-z(2!x3%658U5@r0#p&zUMSY1PapUvtz zR`v};@QBNWwF3S*+24-~ZW#p_2XbjfZ19JsfVl7`mw)JW5)}mcFKi{py0J9DOm)y0 z3~Ylj%LYyQ14vH*De1@U5tgm#sSG!=IbBx!I~~o)$W#NHB`8fxY&!(P;O&b>viJ@;L&J^y_qDlBK@7Q@QzVwyEBNR>-$Z|DdcrM*J`&9yJ7f`0Pw?0m9{h(gE1JF zCjro-0O++6PlhWeYct(0Rtzo<_q@~t5Lo}|_|E;is7QZ_p=Ohu(YCxx6mG42Xl{u`1vLq8;s5VB! zNfWuza|B_*7YoO@pYU(DRu;&^K<>jR3dj&%#V2;Zr)k5)uKl;y=1!I4{;-z>{NvDd zB_%!Ih>4V*fsaQKR*ZX10H1Ffz*^_&`X1Lb(-|I4=eKWna%h5;%VETy=?sr3w|)g| znP%C#fjzU?oa*&g!IPSq&LZ%~o_G*c)ki5mp7I(~;%&o}k84b$?WOvw==TxVtDNtp zyn1TB^lV%W)ES`nfN2RN19%u986a2?po&2lsSFR@j;6O;Tvim39B@*)k5xA!|0Qm$}{{f&pjLFA%o@ z#M{7uq5p)OG)WPloc|e+2Y`rM7L*!5;CrJnU{6cHD-9F^9{*0NT#lk37@oNH+TGWF z-~*GJUi(@k`VbH=o_*+{$A0w5Po6n;*IlG@!`^%J0&uc3GlAc3cbao^=&Rv%Diw74 z$2n0Yg*XoGb1n@++wJ&zCR=_~atC^V$cty(vO#mHA{}s^A~gW11n~bT&~K%pT2E^{1agrN@V@9-!Lm*<{%V(!#Weu9Yt!{b+8nJdlCq8~wFX#4g; zdHeR|`NtlcKXvcD24hS`7NSSUPutKe?BUlmv!EO4X-%_6QDTNBdz|~rJoFZVpnfn4 z+9v?Gx86Aqm~P29Kc-nAWBr&3fRE`pA_gd4RDcL&FQvei0ugW#A)!-|N`ufnhi?C9 z7=!u{F8&l=JvM%gM;}u2)P}&eYm})sf|6J0BC?Xx#ya~p&x$x^*jo{ ze7+S(er)hq_+bTP-+YE}Q$NP(mZpxgZ)|3|RDS_?q;`@TR?fc@_G1E9Em(yjF5 zWV*0(S1PwP-a;g0)I1`Wnh}1T5)wL<%~~o z=?9?V0GU!tLsHq11n%qQF#3rfdj1nh;z@ldl`n{(UmzKPJ^|Ps5QUgZphcD)DdNKn z;|N0~9ZscvZ(%-gmzU7^Ps)m;P6y9q9*0gz@v&7X$b*_O4WkFwr~s~2>Azh1{rgG& zwM5llW4$B+RrR%gs)1h6-wpP)L_$FF8gwB900DnG(h|mgu`xhQ2yjNmWYWzN6z~@m z^T#M10O^Hxu5d&?#qfWkE2A?_Y_mPLVkW=h~Mvs?63{FB!i4C{Jo0{{=A$Y0`-J12<%^cUcMm5k^5%_ULfFN@B? z-Jw@~!gNa47*^p*Y-!MSdpPjYk9qFm4?ytCmF$_#F#R8YyHwo$q1WBUa<|+9VqyZc zYp(@uWCX%zpM{CX9)s(ic!Irec6Q5G-}08<{rG1-^XliGd+zN6$Nj+=jGuM_ATfAv zPe9NANpc`=n3Vq;v<_tKH$jMZ0Kgw%ZYXqj6kO^7P@3Fz&8O{5&ceb10$G&Bli54= zvSXzmjR2+ZR~%uU8yN>Xm8JMRsTM#mPNw99^RV*Xt}H>jx=hi3v^oEWp$;9j|PjH24161ghvmFQ5c&xQiambv{n}T5dczWu<@GLyzj{U zckOE}&;RPhZbv`Rem+ltZgao26a(yHu;FFBFg)vX%~VwO&V;aG-&{6JJcSaz@cQtV&IQNfnu?c1EG>X^q9Gc9%8WH z=B&PDZ2;Dr(ZqFeS)6Rsi!M7JV>%^|l1ak3l5B%iJ80F^um+kc~b2SKaiHk4((od^7gyx9exl zoH+EYZ#{Ycr$3EScm&$`g%?Nm?8y)9+vof3cB^{mP`h#RWT!blkHA?~;jx$BkgmB1 z{JBct2rdph(*;e<#B@XmX*s5502anA0dWK&p5y2dph@!9_aoQy(0EWq4yIBO*L6P% zL;P*iwC!|eWCRb4TIJ-)<@u+d&X+c9z{fDIurR!RJNgGKoWB2l-LNdFVBoKGyE8g( zvGR^?{i+I2)%LZBFLn0lj;0xTMI`8HCaeCMjnRN=Zq}@LUeM|Mp>vXl?l~dCI_DS# z7}PN?5MQsz2vi7Q{GT(5Z3DXQOfb-#NHa1la_8gU?H4hOf`S$jy@KfudK5%K`y?6$ zYPvmQ*u`s@W)=O;{9T;;mm6T-HOdO#`SRrKh8u6$1JRzn5O5CmO*eryHl}uZe0oJ! zT?NsXzYK5tv(H%9eei>~{n8h|_~`==Kl~p6p#3~Q!vp{f#|D6dF&KmKawY)!&E3$G z)ue9uA_AXBu;{m;8o00=bYS!BerN^W>xQ&Vg*hv{X0(8?(Nkswn<)e(B z_8*JeMFY1Zd;MW~LH->C_%dxEn}_1$tXyAqsw>h&PktUU1B??IP>Haf^^tfnQj5?d z0*Mgp+sAmscnMGYK_&!PR+5;YT_DK~OC}JgHV541?qUz_yTaJ?jhGzJZ!k^EOkZ)` zl}@g>|ADXk#b1LE_dj3oe=$IQy|1~zIKcG)|9*0E3I3hz>};l_s&LrZe+5mZy&2=mcyjE9~$W?(>(;r2=-%aBQ+61ZV!IWh?9&34{hnqN6!9) zhI*?1>q#!`ekxf&CklYbfw)*pN_?uzDo;1s8*!I5B6iba7+rw}Dr;*7{Ra9)$EIRd zy#H`t1@0nKPUKv!3z6zzOy?jXCdm`KRKgQ83>x)52?3YuB;E_ksdC><3NQln@#9Ik zKam0Sd=GKZlMbNuwgM#00+S>FtYrq6>?7&s9qEUv{XK+0+}p3k)qJY_$JKhls6Bvu zZK;wUvs%;^KxzOWZ-7Kg0DZQXwK*Wp38~EJC>q|4OkQ)%zE}V5?_xiEt8w;hqjK!n z!H56yFR=oSz!|wjbk!f8y7g88sZ_K2)KiVh!GmbFhthd9ZQ$Iam|oeM!&S8B3;nsf zTL7>%Kyihb4&wXDyF+~zNdy>~$L2$6K>XR*DzlHW(`JH|Cz z)2$-P>m^9n&9biBqeuv-$_Ww*K~0FrjnAKe3?G=9`eQ2mp!!RLh}m(l#+Scszv1n)7hHwFE1H3$@ULb`(Ga4Ced} z%orAI+^`=;$G5`aXMXU`cB_i4>Hl`AHxQV%e`4qU_u*PTH#8>Y`B?F9tSmv`wPST} zyiP?!JKKT$$Rs6^K@>$$UpRxN!;l-ENP>SkuriL1*B8zziG070LaA8t+84^+eRT7W z0d6eaFUrs7w_APW)tBZVLE;2!W~fAnQ^EjK6ygm79!AMHN!n_;ALZJQF}c0CjY1H9 zQv10yy=Cj!gOB#}0l@vchX^5T;cc2u2EqT{y%_a}a(^ZHrz%)FZCJ$;n&4>|;m33X2>}$of~?MIu@b;E zr3{_`9DR{8G>ua>pWFeems$yN1+A-kK)*s3$PbSdYwKr{7~l5YX@S0)O%l(0XD8lL-N<{xDdp4Im*O={DgbW{8vg zznc(XWIhIr3j*k*3Qz|wk8N6+pr{)`2UL6(s6&iCFITPqN&_d*Yk;9xgi*y(dpVK- z2x1ZZd!1@^^X|946(#>sJ%cM9hYU zoxabx=gAZgjPr~yqDpn(I69e^%2oi^MMKaiXtjd44GOmfTLJL*y^bOR&;tN3MuFFA z`Cg-8S=nqlGdvuILC|h3FJrSqDl{ z8{E&1lI_cYV{G5Rm_9!yWHJ~B$TYL48<`Edk=~>k&UpO#2rKeY*g4B1Z;?mdJdfOS zoQEy-H_B5LoB~xEn~T)} zxSe?ZZr3#J=IQCFf3<1T<~^@^)vJwdTX(Yi?|l$X9-rTp8y)_=T7Bt1)f$UmiFovD zFSd`hOmGxAT8pC;^ZJ z>E!-T;D0p|AZY;D{W!ip`S^N2(mH$o``uTS{}}vR>8UBxE|v@{U!a^qT|)z`Vo4eR zVx^y%mS#99V1|hYJ5%{vk|+Qvk&h+e)Y<~78qVT&0HOY2tjCM3H-24+wK$EnIvc2# zCX$|e@i`%STuI|ftiqzi49MCnmTx2Z;Xx7srj2c-c%KW-bt~e;J~0#P{Xr-!)r;)Q zg}i!Rz7KFNZ9#buU__u{m5S2fGN`Yn1n4LIXX_<(UPx@01pkac{c7O9yV{>52)YS@ z-p4f7?F*1h59n(2!t)WR6_8-=el40)#PC~KmAju zy|6&hHm}qLEMrDqH_}rW4xwW9!ZreBAtGPXbVoB%Q-(|i$nQdlzC1Z(mET|Fymg#M zVGZ5*dFamb$Xnn%s7v5~zVk%%{HIIPK+P&4A%Ikn;2|b6&@m_p0VEe7@|KW6Vj%qk z)~h^;qOg5hHh(dxEU*=!;EV|ob#zmNm~a5V{Y&%}yz@=Q?$^9^yrnOC4lGq|;P=gg zJ=B3zsRQ|`HWVg{pr=gWK8J7o=tpqpybr(shkpX5X~6ft{~$d2;Nxt3eCpOlqxL(R zrlpF-!t~VC)W*%5H_z_cwQIz(tn||IvL`r?jvYH`@7lG?SX`)~M-a@gr3EFdV+_j0F)f|S{@b(jNB42TZvlXX0pJ^q!MNNB09w%`aSKV;yIld804#$& zEz)oR(qMytJOnTX5!B(VT>GGB7)~_t+chq=F_M|eynkf#?i)4Tgyzap3{XV8=y0TY z9?JW%a*xkpB_AF5yG;R8g_4Z1LlOW_gxjMnrq$nQ6#syaTdBHxp*?NL(5G=^b4?kQUp$fWYcE0Anz z%%6dg*==mob+>%%xqI&Xf)ITELboYd@lO&2-6Q~kKs5h5ADOUPd%+rQ0HV+TYrQ`H z5V~$>re`GhPfbihF>6YW@vhqJPtYd$_=A_Ul4;}pF4(E}IWRPD3xn+D{;i4B%P!#~^P2n!T7{$XJQE zX93N_O-qMt4h(E$<~w`5&(g%X=Srv&}!|w=_4O0jqcrBS$z8G`pV(M=T7|aht1ll zQwaXCx<5Men%5L3?zp3|{KONBr@sB|PV?M3dLMMzAD_Pd`ux!L?I@~2j{x7TR@;ra zxn}*;DFo7pt?2bw*-z&-Z%*ZR?Mme~Zp0lF`OC{*`}FDh!oBw*K$m2joQttN$1pVI zOG5K8N^>HW9Kd7$26WQZb<-}F<>Rsipwo#$6$dJ})z0UQ)YzDvo}R|XWF)9ptwuq+ zty%$6sSs&CztO-%11CK+6b8+v?^Y_37;tc38AiQ!_H3>&IcYm8jbO+A_rCYs@w@Jt zKmEW1l!)*$Tbp9iOYAU=5`Rc$_NELow+&tMRlJP|1j_JH5v5z3H6uNX$pErq&U8o0 z`XhgtN1Zca*f|@8?PEOhmZUMCpoD-6JuhSeVM<00YDR`U1vJe_3m$n9_WVcg9FI`$ zFVzSljt_L{f{85z>Uu^=0;{$%2p+kMQJ@{h*BVxCw>;={XB?+{WRlS$j28$~# z_>({UD4aNP5{8CH$FIENRiDUZb7IHNZIH=iS>T6o_H-R8l`4c`t z{nZy>VSW)z%arW|mTf`ABe~YsHKhRMf`e^mV036^=iJhX&j7&N27qrc2IF!k0BEc# z-R@nxu(-OW0l6aqRKbKcq#ytdjvjv)s?BA%>gqR;H2l&s8=5vXvT5hXt#n4~2CeCQ zNxJPz+`~Y+><7L_)oF^TmXHA*`O)|fd($!6j=&CqbU{ncxEhWG0-E9B`Im474wF#Zn`Ed~8Q>Gr>Sm+6d-8dj-P9xt(BMykm;l$f99{7-8V|hygsk!t=8uK`fIa|9{;WV-!WdK}*Kpmb zXgxk{YhnN1Cy02A3$;KEN%TCOdt?mQ9YadI0}%lVn97wPh)Ae)u3_rZ**`V}M8d?# zhK2~y&`ZjSHIWHSD=Z6TSQcXS7-b$@r%ew-6)#pS;y#Z8)jPaSK5bolPrzR-loKidA_#hce^MckGzBEU-xCv<{Gnqz=?SpxksPR&IPwOd&l>x=aPp;yu^yQNc9Q^%+5s+C0>F@! z@pKx^`mVg`BOgJhd+cjpnScE8>f$rccy6VFN4jR1=FIlDzun62+O=@}>tA0!ch5Z} z_s6+ra?{N>PtM+Qi*#J%QPggnJ6BnJ>Z$6|GtXf4KK^Pry6&fPn>VM6d-vMui3#AX zmfJjbZ29zKk72AHwhLgNeRg!~R?99Fbi=k~RG^FoRA8S=CYg=_6&=XYSTOQ^r8a0Z zP`V%btyajRNVWqQ*(|DbP>Fz~gk@(kc6xl=Nso+JsnJnv3-H=!&IIn_A}R^6eE@s? z-S*Ow=T@s&`L_+n!E^)sTc(xErP9O0joR6>ZhK{AZ2H=3k*t{A@r%EhD{a_t_`p}c z`m$P;GCi$nRw<^rJ*;%2*&od#DC0M*+z!SJY%5C%9#nYbE@`?wt{d5HhMC=pl7GQv zB;Q;VwoimX^KcY2k4BNV0II+Lg((Dy$P+^AFu`;oG)I#prBTuh+tGAq64eAkMA%}0 zpW~!d0-&#eGJ(w?ae&*PhyaxCa7>_Ra30p<6a)H0eiU`iFpN12P%oF;iN=8P_aZ%o zssP;1*jwPG8rNNKOzjXNZ9ZK|L%D|M}N&>cnZ79G``3UajYl{(kzYL+WZzs?K=r`*&aZ8Z?_NNTqCWQZ`@{ zAT3Nh*9ASU{?ows%VvsT*B9RE`JHP4;GqHN8;rrYTnT{gN(<}fLzZ*`=%sEMd2s{4 z)WlBk1&8~8{CAMc4Z$Vudxgx<*dG?gXNCx{3h6dKrOfnV@X~42B%oXkuSqbU&d8qi z(D$Uo9V6@Htf}ju>!vim!`I<$sUr=1=wQTOZH2C$(o?|67N9h}2?EcBPHhE3&waTZ zvydGghd2XH?gQMPNN^}4MXgt!O$P=Z>~=~fC)DRpC-*P#q)Jj&qim*|Mltk~1b|c; zj20(1>{d*3TK*kux0u>{{jVOn=i7e-LaZe@gMRY=?y5h5|D*zdqW?(pPgN-Ty^CxC zfD3ev7gQFvQo|#u-1hBOYIF=G|5*7a@DB|8)X@i^h&`BD!^jm-_Aih4$Pe&!OfyhM ziSkAQ|1r>!z(*tS&j{J{M6D-_uylJZ6F{-vJ(9$LvCJRHr-R^DPt+t8Wl5ghO$5Y% zRDD<;qOqTDn7KTDeOR%?nvY!eNU(uz08u0&&y!VtJmACF87@L00UBB$k%A=Na zfD{1ia*PN>**jLd5jgL?;lm$BW4z_LM;}E300DgHH=Ee=pUzEAPHlVFyCQBFC!hNC zryG@LpQYvg$oLgkY~A`YU}e7cd#rSdy=r1M+0 z7^bdA?%Z5!`A0v($u?h{ot@rz-F2z#=qM6u_TVuc?S2y)(IhT;3J>$!&x>Bh;EnZoRBrm$@rwjN+? zq1!rf!gm+3H{H_=+ctFDZd6a4uv4WHf_{ua^u1aQRTG))=xDpWvU2+94}LH?`>I!= z=fUXo%{OQBQ&Uge_h)~`FZXl+xju2mHQkv&kSqko?;*h-G}Nv&a;9C_tLdpJ1kbWC z9(7J5fHv*o)%duko7ip^g?|0XFlamz__e2^uyg7K1^vC#fK(nts6GHV6+#339ENqn z9?|sFw65DjjOnAyG)hQJ2p-m=uyrB~TF23=0Ov0mJE+nKQqmtl5`w&gWI-4-kH&-n zZmt*l^=Ac-I!KCOYXkl*wOZCN!cdPwh9tw%OGNVBa9euJoDTtfErh?wpM-`M61%Fp zSp`6W8*qbLgdsZ*zN5qUzW#N%@z&SDSHJp2xpop1h(gCeq98^5S`Y*VW1l^O*>-h>CNcuH62!}%^)P_?;@O@G zzkz0d*e)&O(KU2Hmyv*o3&6Vf!4lw14#|s7qSgf2uYsw!^6p9scavSQO;=El=St(6o=t=A(?>R5heym zHA28)<2A2NoqGJ<-|EyWzkMO#zn=mC2>`XERR4Fsrkezy-@(VumnyJE3jkXyDsDA( zfMMl}PIl`SD>XKz8~L1WWOG7}z;ZpgTTO zk$%z%T>?6EJJYBqob`CB^#Fe=vy<_9w-*2;fV)U+;d+ku-fBNlkQ4<7vHcnyd}K%| zquHsL3(!LZQ2jQ}ctepgmyPOrCSy7=p#xkPB9GEgG^z?E2;iQlTlu_v4`~C)WeJj4 z3BjXK#w<#c#EA0{`+eX-zw;NG)TQcv(w$#Rf`0|>=`ma!CnW!LpV|a^!9RHk5J8}^ zq%mMJCNTK}jEoyr>wQXIc4&19$pnC;^gsUcIU~bAS+yrsK!ON}rT$E*0XPs5K)hyr ztO-HwFL7{U9}*xwGBnyOiU_=1NB}ax3q#M_bziZY`oH+gLXFuz878ey!n@(SO!v{VvvE_|#cAnQwdp zZ=;kRi3QEb=QG(&o6@=I=~OzC5mB>=r(k}1-@ekwu3e}&z`rf4_*B7{egV}gml1;4 zG|=e;UajVKmY2OwrQ&r~R#34Jhcqx{`lqD-n({Hh6cb&GV+ZAJJ(Wsjvsu~R?KhiP z)yHl%bndUO96Hpf963@P-np|ldczIAw`EJS@&Fn^<-W`_s7#3bMuY3Vuj`iOwiXw0 z-((9LHmJ|qY9Wb|$qWs3+Lg+wBj5i%MkP*cy!qzh$o~D;zxMZk|G^)8;uHATWqNgI zDCgJB>^2$crzHDxoCj4rUUf6Q$uJAM(Y+sg;Za(T2eNLYH?Y_MkaKT23YyPGQD-jn z>re5>U3iHM@@Ni-`~5p-@CTrF06&{$ z^r}DOfpqM7Ahk zHNIPzo*f#Mz`n6GN3)=e1C&vH>8u3ps#r#VhZN7Ed-kLE?3q~U_au(+y_d^D0NK(= zugg{x$_PIM_X#y7ct{SAj0{10p$u-Lnyl&dO15brfe-{y=(*M8tFhZ4H!|^NByPgM z1H(zv-<9!+rI{_i)_LlokFAw!dp`3&Jst%9yW0RDRsf*%zq`V}ngQSirT~Z}&{^v= z!^NzV-Mq=pOif`nJ%W8~hLtgXvf7r-X+}D&8`#@h9!A+e$=KylNZ_9`;Ia3gsa|g( z2v!3XP-#08h1O)Hzgq#YTJ>Kfx454NK>T0#>sfabQVi@#?jILxN$yVs0V6R3`Iv~f zEn5M$IQk8QnjD12Y}<6oBe7B(iITvuN;0clx{OOOlgS_{K*<1H#Ehw?NhJXK24KB0 z;8BRZ$Ll0?UT9(=%8h!2H>O&KqWa_od}?+e-u~!S$yTAmVhWm_mRT*6i?BQ1dy-L z;&g!cKqP6@OKSeuhZr{ul-eWM-m>TIZ^!!!r|-KDd;L+~j!ykpsZ+L7Dq-~=m~A_` zjT^JYO`C>Bwr(|awBO9-hQ_YAB3ItB1$*nUQjaEj*jtZ=gYCwdGxh4xqqXJ3hnv;o z$KCewvLpkfMX6~TGRD-lGx_Oh!?bO5<43)dRNmm{_E9l_DFe+W5(M%9!-Ny`4~Sy| zahAuq8m0eu56J}l!S|>x9XwcDdiL4j$s2B%+We+Btt=fp*jRq#5wCUTOvqa;Bv5WV?@@U3~a(N|Z*9_AxT&WwGO=$Rs06Pj=rw=iKKYK1}bxiDxRVVapU%=AXx$ZgY*1V9Z`#82I01xUyL-~JD zHH`Euk_0-y2Hi+a`|i>`q2G9hJOViPmI5zwh2Xv}B3C!lvx3oFspd2ubq!1G{e zbQC5h$Kjv;@lGfY4?(JxbNH%HBDd9(1 zSgR4Y0SHMFU~&L@C#O-?=_}_d`H`Q%lF5 z`8mJc{Ob9D|7t`40e%Aec-t@xqx&%e`gj{XsR{IVSO1f(07Nj5V&DSL!&QL-%2)05 zYm5L$@lIyec ze%CL=v_XCJ@&Btv{ZY?WV`*F`yzT6Qjna`@@3Kl`&zdU$x@^iO_*(tWI+Bk;#6_tfS)?kLT? zp4V=kJBI{8zPxRl?^UaAYheLT>ZNlJJg~Cx*kc>EzwK@1 z@eh39?BTC|wNpQI2$Kbn0Kom!s2)F_N{@`BvSVY|o)ASrU^}@Se$i)7{P@TC>2_W7 zzW0?z_V0hy9e?l#_kQPhen++yT_#s`!^&<$fUoP$R1|hj$Gz+;D2q4k;(krDM>WkT zM3Fa#F@5OxFCuSFIW7b%Sm{S+|JW?>`5epfJR;A<7n(r8>s~GJYEJ}S{b?Q339Q@> zG&)2RK`=A3QP@5eMV)h+h}?jO4KAX#|$I@&-WDzrd?LsXng= zbThj{6Cx1OdqB0Ay~s*{C(Z^{QPwl)Vz}zMYPE%f8@lmiOV6r*>(y#|lF56o* zccD1yT1 zl#=cf&`AP%A_K52ok~OCc3!E+ss#DiDuMBTbb-i@OeE#|icD!YrLsY)${B;)$b@VM zK=Z|9F;pMa$D}~A1)%$Htp)s(@o?v5;sB#6hlcIU>;|m->t>;#YS=-5 z&i=TVMc}XLmSZ_%-lA%<>Mwc}0FZbM^r!(u zvfwQs;Ty0{EUSXt={Ci#(GI36e_R-*+XTEQ5P%LjvJjv>F7*&dS7IK3?EBZ4rkQrJ zECEjp{7q|U7@t$wi4JHbX3s+ zDGy*q`QRd!_6zFqC%Jz&5unaj6mqb*Pd_FE7$eyUg-dpWcp!7Y1PLIB1OVub2o&nz z)adswl_?Pj_GY{`YechOOGEQ+NHZcfG5+c<^Apw0SdD>+xK0va_>W_x_uIGd8_{ zKg#AYQ2@a?R`};n-g_^a0#=vM9Pr>l?5ju6&y0K?BM9y6=FRA#5qOnK;LXh?R5Yt2 zJl}Nz(AaNfrB&~q;|;?=qrS}8SaE3cX45H`mGr+>!#O*Z86GZ=?cIx?yRvZL0GbmP zhj;IG+Y1Yw_TnOL@9~3Q{9-mgJG=SnkA4&t5{oCk@r}r@R#9!hG+l4E=I7DiFjw5P z3B3{olCusvt8sq%=-qdt%3}BRAN=6x)GfDMd+SF(`ruuk_{61729VYdW_GJ#=6CC6 zW(zvmN0ECr3Oh)KjGA_7zouCuz?c~Xji-6&k`xjNAfHFxO57iRk=wych7o>DPcz*t z=(;_IEd`pMn$!(v94-DOaF@n>Q5$&Jz~R4_6SK|SYwMewjG6fj?lIKWdd zh{E=9^d>;?ui@X4r?HtA!dv2zJCAAs2qMoHk!z*Le%3HhEs&bh_4Guib?Pf|pFjRN z^ptoKKO?GxG{c!?X6rW50-UeMtc13Xmy}O3>I?q|_piU>~dg=m|iR zAG!03K8arVe)yV9X;@al>+@$Q;_nrCuwpv|R`Gk*Ey*=Z{LQzj%S5cmb_+B<#DdLg zW`{_y;C@dIR9pip^O-*wxTpC?@!ksb{!PJIFyQ8)qlk;xl6vGL;hfPWIK zuhs^TYyqJDe**tJ9;Rnke&RBn6iRbI}j@#~+MTFQO0dPxu4$X#o&@j-S=G zob_mk=<6c8ck2CTi9~?zGyoyv-Fwsk)D}Qwfy9Tn6AV*n!=n&iiROTjSu917+tIl1 zW0HcLFr+sC=Q;?btiTC@(*~I)qCjN|Sd!@h$`tUt#Lo*gdVA{0@jt!|J<)%?;GeM` z6#zXRgMUf`kdG4yptGJt07#Mpif|A_0!Shv2L0$YK`kadZ2<(EA!!EK&vu4f|Kpc& zLH+-|WB^tDS0e)OV{pcl^k1n#DE5y>4-MBELlsn0?O9c}wd zO9DvAy5DXOja_xsuD>3);P}CBeB<7K`tXObl3p0vwyjymN_r+UHhtrb`(E|yzm66E zbZ%k-E9Fb)9(@#l@NZ$VK(l`Gq}Qodb*orRWoKt|!&|mQL8XGxf1T#BWAYrk&_xR) zF95oLt42hu*f(qKcC&us1QG(4Q!b-)Ka-o8u^d$Da9${H-8wRP_0>pBAQ@s>`8+BW z8r5UR&~&iVI(P2C4?g(8t@}Roq4M>A^hbvu{@BMbHV|7S7>dF>l?so-5Z{Lj-)CAX zWjTdHMnuukgWvonDlB$g^Zxg5-1Uxkbn5f-Pd@aQe|f2{Q$<~A92@mkX=T!Da? zN1fAQ&^V+U=}E)NU!iG65nmX1)rYVx0DS>e3ydT@gNs~5*cvl(n&FJ;dTLTLQnRL2 z*o(dPSY_9BXAB7e)RUw6Am{!H$M`@VEF9gvm*U zs`fn**97W?@?gR?OnFJGRw~lKm24-CR6qy0QwpKC9D55x?2FctN-K&kW3IDk|5b`aIs$j-M|H` z>5Pt<&d7*vrZXs!m5`TVKDKG1^c+b51gfSpJR)SpF_Ll$EtYpPrW>dbKq?_FeKU~& z{Hs>|lh5}6{eC8Z{k#DB-A~LtqFaAN1Z0fCh!CLOe?f|J;sq!ckg2q{K578@o#G4P zS}$XUsT38VkH2JCxk3~+o7nq|J_?3x2MDF%S%gwxLwyHPYzTmBP$XBR37VP9$_(;Y zMUYf_^ox0Xe&C<7>FG8Bbh@3C>i6{guLu0&eVqwX1oWx_NGZ?_{D}|{$|HaPKPdnh z^pXK|qOdj23EF4W0w7{!O>%#V091gV-2Qus0P5?fs(+;Ldkp^LctBv76;74>81d78 z>UMle#0Nj41CYfmL60dQlZ+G@QgoYayx7Q3w=A5ovW3~%O}pRv)_Ud05tOkTRwmO% ziF~J8o!avH*B2+=@P_4c4?T45@ZbI|s#p-r{`|Y{x+_=OxDjLV9=z*6|K}&}{o_AI zNk8`bH|q-v7(crA`uD$o>z=p1RX4FMDV?4>dCxtk4}a%73uhjBsJis@(`ev_leLwe zo-R*ae?9J_PUGm&PW`#(qOje*xXL(ze@!D}5C&ADqra5CWZjfoVoENxzF690^7hzjqg+KBZvDcnQK~)I9 zE~2O{fVV+}o)7}#34I}iuhI&z`Y$fFtpWjmB{>HxLqUHDNdUKb=Icl>*s1ZKHLc>+ zEN5ig=E?sN__ZhF%?xp0fh8@EQ5BK`?k!=T003^^i)H!=zxNlN2X6aM#;to^?Utbp zA>8L+7&lw1mrOnpMuF@EWE6HPM9(@-5;~Mpw`@E3c&dh$$6hs5~H;ib1%~743(xgz0XW#WL~|M z%E~G~PIM^MM+rGg_Aadf{0+x}+|amG5)gZe>&p7V*;nc@s@B9Bwo(kQ4*oR_+SO&S zGkHmjv{udmd7_~y9~ETUwdJG|L>^|gY$>4kRf-FZ8L)Kn@Bsi=jMsPB;>7I#+UZVy8r7QVePpl|W zdG5sBcUPAV9SZ!0lmXkR$;sUCwbvrpZr7f9#&_rECGfw{ihuV7NEI410{t}O(rizY zJ~kwRjDo=UPdty&hoD+Ld;IRZ=T6;s-|)n~eW(J!_ZpeJ=9=R0jvZ%@-E|id9M~$c zGJoIz8YVU>2M<2={dd3nirfC?Z;m|nna?br{?@m!B?t*V->X!r%ZCq3B|zBepg&70 zGddcDozCO;e(F=j;a$6MA7AzA|M(wkl_N(gi_bmxQeMq9BQ;^C#@=8#qqm`3eiSsH z_T0rEF=nI?kP9I~5&i${y$O(HXL%+1{ddhhYhSvmclDxHwgyDINmkEclXAI-9Wgf%WU=v`>B4h(v5R%Zow$$ofy;ODWTUO*V;1fevL(r?yh?~Ou#F_qo$9?Q<{PUpA$8db*r)^9F7%kK@m<%71{Ws>3ap_L(s zlyTt2jDK9Nk^j~|DBu6x|0{FdRkt=qs6TS(p7cD`jfhMsk^^rF;ug7VI#0QtA(|XN zNGZc%+k&>S8NNA-rD=*}NV!axy45{1`&1tBi5noqc zZX-BiWwZj1$w>iH)1t27O_VBhk>nvA=c6|2%0N*3Tdn?+q*S&*mg_PR67MrZ$?r>( zrjI!9sryQKDh^N)O1Xd#&&O!uqDv^_6rP6k4Z~#63DsNul7&WFf3^x5UQ)z&I(~9#NDU4)n zvY_ARro=gc|0n_M*YX0OHCqCbU_WW_muxd)9LAsH3k=n?Q0aq_n2H=T9Y+Aj zD2^lyW5ZA%tpK*$+Y3MdB|*~b;R2}uL{b63tsU)-|6I)%t+M=$F0}hSe$}0^j(azx`V) zmCNDc|AVjIdh7huGtX?ihhsOkk5yHrK0=$J6#V!YdQ|D#EK4#!cco~L<|o3hD7`& z&5y10iC!Tl$+cq$A?X^$^SXMf{W%qmDvov?`;LP~L z5BCi2+lN*OY*#8{Sw{(I z^SQ#tjUZc|`q5`T^QPOr{N-HN_U%`_;nSb~@pnJ|arhCuD&XI6d)?H)Po**=?~S77 zobN3^)2L1T0F`QC7->|~5pfp=)v90r`HIPUE1pyo) zUda#$hJR?G^P5XgVcXp7hM$2sVk$TKeq1;G=Hk=wTLZtj{G#o4U2Yh5w`rzF{jmAm zMgCq-)+u=XpVuDw{mZSvkN-lr&;EUHH$CgD&=bxQO`8p>i-;^~Pjc1B&_k>a0h1t~D^mZ!#(mwmOBPz~gIhxAZ1?)z_6mdSKds%-$R1pk&NfFtY!uU4Vz z;yh)0`c&*+WqyV#3p46HJ)_%HjN;PdX>~fl69KIjGB%gN`?$v}Ie|P;#0uEyMqQ-` z*qLl|?$ptHNQlDV_Puv*f9;!ZQI-EU(xV9S6)43XI-Om#E)ZHqr`&Vf3uM zU8}bMB&GkYBmjTbh#Tm*|DQtFod~O-qA`k!wZ5aRrQU>99_ClO% z^?x<#zi2o8Yf}lB+Sxw__-%%NYl8o_*SPYp|E_?)8G~-K75FpJ5a%$)>n06eZzcg4 zgvZA_NtEzWWEB7t0j((j3=kFI7wiELs{s_Nqra1p5UP2Ei2zOk;1h@qJl7%ts68Ek zjRBaD;H-)^KLA4uS=cS`Vn+i~+>#Om+b{ctUqEFWpmt$;|9;!a<*F-Z&Y(wq!?t(5 ztKPJ%*;D`U4_;$>8om2Bz2ozrx7=(N7u37I{=WAu&mTRyamPE}F?s5N2LQc?H{X0S zWdF@(wQ5IE^!%fL_GhOL|KmTRQqD`xcJ1Ds?Sj$X#6-1p_;Bd2tiTf^k&Y3Q6t3&0 zdwV%r4@m)-7uFqQgq`l{f+E3kb2-aOr8v$n3OvvEt5yB}dOh%~Rs7cNQKkuy4>Ey| zfg%V5OkMSJqzK?RfMl2&d-!4On~j&e^{v_B=xF!Ao;|tZ=;-OAcin|}Ll6XWQ_nnu z#Do3!{kwm+`^L|H*0g`;cg9}$!#~sqI|!Qf`T5GSBZv<*K>`#vZ9?L~(+~XK z@7?&e|MuVVg`GS1z4oIYed_){`IC!n3Mhn?v)%4%Q@PP!kV1yOS9-QlIrB}DQ3I8G zNZl!d++R7@N9Q&)aC%HDv(d71JGFu;SSArR(33A^P?aKTB3>`9(g&R?`sX=C%J2`y zdj#^-k{jj^~4!-xw0P_g!HP z4qa&uP~Pq%mrTk>mbyouiB{-9RHO0Z2mZN2!T%znA9}vh^P|F(jgL(lc1lS4B%)qJ zh(RL4&n8QVr9jHBNg`}-oz|!IX?^-PLIAXu?$3rt_^%|$5{4T2;a#>c^)NafEE&Rh zwR_`HvHwWd@RkBImTo4m4CC+&4)wZXZz#aizje0)v#rPg{pfD4NX4Ozx{P}uU=E1h z?5GofKMVNp^f$&fQNjQ)A@`T^Yo$ksSO zgTL-VsR6x5=qm)HZwr}8-w(-fq(7Lty%%N*FW|I zFeRr5Cvahw_y21=&n{RY zGf{Cnz*Yy6Z-_zvV4(`JXuX z!yl$Hy}fYY$F*$Jj(5Mi;ipo|bI(3oo`3R5eCpaa{lOn(3!|e@4m|YTkA4)D?@c@3 z^{z87-E$9Q6eHW-{N`o>}N}J`}gxwp$I7UU4Ok{WwX`N!GnHt zaWM?a<(+d6)23zkW)T~ReH=!f2SUKBFD-e^av5fRS_Wm?P(Z-(AIp|x7$9%4 zownn;RulxjU#q?J;y?UD@8G_D8@9gT4Oq<$Ti*D_nej&+!5oG*-gFaU6K%IpIQ+ZvpbL#ou{ax)J(rh-W)6-a|RHmoLaa|WAKq}R2F3ub{aOjyYd|}s> zAN*if@6}h2Zom2FGcP^xz{R?c8gvxgO9ST*ITYHp5 zt)CNymDMiy%4MIuIc?kR+Gjb1y@r|EpeyaonINdX6#CWEEPLn3ybC>{O&|=brbaD0zspPwz8POD^nW79vGj^sCC#tag_n~LNT^sutPA@0kpYVqiJ6xUQaV?p-r-AV zVeBO({l|U*2+t30P-=lzLp~@gR^LBT0eYA-di5Gr7G~A_vHkVs#jY!V`j_rA3^RkR z#xl?vU>15*6k%y{jKRN}!oXMaz&bQ4E0pU=Q7W6?S&bD6YXSe&+5lRs{+$Q_RsbZy zKdS>)tNx#-7XVK$BayUR3{MX@wy}&o}I>gNnYP%;}0)0xQ1WK~=s z{2@?nB-c?Km=PHWi9}Tp{lH8DM4{I_SMujujDBmk#VN==xs06yw;F^Q}{he3*@-G7%Pn~|~A=9*N^y#AoV9TysZ}nw1>-$kOH};Kh-~)TE{@BO* zhOfE`p!n$rfB*NF7mgg+wBudxnmBRKJ)p)mY`Nu@;mxmqeXTq@i}}3x#OFWXtk3WT zmtazw@4f0O#Nstz@aF@7mr7BntMZztciq9!>#i$wZQ3+HbKt<_7{Ij0E$)B%%}wf{I104ye@-bBN`eRyvJ+g70VumKzsIE0s!F zsg&?HuTCHB0m;l*;yGAD0-w%)-_$wTu2gA|+oZAoQEeiku%fxmLFRzCSfxa+rKJgo$1`&0_1eIUbBdg}EG(+0w2)f+0=*{^YO$9!ksIE}4YnVniZl#Iw zqclDF5~O8!T{RcmF3c(qfK>r*446{+E~O-ZTwUP{DHSQv z$xRiTIHST1R!VqLRj*9N<8Qn@K79%cE6BBxT z+B33MRsPWqfOUiq0M@g6bSumL<83jhJU2;=Sf;-kF9IS3`(okrQT4ef@YNq|HA^wEE_8tiQ0)K)GVM{-N~JBg*ewk7{*y@d{dbc6Qych?*!Lm^&YcnhS{?sa ziw8_9K$E0_Y;WgIzOU7LM6|03lA@&~Y;2D#W|Dx9p+?JUze*Viem5u{IETaJ4?6)p z$jb4%iGinwDj&@KR5eoy{vLDSVhpTbZCp+JaD=R^BVL^lc#YN@9ufJ_#WZN6xxM}-a-?}(= z=+MN8AO6s9mdojEf4}YI^U9oX@x+N*`OFy*6fZX&KvT3q01^V#f2aX)O$5Zp55PD; zy>6v43~m9CDr+T^v7B_;0#Q;gm9XEieww(jZL}DKL9>ZI|1#7HZZ0=Baqqo@8{hJl zbn%KSR^}dgM6W@kfg6DBYVskK9T?EQAs_0&BfV6hc5JZ2r_*)J@8X7 z{)?jKOuc;ii-A{qe(lfL1;;I14r4&L@}RnpvbJG3z3JTOd)@4Y_rmNCz`t3WzANyS zUm!YHFs)8_OaB-aUuRkyvtA)7P*-XMuY5G{R$dJJ^1(2uzJwj2Q~`EwyXE9|Syp-o z(S|zV;Cz><2$HN)){yc#NaJFU;j-RWd|y#OU#j*8VY-S8K+K^cB%^hcy!B~)T2}!4 zq)e^j8qr}q%8!ZChDDd>N660&5gO}?`s1OTBfhY1Z#xd&ZJ>fL+^IjM{SmN2fv)U#>3A_S7aeBtyl-7;VpX@je_UkTun%c}2vuR{mSrg!=L# zO&xxYw%_nm>QwWp)uXEog_BbWKs)uBTJh4F+S(lTLHe5 z9gG0E>d#7#_;W<%111v!lFN?C7j6k)V9suj9rg*INF4dcC!Ka|6m1HCR_VWbZm`*(ZUvA` z0;nsGek@x%@?}y9z+PA}nW2^+n;y2U3mf~f>LOkjBR05Dk`%#Nf$b>>7gPl>y8V`0 zhBm+94FJ2R4uAXG+5CnLsA4;Aq0l#U_0^5ASS-)of4|?DoyBYWZusOU@j0{!j358r z_aJv)oO%BFW_@`X6>G%g)hqM!jr#KPu-R#~2yXlo5PM}i}^H#PXq!Lcy0 zH-n;LHR%ec{vbeVN6eiW%H}ijed$Z73v$JPjy7%7R zq028vMIXum59WPBh`tS1T{SoP^wX|eC>(q0Q=i&>!{2J-c`3yEktxFP%Ddp^iJgv!<0Eb<+KB2*dh> z*Oc`s@#N0)Y&a7Xq1-mzozU^MUWRJC93A>0*xt{xL}a0N=e~iy{J6rpIYzX=2UzLCg=) zc7fk)8{@Q^7J_(yk^%U_PGu>TV={owu~k4)Wp+wA=L5?amZ_@du4;P-QRt+?z=#6; zSZ)|A7gS3`6w%`3DWoi@ZAC&rYkn-=58|Q(>3@gq#CmrPZ`OVaD@&`B1W`okVz)9F zM6!TtB{0lR`;6+#C3OseO|Z`;$!4dmPxk6}a{X^r25|Ks14$VEQ5*+|3C~+Ui}&I6 zPNc(GzI|;ID*jGtaL_O_8N;w0cEHws{ka_aY;C8z2Y>5yO1-@TuvyN z@oM0oL4MTXb=j82)JZKMlNEeU%4m%YY{gRN6a~niYVG}JbpcEMxow(d{vvkwr6yfFKi`2`()drb$^7FoHcR@G(*I=Nf7~*_ zB!C&m__bEy8T?xe{zXg-FcF~ND_e~M+dt230P*kmC~|v(A=~5sIz<7tNkasmcpUrJ zX8Nc4`5BCdaTFlWH{_it+mJUK{85shA#Ezhr?}80KrHtcBu(x5r_v*1l1Q0wvh?4G zdAN9ev>~8gq!erjcp<$294DLIb>*-ADtgtAzwp(s;{0pW7Z;n2Qfcd@?|DzPR;$^$ z-ro7~?|cXAv-_%#e8fo=i;dd+{E=tA_{Cz+&Yf`bUs*bJ%1L#1=eo9Rsn<#+T;CR^ zpL-5&{v6@wW`>9D^o9+PzJqK)tBYy)eyCJ5VYuh24}1U;splU4^FPPm0sgT}uTd(U z8_;K21>fj6+62TauDgz7SdL>Mk`svs!Z1+rN3|W*epKw?8xRJZJP_&jX3Wa~q3ip& zzN76S44chrd1@+G7#&6RK5LjJ5&-6>_wR>S0on>oJC(w`u^Qd|mtML!`{Ii*20Zfk zCqH@VO<($w*O;6vP2G1NmQ$~cjad%VTT*7Sxt!N*BFjEpS$yfGY;I^M-?epX@4)4k zS4!jK^5sS%CMOt|r2F5fT#fw7;YM}hJ8@iIrvX$dl^uD9HiPpQy=G}Y`uGhiGm_4Y z{=DP%z8*WRQJegSMrGp8b1~He;CE6z*IG_~50UDJPYWR|+(tO=qsUu~s5u)c zl~qt78CEaU`L9XApn}AS(663q)~4@v-0rKL^x#_zD>dx6eXldE%oe|~_-Gi`CsjHD zNk8^AnD5lHPZU8tGGjWyeOe~~ zUMAhxJ`7rIRHhq3B@^!|KQsi99K9+8q?PX<{ts?CE21dSRpv~dnzb_7sWgN8xEdH& z=?mSI>F(qHP99gN=S!*rUghzIs)|Fdj=XzP6>fI_*QS9^Hm{`q0OATOXoqnHN$8D>80N7j!CD7{*V(I=saac5m3*iU+*~0^)^wVOlFeI|rF!gB*?hd6q1qm- zb7gT>?F0NR-#@IK`kM{v9o?>y6=cGjK&TdpDlLtl=(PUo^}emUs4_pLR1T|y|B!Nh z!&DgDpbQ96-R}hcd0Wc!Q;3ODafKjIYKybaB0uzTXP| z*D?V-UkwhgCMx}w+uMtZ5oG;Jif-uYziAZ;hT*u%_%BWcP(NCw5SgZ(Hmz)40ob;< zJ(-l=uiEo3=`3JBR-Gh$0vPJIwFI;&18CJ4K$&#@XK6Ggd;i&KJ&yPzHvVG_%tS!M zq(JNqV6-VqI1UgbfNnWwlQsp?3?zhWn|3fQmK{cZQ@6qZBt$A3l+yu7y23t=jwP1nVG0F0yJZfG+f2@uat|194}{}l-U{U9K} zT5ZOXepKn9Xn@(FWoI&I2T-j5ex-u_0i!=XFn}_^_jMb9ZX3{g4Jpf|Q>O~u+qb)^ zzCN{%m6;hBC+3P9H=_4H4M~68N>J$8z8%}=xW(epCqDl19oOG+hgX}JsI4410)LQN z`Sj_0*REal>cT=MH!z^cWUpKAg6wQ<=dx8KyIee*b25`Z0i5~hj&7!_5jQm-Tp9~0)7jjU5^Z$8>XdICpZCY+d$<}?WRyW${TE_ zthdT`dU|}jSct;8xtDuU<}ccs)qnoct}d%d{}aHxEhV76@-I2&k6O+CxM!bR1o(%+ ze_Zu%Cjw-=4l(GD`!ysh0fb~A+=(6&4EQOQ{PT$^m=K5r%kXstE@J=M_*6;~D58~- zN-6vc;y4yx+S+SnMXstP$;*{q!!7!Vw-Cq2(~ZF_m)S4d1|UwnVM?W zmzL1)uP?f|UP|dTS5|OA#x)bw{B&+`5S&51Haok#aP(-sIy(zOK_v-*yf6)QgBLNQ zhvngY*p75=cv!7_l?d{EkRw=M>{pPpSZAzbdHM8d5Eo-FeC9KoF8}nWk3atFzaIF@ z%RzH#sacr zu|UsjOe?zs6?(5R|6mja6~lA~QrY2KO*?x@7&c~_wV6AcwW)i~CXYAm>^3(&^cKr0 zUTN9cOEAyCES+^!lMmSbH%5bmfPkccq)2y+?v`$(TR@N+3>3Z~NJ>eJPAR2pAWC;P zDBWFyZNI(m`#aB{JI^`KA3N8%21t_Z%jajqXGZB2nueR% z*IDhrZqKqnoTgd++!OxzZ>3q>Nhyigy)Bs!+S^%V)v~N`%Dc49gnbegqhAd_EqW1; zSvM)Px@^7qvW}ViGm1mV-y5mSHdOM1N6?w~T^3zvIbSD)zp)z-zAMY1OC*{Tkj%|L-GTDi*+jFUleG zQHExjrAt#eOY6Dak~hw$I}DYHOgj-(+%Jj^u_H9-#DkfQC28D^Q3c{qw_k%>M#GV= z?P?rJK5S!^-LQzjrw#URC&t+T!~h`5!UAA!0W`P34K(LLomv_JyOo=kSF3~3qhE=H zoIHaQ55iw_X!VP{eJXcdNHMayd~U#E(X&@Z?u4LeZjzH4RFF9sKg; zYQR#StF(B!FhDs%wOk32CtJpAK~uvMj~o1-6&J|HB@51##sq4hL1b6VY4ZZ9i_{bv z3oL-?8V0R4HG^dVZN?O;2f3Qpa1kK1=fh*ilSjYxa0_%8{WZtpD}J+k8zf$F4DG1} zJ8|HmmQr~Dfa{Y>oRCNRwpwy=dRCm1Gb9}?bY}8ila3(2(kE&2zepKen!8K0f%YyW zEo^~(eaRFjzv}S_lXl~AL+c?xGYv$$OUizWKmno zIUz@~Fvli@x&rFO;+fB+r?pES5x+l~OedgQZWg@4;cd7;Km`%!K-$TP z?Bh{J*H>&*CZUW}0I^rcUtC3~?ZEceHVtwtMa9L(vv<#+EiFFwrFC|ob^Q8XX-t^0 zNl?P9N=wIhI5pMO*@N}plPaFT;}P0SLTL256%=Lx1$>xrEejJbsFRcEm zw(`D+)3BIa4UIJk811%@h5G+IS_xpoPa-2R$HmBK_E6&z*hWSoi=8|dDW)C6jIa{NZbL}MFekz_6H*0zTMM7JyQz}DJx^xA z{$`yT@0L~5ir9&CTna~y_>peS4hQ-l4(E7y1#mkjk{3S>2~OZ`=PS)cRt! zoqVG_ir|Ef-iH^?FvxxqRslbQaPC(@GLJWm`BxOt4L|scc$R&(8FwNF)!CXHt069# zO@cFTx`_EHjT7#GyyIHsT`0qXY~o&V45F)q(CX_coq;XmXRLCD4mafrW?TG)M!PsH zXw0HwHsJK54ld+O5z6=L-~Q&1E^}-6Ib#F=l}DFS1?WmZy!oMfWw5vM3#eFoywB4O z$xbQ@kyH6QsWXdqAc7`mrpN+TaJzW{(uvG@<`#fVz#b(qu<0@r?gltdpI#u8~1FsYp#ho#onE0vc z#mPdECZI+`$Ng=gAAlUNCQCjYj0si#{i#W@G}}NWBIzklnGXXxpV^rb*Wfq1J z`PxoE2V%x>gO?AU<8Cd8Rrlr^_JF3{Xy(9ckUZoWpTWMP#>5o*!mFdh2|mgV)~r2> z8`BIJHv&F}v4fO6aQi%gmO$!PQU8uTQlr#l`QU^(78c@>S;K^d^)HpBc`R@Ji zuYAqa^fG<-3>o2PACoGWf)NQ)EAMqlgO?iFx@v3ZMw~R?+^*5#&T?0d|5;;@Vm^n7 z2cePWF`L|`X0i}-y6qS2i38eCh&OPJEhGZs7hQ9D6$Y<L; zI>>2mEge9NO<>ObN-BF4!&1o080r1*SVa~ba#3Zo8gLCmxsFFSclrBVoU}XAG-JI# zT{5cWeO;*i;>=B?oL2DuuN^1lR8~)qi2|Ve-T047DYhv8+WI>+N)f3)MBEi!*^I#y z$ytgbl4nDBv7bEKtxPuCpDTwgR*kPQX#SN-#%ETH)2T%Jr{}IFoVJ~&*<8^PB`RLL zF3M+D4+bpdj=5SY%86zgJFza|5DVcbtEYe3?#pA)FJ`;M_`FvClZPm{)j~}qmF@Io z2v`+*-v!qltBH5ZHst=3&1Cx5{^Z|_E1q2LX~C-@RTe3DKgM==RQ~Y1LE^nR+*IV< zi1uyg+7G|>BxACuFN>G$cX3|o7lN~HMBeNx26xun5`%^Y8+bFq(%cyt`v+Cl8BY|^ ze&aG|@v;BfQ7^kuj!GGw$$MYKC{{Z%T=*yfX4?|-TTfd*JY5Zn-WvfHf=Hjr1cE1# zd`~-RCjZp1)co(zy3VO*|Iyd{?(J`dwm9zdwhH&a;WbYE{eE%6lk1CD8%%;omDb`P zdnQ#{AVcSNJmCuRs7fYA13%A4>dCDF>aST0TIXNMZ40uW^(DM?ydd1mpmti+mTaXd z!3EeERD9Q?7()x3f4P;c5N`GQOwaL$`U9?oMujEDCRhtXDDYWJ{OD)TEI1o-c;+25Mf7RaC;`WuDAkh{zF1nhR`HHE2hW$v2NGK;{_9#Lc=X$by(zr^P;~_3s6jQe135F!17{NF zEsOwFjiB%B7;(-}F>*XoV4MvH7QLz{+OuPEUdqC%98J2VV|VzubVmv~5RZ&O3Vk=k zrD|=AM+f>eIMs%~7d>MF9XKq@O*!XVMaktZ0gPAaI@+-{>m^>~cP{C!(B=c-6F#Sw zNL|Cn%>cmU0Uq=HWuyg`9F`ibnBlL-@pqQwLE4HfUTlV^vbG((qguEd>-;Yre!q(% zdEYNaFG9uif~q1v^Y!qQN&=g9yJ^Ep-dcCBt<8{MX9xQz8XN4~o%0=acuQmH<5h*a z3`yYv5})9h9Qj{^UGK_z;93oUfu;b!q7Ea?50NF^A6&L8SluHeOlM68U>Ir2!~VV1 zH^>w~CM7t#C@@?9JkbFoirOf?)OGM+*;AO+XJLm_CE1=uzKAsZ4)hGlV4aNhb^rcu z^)a5$HcaY?IGG-M2_N5OSL{NU<#>%1pfZ)?6wcHa#$Q3V_K2A0%VVx_Fsda!DZ5-m|h>GP1^>!Vs8XpbH z>XGl~dIqXBaHT0F*akF>1RFT2x8+F^xm&(QZ_bu7;UkC6f4;;s4X_hSe#h*5`<#gM!L)`rdoW>A zCzbz*1s`y2FAj;`CyvDCADO{bG}_S)+%Wu=A3#WTHBn2iY#~oGGe$N@;)VD{9*wYU ze8U6|UoXm+<$6L!$;M(QUN89ew=ZEvTlBJ~V7W+9ezY69@|D6?nr(y2VrwqOQUr=2 z#k7~3v&~k~p9k=LrL=iO9NPczd~59M+`Y8QVEfS9M~FiubK-Bx|9l-L@r%tsU`jhs z(rEZ)Kiyl48$3Y19hR`SE30so%o9@sm=KeUiIK-WVp)oU-9GJX zR-akXZ9o$#+1yD^&hscynZxGF{INC)^F!-JapbCI_a#Hs;Gc`3an*o#eo-);ZNf;N zNogP*Ff_mb;Bt1#brx?b#ek#b;~Cwo0rC)^x}1AHbgNm8-y?*VXV?ejcGC;_s2>!@ zPJo&fbmNJu!V2eX)GSdJOm}isohzw|j&^Z5B=a|8$8nLklKxg>xUW^BP`2ab!v54y zgq}O#I%%_wu+Cn=JyP_wu%U%~+d|0z)Q>@R1H!*zza4>f>uI}YkWcr!dl3rOZIKA# ze(iI8%e@=sf&Q(Y+Y!*jB5{k<{o;D&WL9|#rs{t^29ss4()3%$`0!%20TlWWbt*ZY zvwrU+U^P256E7ZMQG%`t!W5qfsUW~vaUnYA?PLQHj!6C&EZr2*Dd;1(22~cd-}bJ^ zWW$CQ@Qpn_=Y@^8nEvK3*QzV~C2qI99lg?&l(b1ZQ)26E% zNA}~`_kCHJ=QBA(?mhzyRsvD&eXdKS%%U^X5S%^N=+;65Y#yQTUhODBLb+dZZz-cj z$sFQqbSf7(bhqPpsw9@@I?*q<)hZ8aome0?1RMV5_89lz{+o)>?LRgllH~4L>?6J9qpqZF>^D)yV>=v`@YYh-<)n6 z4L?x};% z|INcm`h&09iV)t*S@E!gW2CM#@sa5cP{q9K%C_1PZv6Dy-lca;(mZ_rSJLbCN&GopFXAb==feE% zqwd;iYr;-Py_#|!9n&pV4lxcw6=F9J^Yx@DwR`LREWJOo)j_C&ZQ|KIIhE0@V0#ph zHYjeleT{!+dI!2@z#PvCIEgNJdmT+IBtp!efC?siQku5-Tq0^X)cyXxn@8p_ga^;~ zut|yjaNZaq!OmF(-2gf+Bwc1Z1;nMEz$HFMI@Zdfp5g z>70DAoeB6n4({ha=W_V(#& z+z?7gX?&v*{sNI5Ru~3Fl9EGQ@?22dg;n{KEwOv0bTM8n>3d7-Y=}`X3!x5sUFJ3wbL1BPAV9${!$=UyUF`I?tM z-zepS*qaT1r>w5e%k~qI2be^`Oo203S@DH=V?~sk-P6(J`SKbqdmROAg(k%3p!Y8$rWsk)S->Rc(kug zoH#_tllW3{hw9AM%~Z&8Nhr9|KAoh?&Id&Pyr7BA84r(r`OT1Ch{oJmFuzt z8Y0h(Z^KfmxUuGL2xG?HV$qDFU#SD){g)b4Rv!3T&!u$ScUc5L5M#iA@ohNn!*}e7 z-=D%dbBXmTfafpuT&2ZZwKJXAipWaBQgGwZQ!1Yxbvcrv=kq!Fje;1so*1a;Id&7t zA?%n9KQTLD-OEuPJOkKi*nQH&E?1K)E9-9{yywhu&&i;#;zj7j==_#zSCES#nGFxC z7U@c)0vy!4T!UP~SLQBZ-yexYL6jJf|9PN_2YU=IK?1fgP5xz%WB%)>yST6?M<}M+ z5D%>v4V&KS`CHKO|B&GncExIqyLBR} zrcqYq?r_N4OdoRN2lJawnx!TL^hTr{sgfh^h*qUO+<0TCxqr25Ll_WO9J-i%#N9d5 zW4CwBcUu{GfL2}`8Z|UEm`Zr3Nb0r}>w26~``v=X8oA)=hPGilSgi zb6#C7Y4m_ISW4`ED>cI!IhpwDtM_3^^J?_8L-0{Qm;~wc=4GvEQ*|eRvi!a6hM3Pq z*Mq1>*LM0F)vikh=(P&O4!Hc}jHD5#iQyC0K&m`Xnxx;qF)6;*6O47jVx^UWm(u0o z{F|nxPGwpDty^QTzYjTVxb0p#tO!!z+l3A2DmQlH{QOAug4hHYZuoQCE$H%BfPsuy zW&q0IQHBs{Kp8}|7nh-L3W7824WSotiCI$YdhxS=T2EvKwJzSU6$MkWKZ)JI+)@pj zkIM_19`b6;S$WC!J<@I=XqngAD^sV|4ih`wnR;WVN9TTx7gKB_pcD*J0}Sggn_WJ? zOk|F=t^O9pm?6B21rJSfi_RV*K{wbH|CeKUdg!pl7mS&v8DA>M(dV1M!Y3MhrRr^R z4Nt#d){40d_?h@&_!w(8_T2bu%Y!Jt%Uy)ke0^jKui1As2S+*^p2-f1L`D`7(JM&e z!KkE!e@58(ZuoIJU+DQb%Eim;WPV>^_%PNb)8+0`2^KCk+0MYSOF7A9cn)0akL{CT z@z2YDlHVvTpdx%@U&yqs{r(n4j-=HBhUe|=7BI>^bZ5kLy{DV>Wa2>FQBKZCCRxHz zjXGdgC+eVHez3p-*scDXVfp6_+}zU7RPvpZh5L&_4f5g*Jj+!sEykbh2~zVc^NNE@ z<9wsSxGCd=g|45Dj^_1cT-WklY0#DWzgeHNLNAU!!wE(`N&UdXr5@V#L2vjvwVC&Y zOVCcdZw>YN0?l~{GtOD-+^wCoKKa^ zr1u724R}ebx0KaJ&5a@))OubmtCuq6l&NjmxJ@mCm?ER5Rk^H=>{%uCP8;?=&qo4M z9!?SMVEm50)G983u^(br0}Ke`&a<5N7s}F#hS~qS^;wqVA&0IrgYLvsvEP0UoZ|hP zLI5REf-dzWp~`$Mn!5ioZSvDA5p(jk>(%AF&2a4Xs9bPdSbX&rko3rN=I!+3*QZCO z3P60ENfqkNFH&aU*}Ml{Qf_zn4+f~}T5LMttpc;U+L?Iq@wLN=ntPe3_X~KpCxEiZ zn!O>Vwiz{twqWg3)>lF2@avA@mC(nJuSy(!^KiSJ(4QFt<*#c3NQ_fG;=S9r`uUA>t8%3+cX z=yM3HRlOkct(neqm%T_{dopkN<{S9E%fS_hH2=q%N4f^!VYIsmc%(TEMkF6^`SLf> z(R8AMg-MM}*x5__8N+Cl5)mxYRCcb<@vTK_E%;L$$qSw6aFxSb)N!Yq&;48vIX9c*g)=*ukmR9dh&R6++ z%K%w?Y%3XOz0d+&!h`6)Ak+Wk?F|OeofmeQgwbI*lb_?3vT>XuqN`bC$^Q03vmMBy zMqgSwV2n+@bw8Kw3}U`!bl2ud)19RyleV@}<9;!levjalYS#X8#o}$9{IaSLu~TSQ zg7_O{o9RWW_DSb8nyegJE-*S$j=A%s-IBu-p|Gdk$>1fjYSnpOk^r*HJlG1!otT84 zyW`S2EW5Vd?_|FYxvKv!A=>WlUle^=fjL^c(7SLPu49Ooga<_fCrO{hKC`I01u22x z3RgTyC_JT}jMy&Xr_csNR!bIhtQTiSg|#d%0Ygxp*qTs|Nhughuv?_dTL!HfUG#H~ zO`GA*HI7+IU+EbJn@o(p8NaW8lmc7`HA`gWm{$K_Xx6DU=FfL?%_~B^4}%ny=G@z{ z%uAB=%P@U{w#9s7*JgrPODygN;|ah2%<|Ij)R5}GVOhlVawb!6e%f^ZUTTI{3Ap7i z_bfYk&aNz$ncg+z`GC_Nyleki+v!~MMZ~THZ$%5H6|nTxHdNqXCVc|i&tAR8iePTefjP#6GPQ@3yz`>T19&=zC-o*s8~Sl zmTE9Y93M-ovIFqP;KHUkKU_rh8bFX16LUw_?&IWJ$FVNFtiolH8NX{qxkB;+!&el3 zFL#G;-cLv*KOMY@o-HC|=<>c;-d*iHD zRsiTem*;_gCdbJ3e0@aaI!^a5-?nxj^O$I$j`97n4MpTA+I;oO?Csbx%hEDdO2T9H zRJh`>9ga!!7o7z3t7F~B@Iav24JhepeHksOw;u+W`llqj-;~Xq* zos=Vtd|dUSL*#G%oHjl?(@dM$kt#FA=cp}GZ@!0TzsGS-nKXWLe^&baHk-DH-7zzM zW7D2(#X8k9@SjI@&>&YDEzKU|Li>FEPcx{w;TF%Zz5P9AaK(f1B_TxD!X8!zYs09R zh1MH`gb?fcttRBbvLn|!JE3s%SuvdH_tU+-F}RjlkR95tpkKd9KSSTHcR~11EOLT& zvb4f_amDu^tXt#VjU~k-m&6{I=A8(an_euPjA-7jg&f`Ug$Fr37X0_lk)Eb?=bJ{5 zhsVVh>{=XKc;j;mouCQoeUWJo4Wx(24PERC?o zGPr#_Np>Ra-227<_sQmgq{5Vd&8pf|Wue#Z2UU4{LRM&ZZ5L$}>PNhS;XmNJaiixt z!L+}~qNnXMPx9?rAZ#N?IP6$hnY*q}ZMSi*=I42wQT4{M*J9QXQ~~GJPS20NSoUhB z>(JT;xOMJbdVGgO?}&%iZWC&K@!w0Pmx5zW;YAa*2@j(s9N!u%+HF^yCGJ<#r~ONS zHc*m>U+yC^F$Z0CC1Mg4d2~`#4-M3E#|>^=WKLs0{4B=(|0A0O;>(zD#~GS)@3&`4 zZV2A2rko!e^>G6{pW%-~OHIlyh6J~#K>MVqq5r}%VuD}Kh(Gy(JbeoJKsuSHsPtbx z;7)k5%sIwsYxqj2XZI{6V9(cf{u8LGu9i_BjBu$F8VMtfLtY9hf*Q(Ac#iq&?vyeQ3-E1TpXoX z80R8sXFhZdi*UTiUaUaCzTR`JaipF~%@2V;dZCEX?l?!kO z2ibSAZG~o8TBYved1?1$d2cUeXl`3E8#ND~<)%@o^~=1?abzMI_)#YFs;7>0*w+98 z0nvGP(Gmg!vErE?cEe>MTNdl)X5zt=X(wwv!>=vAt-`~75Usn$84vy6g*$WT^eOEa z$Vl;(K{3GJPi{z#mdj$GO^2-d8z$V17gxe%8jOLDmoU}0fHjl7#il3Wq`kp1X|JDA zMf~Spi$GP*HXhZk6n*^`o+XFNv0dm=lG_#gYevg`h^ zkOV$V)aFKu0cG9WW#+StofOMji>_IS56XNX^*O&78=P`BZ+g2=p{HW5u0iQ;v)@q9 zm8-D<6w3(4K{hDUT_x4VOoc%3u9O%2{b5rz`d)!PX`ZZe=QI`-mgGVPL3y(V)8#z! z8Ny|EKHl4PWrEW`Zg;Bi24l<%a|BSLkKHNCgH7=#cSiM+&J&f5hBiw{+1Q*d6FhMb zm9FiIFxQ%qp~b!d>C4e<2lDod$zj=Vnx0`EG2hiM`9Tc>ZCxk?22Wo&BMox znO*y~dLQ`KRc}|qcp!yf?OAH3vh7ya)#u58S#w%4{k;%F3+v*kD_Zk!&x?W`&8~O+ z%z>(p^}1L*xHC7w+D2L7B@~Zj8y5UNXRgp7*|?b>XQ4iiFMk-&uHm^^MmW!aX9%x8txfeQ_}-l3jOn9K zn2tIQz-K!zLYe|gU!j2Pykki%BH&+ss+jy&4;$N;q=_lZ1F;Uiz{XBp*qynccc#Jt zYZWP9D2=6wD(Jvo@%iJjLbBi^9WN`!t_gV6NUp#m@=2$t&R2p)Ht)$98xQ(;*3m7s z?dJ<-_!{n`G7DkdvCK+s%}>IL>Sn9kQz6^gd)yQou~a15GRlNK@(0z7dqp_$z;e}1 zHM32hLqz4pWnyq1GfpP4o~;c;hbg?H*&pEweF3#wv?$F7({ zu%>{&vb{Cd^og;dsCtmdp`biGS#KWK_V?FLESU0I=3iD6p}n}WJk=KC&1=>C6JEg> z)~pBJqCca^Z`HT4^bmc|_HxVugGLw*@LcPVzT8ShJbxl83_CqoZvU|P5(8?yn}k0| zz2P$Xg#YN)sLz*{^o+mZp4YqQ-g0lPjp|S!2($2~Yg{ywLnzFr^AZU?+#bfrqkin4 zf*c-9`3%?OHM*5_$(?r{C3`cPI3u3}Z9{!-qNw>{ClSMZd{>sfvD+JnB{xDk>`|49 z;#p(;_a11IE-XP%2Iy*&wUF;@$niIY+pg*IoQ_}?Y3V<2Gp zl$ACVzR34-J@N+dg1A4Ry*A=KQ{qRbeb>yX&JOaTtp9-nIWD%YmZq(-Vek{0-{K>w zf{lunC&Kc#E^~3!TM}n5d`tMmcir%Hegj3XfV~@!zbT|JZ2~fwu6Awxnc4;~xXfIK zxJr{Ipr$ud;_91bVs9!yAhKy0VpVp^ufJ6lC@-JvS|XNh>@+PAwl1*nV3R5D>X^XI zGrSd~easLAi#fga5wft1dGmRepQU!OSmmcmBDl$BC2V;d^_=`T!M zA2*zd8G*U;vW26A{`JU@DMp5SF6vg~8wvl1gQx@OnBoEoOMKxnyGc|mic)W~OX1a; zxo{b)O78DA{;&BWvmv0sgyOR*N48Mbwx#Fe_q3qjwgx~e!{apFuXcO%4>ZE!`yK|> z`Ndb4prKC%Q<)G_xPmzeCBW0CKu1Az(J;udq^tBl9tqilyW$4CFQbz;PFqP#*W z@7u@?4<#sdG^J8XnAfS}`|)G2BGZwNE9$<#yo0}=0JmC9`6hV6+DO0H;o6+xojEyH zV28Af4$sdw4T3@y^mo)8I{HEKWehpa1%(jwb4l)yup^q$JaMIc%j63r-Ar&qgK1W7 zK8ASoK8N*`snJ_=2JSEB|HY#q%bw4$FAs7zKhOA_;|<{MI-suW8-Xp)-R^oddBorz z-1r`xt9=9eUSe7yj6h(}Wcmv(Da5QYasgI~E@!oP`EB!bKi-Sz#Ya>KVr#7VrSbx1 zma^eX>#0z2E?AkL8=fr~n3w1f8}5D}XK({^0lF9g`N_Lso*d-Hnj9|P_8aS3_-q!y zrLSb)v6!co1{u9H0b>Rb^)qTU)Qjs6ZxlFNYl|$f{|V#b-0;SY^B2eyXD|3UWWC*% zV>1mX$o#Goz~Vw-6dty~jrLA^5ZXwb1$h33zDO~0E8v+=S%+6Px0! zNAo9NSBwzx7;67$!xrO_-v76uEoSr#7ECBdU2_}r(CZBi?;!OFX=6$JIqQE3F|o1w zhB{A_-{gs08Qs2El?vDj2{<02QdKF{2}3^&)b~FgG~NeIf0{;XixtQ)ryifG7O$;j z{l`f7QA1f}l>Ohaae4xix1qB$mktj=E&5W%;i@Tj7|2gopArjKEwtMA?V{-MAX5o1 zX$9eZmRWB8aDB2up!|uPq9RmYiOL3veT`U{3`aRDcWE5&0^j}?mOFI(>7$ugahtlC zBmH>n?Y$5@%&VunA;fGrVGV7<>Ht09C7@jT_ZYe^hFYg>9?aKwmc5;wXH@*%2!{!N zF}sLjBISdCGa+&CMejS$vN}~7V_D+LGGkEh61`q#K;>?ucy$sbS@u8w$|-Jd;EV4H zN9&VK-R}eLa?^9+BMpMtMFTb|$#BZRv#0n&;ABOM6!{{_^Dj=20~mG${(hT4E*<2y zHPF|!QT|?!W`={fcmL0>x~asA@0J&x1vU&s--dNnli?mq_g4HoN5adTSI;H_UJ$o0 zV^j^R!dIsldy*O_wimNVt9of}W~T3%OT*z>*qMv1w_$U@)POZ}C{p>A=c+AxZ7pQK zq#b;&adQZJisaHlB#<*a7!}$?IiTM%s{VgL0UK3eT;2bJL>$h&b4u=*|6ykQplzfg zY?fUF(&U?L=D3|^f(6E)rjsA`&@wlQlKNH~_%EFpV_)-A(C8uw8&nbh(kKrIkK4SH3c7QD9QtZ5^a7w+J zAT=ci{Nb3RTmBuUj;s2Z97DS)$Hn!l`;8b0=SvK6z>uECRY*(PW+SmeIOrS3Us)xJ z_s|kDeRJ1A;CgU&S!u+YcIx#T0 z;6aiZ%i#s;cCSXF)t}~5J#u8M4g&OmYOK}8kL5OYyY{;Hvzy+_zpw`y-eyUpgX#vK zzMp;L)i8{*;8~gJ39W6^&>@)OdV%z=nrN1K7&c-BwWh4EJ(c?ouvG@!@;0G%Tt2Yl zJ5&imnSLID4;mN=wiQCK-}>4N7K0<#ycNPV7#J;>Sl=iY(Uztf$e?i5Xnynk%iQ}6 z{sU04v3%#zV6F&@6-cET&Y4|wroP}dKl9iK_kYT~Pc*^(f_f=Qb}@X64eC<+Rui{m z@BnW6Zp0JdNgmmzYVA7%!&+8Q3qXpQ`qs(?5Th3HlfbN-)?p~SO}Uy!3T|{t)m@;s z10n67Pr#2s>8Q&eB`?jX2(_?&AHKv~?^-#SNdMf;g`;k-aD!!gcx-H>oPBRASn=XK z_~~Bl67D-ufL80T=qJCl%CfKjC~sk)#5KY5Pp+!Vro%9MB7p!vdHE04JW`_oB~(E$ zY4_0Ze?2bq-LocqI?{K{*76p>FodY3-)MC8Y3T0xt}HqTM^9ZNllWgv@^Rahf#HIY zxrS-gXae{yf8NqkiHCxFDHDF+^Wicmb5}yAV52k`6@IgZt(I~qP5NkK?SCt?DnkvW zrTO5SW)g1*-hTB?hH0=0H zC>x(TniZ>krc~F*B8b3_@go_T6oQzT%xCq7(5;7@CJuz^FH$=}feY%C?WNp2LYU_g zvW`Zsi+wz3DYI}4T~|DEEg-bRZ#Wb%-TP2$^^scM&{bFtOQ~_+m5ipw7r@MT0K5Zc z9{Q*M1(HS$?k{@@fvpTdBTauFZrd|nYmco2IZH1sVZDg6pV;A4V!?U=z1AMjm6%=) zJgV=T>AZ~$owToLS)J?085Hz^CyxIMPJ}eU^xu#*dQn@8#~tdXU%k#S?6Fsx4YKyn z`xNu9XQHw$A$Lc0fLW3-Jh#+iQb<4tglRu| zU46Q?g_!cqp^t;#kd*cACjrFC*q3AJ-hlx6_cq^krh8N4t~QDK_jJA5qq=`a0D8_~7Keb@$Abgf%Cvo7i_fbwDPzo${5k-UyM;#xvfv^;@tBl?@3T z@eZ*A?>F{{m@Zo{tM80wCJ7EeNPS_pQ@AZ2GlcIkFNU}Djc%+1#?gCWO<)1GP6b&MJ>GG=02;~D50$1 zSR)@My|-^F3q^+hS#5AcVE!x>QxluARW%D$&d}rHXzFhx<(=;%YGf~4yqKV$m>dR^ zm#vEuDJXFL4~B%xo`v6vnS}epABsmvnNLC87vZ=V zLg~*%7vbmkqJVk8nQdD5C96>WkIE1&J^v{={oCB=!3KgxzjXY?!=Sl01rHVKfP zl(+})C9!O=v5|!U1C!A1Pvy!6gT!%x+~_5c+?_eXTfR$1g_)p%TTatmdiq&DA4y~h zxoFD-Cs+^peLg_S-6{(VQlF>p-l2czeJ`#qX>uo%u)2AFsS;U;??!vH1h?dMPJ?pZ z%+S3Xscpp&3|eb$h|-TKLa;Vo_(uZ3l!e$hbO3WfXbb_UlfLYNiJzeRaMROP5Nh)w zo-Am2#hAd@jFRU;`Rw$$KwC9UVg49r67Ww0mh4`LC#YO(XBSy#yzB)(i>z@b6&2mM zA~iwpjC>^Zs)d~Rd2kZmgV~OgYKvI-w%>^#d3(^jJAC+35puHM2uB!|5JSIIQc!#u zwD8W&>DE-JyVq2Q2rJveMzM)3RxLA5Ohg zdQun#AS7DRt0(K)4naS6z2T2S0zkO=8 z9o<^3`q3p_Ir9u|ritDhOLbj>>pgw*UqHh>v&XMd6n-W&G+d_mI1N$%;lb`Q;N^6l z)&sReq-lGx-%rwxzZ-*0AYG?#cb*m(Pa7(_1jl7BuRsE`USB7_<`{q zmnNRcw8Mid4Ns&R*BjbQoyDG~_>|*B9LPGKA%ytIQ8dNWE0o?(+4{6%0Z)HpS791g zFjPA0^&++0H#NCG+|XA=f8WUs5A(d=5g`?24BSA$f38DfW8g4$#6F=ujzBn!1@W~_ z;7^wim1fj6QgX7^9=VX9<~{ZIy*R^D0AB9UNu#n_!DVvj(o+${kIa(9~jXi-GY z2O_JYZ#Z>*pl+;|Lu~-y)oWjzCC-vgmh1>ZF=@c7B)kD79J(k2ag?7Vut}GP;FVqS zqHI{a6#Fxsz4O5vga~r6<7Zdmd52&p5-=LGKq2adS=x2L8=l&E#;%3$=x7KErBBMi z(Ch@UBR7v0$(-*#Qr~TvC|vx4S|N{=8O6_NEKSlHpmE7en^XfXeBDNiCA z=el{ht+QuZ-H8@w_Ic2+c>vRc0(H@wpEkI;+PQ2KT>vQKJ^8|%A`kWJ`F6PFw+WR=M8imP!SgOEQUXz+!>xH-`_zkNzS|^$`k7d62LLW2`^>z^Npl zC32hsxbnQOHu-iF zj9lwe=?uCmKgYsXHK^V2_bwTxnX+XCntij%ZU+cNrG#ECB$8hqDsTVMCWAWF-1lzfm$!ao7d^bVo_8K zshmH7PpPEI8zSq%vLDP!rt(IjHO)jj*p(KZvXp1=QgGqMh#P8{motP>rJX~#T3k3qUF1Ox z%H)6A_8j=qQ$mt!#DMu?Es;YqAMboxxEa1^S+2~riK2vjd=>45`!5eas~Mqj?!LMj z+=V3-*h}2sfBCewNyz!9H^MBM|94Ma^XM(;z|(W;13g$lwK7@#jqM`*{DZxo+OOM* zG?ni6@u=C{RDU7qrVz0m< z4pX7v9P0yGA>S=n5nFa4Sh?0JuFnsz07(F|ZwI@~hIQUe>3q{AeBlwV!?*eN52nMl zt9D_fvqa;21HVhk7>i13!(xrcz}m>MXwi$f=cSG04w}x}f>HWL<8ct&jq%ciu`dag zUkKbrUhRFo)D&lC8+&L3K)molE1SDta`p{ z?x*a;5-OibnVu28+;2j42uJmB6r;^Qdv%w}66ClwS^P1%hato(z+aA$OmrNkfnQcW zOYy$9;BnWVYjYl_v87XH-qk^(b^*bmch-9Wo zHgMkInzRj&f&o_d^U2ViyFFR^9)oaMthT9&?LH?%+(bMu0DrOiU$Z?LOvN*T!_U1U z3>d1yj$a%WpYHD1XZrY7x9-*2O`nBCr*kpdqqIMNsiUT)(o4Qg&oX)54G0K^wRm=G zASKxKk{iN+DLja#Hc~%u5+KD9*`@dVD$yP9%=Ak>yvmkB(GmW}dTqRxNcA6#L*+=3 zs`4>!I;E$7dN`HuSM_6iv(Y@BZ3cm_??jrox_%?>yR>ggpT4ObWEW{^E5SG-0mwV% zDrPghqa&|8@c1xc;h?(Gn*;PDE>RR!`27})|Gc?-X8f{9BI}Fs*P-A?Ys1`D zFh0lW?c-3Wpy|VL2oHic_Tyt z@Bo9r$*)rO=_Ivgib{6_hQsM<+;qk2x30y4a=g$cU^!44{=-6v=}GkJI{qVPR<5iH zUH1Hyr`s|Dh$%hYq^*$6wSOU$Z-YBuTUnSFh;{uv+@YqXhTDUs&LK*tL@`)2=e*>d zuXX`*ao6@zYh_~l?<8|b2%t!vw_-SQVezfhUr2`&Heky0T!g>P6m$EVy$GTEOHsfH zXj_#DR~*G?;9Jy5pIh=Pz%$*qNOS3hPAR?T{wGXj-)runwPDW60){9>V<$-qwGlA^R2*|UM=z0K1gYDl(N{wN13 zMa8vp^F}V1xSatqjn5-O=O&v)b<(}I;D~B zluqgHlm;p32I(A9KnV%ymKFw(lo(37yBq25-aPMqj{SaHKj2<<#d)DzZXXE95Z!1q z6qShb%1uYvikP%*L~rw06Y{17kDBNFX&1wCb$R@e{j7Pv`|@D_VsWrvm@}vL7p4s2 zV8e;`yKh3EqyXvFefX<-SN77#2bjMEFE7Bk`-q_{TfQ579m~LCyZM^2z$P?k_*-z~ zmsg-40;Q7b^r{B9aV>S#6D8OjD%=F+OeH_)Q@hI!9MHY}8k!`mzgCa)&Etq-woRSm zHgUvjIqEcbLv)P~phMLqTsaAmJi2xc>_t4y_=F4o<00Oh`r9G0P-w~i8(MHF+y1jP z%-HKw% zG7dQ81Po%n{H87Cac<>BP9L^ttS?efm!$A3hL3s~dVGz(FsNlqYXT6qcJB7`fBU*H zR1dgzPF#G=^xY2HqnkWt#^yIhCn%=mvh3=b;R|b{@$R<`qim1=2CaU<5n%{r*#%f3 zKIry_F0icU!fJ4A*s)iU1oI7NCe~jsa^zSyum6RkaopOgW(sibW(w)rXNfviqG-~0 zU3nPsnEn0fBA8w93h3!i2sx9U^?sCTu`BevBpEX#$I=l4of^3DX=CG; zknM@EgCn=S^a!&LMpa&Ql*|d z3RScWNQJYz5M4rl9Qe+W-bkp3{s3|7lEW*Q8XUcs42#L)FA5@d4e$JEu8b@Nkj^`b z%SpfZI6e&&mroPj@LJPk(bnd6t}B&Lu|EgaNPeOCN4AdVuJ3M?wr2 zqz-I}0FC(VS=aSue*A)yh(9$G!Ct}W$|I#M6tmKvQO>#vyf(g!b7DU58b=9dhW*2i-;&yB}gygSII;W zw))$>NF7J86(8Q>0MR-!!mPQ zk;m^b>tw0%v0rUrzzu#-qQ&&{{#0qjbT7Hmrjza-V=c!wI|fzpT5_zE6#J`ErmZ<$ z=ETISe;d?gPn5K|8k_l57aAvE|;61kPR*P3(FnT}4zTxxucL zi4(el;arreUOvlY}g| zrXhqnH7w-?b+F84=P{5!yp&9~$#Q>gSV^^S&`kVm_mOia(C;W6v1(VNw-F-{4BwFM z%&;{dN;DR5B9DokovmxNH|NSHF7_i1trYQ*NKC2~qe&PSpe=zl$;Ocyav1HmsP zkEhI2a+khnv(YA0;%lD$XwbcA6Y)j#0ThNeRgS09P~z$kYtX=|elde!w^A>EmG~8p zER70kz+@iUdJo1P=isG|ISG126rG(stKQGgX6B}$sg0dqsA(`4mQLu}sh8N_i6y{K zjJLlfA4uTd&P@b8x7TN+j5v!vq{Tf;Kb+q+ycz$*PVm@Vck!>~T>@#WL}STj^2%YSc$V?8N}Fid26O<*HpG*8s`}%anhdUR z+r=LopD)7dTIRKKe~s_`B_Tp;D|^t+i!@sT2;z{gpj}dHXR#>C10gfVq*}7vd?Z5q7b}i@0^s z&YQ_{o$?hY^nC}uYsUKl=w}n*(4cI&mkfzEoWp46@|QmYm8b!ie0Eq+wAf{u%8Ad? zImvq@IO3edxxaJ)rH5hRZ1ddF>1Y3Yh?@$UhXJVJ-Ig}+s!=ddAQL`b+~_)GNT0Dc z^?Y^8knLaX{5*^7Lda#*fTciYiG%}~Qnb5sluQv2{`U6ZRX~D=XgRhK))_2Zt(H&M z^DD#JKtVCG>S%Vzmq)s< zclEAEFE4sK;o2%K#xJNdYtS~!t#CW+`z=Yqhe=cp(l%Bi^}@ZGp1X^>od$Y$c zPdr|i9Y`t^qQ4janNJ-VHAl=K78ZQ|W?N37Q@%*T-lFcz#%jYY&c%#UssftiLEgW* z-v6LRr_fNoNho)4kbFO0km(lRQ*vJ{e_CiUb<`;Z3{Z-dXnD4&=~#vDsO>7>aWS=78xNoH?`O#Z23{y-T`S5cq-grGx z8EKH~z$9VfC*iGx2NiOL*V@C$_Jx55)%Ms0vz#!@cjzs=>gz2YD)$33C6{1q7L)9( zVX_91T|Uhn>_fExgdrD&>HZ^APZfnNFWw$?yiR50=a0<%(5c?%VX)QAs|8Vt=_X9@ z6na`G>ged&1Rh|yMs+pw=bypwi5i+UWz2_R5?M4G>eJd;{|=En`V;KvEr{7(fa ze*0Ub>>Q@UsA1HKFER&Ku@sys3=El5OAhq6r51bNdKB9*R-Fi4RpD_NL-|%}v8G?L zdq&`$jd-2DO^RXrT5MTF6^Xk>sKR`R@}c)HITBX`;<2q51K}mnN%sG$e5;W?>>^V-MIcV zB^;2M-^3J4=@kVL`3`cWw@tFT?CZz9eDU9Dn4s{#n4R>xhu;@FLojGNB`xGCQ2Z29 zHmrcktX(-q0w+`S)A*+uw;WzQ^dqV8&Cbi!Y^CsB3RFq1E2j{C#bTfjNCCSn0(0Q_ zj=;VT$T{{GC;sS^O-BgLGB5aieX}ClVT(07KoxDsuO(7uczDb@iCjfZ(Xx7xc98-y zTe0LfAU25C*2~uQQ1e<7QMH^?cQ)GGU6Z?nNCx70fz9XNb59(QIaG=bLn& zPPbz}%Xjd{U3_)iGPWJiPl$Rhebz4!^D7hAuK>KukI~;0fFJy>U0d(ksyCb-FVG8K z_yO48?|dc!a1kCe{qE=E#9iKkLj4wh=cL@Dbx1>+DNxsPUXBih&<>MXPQ2LLHYeUj z(?W8qp(ov47t*;byd}!m3`kNUOvyX}SMmf3iB5#GF?OE<+ca~srng=t)+d9C*;co3 zXZO0O=HvZ_9N*}auZ``#2i;M7G&f7|1@FBPfg#B%QF zuI0M!w;Y8x@Sx+&p7w;g8fVeiM65&4;ImrFs`5eWSwsauRdofSv@-*>YUqCDr< z+!h&lJ@B23-YJ&QALqy6I{1*0tbN#4hE~pc1XcBaA;T>w>=5drHrXtIvHx zH#Kd3mqBlh$ z(f!B*O>}Qm@M|0bX-Xxz008C;^5T2D-{#$d#12t}NqrqgRN&*{D>aer`&g>}G$UiT z8RDOT3FL4x!guOOHQ~5O--86^Tx4hAt@?}fuMM$JE~>c##~BjwDi#6L(6A&)jXpWvBTL}yC{r<64012npTe6!NUHGl;+vWA%^FO3 zXx+BFY?nf5?*_wLGeH{$UnGtZB5w^1>{Q9c+Lqhg70Tgea)O?>vQB(wJNp}25C)dlXn`z zRG1LRWhbV?m-7SqF#RcTu927Ia@1!HQw|obN21VDG%*h zUYhE4m#x&bS78~>rCkG!ifqNb`E76DGQB!C6P!98I<(@$#NPLBxaH=x?N$x&yIgfd zHx|Up+}tX#$Jho9$q+UNk6q}GAG?z&Y-76h^`%F0cr%9Y%b*4owjab^7c(nhaCq<* zqZp4FlVIPB@`BeNKxl%*%kKiG9o?ja6erqKubgICNU9#FT|B4!F%vtU0q9Y9v5h+q z61uDr&)%eJyd1)n2Ucg{K;H|O#GF7S1E1Z>9E^0XW6|!>w#1ERPU;aFkHA{L9$8W# zEF4)wDZN1W}B-o;56%2Q`v6UtQS7--t0{BMXmuQ|EdsWMOW^xAKE5&f_Wk64LuuTEs73DuRAJgT(dyb-#hDW^VT&E-U#GyyYpWtAe>hy29hOZI|vw# zV8%^%=Yw9~GD)j`9ir*jJw5RdH}PW`x(oZGie#7}RAuQeAy#H(=z2VJ-5c$E)Ixo` zOV5NS+hOhBG~5RI&9Y{%ChFAG*1_UY1$!gfYh88KKXum(aqsrwt2C^U0s$Dhr@UE> z0wN=+yHVTHc84FR2>Q}-12cCwy)m7GrPLt*$sf%*4#e$#9NLJLHdW~v&CIKPP*_?8 zwLy#hGZ?5BxJ2%S2LE{+dj6O&uAVdYO7Xmlk(PA9c5UKk#FBY7TQ`Xg{65kVN%YYXH2>auX3`4-9z>7V~Qt`3GDp2?!Igr;K5| z9=M+=gbbkLekXrI+fIg-lbG`hjpMTC=YFzR{u=*Gl44srTRcr0F2k>oS28(ofFI~G zKC@VuG;hGQ8^B3?EtW>d>BP63vTrdO>VbZk-pzf7q}2^*9<509v3#McASom-mI!{5I6h*sWSAT6CRrXsCvSLf&E zg0UmcE{IGG0jvhNJtoJ2-R&ULPB{O+N2CMs2+Tn)tN?d)u;pPUBm9r8%j^?r?8xd; zxQHbVPj|LR%c`LYP>b9xb1KxGFaYkhqdlh|`JmC{aGX6Pr~(;-ZZXIt<#bDxI#ZcV)^dcP^)2gjx|AG@jPUfs8a$n*R^&b9Ig}*ZN4JbO`wC=(6iOQlU71-gjV+KK_!&M zZ-(j*);{avF}bQ3-=vb{~t8AdT>*O+;2n^y zVYOYG=FH0%YdL&%=f`H%f(OD*^94v8bKjY>+NjBqDE7C>nd4wSD_RM}sss$f-BE8| zwbGmA)k*r;;vSJI#;N5Kuit6Y-ADthaT^^_2QPjxj`?&9y_l%4a$bHJA!+J^Q0y0m zLURgc3p~3*aZ;N7v@)!=z4eB`!_A-#9DqlGN1t~e$hHyF_Eol*wkMG$5gMLk*!PNj zfBffK5q!Ese--p!5$vqt1L7m;Ow*y%h)pjxz%L70y9>53b!Hwc+hSoVR`hA5?}&nH zaT3{(LIZlFpDH}cBEG9q#DCjy=;$gB!y8r}bILY(po4SaoDDiqM-s<3rO=RfZ7!b% z=3S(dtdzkmCDlZvUo~y7I~?fpp+fcYL7TT4Dw3uxA_)__K_YR_XL2vQaiWh~iDI{I zIa`}}KxLSiGkAC4@xl@Aam5(&5}RRBhhxB%4gJRw3s-AhMGyR}$nIC(qYzK`{iA4> z%BOvOfFF+dlAwhphmpH9`|%DIdb9i!(Dhh*#?;qeJC1in@O_|bWHu?e-RXGkAgNnQ z+B3h!jc%Q*K$~UnfRjEzfSAL?Uy6_EuIGv3J3yk|dD+inmT@F2fJE{{K#N=|{ale)Ga~-(&L+ zMGx7^U8FW2a!pFXX5|QDsWvo%ueciP>vHX63`CbjC_e!~XIT`K#62aY%f{Dttkr)W zJ5Dled`S7dQ?TC+M#jRXoy&C4WLqte~6u6Ad)yfgr0e9 z*@~*OD2ic-FJ|1RU$6gbQIfK+Vv!@=WOe0JCt8N2H^)_}mBNWpf;(*Am?L?>w}|>U z`wO&Ep%a&K;GSdSqU&D4yT#jhhnQ(|`s`9;;RDx-df;}+j<(h0uiqi>Lnzr74D-d; zjpI|D6iZlZs~s?~WGt&=j-_8L?fs6PD*jE`pL_9k8`8YeF|$>42rvMYe>boXC!ZpdrfYlqRg@p;unps0G z#DZ3b*G#hDMWFt{A;upSV)HKUiiOU}2*{HQGcCbwYQ@FH z#?Hu}eD%?D@RU@^xJ*fJcL*S^l&f@rXY|t|2{9!RqhY&q!3L2Y*T$AR5bBdudRfTC z#7?*V3`{w(uCPh38jFb;_du5zUj3rLu9(BmqU`6|zOsd^NQ_DQgUl}>JsQY&LCsJC z15i&H*n8snW2cr{e?6!@Y3lbmVn^)#zf{x=>b0~afG+-TQj-`@stdyA{a;)DO&E@i znCd%9qmA}$N3`>xo2O2MWHZ5=m(RVjM=)wP{+F|s0QYFL6sa^f7c4zz zBkmiw;wyi2rVZlL@QBC5 z_kcruI19@Jz;5AC&ZJoc@KPc=1G`#IZoklKT&h?4>#!~Q zU1@GjrX|M}iSq{Lmd0{MEjpe0eJ2}UMolDA8G%+09CH&m|aNgdrRzh z4E?7Ke_F3$SvDj0zu?9yfG1JyGHtHqZ!^DpBQWlaa|f|QC347pCl|*iA&Q3-1 zZ{Fd&+xSF5e}9@K?e$DF9#;)oHU3i44EoFnJii$iLmlQjwDpDT2EV$r*xw;1biV8} zpJR3xsOE(Kli*mUr)Fx@`sWL5J*6COorExP6vxH|+)E{>ev}2t4SbVMFk1ayp5*T9dr$Occv5M2 z;D^>uZ}7#V|J}fgfDg?6K81nsS_v`L)4XtaP2fW&_l8P1Qo;+ZhB*(lBVO@GyvqZk zxNX1bn`pAztB?kyuUZ4`0rNGl)EUd1&&i-l?$?(YF7>ASq|>B^@ybb?>?Y_j7C-2D zOwX#ll`r3_b4%F@{e{C^msFcFt#Q4{aVQmPq1mE-7IKrg=%XH8b(_`g1j{^2c0n9q z6W7_oK^mx{Wql!>VN5VYWNmD~`db}>{@f%3VOXAZZj{C4?L!I+h8fdvbF_#~l2K+7 zAZ<4ubAM5vG1sVP|0pSaYK7uw{59(a>c;XUL?%So@@C^;j3JiX-4S3E#u|MxHSg3) zn8a(Z<@FeRm%M*@d4IkcXU&L|up<%cbWCVQq#a92e4PrM3L638mrs;sv;FjmK=+J6 zv08&}j=!c=j{`QLBqO>waM=Jgo(>D~y#8`YF&?;|tjRRPjOee{O=P~BdlO{;lxB^c zAt2~C`w^GBSgrTWrLoR+T~c^}>y|p~&CM>!rVJ6)2K4N8>L{ReLaUGRv>*zFgv@Tr zfO*iA)n>-tfVMWeT?Y}b_}i}g_v%FwCY0RhaJY8+!f?OXHK*^4$)0s#uXr}VT{G4Q!Ed~gHr*k(KiQ~P*N1s4T)m;n70QDOYjcb&&zX!~d+P+5X zT(ugzM0zSfWbUs3Q_{3tnj-K5s}>>&X0YPOa}kzDJ^#w8o${(CEg$WbpNL(Z!Qq1) zn|8LG2Hqa0qn~}~@vkL5Zb8Ajo{EZmEP(mkDEXC5=7SA*d3aHQy`wb`EZolb?NKDx$Iu=z0@~wSlSDh_qrm`ve@4osnmgf!LF) zr&U--F+_#rv;fj6o6J1vJZ3z`mpKAW%?TDuxYNkyWkpLnR4^cSSN9tGwrUPo zhl{1h!OY*^qGbW2a}KU*&}>d&m1|o{w2m26EB=-Czi)eHNd+i%-0*E~S))E(18ZM& zH{8GJ2`+P2ZpnL_4GvuNhWIfhR)m!12*oMayT6YJ(KKyTrTy~POkz8dVoEh#?|s@> zxqkweF+2@)^RZ=LgO>JCIA~&I%jTnk)KBaooaBV~lf={O^y5x`d2~|OoVYsT($j;7 zrN_?&-luuSu!8e0oKIRJ6Hm{-+Pm=Sko{4AMY??coW;jipZ{vFO&WR{bZp*>(2#NfmmRa%cZB1GWAoj~d% zCE)Ws^_zg=DO+~Op9+tO(w9d)H=BsdRY=RLubM(iu&B_n4&F3L(q%L4_pa`LT zpga{2pQi9b#Js`%{B>&9ip2@qdK4PSgi6!d-Q9&f2GwRvx6||pjNX^CF5weXF)PPp z4?lar`jmO<>x1VqePYTVeZYGJp7|&S;c^j+Wpxn~b80G64(SvVDgfe#n9n{F@tFcp zd_dFM-%v(8ld-`h6jW+UH%DVb&qz0?1?Gfc~Y(Jbof-S7NUDc2L!CF8+s+SUsP}S z%wgsD~$zh*|`_t}U$?kT}Z_ zMsYMC)Nc|9y@rhUWv`I`8@4!CgpcCcZ&-}!FOU-%UAm7g=(FJ z43MJZsL;W_i7PZ%5;626`&FIB~`}$xzuvb68-HHC0cWi z{*lBs;VuWaG-&f0`{Rj%)jUN#)OhL0>SyoX^bFqL&^FIw7+VzZr}LQmNr_p>11fT@ z!$qq8$v1XEK{8+xvrkc*CJ>P`zD?__HxqBo_M)Rozj%KMk2iKyBfvGHGb)`Pxo3k@ z2j2Vn>oTBNsKwsks-A}0j&Oh!@FD}^#ETzRG2xW5a2P%kpX_ttUZ&5*2kFD@`532E zP9F_i{$MsVTR}T#6k;}4tJpDDQ@3$Oyh6${68}eFdh^v~&`LAnjzufZktv+zuIOqO zS7*PgwFUkBuAqqPbpW1kV!RfQG%0lsgXf1lY0|=?@jS~XCeQhpGRRod*|#^sVmoj_ z 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 - - Play - - {sourceSelectOptions.length && ( <> Animations From f1d80a2af3f0a3788b10223bbc02cc8e99c961d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davy=20H=C3=A9lard?= Date: Tue, 16 Jan 2024 10:15:45 +0100 Subject: [PATCH 76/80] Add a warning about the license. --- newIDE/app/src/ObjectEditor/Editors/SpineEditor.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 9825cf2a5ae1..041a2abc1677 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -305,6 +305,12 @@ const SpineEditor = ({ <> + + + You need to own a license of Spine to publish a game with a Spine + object. + + Date: Tue, 16 Jan 2024 10:31:47 +0100 Subject: [PATCH 77/80] Remove the opacity property. --- Extensions/Spine/JsExtension.js | 1 - Extensions/Spine/SpineObjectConfiguration.cpp | 16 ++-------------- Extensions/Spine/SpineObjectConfiguration.h | 1 - Extensions/Spine/spineruntimeobject.ts | 6 +----- .../app/src/ObjectEditor/Editors/SpineEditor.js | 6 +----- 5 files changed, 4 insertions(+), 26 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index deab1cab66f7..a98881711572 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -278,7 +278,6 @@ module.exports = { if (spine) { spine.width = width; spine.height = height; - spine.alpha = this._getProperties().get('opacity').getValue() / 255; const localBounds = spine.getLocalBounds(undefined, true); this._spineOriginOffsetX = localBounds.x * spine.scale.x; diff --git a/Extensions/Spine/SpineObjectConfiguration.cpp b/Extensions/Spine/SpineObjectConfiguration.cpp index cc4288c64aa8..57ca022c6cbe 100644 --- a/Extensions/Spine/SpineObjectConfiguration.cpp +++ b/Extensions/Spine/SpineObjectConfiguration.cpp @@ -21,17 +21,13 @@ using namespace std; SpineAnimation SpineObjectConfiguration::badAnimation; SpineObjectConfiguration::SpineObjectConfiguration() - : scale(1), opacity(255), spineResourceName("") {}; + : scale(1), spineResourceName("") {}; bool SpineObjectConfiguration::UpdateProperty(const gd::String &propertyName, const gd::String &newValue) { if (propertyName == "scale") { scale = newValue.To(); return true; } - if (propertyName == "opacity") { - opacity = newValue.To(); - return true; - } if (propertyName == "spineResourceName") { spineResourceName = newValue; return true; @@ -48,13 +44,7 @@ SpineObjectConfiguration::GetProperties() const { .SetValue(gd::String::From(scale)) .SetType("number") .SetLabel(_("Scale")) - .SetGroup(_("Appearance")); - - objectProperties["opacity"] - .SetValue(gd::String::From(opacity)) - .SetType("number") - .SetLabel(_("Opacity")) - .SetGroup(_("Appearance")); + .SetGroup(_("Default size")); objectProperties["spineResourceName"] .SetValue(spineResourceName) @@ -91,7 +81,6 @@ void SpineObjectConfiguration::DoUnserializeFrom(gd::Project &project, const gd: auto &content = element.GetChild("content"); scale = content.GetDoubleAttribute("scale"); - opacity = content.GetDoubleAttribute("opacity"); spineResourceName = content.GetStringAttribute("spineResourceName"); RemoveAllAnimations(); @@ -110,7 +99,6 @@ void SpineObjectConfiguration::DoUnserializeFrom(gd::Project &project, const gd: void SpineObjectConfiguration::DoSerializeTo(gd::SerializerElement &element) const { auto &content = element.AddChild("content"); content.SetAttribute("scale", scale); - content.SetAttribute("opacity", opacity); content.SetAttribute("spineResourceName", spineResourceName); auto &animationsElement = content.AddChild("animations"); diff --git a/Extensions/Spine/SpineObjectConfiguration.h b/Extensions/Spine/SpineObjectConfiguration.h index 1bf5179a1bbe..d60fcb9041f2 100644 --- a/Extensions/Spine/SpineObjectConfiguration.h +++ b/Extensions/Spine/SpineObjectConfiguration.h @@ -153,7 +153,6 @@ class GD_EXTENSION_API SpineObjectConfiguration : public gd::ObjectConfiguration private: double scale; - double opacity; gd::String spineResourceName; diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index ba54d4dfe309..7a00c6f24f08 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -19,7 +19,7 @@ namespace gdjs { gdjs.Scalable, gdjs.Animatable, gdjs.OpacityHandler { - private _opacity: float; + private _opacity: float = 255; private _scaleX: number = 1; private _scaleY: number = 1; _originalScale: number; @@ -47,7 +47,6 @@ namespace gdjs { super(instanceContainer, objectData); this._animations = objectData.content.animations; - this._opacity = objectData.content.opacity; this._originalScale = objectData.content.scale; this.spineResourceName = objectData.content.spineResourceName; this._animationMixingDuration = 0.1; @@ -84,9 +83,6 @@ namespace gdjs { ): boolean { super.updateFromObjectData(oldObjectData, newObjectData); - if (oldObjectData.content.opacity !== newObjectData.content.opacity) { - this.setOpacity(newObjectData.content.opacity); - } if (oldObjectData.content.scale !== newObjectData.content.scale) { this._originalScale = newObjectData.content.scale; } diff --git a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js index 041a2abc1677..cf4b89877dd4 100644 --- a/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/SpineEditor.js @@ -356,16 +356,12 @@ const SpineEditor = ({ ) : null} - Appearance + Default size - {sourceSelectOptions.length && ( <> Animations From 35cf1cfb8c8d3cd5f76891a1ecc5a1a733a3758f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davy=20H=C3=A9lard?= Date: Tue, 16 Jan 2024 10:40:29 +0100 Subject: [PATCH 78/80] Fix default size update on hot-reload. --- Extensions/Spine/spineruntimeobject.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index 7a00c6f24f08..de308ca63265 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -85,6 +85,8 @@ namespace gdjs { if (oldObjectData.content.scale !== newObjectData.content.scale) { this._originalScale = newObjectData.content.scale; + this._renderer.updateScale(); + this.invalidateHitboxes(); } return true; From c6d96ad697e96f47a7cb6f55c85554d19be84b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davy=20H=C3=A9lard?= Date: Tue, 16 Jan 2024 10:46:45 +0100 Subject: [PATCH 79/80] Update the hit-boxes while the animation plays. --- Extensions/Spine/spineruntimeobject.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Extensions/Spine/spineruntimeobject.ts b/Extensions/Spine/spineruntimeobject.ts index de308ca63265..a15c8862d59b 100644 --- a/Extensions/Spine/spineruntimeobject.ts +++ b/Extensions/Spine/spineruntimeobject.ts @@ -65,12 +65,14 @@ namespace gdjs { if (this._animationPaused) { if (this._isPausedFrameDirty) { this._renderer.updateAnimation(0); + this.invalidateHitboxes(); this._isPausedFrameDirty = false; } return; } const elapsedTime = this.getElapsedTime() / 1000; this._renderer.updateAnimation(elapsedTime * this._animationSpeedScale); + this.invalidateHitboxes(); } getRendererObject(): pixi_spine.Spine | PIXI.Container { From 15442f06ae19368cbf5920f251a6d78f480bac15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davy=20H=C3=A9lard?= Date: Wed, 17 Jan 2024 12:35:01 +0100 Subject: [PATCH 80/80] Remove deprecated actions. --- Extensions/Spine/JsExtension.js | 105 -------------------------------- 1 file changed, 105 deletions(-) diff --git a/Extensions/Spine/JsExtension.js b/Extensions/Spine/JsExtension.js index a98881711572..b4c654cdbd75 100644 --- a/Extensions/Spine/JsExtension.js +++ b/Extensions/Spine/JsExtension.js @@ -64,111 +64,6 @@ module.exports = { .addIncludeFile('Extensions/Spine/managers/pixi-spine-manager.js') .setCategoryFullName(_('Advanced')); - // TODO Remove before the release. - object - .addExpressionAndConditionAndAction( - 'number', - 'Opacity', - _('Opacity'), - _('the opacity, between 0 (fully transparent) and 255 (opaque)'), - _('the opacity'), - '', - 'res/conditions/opacity24.png' - ) - .setHidden() - .addParameter('object', _('Spine'), 'SpineObject', false) - .useStandardParameters( - 'number', - gd.ParameterOptions.makeNewOptions().setDescription( - _('Opacity (0-255)') - ) - ) - .setFunctionName('setOpacity') - .setGetter('getOpacity'); - - // TODO Remove before the release. - object - .addExpressionAndConditionAndAction( - 'number', - 'Scale', - _('Scale'), - _('the scale (1 by default)'), - _('the scale'), - '', - 'res/actions/scale24_black.png' - ) - .setHidden() - .addParameter('object', _('Spine'), 'SpineObject', false) - .useStandardParameters( - 'number', - gd.ParameterOptions.makeNewOptions().setDescription( - _('Scale (1 by default)') - ) - ) - .setFunctionName('setScale') - .setGetter('getScale'); - - // TODO Remove before the release. - object - .addCondition( - 'isAnimationComplete', - _('Animation complete'), - _( - 'Check if the animation being played by the Spine object is complete.' - ), - _('The animation of _PARAM0_ is complete'), - _('Animations and images'), - 'JsPlatform/Extensions/spine.svg', - 'JsPlatform/Extensions/spine.svg' - ) - .setHidden() - .addParameter('object', _('Spine'), 'SpineObject') - .markAsSimple() - .setFunctionName('hasAnimationEnded'); - - // TODO Remove before the release. - object - .addExpressionAndConditionAndAction( - 'number', - 'Animation', - _('Animation (by number)'), - _( - 'the number of the animation played by the object (the number from the animations list)' - ), - _('the number of the animation'), - _('Animations and images'), - 'JsPlatform/Extensions/spine.svg' - ) - .setHidden() - .addParameter('object', _('Spine'), 'SpineObject') - .useStandardParameters('number', gd.ParameterOptions.makeNewOptions()) - .addParameter('number', _('Mixing duration'), '', false) - .markAsSimple() - .setFunctionName('setAnimationIndex') - .setGetter('getAnimationIndex'); - - // TODO Remove before the release. - object - .addExpressionAndConditionAndAction( - 'string', - 'AnimationName', - _('Animation (by name)'), - _('the animation played by the object'), - _('the animation'), - _('Animations and images'), - 'JsPlatform/Extensions/spine.svg' - ) - .setHidden() - .addParameter('object', _('Spine'), 'SpineObject') - .useStandardParameters( - 'objectAnimationName', - gd.ParameterOptions.makeNewOptions().setDescription(_('Animation name')) - ) - .addParameter('number', _('Mixing duration'), '', false) - .markAsAdvanced() - .setFunctionName('setAnimationName') - .setGetter('getAnimationName'); - object .addExpressionAndConditionAndAction( 'number',