/******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ 4399:
/***/ ((module) => {

"use strict";


var has = Object.prototype.hasOwnProperty
  , prefix = '~';

/**
 * Constructor to create a storage for our `EE` objects.
 * An `Events` instance is a plain object whose properties are event names.
 *
 * @constructor
 * @private
 */
function Events() {}

//
// We try to not inherit from `Object.prototype`. In some engines creating an
// instance in this way is faster than calling `Object.create(null)` directly.
// If `Object.create(null)` is not supported we prefix the event names with a
// character to make sure that the built-in object properties are not
// overridden or used as an attack vector.
//
if (Object.create) {
  Events.prototype = Object.create(null);

  //
  // This hack is needed because the `__proto__` property is still inherited in
  // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
  //
  if (!new Events().__proto__) prefix = false;
}

/**
 * Representation of a single event listener.
 *
 * @param {Function} fn The listener function.
 * @param {*} context The context to invoke the listener with.
 * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
 * @constructor
 * @private
 */
function EE(fn, context, once) {
  this.fn = fn;
  this.context = context;
  this.once = once || false;
}

/**
 * Add a listener for a given event.
 *
 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn The listener function.
 * @param {*} context The context to invoke the listener with.
 * @param {Boolean} once Specify if the listener is a one-time listener.
 * @returns {EventEmitter}
 * @private
 */
function addListener(emitter, event, fn, context, once) {
  if (typeof fn !== 'function') {
    throw new TypeError('The listener must be a function');
  }

  var listener = new EE(fn, context || emitter, once)
    , evt = prefix ? prefix + event : event;

  if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
  else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
  else emitter._events[evt] = [emitter._events[evt], listener];

  return emitter;
}

/**
 * Clear event by name.
 *
 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
 * @param {(String|Symbol)} evt The Event name.
 * @private
 */
function clearEvent(emitter, evt) {
  if (--emitter._eventsCount === 0) emitter._events = new Events();
  else delete emitter._events[evt];
}

/**
 * Minimal `EventEmitter` interface that is molded against the Node.js
 * `EventEmitter` interface.
 *
 * @constructor
 * @public
 */
function EventEmitter() {
  this._events = new Events();
  this._eventsCount = 0;
}

/**
 * Return an array listing the events for which the emitter has registered
 * listeners.
 *
 * @returns {Array}
 * @public
 */
EventEmitter.prototype.eventNames = function eventNames() {
  var names = []
    , events
    , name;

  if (this._eventsCount === 0) return names;

  for (name in (events = this._events)) {
    if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
  }

  if (Object.getOwnPropertySymbols) {
    return names.concat(Object.getOwnPropertySymbols(events));
  }

  return names;
};

/**
 * Return the listeners registered for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @returns {Array} The registered listeners.
 * @public
 */
EventEmitter.prototype.listeners = function listeners(event) {
  var evt = prefix ? prefix + event : event
    , handlers = this._events[evt];

  if (!handlers) return [];
  if (handlers.fn) return [handlers.fn];

  for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
    ee[i] = handlers[i].fn;
  }

  return ee;
};

/**
 * Return the number of listeners listening to a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @returns {Number} The number of listeners.
 * @public
 */
EventEmitter.prototype.listenerCount = function listenerCount(event) {
  var evt = prefix ? prefix + event : event
    , listeners = this._events[evt];

  if (!listeners) return 0;
  if (listeners.fn) return 1;
  return listeners.length;
};

/**
 * Calls each of the listeners registered for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @returns {Boolean} `true` if the event had listeners, else `false`.
 * @public
 */
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
  var evt = prefix ? prefix + event : event;

  if (!this._events[evt]) return false;

  var listeners = this._events[evt]
    , len = arguments.length
    , args
    , i;

  if (listeners.fn) {
    if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);

    switch (len) {
      case 1: return listeners.fn.call(listeners.context), true;
      case 2: return listeners.fn.call(listeners.context, a1), true;
      case 3: return listeners.fn.call(listeners.context, a1, a2), true;
      case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
      case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
      case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
    }

    for (i = 1, args = new Array(len -1); i < len; i++) {
      args[i - 1] = arguments[i];
    }

    listeners.fn.apply(listeners.context, args);
  } else {
    var length = listeners.length
      , j;

    for (i = 0; i < length; i++) {
      if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);

      switch (len) {
        case 1: listeners[i].fn.call(listeners[i].context); break;
        case 2: listeners[i].fn.call(listeners[i].context, a1); break;
        case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
        case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
        default:
          if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
            args[j - 1] = arguments[j];
          }

          listeners[i].fn.apply(listeners[i].context, args);
      }
    }
  }

  return true;
};

/**
 * Add a listener for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn The listener function.
 * @param {*} [context=this] The context to invoke the listener with.
 * @returns {EventEmitter} `this`.
 * @public
 */
EventEmitter.prototype.on = function on(event, fn, context) {
  return addListener(this, event, fn, context, false);
};

/**
 * Add a one-time listener for a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn The listener function.
 * @param {*} [context=this] The context to invoke the listener with.
 * @returns {EventEmitter} `this`.
 * @public
 */
EventEmitter.prototype.once = function once(event, fn, context) {
  return addListener(this, event, fn, context, true);
};

/**
 * Remove the listeners of a given event.
 *
 * @param {(String|Symbol)} event The event name.
 * @param {Function} fn Only remove the listeners that match this function.
 * @param {*} context Only remove the listeners that have this context.
 * @param {Boolean} once Only remove one-time listeners.
 * @returns {EventEmitter} `this`.
 * @public
 */
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
  var evt = prefix ? prefix + event : event;

  if (!this._events[evt]) return this;
  if (!fn) {
    clearEvent(this, evt);
    return this;
  }

  var listeners = this._events[evt];

  if (listeners.fn) {
    if (
      listeners.fn === fn &&
      (!once || listeners.once) &&
      (!context || listeners.context === context)
    ) {
      clearEvent(this, evt);
    }
  } else {
    for (var i = 0, events = [], length = listeners.length; i < length; i++) {
      if (
        listeners[i].fn !== fn ||
        (once && !listeners[i].once) ||
        (context && listeners[i].context !== context)
      ) {
        events.push(listeners[i]);
      }
    }

    //
    // Reset the array, or remove it completely if we have no more listeners.
    //
    if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
    else clearEvent(this, evt);
  }

  return this;
};

/**
 * Remove all listeners, or those of the specified event.
 *
 * @param {(String|Symbol)} [event] The event name.
 * @returns {EventEmitter} `this`.
 * @public
 */
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
  var evt;

  if (event) {
    evt = prefix ? prefix + event : event;
    if (this._events[evt]) clearEvent(this, evt);
  } else {
    this._events = new Events();
    this._eventsCount = 0;
  }

  return this;
};

//
// Alias methods names because people roll like that.
//
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.addListener = EventEmitter.prototype.on;

//
// Expose the prefix.
//
EventEmitter.prefixed = prefix;

//
// Allow `EventEmitter` to be imported as module namespace.
//
EventEmitter.EventEmitter = EventEmitter;

//
// Expose the module.
//
if (true) {
  module.exports = EventEmitter;
}


/***/ }),

/***/ 1847:
/***/ ((module) => {

/*** IMPORTS FROM imports-loader ***/

(function() {
var __extends = (this && this.__extends) || (function () {
    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);
    };
    return function (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 __());
    };
})();
var spine;
(function (spine) {
    var Animation = (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;
        };
        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;
    }());
    spine.Animation = Animation;
    var MixBlend;
    (function (MixBlend) {
        MixBlend[MixBlend["setup"] = 0] = "setup";
        MixBlend[MixBlend["first"] = 1] = "first";
        MixBlend[MixBlend["replace"] = 2] = "replace";
        MixBlend[MixBlend["add"] = 3] = "add";
    })(MixBlend = spine.MixBlend || (spine.MixBlend = {}));
    var MixDirection;
    (function (MixDirection) {
        MixDirection[MixDirection["mixIn"] = 0] = "mixIn";
        MixDirection[MixDirection["mixOut"] = 1] = "mixOut";
    })(MixDirection = spine.MixDirection || (spine.MixDirection = {}));
    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 = spine.TimelineType || (spine.TimelineType = {}));
    var CurveTimeline = (function () {
        function CurveTimeline(frameCount) {
            if (frameCount <= 0)
                throw new Error("frameCount must be > 0: " + frameCount);
            this.curves = spine.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;
        };
        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 = spine.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);
        };
        CurveTimeline.LINEAR = 0;
        CurveTimeline.STEPPED = 1;
        CurveTimeline.BEZIER = 2;
        CurveTimeline.BEZIER_SIZE = 10 * 2 - 1;
        return CurveTimeline;
    }());
    spine.CurveTimeline = CurveTimeline;
    var RotateTimeline = (function (_super) {
        __extends(RotateTimeline, _super);
        function RotateTimeline(frameCount) {
            var _this = _super.call(this, frameCount) || this;
            _this.frames = spine.Utils.newFloatArray(frameCount << 1);
            return _this;
        }
        RotateTimeline.prototype.getPropertyId = function () {
            return (TimelineType.rotate << 24) + this.boneIndex;
        };
        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 MixBlend.setup:
                        bone.rotation = bone.data.rotation;
                        return;
                    case 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]) {
                var r_2 = frames[frames.length + RotateTimeline.PREV_ROTATION];
                switch (blend) {
                    case MixBlend.setup:
                        bone.rotation = bone.data.rotation + r_2 * alpha;
                        break;
                    case MixBlend.first:
                    case MixBlend.replace:
                        r_2 += bone.data.rotation - bone.rotation;
                        r_2 -= (16384 - ((16384.499999999996 - r_2 / 360) | 0)) * 360;
                    case MixBlend.add:
                        bone.rotation += r_2 * alpha;
                }
                return;
            }
            var frame = Animation.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 MixBlend.setup:
                    bone.rotation = bone.data.rotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha;
                    break;
                case MixBlend.first:
                case MixBlend.replace:
                    r += bone.data.rotation - bone.rotation;
                case 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));
    spine.RotateTimeline = RotateTimeline;
    var TranslateTimeline = (function (_super) {
        __extends(TranslateTimeline, _super);
        function TranslateTimeline(frameCount) {
            var _this = _super.call(this, frameCount) || this;
            _this.frames = spine.Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES);
            return _this;
        }
        TranslateTimeline.prototype.getPropertyId = function () {
            return (TimelineType.translate << 24) + this.boneIndex;
        };
        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 MixBlend.setup:
                        bone.x = bone.data.x;
                        bone.y = bone.data.y;
                        return;
                    case 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]) {
                x = frames[frames.length + TranslateTimeline.PREV_X];
                y = frames[frames.length + TranslateTimeline.PREV_Y];
            }
            else {
                var frame = Animation.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 MixBlend.setup:
                    bone.x = bone.data.x + x * alpha;
                    bone.y = bone.data.y + y * alpha;
                    break;
                case MixBlend.first:
                case MixBlend.replace:
                    bone.x += (bone.data.x + x - bone.x) * alpha;
                    bone.y += (bone.data.y + y - bone.y) * alpha;
                    break;
                case 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));
    spine.TranslateTimeline = TranslateTimeline;
    var ScaleTimeline = (function (_super) {
        __extends(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 (!bone.active)
                return;
            if (time < frames[0]) {
                switch (blend) {
                    case MixBlend.setup:
                        bone.scaleX = bone.data.scaleX;
                        bone.scaleY = bone.data.scaleY;
                        return;
                    case 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]) {
                x = frames[frames.length + ScaleTimeline.PREV_X] * bone.data.scaleX;
                y = frames[frames.length + ScaleTimeline.PREV_Y] * bone.data.scaleY;
            }
            else {
                var frame = Animation.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 == 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 == MixDirection.mixOut) {
                    switch (blend) {
                        case MixBlend.setup:
                            bx = bone.data.scaleX;
                            by = bone.data.scaleY;
                            bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bx) * alpha;
                            bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - by) * alpha;
                            break;
                        case MixBlend.first:
                        case MixBlend.replace:
                            bx = bone.scaleX;
                            by = bone.scaleY;
                            bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bx) * alpha;
                            bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - by) * alpha;
                            break;
                        case MixBlend.add:
                            bx = bone.scaleX;
                            by = bone.scaleY;
                            bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bone.data.scaleX) * alpha;
                            bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - bone.data.scaleY) * alpha;
                    }
                }
                else {
                    switch (blend) {
                        case MixBlend.setup:
                            bx = Math.abs(bone.data.scaleX) * spine.MathUtils.signum(x);
                            by = Math.abs(bone.data.scaleY) * spine.MathUtils.signum(y);
                            bone.scaleX = bx + (x - bx) * alpha;
                            bone.scaleY = by + (y - by) * alpha;
                            break;
                        case MixBlend.first:
                        case MixBlend.replace:
                            bx = Math.abs(bone.scaleX) * spine.MathUtils.signum(x);
                            by = Math.abs(bone.scaleY) * spine.MathUtils.signum(y);
                            bone.scaleX = bx + (x - bx) * alpha;
                            bone.scaleY = by + (y - by) * alpha;
                            break;
                        case MixBlend.add:
                            bx = spine.MathUtils.signum(x);
                            by = spine.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));
    spine.ScaleTimeline = ScaleTimeline;
    var ShearTimeline = (function (_super) {
        __extends(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 (!bone.active)
                return;
            if (time < frames[0]) {
                switch (blend) {
                    case MixBlend.setup:
                        bone.shearX = bone.data.shearX;
                        bone.shearY = bone.data.shearY;
                        return;
                    case 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]) {
                x = frames[frames.length + ShearTimeline.PREV_X];
                y = frames[frames.length + ShearTimeline.PREV_Y];
            }
            else {
                var frame = Animation.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 MixBlend.setup:
                    bone.shearX = bone.data.shearX + x * alpha;
                    bone.shearY = bone.data.shearY + y * alpha;
                    break;
                case MixBlend.first:
                case MixBlend.replace:
                    bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha;
                    bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha;
                    break;
                case MixBlend.add:
                    bone.shearX += x * alpha;
                    bone.shearY += y * alpha;
            }
        };
        return ShearTimeline;
    }(TranslateTimeline));
    spine.ShearTimeline = ShearTimeline;
    var ColorTimeline = (function (_super) {
        __extends(ColorTimeline, _super);
        function ColorTimeline(frameCount) {
            var _this = _super.call(this, frameCount) || this;
            _this.frames = spine.Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES);
            return _this;
        }
        ColorTimeline.prototype.getPropertyId = function () {
            return (TimelineType.color << 24) + this.slotIndex;
        };
        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 MixBlend.setup:
                        slot.color.setFromColor(slot.data.color);
                        return;
                    case 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]) {
                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 {
                var frame = Animation.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 == 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));
    spine.ColorTimeline = ColorTimeline;
    var TwoColorTimeline = (function (_super) {
        __extends(TwoColorTimeline, _super);
        function TwoColorTimeline(frameCount) {
            var _this = _super.call(this, frameCount) || this;
            _this.frames = spine.Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES);
            return _this;
        }
        TwoColorTimeline.prototype.getPropertyId = function () {
            return (TimelineType.twoColor << 24) + this.slotIndex;
        };
        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 MixBlend.setup:
                        slot.color.setFromColor(slot.data.color);
                        slot.darkColor.setFromColor(slot.data.darkColor);
                        return;
                    case 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]) {
                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 {
                var frame = Animation.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 == 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));
    spine.TwoColorTimeline = TwoColorTimeline;
    var AttachmentTimeline = (function () {
        function AttachmentTimeline(frameCount) {
            this.frames = spine.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;
        };
        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 == MixDirection.mixOut) {
                if (blend == MixBlend.setup)
                    this.setAttachment(skeleton, slot, slot.data.attachmentName);
                return;
            }
            var frames = this.frames;
            if (time < frames[0]) {
                if (blend == MixBlend.setup || blend == MixBlend.first)
                    this.setAttachment(skeleton, slot, slot.data.attachmentName);
                return;
            }
            var frameIndex = 0;
            if (time >= frames[frames.length - 1])
                frameIndex = frames.length - 1;
            else
                frameIndex = Animation.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;
    }());
    spine.AttachmentTimeline = AttachmentTimeline;
    var zeros = null;
    var DeformTimeline = (function (_super) {
        __extends(DeformTimeline, _super);
        function DeformTimeline(frameCount) {
            var _this = _super.call(this, frameCount) || this;
            _this.frames = spine.Utils.newFloatArray(frameCount);
            _this.frameVertices = new Array(frameCount);
            if (zeros == null)
                zeros = spine.Utils.newFloatArray(64);
            return _this;
        }
        DeformTimeline.prototype.getPropertyId = function () {
            return (TimelineType.deform << 27) + +this.attachment.id + this.slotIndex;
        };
        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 spine.VertexAttachment) || !(slotAttachment.deformAttachment == this.attachment))
                return;
            var deformArray = slot.deform;
            if (deformArray.length == 0)
                blend = 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 MixBlend.setup:
                        deformArray.length = 0;
                        return;
                    case MixBlend.first:
                        if (alpha == 1) {
                            deformArray.length = 0;
                            break;
                        }
                        var deform_1 = spine.Utils.setArraySize(deformArray, vertexCount);
                        if (vertexAttachment.bones == null) {
                            var setupVertices = vertexAttachment.vertices;
                            for (var i = 0; i < vertexCount; i++)
                                deform_1[i] += (setupVertices[i] - deform_1[i]) * alpha;
                        }
                        else {
                            alpha = 1 - alpha;
                            for (var i = 0; i < vertexCount; i++)
                                deform_1[i] *= alpha;
                        }
                }
                return;
            }
            var deform = spine.Utils.setArraySize(deformArray, vertexCount);
            if (time >= frames[frames.length - 1]) {
                var lastVertices = frameVertices[frames.length - 1];
                if (alpha == 1) {
                    if (blend == MixBlend.add) {
                        var vertexAttachment = slotAttachment;
                        if (vertexAttachment.bones == null) {
                            var setupVertices = vertexAttachment.vertices;
                            for (var i_1 = 0; i_1 < vertexCount; i_1++) {
                                deform[i_1] += lastVertices[i_1] - setupVertices[i_1];
                            }
                        }
                        else {
                            for (var i_2 = 0; i_2 < vertexCount; i_2++)
                                deform[i_2] += lastVertices[i_2];
                        }
                    }
                    else {
                        spine.Utils.arrayCopy(lastVertices, 0, deform, 0, vertexCount);
                    }
                }
                else {
                    switch (blend) {
                        case MixBlend.setup: {
                            var vertexAttachment_1 = slotAttachment;
                            if (vertexAttachment_1.bones == null) {
                                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 {
                                for (var i_4 = 0; i_4 < vertexCount; i_4++)
                                    deform[i_4] = lastVertices[i_4] * alpha;
                            }
                            break;
                        }
                        case MixBlend.first:
                        case MixBlend.replace:
                            for (var i_5 = 0; i_5 < vertexCount; i_5++)
                                deform[i_5] += (lastVertices[i_5] - deform[i_5]) * alpha;
                            break;
                        case MixBlend.add:
                            var vertexAttachment = slotAttachment;
                            if (vertexAttachment.bones == null) {
                                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 {
                                for (var i_7 = 0; i_7 < vertexCount; i_7++)
                                    deform[i_7] += lastVertices[i_7] * alpha;
                            }
                    }
                }
                return;
            }
            var frame = Animation.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 == MixBlend.add) {
                    var vertexAttachment = slotAttachment;
                    if (vertexAttachment.bones == null) {
                        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 {
                        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 MixBlend.setup: {
                        var vertexAttachment_2 = slotAttachment;
                        if (vertexAttachment_2.bones == null) {
                            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 {
                            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 MixBlend.first:
                    case 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 MixBlend.add:
                        var vertexAttachment = slotAttachment;
                        if (vertexAttachment.bones == null) {
                            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 {
                            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));
    spine.DeformTimeline = DeformTimeline;
    var EventTimeline = (function () {
        function EventTimeline(frameCount) {
            this.frames = spine.Utils.newFloatArray(frameCount);
            this.events = new Array(frameCount);
        }
        EventTimeline.prototype.getPropertyId = function () {
            return TimelineType.event << 24;
        };
        EventTimeline.prototype.getFrameCount = function () {
            return this.frames.length;
        };
        EventTimeline.prototype.setFrame = function (frameIndex, event) {
            this.frames[frameIndex] = event.time;
            this.events[frameIndex] = event;
        };
        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) {
                this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction);
                lastTime = -1;
            }
            else if (lastTime >= frames[frameCount - 1])
                return;
            if (time < frames[0])
                return;
            var frame = 0;
            if (lastTime < frames[0])
                frame = 0;
            else {
                frame = Animation.binarySearch(frames, lastTime);
                var frameTime = frames[frame];
                while (frame > 0) {
                    if (frames[frame - 1] != frameTime)
                        break;
                    frame--;
                }
            }
            for (; frame < frameCount && time >= frames[frame]; frame++)
                firedEvents.push(this.events[frame]);
        };
        return EventTimeline;
    }());
    spine.EventTimeline = EventTimeline;
    var DrawOrderTimeline = (function () {
        function DrawOrderTimeline(frameCount) {
            this.frames = spine.Utils.newFloatArray(frameCount);
            this.drawOrders = new Array(frameCount);
        }
        DrawOrderTimeline.prototype.getPropertyId = function () {
            return TimelineType.drawOrder << 24;
        };
        DrawOrderTimeline.prototype.getFrameCount = function () {
            return this.frames.length;
        };
        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 == MixDirection.mixOut) {
                if (blend == MixBlend.setup)
                    spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
                return;
            }
            var frames = this.frames;
            if (time < frames[0]) {
                if (blend == MixBlend.setup || blend == MixBlend.first)
                    spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
                return;
            }
            var frame = 0;
            if (time >= frames[frames.length - 1])
                frame = frames.length - 1;
            else
                frame = Animation.binarySearch(frames, time) - 1;
            var drawOrderToSetupIndex = this.drawOrders[frame];
            if (drawOrderToSetupIndex == null)
                spine.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;
    }());
    spine.DrawOrderTimeline = DrawOrderTimeline;
    var IkConstraintTimeline = (function (_super) {
        __extends(IkConstraintTimeline, _super);
        function IkConstraintTimeline(frameCount) {
            var _this = _super.call(this, frameCount) || this;
            _this.frames = spine.Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES);
            return _this;
        }
        IkConstraintTimeline.prototype.getPropertyId = function () {
            return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
        };
        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 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 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]) {
                if (blend == 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 == 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 == 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;
            }
            var frame = Animation.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 == 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 == 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 == 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));
    spine.IkConstraintTimeline = IkConstraintTimeline;
    var TransformConstraintTimeline = (function (_super) {
        __extends(TransformConstraintTimeline, _super);
        function TransformConstraintTimeline(frameCount) {
            var _this = _super.call(this, frameCount) || this;
            _this.frames = spine.Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES);
            return _this;
        }
        TransformConstraintTimeline.prototype.getPropertyId = function () {
            return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex;
        };
        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 MixBlend.setup:
                        constraint.rotateMix = data.rotateMix;
                        constraint.translateMix = data.translateMix;
                        constraint.scaleMix = data.scaleMix;
                        constraint.shearMix = data.shearMix;
                        return;
                    case 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]) {
                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 {
                var frame = Animation.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 == 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));
    spine.TransformConstraintTimeline = TransformConstraintTimeline;
    var PathConstraintPositionTimeline = (function (_super) {
        __extends(PathConstraintPositionTimeline, _super);
        function PathConstraintPositionTimeline(frameCount) {
            var _this = _super.call(this, frameCount) || this;
            _this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES);
            return _this;
        }
        PathConstraintPositionTimeline.prototype.getPropertyId = function () {
            return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex;
        };
        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 MixBlend.setup:
                        constraint.position = constraint.data.position;
                        return;
                    case MixBlend.first:
                        constraint.position += (constraint.data.position - constraint.position) * alpha;
                }
                return;
            }
            var position = 0;
            if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES])
                position = frames[frames.length + PathConstraintPositionTimeline.PREV_VALUE];
            else {
                var frame = Animation.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 == 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));
    spine.PathConstraintPositionTimeline = PathConstraintPositionTimeline;
    var PathConstraintSpacingTimeline = (function (_super) {
        __extends(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 (!constraint.active)
                return;
            if (time < frames[0]) {
                switch (blend) {
                    case MixBlend.setup:
                        constraint.spacing = constraint.data.spacing;
                        return;
                    case MixBlend.first:
                        constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha;
                }
                return;
            }
            var spacing = 0;
            if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES])
                spacing = frames[frames.length + PathConstraintSpacingTimeline.PREV_VALUE];
            else {
                var frame = Animation.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 == MixBlend.setup)
                constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha;
            else
                constraint.spacing += (spacing - constraint.spacing) * alpha;
        };
        return PathConstraintSpacingTimeline;
    }(PathConstraintPositionTimeline));
    spine.PathConstraintSpacingTimeline = PathConstraintSpacingTimeline;
    var PathConstraintMixTimeline = (function (_super) {
        __extends(PathConstraintMixTimeline, _super);
        function PathConstraintMixTimeline(frameCount) {
            var _this = _super.call(this, frameCount) || this;
            _this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES);
            return _this;
        }
        PathConstraintMixTimeline.prototype.getPropertyId = function () {
            return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex;
        };
        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 MixBlend.setup:
                        constraint.rotateMix = constraint.data.rotateMix;
                        constraint.translateMix = constraint.data.translateMix;
                        return;
                    case 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]) {
                rotate = frames[frames.length + PathConstraintMixTimeline.PREV_ROTATE];
                translate = frames[frames.length + PathConstraintMixTimeline.PREV_TRANSLATE];
            }
            else {
                var frame = Animation.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 == 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));
    spine.PathConstraintMixTimeline = PathConstraintMixTimeline;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var AnimationState = (function () {
        function AnimationState(data) {
            this.tracks = new Array();
            this.timeScale = 1;
            this.unkeyedState = 0;
            this.events = new Array();
            this.listeners = new Array();
            this.queue = new EventQueue(this);
            this.propertyIDs = new spine.IntSet();
            this.animationsChanged = false;
            this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
            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) {
                    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)) {
                    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;
            if (to.mixTime > 0 && to.mixTime >= to.mixDuration) {
                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_16 = 0, n_1 = tracks.length; i_16 < n_1; i_16++) {
                var current = tracks[i_16];
                if (current == null || current.delay > 0)
                    continue;
                applied = true;
                var blend = i_16 == 0 ? spine.MixBlend.first : current.mixBlend;
                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;
                var animationLast = current.animationLast, animationTime = current.getAnimationTime();
                var timelineCount = current.animation.timelines.length;
                var timelines = current.animation.timelines;
                if ((i_16 == 0 && mix == 1) || blend == spine.MixBlend.add) {
                    for (var ii = 0; ii < timelineCount; ii++) {
                        spine.Utils.webkit602BugfixHelper(mix, blend);
                        var timeline = timelines[ii];
                        if (timeline instanceof spine.AttachmentTimeline)
                            this.applyAttachmentTimeline(timeline, skeleton, animationTime, blend, true);
                        else
                            timeline.apply(skeleton, animationLast, animationTime, events, mix, blend, spine.MixDirection.mixIn);
                    }
                }
                else {
                    var timelineMode = current.timelineMode;
                    var firstFrame = current.timelinesRotation.length == 0;
                    if (firstFrame)
                        spine.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 : spine.MixBlend.setup;
                        if (timeline_1 instanceof spine.RotateTimeline) {
                            this.applyRotateTimeline(timeline_1, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
                        }
                        else if (timeline_1 instanceof spine.AttachmentTimeline) {
                            this.applyAttachmentTimeline(timeline_1, skeleton, animationTime, blend, true);
                        }
                        else {
                            spine.Utils.webkit602BugfixHelper(mix, blend);
                            timeline_1.apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, spine.MixDirection.mixIn);
                        }
                    }
                }
                this.queueEvents(current, animationTime);
                events.length = 0;
                current.nextAnimationLast = animationTime;
                current.nextTrackLast = current.trackTime;
            }
            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;
            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) {
                mix = 1;
                if (blend == spine.MixBlend.first)
                    blend = spine.MixBlend.setup;
            }
            else {
                mix = to.mixTime / to.mixDuration;
                if (mix > 1)
                    mix = 1;
                if (blend != spine.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 == spine.MixBlend.add) {
                for (var i = 0; i < timelineCount; i++)
                    timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, spine.MixDirection.mixOut);
            }
            else {
                var timelineMode = from.timelineMode;
                var timelineHoldMix = from.timelineHoldMix;
                var firstFrame = from.timelinesRotation.length == 0;
                if (firstFrame)
                    spine.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 = spine.MixDirection.mixOut;
                    var timelineBlend = void 0;
                    var alpha = 0;
                    switch (timelineMode[i]) {
                        case AnimationState.SUBSEQUENT:
                            if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
                                continue;
                            timelineBlend = blend;
                            alpha = alphaMix;
                            break;
                        case AnimationState.FIRST:
                            timelineBlend = spine.MixBlend.setup;
                            alpha = alphaMix;
                            break;
                        case AnimationState.HOLD_SUBSEQUENT:
                            timelineBlend = blend;
                            alpha = alphaHold;
                            break;
                        case AnimationState.HOLD_FIRST:
                            timelineBlend = spine.MixBlend.setup;
                            alpha = alphaHold;
                            break;
                        default:
                            timelineBlend = spine.MixBlend.setup;
                            var holdMix = timelineHoldMix[i];
                            alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
                            break;
                    }
                    from.totalAlpha += alpha;
                    if (timeline instanceof spine.RotateTimeline)
                        this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame);
                    else if (timeline instanceof spine.AttachmentTimeline)
                        this.applyAttachmentTimeline(timeline, skeleton, animationTime, timelineBlend, attachments);
                    else {
                        spine.Utils.webkit602BugfixHelper(alpha, blend);
                        if (drawOrder && timeline instanceof spine.DrawOrderTimeline && timelineBlend == spine.MixBlend.setup)
                            direction = spine.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]) {
                if (blend == spine.MixBlend.setup || blend == spine.MixBlend.first)
                    this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments);
            }
            else {
                var frameIndex;
                if (time >= frames[frames.length - 1])
                    frameIndex = frames.length - 1;
                else
                    frameIndex = spine.Animation.binarySearch(frames, time) - 1;
                this.setAttachment(skeleton, slot, timeline.attachmentNames[frameIndex], attachments);
            }
            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, spine.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 spine.MixBlend.setup:
                        bone.rotation = bone.data.rotation;
                    default:
                        return;
                    case spine.MixBlend.first:
                        r1 = bone.rotation;
                        r2 = bone.data.rotation;
                }
            }
            else {
                r1 = blend == spine.MixBlend.setup ? bone.data.rotation : bone.rotation;
                if (time >= frames[frames.length - spine.RotateTimeline.ENTRIES])
                    r2 = bone.data.rotation + frames[frames.length + spine.RotateTimeline.PREV_ROTATION];
                else {
                    var frame = spine.Animation.binarySearch(frames, time, spine.RotateTimeline.ENTRIES);
                    var prevRotation = frames[frame + spine.RotateTimeline.PREV_ROTATION];
                    var frameTime = frames[frame];
                    var percent = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + spine.RotateTimeline.PREV_TIME] - frameTime));
                    r2 = frames[frame + spine.RotateTimeline.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;
                }
            }
            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];
                    lastDiff = timelinesRotation[i + 1];
                }
                var current = diff > 0, dir = lastTotal >= 0;
                if (spine.MathUtils.signum(lastDiff) != spine.MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) {
                    if (Math.abs(lastTotal) > 180)
                        lastTotal += 360 * spine.MathUtils.signum(lastTotal);
                    dir = current;
                }
                total = diff + lastTotal - lastTotal % 360;
                if (dir != current)
                    total += 360 * spine.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;
            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;
                this.queue.event(entry, event_1);
            }
            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);
            for (; i < n; i++) {
                var event_2 = events[i];
                if (event_2.time < animationStart)
                    continue;
                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;
                if (from.mixingFrom != null && from.mixDuration > 0)
                    current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
                from.timelinesRotation.length = 0;
            }
            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) {
                    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];
            spine.Utils.ensureArrayCapacity(this.tracks, index + 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);
            entry.mixBlend = spine.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 != spine.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 = spine.Utils.setArraySize(entry.timelineMode, timelinesCount);
            entry.timelineHoldMix.length = 0;
            var timelineDipMix = spine.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 spine.AttachmentTimeline || timeline instanceof spine.DrawOrderTimeline
                    || timeline instanceof spine.EventTimeline || !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;
                }
            }
        };
        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);
        };
        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.emptyAnimation = new spine.Animation("<empty>", [], 0);
        AnimationState.SUBSEQUENT = 0;
        AnimationState.FIRST = 1;
        AnimationState.HOLD_SUBSEQUENT = 2;
        AnimationState.HOLD_FIRST = 3;
        AnimationState.HOLD_MIX = 4;
        AnimationState.SETUP = 1;
        AnimationState.CURRENT = 2;
        return AnimationState;
    }());
    spine.AnimationState = AnimationState;
    var TrackEntry = (function () {
        function TrackEntry() {
            this.mixBlend = spine.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;
        };
        return TrackEntry;
    }());
    spine.TrackEntry = TrackEntry;
    var EventQueue = (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 != null && entry.listener.start)
                            entry.listener.start(entry);
                        for (var ii = 0; ii < listeners.length; ii++)
                            if (listeners[ii].start)
                                listeners[ii].start(entry);
                        break;
                    case EventType.interrupt:
                        if (entry.listener != null && entry.listener.interrupt)
                            entry.listener.interrupt(entry);
                        for (var ii = 0; ii < listeners.length; ii++)
                            if (listeners[ii].interrupt)
                                listeners[ii].interrupt(entry);
                        break;
                    case EventType.end:
                        if (entry.listener != null && entry.listener.end)
                            entry.listener.end(entry);
                        for (var ii = 0; ii < listeners.length; ii++)
                            if (listeners[ii].end)
                                listeners[ii].end(entry);
                    case EventType.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.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);
                        break;
                    case EventType.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);
                        break;
                }
            }
            this.clear();
            this.drainDisabled = false;
        };
        EventQueue.prototype.clear = function () {
            this.objects.length = 0;
        };
        return EventQueue;
    }());
    spine.EventQueue = EventQueue;
    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 = spine.EventType || (spine.EventType = {}));
    var AnimationStateAdapter = (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;
    }());
    spine.AnimationStateAdapter = AnimationStateAdapter;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var AnimationStateData = (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.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;
        };
        return AnimationStateData;
    }());
    spine.AnimationStateData = AnimationStateData;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var AssetManager = (function () {
        function AssetManager(textureLoader, pathPrefix) {
            if (pathPrefix === void 0) { pathPrefix = ""; }
            this.assets = {};
            this.errors = {};
            this.toLoad = 0;
            this.loaded = 0;
            this.rawDataUris = {};
            this.textureLoader = textureLoader;
            this.pathPrefix = pathPrefix;
        }
        AssetManager.prototype.downloadText = function (url, success, error) {
            var request = new XMLHttpRequest();
            request.overrideMimeType("text/html");
            if (this.rawDataUris[url])
                url = this.rawDataUris[url];
            request.open("GET", url, true);
            request.onload = function () {
                if (request.status == 200) {
                    success(request.responseText);
                }
                else {
                    error(request.status, request.responseText);
                }
            };
            request.onerror = function () {
                error(request.status, request.responseText);
            };
            request.send();
        };
        AssetManager.prototype.downloadBinary = function (url, success, error) {
            var request = new XMLHttpRequest();
            if (this.rawDataUris[url])
                url = this.rawDataUris[url];
            request.open("GET", url, true);
            request.responseType = "arraybuffer";
            request.onload = function () {
                if (request.status == 200) {
                    success(new Uint8Array(request.response));
                }
                else {
                    error(request.status, request.responseText);
                }
            };
            request.onerror = function () {
                error(request.status, request.responseText);
            };
            request.send();
        };
        AssetManager.prototype.setRawDataURI = function (path, data) {
            this.rawDataUris[this.pathPrefix + path] = data;
        };
        AssetManager.prototype.loadBinary = function (path, success, error) {
            var _this = this;
            if (success === void 0) { success = null; }
            if (error === void 0) { error = null; }
            path = this.pathPrefix + path;
            this.toLoad++;
            this.downloadBinary(path, function (data) {
                _this.assets[path] = data;
                if (success)
                    success(path, data);
                _this.toLoad--;
                _this.loaded++;
            }, function (state, responseText) {
                _this.errors[path] = "Couldn't load binary ".concat(path, ": status ").concat(status, ", ").concat(responseText);
                if (error)
                    error(path, "Couldn't load binary ".concat(path, ": status ").concat(status, ", ").concat(responseText));
                _this.toLoad--;
                _this.loaded++;
            });
        };
        AssetManager.prototype.loadText = function (path, success, error) {
            var _this = this;
            if (success === void 0) { success = null; }
            if (error === void 0) { error = null; }
            path = this.pathPrefix + path;
            this.toLoad++;
            this.downloadText(path, function (data) {
                _this.assets[path] = data;
                if (success)
                    success(path, data);
                _this.toLoad--;
                _this.loaded++;
            }, function (state, responseText) {
                _this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(status, ", ").concat(responseText);
                if (error)
                    error(path, "Couldn't load text ".concat(path, ": status ").concat(status, ", ").concat(responseText));
                _this.toLoad--;
                _this.loaded++;
            });
        };
        AssetManager.prototype.loadTexture = function (path, success, error) {
            var _this = this;
            if (success === void 0) { success = null; }
            if (error === void 0) { error = null; }
            path = this.pathPrefix + path;
            var storagePath = path;
            this.toLoad++;
            var img = new Image();
            img.crossOrigin = "anonymous";
            img.onload = function (ev) {
                var texture = _this.textureLoader(img);
                _this.assets[storagePath] = texture;
                _this.toLoad--;
                _this.loaded++;
                if (success)
                    success(path, img);
            };
            img.onerror = function (ev) {
                _this.errors[path] = "Couldn't load image ".concat(path);
                _this.toLoad--;
                _this.loaded++;
                if (error)
                    error(path, "Couldn't load image ".concat(path));
            };
            if (this.rawDataUris[path])
                path = this.rawDataUris[path];
            img.src = path;
        };
        AssetManager.prototype.loadTextureAtlas = function (path, success, error) {
            var _this = this;
            if (success === void 0) { success = null; }
            if (error === void 0) { error = null; }
            var parent = path.lastIndexOf("/") >= 0 ? path.substring(0, path.lastIndexOf("/")) : "";
            path = this.pathPrefix + path;
            this.toLoad++;
            this.downloadText(path, function (atlasData) {
                var pagesLoaded = { count: 0 };
                var atlasPages = new Array();
                try {
                    var atlas = new spine.TextureAtlas(atlasData, function (path) {
                        atlasPages.push(parent == "" ? path : parent + "/" + path);
                        var image = document.createElement("img");
                        image.width = 16;
                        image.height = 16;
                        return new spine.FakeTexture(image);
                    });
                }
                catch (e) {
                    var ex = e;
                    _this.errors[path] = "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message);
                    if (error)
                        error(path, "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message));
                    _this.toLoad--;
                    _this.loaded++;
                    return;
                }
                var _loop_1 = function (atlasPage) {
                    var pageLoadError = false;
                    _this.loadTexture(atlasPage, function (imagePath, image) {
                        pagesLoaded.count++;
                        if (pagesLoaded.count == atlasPages.length) {
                            if (!pageLoadError) {
                                try {
                                    var atlas = new spine.TextureAtlas(atlasData, function (path) {
                                        return _this.get(parent == "" ? path : parent + "/" + path);
                                    });
                                    _this.assets[path] = atlas;
                                    if (success)
                                        success(path, atlas);
                                    _this.toLoad--;
                                    _this.loaded++;
                                }
                                catch (e) {
                                    var ex = e;
                                    _this.errors[path] = "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message);
                                    if (error)
                                        error(path, "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message));
                                    _this.toLoad--;
                                    _this.loaded++;
                                }
                            }
                            else {
                                _this.errors[path] = "Couldn't load texture atlas page ".concat(imagePath, "} of atlas ").concat(path);
                                if (error)
                                    error(path, "Couldn't load texture atlas page ".concat(imagePath, " of atlas ").concat(path));
                                _this.toLoad--;
                                _this.loaded++;
                            }
                        }
                    }, function (imagePath, errorMessage) {
                        pageLoadError = true;
                        pagesLoaded.count++;
                        if (pagesLoaded.count == atlasPages.length) {
                            _this.errors[path] = "Couldn't load texture atlas page ".concat(imagePath, "} of atlas ").concat(path);
                            if (error)
                                error(path, "Couldn't load texture atlas page ".concat(imagePath, " of atlas ").concat(path));
                            _this.toLoad--;
                            _this.loaded++;
                        }
                    });
                };
                for (var _i = 0, atlasPages_1 = atlasPages; _i < atlasPages_1.length; _i++) {
                    var atlasPage = atlasPages_1[_i];
                    _loop_1(atlasPage);
                }
            }, function (state, responseText) {
                _this.errors[path] = "Couldn't load texture atlas ".concat(path, ": status ").concat(status, ", ").concat(responseText);
                if (error)
                    error(path, "Couldn't load texture atlas ".concat(path, ": status ").concat(status, ", ").concat(responseText));
                _this.toLoad--;
                _this.loaded++;
            });
        };
        AssetManager.prototype.get = function (path) {
            path = this.pathPrefix + path;
            return this.assets[path];
        };
        AssetManager.prototype.remove = function (path) {
            path = this.pathPrefix + path;
            var asset = this.assets[path];
            if (asset.dispose)
                asset.dispose();
            this.assets[path] = null;
        };
        AssetManager.prototype.removeAll = function () {
            for (var key in this.assets) {
                var asset = this.assets[key];
                if (asset.dispose)
                    asset.dispose();
            }
            this.assets = {};
        };
        AssetManager.prototype.isLoadingComplete = function () {
            return this.toLoad == 0;
        };
        AssetManager.prototype.getToLoad = function () {
            return this.toLoad;
        };
        AssetManager.prototype.getLoaded = function () {
            return this.loaded;
        };
        AssetManager.prototype.dispose = function () {
            this.removeAll();
        };
        AssetManager.prototype.hasErrors = function () {
            return Object.keys(this.errors).length > 0;
        };
        AssetManager.prototype.getErrors = function () {
            return this.errors;
        };
        return AssetManager;
    }());
    spine.AssetManager = AssetManager;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var AtlasAttachmentLoader = (function () {
        function AtlasAttachmentLoader(atlas) {
            this.atlas = atlas;
        }
        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 + ")");
            region.renderObject = region;
            var attachment = new spine.RegionAttachment(name);
            attachment.setRegion(region);
            return 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 + ")");
            region.renderObject = region;
            var attachment = new spine.MeshAttachment(name);
            attachment.region = region;
            return attachment;
        };
        AtlasAttachmentLoader.prototype.newBoundingBoxAttachment = function (skin, name) {
            return new spine.BoundingBoxAttachment(name);
        };
        AtlasAttachmentLoader.prototype.newPathAttachment = function (skin, name) {
            return new spine.PathAttachment(name);
        };
        AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) {
            return new spine.PointAttachment(name);
        };
        AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) {
            return new spine.ClippingAttachment(name);
        };
        return AtlasAttachmentLoader;
    }());
    spine.AtlasAttachmentLoader = AtlasAttachmentLoader;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var BlendMode;
    (function (BlendMode) {
        BlendMode[BlendMode["Normal"] = 0] = "Normal";
        BlendMode[BlendMode["Additive"] = 1] = "Additive";
        BlendMode[BlendMode["Multiply"] = 2] = "Multiply";
        BlendMode[BlendMode["Screen"] = 3] = "Screen";
    })(BlendMode = spine.BlendMode || (spine.BlendMode = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var Bone = (function () {
        function Bone(data, skeleton, parent) {
            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.a = 0;
            this.b = 0;
            this.c = 0;
            this.d = 0;
            this.worldY = 0;
            this.worldX = 0;
            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();
        }
        Bone.prototype.isActive = function () {
            return this.active;
        };
        Bone.prototype.update = function () {
            this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
        };
        Bone.prototype.updateWorldTransform = function () {
            this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
        };
        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;
            if (parent == null) {
                var skeleton = this.skeleton;
                var rotationY = rotation + 90 + shearY;
                var sx = skeleton.scaleX;
                var sy = skeleton.scaleY;
                this.a = spine.MathUtils.cosDeg(rotation + shearX) * scaleX * sx;
                this.b = spine.MathUtils.cosDeg(rotationY) * scaleY * sx;
                this.c = spine.MathUtils.sinDeg(rotation + shearX) * scaleX * sy;
                this.d = spine.MathUtils.sinDeg(rotationY) * scaleY * sy;
                this.worldX = x * sx + skeleton.x;
                this.worldY = y * sy + skeleton.y;
                return;
            }
            var pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
            this.worldX = pa * x + pb * y + parent.worldX;
            this.worldY = pc * x + pd * y + parent.worldY;
            switch (this.data.transformMode) {
                case spine.TransformMode.Normal: {
                    var rotationY = rotation + 90 + shearY;
                    var la = spine.MathUtils.cosDeg(rotation + shearX) * scaleX;
                    var lb = spine.MathUtils.cosDeg(rotationY) * scaleY;
                    var lc = spine.MathUtils.sinDeg(rotation + shearX) * scaleX;
                    var ld = spine.MathUtils.sinDeg(rotationY) * scaleY;
                    this.a = pa * la + pb * lc;
                    this.b = pa * lb + pb * ld;
                    this.c = pc * la + pd * lc;
                    this.d = pc * lb + pd * ld;
                    return;
                }
                case spine.TransformMode.OnlyTranslation: {
                    var rotationY = rotation + 90 + shearY;
                    this.a = spine.MathUtils.cosDeg(rotation + shearX) * scaleX;
                    this.b = spine.MathUtils.cosDeg(rotationY) * scaleY;
                    this.c = spine.MathUtils.sinDeg(rotation + shearX) * scaleX;
                    this.d = spine.MathUtils.sinDeg(rotationY) * scaleY;
                    break;
                }
                case spine.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) * spine.MathUtils.radDeg;
                    }
                    else {
                        pa = 0;
                        pc = 0;
                        prx = 90 - Math.atan2(pd, pb) * spine.MathUtils.radDeg;
                    }
                    var rx = rotation + shearX - prx;
                    var ry = rotation + shearY - prx + 90;
                    var la = spine.MathUtils.cosDeg(rx) * scaleX;
                    var lb = spine.MathUtils.cosDeg(ry) * scaleY;
                    var lc = spine.MathUtils.sinDeg(rx) * scaleX;
                    var ld = spine.MathUtils.sinDeg(ry) * scaleY;
                    this.a = pa * la - pb * lc;
                    this.b = pa * lb - pb * ld;
                    this.c = pc * la + pd * lc;
                    this.d = pc * lb + pd * ld;
                    break;
                }
                case spine.TransformMode.NoScale:
                case spine.TransformMode.NoScaleOrReflection: {
                    var cos = spine.MathUtils.cosDeg(rotation);
                    var sin = spine.MathUtils.sinDeg(rotation);
                    var za = (pa * cos + pb * sin) / this.skeleton.scaleX;
                    var zc = (pc * cos + pd * sin) / this.skeleton.scaleY;
                    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 == spine.TransformMode.NoScale
                        && (pa * pd - pb * pc < 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 = spine.MathUtils.cosDeg(shearX) * scaleX;
                    var lb = spine.MathUtils.cosDeg(90 + shearY) * scaleY;
                    var lc = spine.MathUtils.sinDeg(shearX) * scaleX;
                    var ld = spine.MathUtils.sinDeg(90 + shearY) * scaleY;
                    this.a = za * la + zb * lc;
                    this.b = za * lb + zb * ld;
                    this.c = zc * la + zd * lc;
                    this.d = zc * lb + zd * ld;
                    break;
                }
            }
            this.a *= this.skeleton.scaleX;
            this.b *= this.skeleton.scaleX;
            this.c *= this.skeleton.scaleY;
            this.d *= this.skeleton.scaleY;
        };
        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.c, this.a) * spine.MathUtils.radDeg;
        };
        Bone.prototype.getWorldRotationY = function () {
            return Math.atan2(this.d, this.b) * spine.MathUtils.radDeg;
        };
        Bone.prototype.getWorldScaleX = function () {
            return Math.sqrt(this.a * this.a + this.c * this.c);
        };
        Bone.prototype.getWorldScaleY = function () {
            return Math.sqrt(this.b * this.b + this.d * this.d);
        };
        Bone.prototype.updateAppliedTransform = function () {
            this.appliedValid = true;
            var parent = this.parent;
            if (parent == null) {
                this.ax = this.worldX;
                this.ay = this.worldY;
                this.arotation = Math.atan2(this.c, this.a) * spine.MathUtils.radDeg;
                this.ascaleX = Math.sqrt(this.a * this.a + this.c * this.c);
                this.ascaleY = Math.sqrt(this.b * this.b + this.d * this.d);
                this.ashearX = 0;
                this.ashearY = Math.atan2(this.a * this.b + this.c * this.d, this.a * this.d - this.b * this.c) * spine.MathUtils.radDeg;
                return;
            }
            var pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
            var pid = 1 / (pa * pd - pb * pc);
            var dx = this.worldX - parent.worldX, dy = this.worldY - parent.worldY;
            this.ax = (dx * pd * pid - dy * pb * pid);
            this.ay = (dy * pa * pid - dx * pc * pid);
            var ia = pid * pd;
            var id = pid * pa;
            var ib = pid * pb;
            var ic = pid * pc;
            var ra = ia * this.a - ib * this.c;
            var rb = ia * this.b - ib * this.d;
            var rc = id * this.c - ic * this.a;
            var rd = id * this.d - ic * this.b;
            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) * spine.MathUtils.radDeg;
                this.arotation = Math.atan2(rc, ra) * spine.MathUtils.radDeg;
            }
            else {
                this.ascaleX = 0;
                this.ascaleY = Math.sqrt(rb * rb + rd * rd);
                this.ashearY = 0;
                this.arotation = 90 - Math.atan2(rd, rb) * spine.MathUtils.radDeg;
            }
        };
        Bone.prototype.worldToLocal = function (world) {
            var a = this.a, b = this.b, c = this.c, d = this.d;
            var invDet = 1 / (a * d - b * c);
            var x = world.x - this.worldX, y = world.y - this.worldY;
            world.x = (x * d * invDet - y * b * invDet);
            world.y = (y * a * invDet - x * c * invDet);
            return world;
        };
        Bone.prototype.localToWorld = function (local) {
            var x = local.x, y = local.y;
            local.x = x * this.a + y * this.b + this.worldX;
            local.y = x * this.c + y * this.d + this.worldY;
            return local;
        };
        Bone.prototype.worldToLocalRotation = function (worldRotation) {
            var sin = spine.MathUtils.sinDeg(worldRotation), cos = spine.MathUtils.cosDeg(worldRotation);
            return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * spine.MathUtils.radDeg + this.rotation - this.shearX;
        };
        Bone.prototype.localToWorldRotation = function (localRotation) {
            localRotation -= this.rotation - this.shearX;
            var sin = spine.MathUtils.sinDeg(localRotation), cos = spine.MathUtils.cosDeg(localRotation);
            return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * spine.MathUtils.radDeg;
        };
        Bone.prototype.rotateWorld = function (degrees) {
            var a = this.a, b = this.b, c = this.c, d = this.d;
            var cos = spine.MathUtils.cosDeg(degrees), sin = spine.MathUtils.sinDeg(degrees);
            this.a = cos * a - sin * c;
            this.b = cos * b - sin * d;
            this.c = sin * a + cos * c;
            this.d = sin * b + cos * d;
            this.appliedValid = false;
        };
        return Bone;
    }());
    spine.Bone = Bone;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var BoneData = (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 = TransformMode.Normal;
            this.skinRequired = false;
            this.color = new spine.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;
    }());
    spine.BoneData = BoneData;
    var TransformMode;
    (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";
    })(TransformMode = spine.TransformMode || (spine.TransformMode = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var ConstraintData = (function () {
        function ConstraintData(name, order, skinRequired) {
            this.name = name;
            this.order = order;
            this.skinRequired = skinRequired;
        }
        return ConstraintData;
    }());
    spine.ConstraintData = ConstraintData;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var Event = (function () {
        function Event(time, data) {
            if (data == null)
                throw new Error("data cannot be null.");
            this.time = time;
            this.data = data;
        }
        return Event;
    }());
    spine.Event = Event;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var EventData = (function () {
        function EventData(name) {
            this.name = name;
        }
        return EventData;
    }());
    spine.EventData = EventData;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var IkConstraint = (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;
            }
        };
        IkConstraint.prototype.apply1 = function (bone, targetX, targetY, compress, stretch, uniform, alpha) {
            if (!bone.appliedValid)
                bone.updateAppliedTransform();
            var p = bone.parent;
            var pa = p.a, pb = p.b, pc = p.c, pd = p.d;
            var rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0;
            switch (bone.data.transformMode) {
                case spine.TransformMode.OnlyTranslation:
                    tx = targetX - bone.worldX;
                    ty = targetY - bone.worldY;
                    break;
                case spine.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) * spine.MathUtils.radDeg;
                default:
                    var x = targetX - p.worldX, y = targetY - p.worldY;
                    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) * spine.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 spine.TransformMode.NoScale:
                    case spine.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);
        };
        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 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 = parent.a, b = parent.b, c = parent.c, d = parent.d;
            var u = Math.abs(psx - psy) <= 0.0001;
            if (!u) {
                cy = 0;
                cwx = a * cx + parent.worldX;
                cwy = c * cx + parent.worldY;
            }
            else {
                cy = child.ay;
                cwx = a * cx + b * cy + parent.worldX;
                cwy = c * cx + d * cy + parent.worldY;
            }
            var pp = parent.parent;
            a = pp.a;
            b = pp.b;
            c = pp.c;
            d = pp.d;
            var id = 1 / (a * d - b * c), x = cwx - pp.worldX, y = cwy - pp.worldY;
            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.worldX;
            y = targetY - pp.worldY;
            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 = spine.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) * spine.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) * spine.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;
    }());
    spine.IkConstraint = IkConstraint;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var IkConstraintData = (function (_super) {
        __extends(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;
    }(spine.ConstraintData));
    spine.IkConstraintData = IkConstraintData;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var PathConstraint = (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 spine.PathAttachment))
                return;
            var rotateMix = this.rotateMix, translateMix = this.translateMix;
            var translate = translateMix > 0, rotate = rotateMix > 0;
            if (!translate && !rotate)
                return;
            var data = this.data;
            var percentSpacing = data.spacingMode == spine.SpacingMode.Percent;
            var rotateMode = data.rotateMode;
            var tangents = rotateMode == spine.RotateMode.Tangent, scale = rotateMode == spine.RotateMode.ChainScale;
            var boneCount = this.bones.length, spacesCount = tangents ? boneCount : boneCount + 1;
            var bones = this.bones;
            var spaces = spine.Utils.setArraySize(this.spaces, spacesCount), lengths = null;
            var spacing = this.spacing;
            if (scale || !percentSpacing) {
                if (scale)
                    lengths = spine.Utils.setArraySize(this.lengths, boneCount);
                var lengthSpacing = data.spacingMode == spine.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] = 0;
                    }
                    else if (percentSpacing) {
                        if (scale) {
                            var x = setupLength * bone.a, y = setupLength * bone.c;
                            var length_1 = Math.sqrt(x * x + y * y);
                            lengths[i] = length_1;
                        }
                        spaces[++i] = spacing;
                    }
                    else {
                        var x = setupLength * bone.a, y = setupLength * bone.c;
                        var length_2 = Math.sqrt(x * x + y * y);
                        if (scale)
                            lengths[i] = length_2;
                        spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length_2 / setupLength;
                    }
                }
            }
            else {
                for (var i = 1; i < spacesCount; i++)
                    spaces[i] = spacing;
            }
            var positions = this.computeWorldPositions(attachment, spacesCount, tangents, data.positionMode == spine.PositionMode.Percent, percentSpacing);
            var boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation;
            var tip = false;
            if (offsetRotation == 0)
                tip = rotateMode == spine.RotateMode.Chain;
            else {
                tip = false;
                var p = this.target.bone;
                offsetRotation *= p.a * p.d - p.b * p.c > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad;
            }
            for (var i = 0, p = 3; i < boneCount; i++, p += 3) {
                var bone = bones[i];
                bone.worldX += (boneX - bone.worldX) * translateMix;
                bone.worldY += (boneY - bone.worldY) * translateMix;
                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) * rotateMix + 1;
                        bone.a *= s;
                        bone.c *= s;
                    }
                }
                boneX = x;
                boneY = y;
                if (rotate) {
                    var a = bone.a, b = bone.b, c = bone.c, d = bone.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) * rotateMix;
                        boneY += (length_4 * (sin * a + cos * c) - dy) * rotateMix;
                    }
                    else {
                        r += offsetRotation;
                    }
                    if (r > spine.MathUtils.PI)
                        r -= spine.MathUtils.PI2;
                    else if (r < -spine.MathUtils.PI)
                        r += spine.MathUtils.PI2;
                    r *= rotateMix;
                    cos = Math.cos(r);
                    sin = Math.sin(r);
                    bone.a = cos * a - sin * c;
                    bone.b = cos * b - sin * d;
                    bone.c = sin * a + cos * c;
                    bone.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 = spine.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 = 1; i < spacesCount; i++)
                        spaces[i] *= pathLength_1;
                }
                world = spine.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;
                    }
                    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;
            }
            if (closed) {
                verticesLength += 2;
                world = spine.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 = spine.Utils.setArraySize(this.world, verticesLength);
                path.computeWorldVertices(target, 2, verticesLength, world, 0, 2);
            }
            var curves = spine.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;
            else
                position *= pathLength / path.lengths[curveCount - 1];
            if (percentSpacing) {
                for (var i = 1; 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;
                }
                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;
                }
                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;
                }
                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;
    }());
    spine.PathConstraint = PathConstraint;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var PathConstraintData = (function (_super) {
        __extends(PathConstraintData, _super);
        function PathConstraintData(name) {
            var _this = _super.call(this, name, 0, false) || this;
            _this.bones = new Array();
            return _this;
        }
        return PathConstraintData;
    }(spine.ConstraintData));
    spine.PathConstraintData = PathConstraintData;
    var PositionMode;
    (function (PositionMode) {
        PositionMode[PositionMode["Fixed"] = 0] = "Fixed";
        PositionMode[PositionMode["Percent"] = 1] = "Percent";
    })(PositionMode = spine.PositionMode || (spine.PositionMode = {}));
    var SpacingMode;
    (function (SpacingMode) {
        SpacingMode[SpacingMode["Length"] = 0] = "Length";
        SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed";
        SpacingMode[SpacingMode["Percent"] = 2] = "Percent";
    })(SpacingMode = spine.SpacingMode || (spine.SpacingMode = {}));
    var RotateMode;
    (function (RotateMode) {
        RotateMode[RotateMode["Tangent"] = 0] = "Tangent";
        RotateMode[RotateMode["Chain"] = 1] = "Chain";
        RotateMode[RotateMode["ChainScale"] = 2] = "ChainScale";
    })(RotateMode = spine.RotateMode || (spine.RotateMode = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var Assets = (function () {
        function Assets(clientId) {
            this.toLoad = new Array();
            this.assets = {};
            this.clientId = clientId;
        }
        Assets.prototype.loaded = function () {
            var i = 0;
            for (var v in this.assets)
                i++;
            return i;
        };
        return Assets;
    }());
    var SharedAssetManager = (function () {
        function SharedAssetManager(pathPrefix) {
            if (pathPrefix === void 0) { pathPrefix = ""; }
            this.clientAssets = {};
            this.queuedAssets = {};
            this.rawAssets = {};
            this.errors = {};
            this.pathPrefix = pathPrefix;
        }
        SharedAssetManager.prototype.queueAsset = function (clientId, textureLoader, path) {
            var clientAssets = this.clientAssets[clientId];
            if (clientAssets === null || clientAssets === undefined) {
                clientAssets = new Assets(clientId);
                this.clientAssets[clientId] = clientAssets;
            }
            if (textureLoader !== null)
                clientAssets.textureLoader = textureLoader;
            clientAssets.toLoad.push(path);
            if (this.queuedAssets[path] === path) {
                return false;
            }
            else {
                this.queuedAssets[path] = path;
                return true;
            }
        };
        SharedAssetManager.prototype.loadText = function (clientId, path) {
            var _this = this;
            path = this.pathPrefix + path;
            if (!this.queueAsset(clientId, null, path))
                return;
            var request = new XMLHttpRequest();
            request.overrideMimeType("text/html");
            request.onreadystatechange = function () {
                if (request.readyState == XMLHttpRequest.DONE) {
                    if (request.status >= 200 && request.status < 300) {
                        _this.rawAssets[path] = request.responseText;
                    }
                    else {
                        _this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(request.status, ", ").concat(request.responseText);
                    }
                }
            };
            request.open("GET", path, true);
            request.send();
        };
        SharedAssetManager.prototype.loadJson = function (clientId, path) {
            var _this = this;
            path = this.pathPrefix + path;
            if (!this.queueAsset(clientId, null, path))
                return;
            var request = new XMLHttpRequest();
            request.overrideMimeType("text/html");
            request.onreadystatechange = function () {
                if (request.readyState == XMLHttpRequest.DONE) {
                    if (request.status >= 200 && request.status < 300) {
                        _this.rawAssets[path] = JSON.parse(request.responseText);
                    }
                    else {
                        _this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(request.status, ", ").concat(request.responseText);
                    }
                }
            };
            request.open("GET", path, true);
            request.send();
        };
        SharedAssetManager.prototype.loadTexture = function (clientId, textureLoader, path) {
            var _this = this;
            path = this.pathPrefix + path;
            if (!this.queueAsset(clientId, textureLoader, path))
                return;
            var isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document);
            var isWebWorker = !isBrowser && typeof importScripts !== 'undefined';
            if (isWebWorker) {
                var options = { mode: "cors" };
                fetch(path, options).then(function (response) {
                    if (!response.ok) {
                        _this.errors[path] = "Couldn't load image " + path;
                    }
                    return response.blob();
                }).then(function (blob) {
                    return createImageBitmap(blob, {
                        premultiplyAlpha: 'none',
                        colorSpaceConversion: 'none'
                    });
                }).then(function (bitmap) {
                    _this.rawAssets[path] = bitmap;
                });
            }
            else {
                var img_1 = new Image();
                img_1.crossOrigin = "anonymous";
                img_1.onload = function (ev) {
                    _this.rawAssets[path] = img_1;
                };
                img_1.onerror = function (ev) {
                    _this.errors[path] = "Couldn't load image ".concat(path);
                };
                img_1.src = path;
            }
        };
        SharedAssetManager.prototype.get = function (clientId, path) {
            path = this.pathPrefix + path;
            var clientAssets = this.clientAssets[clientId];
            if (clientAssets === null || clientAssets === undefined)
                return true;
            return clientAssets.assets[path];
        };
        SharedAssetManager.prototype.updateClientAssets = function (clientAssets) {
            var isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document);
            var isWebWorker = !isBrowser && typeof importScripts !== 'undefined';
            for (var i = 0; i < clientAssets.toLoad.length; i++) {
                var path = clientAssets.toLoad[i];
                var asset = clientAssets.assets[path];
                if (asset === null || asset === undefined) {
                    var rawAsset = this.rawAssets[path];
                    if (rawAsset === null || rawAsset === undefined)
                        continue;
                    if (isWebWorker) {
                        if (rawAsset instanceof ImageBitmap) {
                            clientAssets.assets[path] = clientAssets.textureLoader(rawAsset);
                        }
                        else {
                            clientAssets.assets[path] = rawAsset;
                        }
                    }
                    else {
                        if (rawAsset instanceof HTMLImageElement) {
                            clientAssets.assets[path] = clientAssets.textureLoader(rawAsset);
                        }
                        else {
                            clientAssets.assets[path] = rawAsset;
                        }
                    }
                }
            }
        };
        SharedAssetManager.prototype.isLoadingComplete = function (clientId) {
            var clientAssets = this.clientAssets[clientId];
            if (clientAssets === null || clientAssets === undefined)
                return true;
            this.updateClientAssets(clientAssets);
            return clientAssets.toLoad.length == clientAssets.loaded();
        };
        SharedAssetManager.prototype.dispose = function () {
        };
        SharedAssetManager.prototype.hasErrors = function () {
            return Object.keys(this.errors).length > 0;
        };
        SharedAssetManager.prototype.getErrors = function () {
            return this.errors;
        };
        return SharedAssetManager;
    }());
    spine.SharedAssetManager = SharedAssetManager;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var Skeleton = (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 spine.Bone(boneData, this, null);
                else {
                    var parent_1 = this.bones[boneData.parent.index];
                    bone = new spine.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 spine.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 spine.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 spine.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 spine.PathConstraint(pathConstraintData, this));
            }
            this.color = new spine.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);
                }
            }
            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 && spine.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 && spine.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 spine.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 != null && spine.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 spine.PathAttachment))
                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;
            }
        };
        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();
        };
        Skeleton.prototype.setToSetupPose = function () {
            this.setBonesToSetupPose();
            this.setSlotsToSetupPose();
        };
        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;
            spine.Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length);
            for (var i = 0, n = slots.length; i < n; i++)
                slots[i].setToSetupPose();
        };
        Skeleton.prototype.getRootBone = function () {
            if (this.bones.length == 0)
                return null;
            return this.bones[0];
        };
        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;
        };
        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;
        };
        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;
        };
        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;
        };
        Skeleton.prototype.setSkinByName = function (skinName) {
            var skin = this.data.findSkin(skinName);
            if (skin == null)
                throw new Error("Skin not found: " + skinName);
            this.setSkin(skin);
        };
        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();
        };
        Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) {
            return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName);
        };
        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;
        };
        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);
        };
        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;
        };
        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;
        };
        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;
        };
        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 spine.RegionAttachment) {
                    verticesLength = 8;
                    vertices = spine.Utils.setArraySize(temp, verticesLength, 0);
                    attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
                }
                else if (attachment instanceof spine.MeshAttachment) {
                    var mesh = attachment;
                    verticesLength = mesh.worldVerticesLength;
                    vertices = spine.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;
        };
        return Skeleton;
    }());
    spine.Skeleton = Skeleton;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var SkeletonBinary = (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 spine.SkeletonData();
            skeletonData.name = "";
            var input = new BinaryInput(binary);
            skeletonData.hash = input.readString();
            skeletonData.version = input.readString();
            if ("3.8.75" == skeletonData.version)
                throw new Error("Unsupported skeleton data, please export with a newer version of Spine.");
            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;
            n = input.readInt(true);
            for (var i = 0; i < n; i++)
                input.strings.push(input.readString());
            n = input.readInt(true);
            for (var i = 0; i < n; i++) {
                var name_2 = input.readString();
                var parent_2 = i == 0 ? null : skeletonData.bones[input.readInt(true)];
                var data = new spine.BoneData(i, name_2, parent_2);
                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)
                    spine.Color.rgba8888ToColor(data.color, input.readInt32());
                skeletonData.bones.push(data);
            }
            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 spine.SlotData(i, slotName, boneData);
                spine.Color.rgba8888ToColor(data.color, input.readInt32());
                var darkColor = input.readInt32();
                if (darkColor != -1)
                    spine.Color.rgb888ToColor(data.darkColor = new spine.Color(), darkColor);
                data.attachmentName = input.readStringRef();
                data.blendMode = SkeletonBinary.BlendModeValues[input.readInt(true)];
                skeletonData.slots.push(data);
            }
            n = input.readInt(true);
            for (var i = 0, nn = void 0; i < n; i++) {
                var data = new spine.IkConstraintData(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);
            }
            n = input.readInt(true);
            for (var i = 0, nn = void 0; i < n; i++) {
                var data = new spine.TransformConstraintData(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);
            }
            n = input.readInt(true);
            for (var i = 0, nn = void 0; i < n; i++) {
                var data = new spine.PathConstraintData(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 == spine.PositionMode.Fixed)
                    data.position *= scale;
                data.spacing = input.readFloat();
                if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed)
                    data.spacing *= scale;
                data.rotateMix = input.readFloat();
                data.translateMix = input.readFloat();
                skeletonData.pathConstraints.push(data);
            }
            var defaultSkin = this.readSkin(input, skeletonData, true, nonessential);
            if (defaultSkin != null) {
                skeletonData.defaultSkin = defaultSkin;
                skeletonData.skins.push(defaultSkin);
            }
            {
                var i = skeletonData.skins.length;
                spine.Utils.setArraySize(skeletonData.skins, n = i + input.readInt(true));
                for (; i < n; i++)
                    skeletonData.skins[i] = this.readSkin(input, skeletonData, false, nonessential);
            }
            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_3 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
                if (parent_3 == null)
                    throw new Error("Parent mesh not found: " + linkedMesh.parent);
                linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent_3 : linkedMesh.mesh;
                linkedMesh.mesh.setParentMesh(parent_3);
                linkedMesh.mesh.updateUVs();
            }
            this.linkedMeshes.length = 0;
            n = input.readInt(true);
            for (var i = 0; i < n; i++) {
                var data = new spine.EventData(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);
            }
            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 spine.Skin("default");
            }
            else {
                skin = new spine.Skin(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_3 = input.readStringRef();
                    var attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name_3, nonessential);
                    if (attachment != null)
                        skin.setAttachment(slotIndex, name_3, 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 spine.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;
                    spine.Color.rgba8888ToColor(region.color, color);
                    region.updateOffset();
                    return region;
                }
                case spine.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)
                        spine.Color.rgba8888ToColor(box.color, color);
                    return box;
                }
                case spine.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;
                    spine.Color.rgba8888ToColor(mesh.color, color);
                    mesh.bones = vertices.bones;
                    mesh.vertices = vertices.vertices;
                    mesh.worldVerticesLength = vertexCount << 1;
                    mesh.triangles = triangles;
                    mesh.regionUVs = uvs;
                    mesh.updateUVs();
                    mesh.hullLength = hullLength << 1;
                    if (nonessential) {
                        mesh.edges = edges;
                        mesh.width = width * scale;
                        mesh.height = height * scale;
                    }
                    return mesh;
                }
                case spine.AttachmentType.LinkedMesh: {
                    var path = input.readStringRef();
                    var color = input.readInt32();
                    var skinName = input.readStringRef();
                    var parent_4 = 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;
                    spine.Color.rgba8888ToColor(mesh.color, color);
                    if (nonessential) {
                        mesh.width = width * scale;
                        mesh.height = height * scale;
                    }
                    this.linkedMeshes.push(new LinkedMesh(mesh, skinName, slotIndex, parent_4, inheritDeform));
                    return mesh;
                }
                case spine.AttachmentType.Path: {
                    var closed_1 = input.readBoolean();
                    var constantSpeed = input.readBoolean();
                    var vertexCount = input.readInt(true);
                    var vertices = this.readVertices(input, vertexCount);
                    var lengths = spine.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)
                        spine.Color.rgba8888ToColor(path.color, color);
                    return path;
                }
                case spine.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)
                        spine.Color.rgba8888ToColor(point.color, color);
                    return point;
                }
                case spine.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)
                        spine.Color.rgba8888ToColor(clip.color, color);
                    return clip;
                }
            }
            return null;
        };
        SkeletonBinary.prototype.readVertices = function (input, vertexCount) {
            var verticesLength = vertexCount << 1;
            var vertices = new Vertices();
            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 = spine.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 spine.Color();
            var tempColor2 = new spine.Color();
            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 spine.AttachmentTimeline(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 spine.ColorTimeline(frameCount);
                            timeline.slotIndex = slotIndex;
                            for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) {
                                var time = input.readFloat();
                                spine.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) * spine.ColorTimeline.ENTRIES]);
                            break;
                        }
                        case SkeletonBinary.SLOT_TWO_COLOR: {
                            var timeline = new spine.TwoColorTimeline(frameCount);
                            timeline.slotIndex = slotIndex;
                            for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) {
                                var time = input.readFloat();
                                spine.Color.rgba8888ToColor(tempColor1, input.readInt32());
                                spine.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) * spine.TwoColorTimeline.ENTRIES]);
                            break;
                        }
                    }
                }
            }
            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 spine.RotateTimeline(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) * spine.RotateTimeline.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 spine.ScaleTimeline(frameCount);
                            else if (timelineType == SkeletonBinary.BONE_SHEAR)
                                timeline = new spine.ShearTimeline(frameCount);
                            else {
                                timeline = new spine.TranslateTimeline(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) * spine.TranslateTimeline.ENTRIES]);
                            break;
                        }
                    }
                }
            }
            for (var i = 0, n = input.readInt(true); i < n; i++) {
                var index = input.readInt(true);
                var frameCount = input.readInt(true);
                var timeline = new spine.IkConstraintTimeline(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) * spine.IkConstraintTimeline.ENTRIES]);
            }
            for (var i = 0, n = input.readInt(true); i < n; i++) {
                var index = input.readInt(true);
                var frameCount = input.readInt(true);
                var timeline = new spine.TransformConstraintTimeline(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) * spine.TransformConstraintTimeline.ENTRIES]);
            }
            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 spine.PathConstraintSpacingTimeline(frameCount);
                                if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed)
                                    timelineScale = scale;
                            }
                            else {
                                timeline = new spine.PathConstraintPositionTimeline(frameCount);
                                if (data.positionMode == spine.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) * spine.PathConstraintPositionTimeline.ENTRIES]);
                            break;
                        }
                        case SkeletonBinary.PATH_MIX: {
                            var timeline = new spine.PathConstraintMixTimeline(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) * spine.PathConstraintMixTimeline.ENTRIES]);
                            break;
                        }
                    }
                }
            }
            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 spine.DeformTimeline(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 ? spine.Utils.newFloatArray(deformLength) : vertices;
                            else {
                                deform = spine.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]);
                    }
                }
            }
            var drawOrderCount = input.readInt(true);
            if (drawOrderCount > 0) {
                var timeline = new spine.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 = spine.Utils.newArray(slotCount, 0);
                    for (var ii = slotCount - 1; ii >= 0; ii--)
                        drawOrder[ii] = -1;
                    var unchanged = spine.Utils.newArray(slotCount - offsetCount, 0);
                    var originalIndex = 0, unchangedIndex = 0;
                    for (var ii = 0; ii < offsetCount; ii++) {
                        var slotIndex = input.readInt(true);
                        while (originalIndex != slotIndex)
                            unchanged[unchangedIndex++] = originalIndex++;
                        drawOrder[originalIndex + input.readInt(true)] = originalIndex++;
                    }
                    while (originalIndex < slotCount)
                        unchanged[unchangedIndex++] = originalIndex++;
                    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]);
            }
            var eventCount = input.readInt(true);
            if (eventCount > 0) {
                var timeline = new spine.EventTimeline(eventCount);
                for (var i = 0; i < eventCount; i++) {
                    var time = input.readFloat();
                    var eventData = skeletonData.events[input.readInt(true)];
                    var event_4 = new spine.Event(time, eventData);
                    event_4.intValue = input.readInt(false);
                    event_4.floatValue = input.readFloat();
                    event_4.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue;
                    if (event_4.data.audioPath != null) {
                        event_4.volume = input.readFloat();
                        event_4.balance = input.readFloat();
                    }
                    timeline.setFrame(i, event_4);
                }
                timelines.push(timeline);
                duration = Math.max(duration, timeline.frames[eventCount - 1]);
            }
            return new spine.Animation(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, 1, 2, 3, 4, 5, 6];
        SkeletonBinary.TransformModeValues = [spine.TransformMode.Normal, spine.TransformMode.OnlyTranslation, spine.TransformMode.NoRotationOrReflection, spine.TransformMode.NoScale, spine.TransformMode.NoScaleOrReflection];
        SkeletonBinary.PositionModeValues = [spine.PositionMode.Fixed, spine.PositionMode.Percent];
        SkeletonBinary.SpacingModeValues = [spine.SpacingMode.Length, spine.SpacingMode.Fixed, spine.SpacingMode.Percent];
        SkeletonBinary.RotateModeValues = [spine.RotateMode.Tangent, spine.RotateMode.Chain, spine.RotateMode.ChainScale];
        SkeletonBinary.BlendModeValues = [spine.BlendMode.Normal, spine.BlendMode.Additive, spine.BlendMode.Multiply, spine.BlendMode.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;
    }());
    spine.SkeletonBinary = SkeletonBinary;
    var BinaryInput = (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.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 = "";
            var charCount = 0;
            for (var i = 0; i < byteCount;) {
                var b = this.readByte();
                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;
    }());
    var LinkedMesh = (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 = (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;
    }());
})(spine || (spine = {}));
var spine;
(function (spine) {
    var SkeletonBounds = (function () {
        function SkeletonBounds() {
            this.minX = 0;
            this.minY = 0;
            this.maxX = 0;
            this.maxY = 0;
            this.boundingBoxes = new Array();
            this.polygons = new Array();
            this.polygonPool = new spine.Pool(function () {
                return spine.Utils.newFloatArray(16);
            });
        }
        SkeletonBounds.prototype.update = function (skeleton, updateAabb) {
            if (skeleton == null)
                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 instanceof spine.BoundingBoxAttachment) {
                    var boundingBox = attachment;
                    boundingBoxes.push(boundingBox);
                    var polygon = polygonPool.obtain();
                    if (polygon.length != boundingBox.worldVerticesLength) {
                        polygon = spine.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;
            }
        };
        SkeletonBounds.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;
        };
        SkeletonBounds.prototype.aabbContainsPoint = function (x, y) {
            return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY;
        };
        SkeletonBounds.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;
        };
        SkeletonBounds.prototype.aabbIntersectsSkeleton = function (bounds) {
            return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY;
        };
        SkeletonBounds.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;
        };
        SkeletonBounds.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;
        };
        SkeletonBounds.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;
        };
        SkeletonBounds.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;
        };
        SkeletonBounds.prototype.getPolygon = function (boundingBox) {
            if (boundingBox == null)
                throw new Error("boundingBox cannot be null.");
            var index = this.boundingBoxes.indexOf(boundingBox);
            return index == -1 ? null : this.polygons[index];
        };
        SkeletonBounds.prototype.getWidth = function () {
            return this.maxX - this.minX;
        };
        SkeletonBounds.prototype.getHeight = function () {
            return this.maxY - this.minY;
        };
        return SkeletonBounds;
    }());
    spine.SkeletonBounds = SkeletonBounds;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var SkeletonClipping = (function () {
        function SkeletonClipping() {
            this.triangulator = new spine.Triangulator();
            this.clippingPolygon = new Array();
            this.clipOutput = new Array();
            this.clippedVertices = new Array();
            this.clippedTriangles = new Array();
            this.scratch = new Array();
        }
        SkeletonClipping.prototype.clipStart = function (slot, clip) {
            if (this.clipAttachment != null)
                return 0;
            this.clipAttachment = clip;
            var n = clip.worldVerticesLength;
            var vertices = spine.Utils.setArraySize(this.clippingPolygon, n);
            clip.computeWorldVertices(slot, 0, n, vertices, 0, 2);
            var clippingPolygon = this.clippingPolygon;
            SkeletonClipping.makeClockwise(clippingPolygon);
            var clippingPolygons = this.clippingPolygons = this.triangulator.decompose(clippingPolygon, this.triangulator.triangulate(clippingPolygon));
            for (var i = 0, n_2 = clippingPolygons.length; i < n_2; i++) {
                var polygon = clippingPolygons[i];
                SkeletonClipping.makeClockwise(polygon);
                polygon.push(polygon[0]);
                polygon.push(polygon[1]);
            }
            return clippingPolygons.length;
        };
        SkeletonClipping.prototype.clipEndWithSlot = function (slot) {
            if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data)
                this.clipEnd();
        };
        SkeletonClipping.prototype.clipEnd = function () {
            if (this.clipAttachment == null)
                return;
            this.clipAttachment = null;
            this.clippingPolygons = null;
            this.clippedVertices.length = 0;
            this.clippedTriangles.length = 0;
            this.clippingPolygon.length = 0;
        };
        SkeletonClipping.prototype.isClipping = function () {
            return this.clipAttachment != null;
        };
        SkeletonClipping.prototype.clipTriangles = function (vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) {
            var clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
            var clippedTriangles = this.clippedTriangles;
            var polygons = this.clippingPolygons;
            var polygonsCount = this.clippingPolygons.length;
            var vertexSize = twoColor ? 12 : 8;
            var index = 0;
            clippedVertices.length = 0;
            clippedTriangles.length = 0;
            outer: for (var i = 0; i < trianglesLength; i += 3) {
                var vertexOffset = triangles[i] << 1;
                var x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
                var u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1];
                vertexOffset = triangles[i + 1] << 1;
                var x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1];
                var u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1];
                vertexOffset = triangles[i + 2] << 1;
                var x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1];
                var u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1];
                for (var p = 0; p < polygonsCount; p++) {
                    var s = clippedVertices.length;
                    if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) {
                        var clipOutputLength = clipOutput.length;
                        if (clipOutputLength == 0)
                            continue;
                        var d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;
                        var d = 1 / (d0 * d2 + d1 * (y1 - y3));
                        var clipOutputCount = clipOutputLength >> 1;
                        var clipOutputItems = this.clipOutput;
                        var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize);
                        for (var ii = 0; ii < clipOutputLength; ii += 2) {
                            var x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
                            clippedVerticesItems[s] = x;
                            clippedVerticesItems[s + 1] = y;
                            clippedVerticesItems[s + 2] = light.r;
                            clippedVerticesItems[s + 3] = light.g;
                            clippedVerticesItems[s + 4] = light.b;
                            clippedVerticesItems[s + 5] = light.a;
                            var c0 = x - x3, c1 = y - y3;
                            var a = (d0 * c0 + d1 * c1) * d;
                            var b = (d4 * c0 + d2 * c1) * d;
                            var c = 1 - a - b;
                            clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c;
                            clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c;
                            if (twoColor) {
                                clippedVerticesItems[s + 8] = dark.r;
                                clippedVerticesItems[s + 9] = dark.g;
                                clippedVerticesItems[s + 10] = dark.b;
                                clippedVerticesItems[s + 11] = dark.a;
                            }
                            s += vertexSize;
                        }
                        s = clippedTriangles.length;
                        var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2));
                        clipOutputCount--;
                        for (var ii = 1; ii < clipOutputCount; ii++) {
                            clippedTrianglesItems[s] = index;
                            clippedTrianglesItems[s + 1] = (index + ii);
                            clippedTrianglesItems[s + 2] = (index + ii + 1);
                            s += 3;
                        }
                        index += clipOutputCount + 1;
                    }
                    else {
                        var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + 3 * vertexSize);
                        clippedVerticesItems[s] = x1;
                        clippedVerticesItems[s + 1] = y1;
                        clippedVerticesItems[s + 2] = light.r;
                        clippedVerticesItems[s + 3] = light.g;
                        clippedVerticesItems[s + 4] = light.b;
                        clippedVerticesItems[s + 5] = light.a;
                        if (!twoColor) {
                            clippedVerticesItems[s + 6] = u1;
                            clippedVerticesItems[s + 7] = v1;
                            clippedVerticesItems[s + 8] = x2;
                            clippedVerticesItems[s + 9] = y2;
                            clippedVerticesItems[s + 10] = light.r;
                            clippedVerticesItems[s + 11] = light.g;
                            clippedVerticesItems[s + 12] = light.b;
                            clippedVerticesItems[s + 13] = light.a;
                            clippedVerticesItems[s + 14] = u2;
                            clippedVerticesItems[s + 15] = v2;
                            clippedVerticesItems[s + 16] = x3;
                            clippedVerticesItems[s + 17] = y3;
                            clippedVerticesItems[s + 18] = light.r;
                            clippedVerticesItems[s + 19] = light.g;
                            clippedVerticesItems[s + 20] = light.b;
                            clippedVerticesItems[s + 21] = light.a;
                            clippedVerticesItems[s + 22] = u3;
                            clippedVerticesItems[s + 23] = v3;
                        }
                        else {
                            clippedVerticesItems[s + 6] = u1;
                            clippedVerticesItems[s + 7] = v1;
                            clippedVerticesItems[s + 8] = dark.r;
                            clippedVerticesItems[s + 9] = dark.g;
                            clippedVerticesItems[s + 10] = dark.b;
                            clippedVerticesItems[s + 11] = dark.a;
                            clippedVerticesItems[s + 12] = x2;
                            clippedVerticesItems[s + 13] = y2;
                            clippedVerticesItems[s + 14] = light.r;
                            clippedVerticesItems[s + 15] = light.g;
                            clippedVerticesItems[s + 16] = light.b;
                            clippedVerticesItems[s + 17] = light.a;
                            clippedVerticesItems[s + 18] = u2;
                            clippedVerticesItems[s + 19] = v2;
                            clippedVerticesItems[s + 20] = dark.r;
                            clippedVerticesItems[s + 21] = dark.g;
                            clippedVerticesItems[s + 22] = dark.b;
                            clippedVerticesItems[s + 23] = dark.a;
                            clippedVerticesItems[s + 24] = x3;
                            clippedVerticesItems[s + 25] = y3;
                            clippedVerticesItems[s + 26] = light.r;
                            clippedVerticesItems[s + 27] = light.g;
                            clippedVerticesItems[s + 28] = light.b;
                            clippedVerticesItems[s + 29] = light.a;
                            clippedVerticesItems[s + 30] = u3;
                            clippedVerticesItems[s + 31] = v3;
                            clippedVerticesItems[s + 32] = dark.r;
                            clippedVerticesItems[s + 33] = dark.g;
                            clippedVerticesItems[s + 34] = dark.b;
                            clippedVerticesItems[s + 35] = dark.a;
                        }
                        s = clippedTriangles.length;
                        var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3);
                        clippedTrianglesItems[s] = index;
                        clippedTrianglesItems[s + 1] = (index + 1);
                        clippedTrianglesItems[s + 2] = (index + 2);
                        index += 3;
                        continue outer;
                    }
                }
            }
        };
        SkeletonClipping.prototype.clip = function (x1, y1, x2, y2, x3, y3, clippingArea, output) {
            var originalOutput = output;
            var clipped = false;
            var input = null;
            if (clippingArea.length % 4 >= 2) {
                input = output;
                output = this.scratch;
            }
            else
                input = this.scratch;
            input.length = 0;
            input.push(x1);
            input.push(y1);
            input.push(x2);
            input.push(y2);
            input.push(x3);
            input.push(y3);
            input.push(x1);
            input.push(y1);
            output.length = 0;
            var clippingVertices = clippingArea;
            var clippingVerticesLast = clippingArea.length - 4;
            for (var i = 0;; i += 2) {
                var edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
                var edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];
                var deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;
                var inputVertices = input;
                var inputVerticesLength = input.length - 2, outputStart = output.length;
                for (var ii = 0; ii < inputVerticesLength; ii += 2) {
                    var inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
                    var inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];
                    var side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
                    if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) {
                        if (side2) {
                            output.push(inputX2);
                            output.push(inputY2);
                            continue;
                        }
                        var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
                        var s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY);
                        if (Math.abs(s) > 0.000001) {
                            var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s;
                            output.push(edgeX + (edgeX2 - edgeX) * ua);
                            output.push(edgeY + (edgeY2 - edgeY) * ua);
                        }
                        else {
                            output.push(edgeX);
                            output.push(edgeY);
                        }
                    }
                    else if (side2) {
                        var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
                        var s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY);
                        if (Math.abs(s) > 0.000001) {
                            var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s;
                            output.push(edgeX + (edgeX2 - edgeX) * ua);
                            output.push(edgeY + (edgeY2 - edgeY) * ua);
                        }
                        else {
                            output.push(edgeX);
                            output.push(edgeY);
                        }
                        output.push(inputX2);
                        output.push(inputY2);
                    }
                    clipped = true;
                }
                if (outputStart == output.length) {
                    originalOutput.length = 0;
                    return true;
                }
                output.push(output[0]);
                output.push(output[1]);
                if (i == clippingVerticesLast)
                    break;
                var temp = output;
                output = input;
                output.length = 0;
                input = temp;
            }
            if (originalOutput != output) {
                originalOutput.length = 0;
                for (var i = 0, n = output.length - 2; i < n; i++)
                    originalOutput[i] = output[i];
            }
            else
                originalOutput.length = originalOutput.length - 2;
            return clipped;
        };
        SkeletonClipping.makeClockwise = function (polygon) {
            var vertices = polygon;
            var verticeslength = polygon.length;
            var area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0;
            for (var i = 0, n = verticeslength - 3; i < n; i += 2) {
                p1x = vertices[i];
                p1y = vertices[i + 1];
                p2x = vertices[i + 2];
                p2y = vertices[i + 3];
                area += p1x * p2y - p2x * p1y;
            }
            if (area < 0)
                return;
            for (var i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) {
                var x = vertices[i], y = vertices[i + 1];
                var other = lastX - i;
                vertices[i] = vertices[other];
                vertices[i + 1] = vertices[other + 1];
                vertices[other] = x;
                vertices[other + 1] = y;
            }
        };
        return SkeletonClipping;
    }());
    spine.SkeletonClipping = SkeletonClipping;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var SkeletonData = (function () {
        function SkeletonData() {
            this.bones = new Array();
            this.slots = new Array();
            this.skins = new Array();
            this.events = new Array();
            this.animations = new Array();
            this.ikConstraints = new Array();
            this.transformConstraints = new Array();
            this.pathConstraints = new Array();
            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_5 = events[i];
                if (event_5.name == eventDataName)
                    return event_5;
            }
            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;
    }());
    spine.SkeletonData = SkeletonData;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var SkeletonJson = (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 spine.SkeletonData();
            var root = typeof (json) === "string" ? JSON.parse(json) : json;
            var skeletonMap = root.skeleton;
            if (skeletonMap != null) {
                skeletonData.hash = skeletonMap.hash;
                skeletonData.version = skeletonMap.spine;
                if ("3.8.75" == skeletonData.version)
                    throw new Error("Unsupported skeleton data, please export with a newer version of Spine.");
                skeletonData.x = skeletonMap.x;
                skeletonData.y = skeletonMap.y;
                skeletonData.width = skeletonMap.width;
                skeletonData.height = skeletonMap.height;
                skeletonData.fps = skeletonMap.fps;
                skeletonData.imagesPath = skeletonMap.images;
            }
            if (root.bones) {
                for (var i = 0; i < root.bones.length; i++) {
                    var boneMap = root.bones[i];
                    var parent_5 = null;
                    var parentName = this.getValue(boneMap, "parent", null);
                    if (parentName != null) {
                        parent_5 = skeletonData.findBone(parentName);
                        if (parent_5 == null)
                            throw new Error("Parent bone not found: " + parentName);
                    }
                    var data = new spine.BoneData(skeletonData.bones.length, boneMap.name, parent_5);
                    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);
                }
            }
            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 spine.SlotData(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 spine.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);
                }
            }
            if (root.ik) {
                for (var i = 0; i < root.ik.length; i++) {
                    var constraintMap = root.ik[i];
                    var data = new spine.IkConstraintData(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);
                }
            }
            if (root.transform) {
                for (var i = 0; i < root.transform.length; i++) {
                    var constraintMap = root.transform[i];
                    var data = new spine.TransformConstraintData(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);
                }
            }
            if (root.path) {
                for (var i = 0; i < root.path.length; i++) {
                    var constraintMap = root.path[i];
                    var data = new spine.PathConstraintData(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 == spine.PositionMode.Fixed)
                        data.position *= scale;
                    data.spacing = this.getValue(constraintMap, "spacing", 0);
                    if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed)
                        data.spacing *= scale;
                    data.rotateMix = this.getValue(constraintMap, "rotateMix", 1);
                    data.translateMix = this.getValue(constraintMap, "translateMix", 1);
                    skeletonData.pathConstraints.push(data);
                }
            }
            if (root.skins) {
                for (var i = 0; i < root.skins.length; i++) {
                    var skinMap = root.skins[i];
                    var skin = new spine.Skin(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;
                }
            }
            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_6 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
                if (parent_6 == null)
                    throw new Error("Parent mesh not found: " + linkedMesh.parent);
                linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent_6 : linkedMesh.mesh;
                linkedMesh.mesh.setParentMesh(parent_6);
                linkedMesh.mesh.updateUVs();
            }
            this.linkedMeshes.length = 0;
            if (root.events) {
                for (var eventName in root.events) {
                    var eventMap = root.events[eventName];
                    var data = new spine.EventData(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);
                }
            }
            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_7 = this.getValue(map, "parent", null);
                    if (parent_7 != null) {
                        this.linkedMeshes.push(new LinkedMesh(mesh, this.getValue(map, "skin", null), slotIndex, parent_7, this.getValue(map, "deform", true)));
                        return mesh;
                    }
                    var uvs = map.uvs;
                    this.readVertices(map, mesh, uvs.length);
                    mesh.triangles = map.triangles;
                    mesh.regionUVs = 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 = spine.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 = spine.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 = spine.Utils.toFloatArray(weights);
        };
        SkeletonJson.prototype.readAnimation = function (map, name, skeletonData) {
            var scale = this.scale;
            var timelines = new Array();
            var duration = 0;
            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 spine.AttachmentTimeline(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 spine.ColorTimeline(timelineMap.length);
                            timeline.slotIndex = slotIndex;
                            var frameIndex = 0;
                            for (var i = 0; i < timelineMap.length; i++) {
                                var valueMap = timelineMap[i];
                                var color = new spine.Color();
                                color.setFromString(valueMap.color);
                                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) * spine.ColorTimeline.ENTRIES]);
                        }
                        else if (timelineName == "twoColor") {
                            var timeline = new spine.TwoColorTimeline(timelineMap.length);
                            timeline.slotIndex = slotIndex;
                            var frameIndex = 0;
                            for (var i = 0; i < timelineMap.length; i++) {
                                var valueMap = timelineMap[i];
                                var light = new spine.Color();
                                var dark = new spine.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) * spine.TwoColorTimeline.ENTRIES]);
                        }
                        else
                            throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
                    }
                }
            }
            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 spine.RotateTimeline(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) * spine.RotateTimeline.ENTRIES]);
                        }
                        else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") {
                            var timeline = null;
                            var timelineScale = 1, defaultValue = 0;
                            if (timelineName === "scale") {
                                timeline = new spine.ScaleTimeline(timelineMap.length);
                                defaultValue = 1;
                            }
                            else if (timelineName === "shear")
                                timeline = new spine.ShearTimeline(timelineMap.length);
                            else {
                                timeline = new spine.TranslateTimeline(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) * spine.TranslateTimeline.ENTRIES]);
                        }
                        else
                            throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
                    }
                }
            }
            if (map.ik) {
                for (var constraintName in map.ik) {
                    var constraintMap = map.ik[constraintName];
                    var constraint = skeletonData.findIkConstraint(constraintName);
                    var timeline = new spine.IkConstraintTimeline(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) * spine.IkConstraintTimeline.ENTRIES]);
                }
            }
            if (map.transform) {
                for (var constraintName in map.transform) {
                    var constraintMap = map.transform[constraintName];
                    var constraint = skeletonData.findTransformConstraint(constraintName);
                    var timeline = new spine.TransformConstraintTimeline(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) * spine.TransformConstraintTimeline.ENTRIES]);
                }
            }
            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 spine.PathConstraintSpacingTimeline(timelineMap.length);
                                if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed)
                                    timelineScale = scale;
                            }
                            else {
                                timeline = new spine.PathConstraintPositionTimeline(timelineMap.length);
                                if (data.positionMode == spine.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) * spine.PathConstraintPositionTimeline.ENTRIES]);
                        }
                        else if (timelineName === "mix") {
                            var timeline = new spine.PathConstraintMixTimeline(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) * spine.PathConstraintMixTimeline.ENTRIES]);
                        }
                    }
                }
            }
            if (map.deform) {
                for (var deformName in map.deform) {
                    var deformMap = map.deform[deformName];
                    var skin = skeletonData.findSkin(deformName);
                    if (skin == null)
                        throw new Error("Skin not found: " + deformName);
                    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 spine.DeformTimeline(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 ? spine.Utils.newFloatArray(deformLength) : vertices;
                                else {
                                    deform = spine.Utils.newFloatArray(deformLength);
                                    var start = this.getValue(valueMap, "offset", 0);
                                    spine.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]);
                        }
                    }
                }
            }
            var drawOrderNode = map.drawOrder;
            if (drawOrderNode == null)
                drawOrderNode = map.draworder;
            if (drawOrderNode != null) {
                var timeline = new spine.DrawOrderTimeline(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 = spine.Utils.newArray(slotCount, -1);
                        var unchanged = spine.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);
                            while (originalIndex != slotIndex)
                                unchanged[unchangedIndex++] = originalIndex++;
                            drawOrder[originalIndex + offsetMap.offset] = originalIndex++;
                        }
                        while (originalIndex < slotCount)
                            unchanged[unchangedIndex++] = originalIndex++;
                        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]);
            }
            if (map.events) {
                var timeline = new spine.EventTimeline(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_6 = new spine.Event(spine.Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData);
                    event_6.intValue = this.getValue(eventMap, "int", eventData.intValue);
                    event_6.floatValue = this.getValue(eventMap, "float", eventData.floatValue);
                    event_6.stringValue = this.getValue(eventMap, "string", eventData.stringValue);
                    if (event_6.data.audioPath != null) {
                        event_6.volume = this.getValue(eventMap, "volume", 1);
                        event_6.balance = this.getValue(eventMap, "balance", 0);
                    }
                    timeline.setFrame(frameIndex++, event_6);
                }
                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 spine.Animation(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 spine.BlendMode.Normal;
            if (str == "additive")
                return spine.BlendMode.Additive;
            if (str == "multiply")
                return spine.BlendMode.Multiply;
            if (str == "screen")
                return spine.BlendMode.Screen;
            throw new Error("Unknown blend mode: ".concat(str));
        };
        SkeletonJson.positionModeFromString = function (str) {
            str = str.toLowerCase();
            if (str == "fixed")
                return spine.PositionMode.Fixed;
            if (str == "percent")
                return spine.PositionMode.Percent;
            throw new Error("Unknown position mode: ".concat(str));
        };
        SkeletonJson.spacingModeFromString = function (str) {
            str = str.toLowerCase();
            if (str == "length")
                return spine.SpacingMode.Length;
            if (str == "fixed")
                return spine.SpacingMode.Fixed;
            if (str == "percent")
                return spine.SpacingMode.Percent;
            throw new Error("Unknown position mode: ".concat(str));
        };
        SkeletonJson.rotateModeFromString = function (str) {
            str = str.toLowerCase();
            if (str == "tangent")
                return spine.RotateMode.Tangent;
            if (str == "chain")
                return spine.RotateMode.Chain;
            if (str == "chainscale")
                return spine.RotateMode.ChainScale;
            throw new Error("Unknown rotate mode: ".concat(str));
        };
        SkeletonJson.transformModeFromString = function (str) {
            str = str.toLowerCase();
            if (str == "normal")
                return spine.TransformMode.Normal;
            if (str == "onlytranslation")
                return spine.TransformMode.OnlyTranslation;
            if (str == "norotationorreflection")
                return spine.TransformMode.NoRotationOrReflection;
            if (str == "noscale")
                return spine.TransformMode.NoScale;
            if (str == "noscaleorreflection")
                return spine.TransformMode.NoScaleOrReflection;
            throw new Error("Unknown transform mode: ".concat(str));
        };
        return SkeletonJson;
    }());
    spine.SkeletonJson = SkeletonJson;
    var LinkedMesh = (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;
    }());
})(spine || (spine = {}));
var spine;
(function (spine) {
    var SkinEntry = (function () {
        function SkinEntry(slotIndex, name, attachment) {
            this.slotIndex = slotIndex;
            this.name = name;
            this.attachment = attachment;
        }
        return SkinEntry;
    }());
    spine.SkinEntry = SkinEntry;
    var Skin = (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 spine.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);
                }
            }
        };
        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_4 in slotAttachments) {
                        var attachment = slotAttachments[name_4];
                        if (attachment)
                            entries.push(new SkinEntry(i, name_4, attachment));
                    }
                }
            }
            return entries;
        };
        Skin.prototype.getAttachmentsForSlot = function (slotIndex, attachments) {
            var slotAttachments = this.attachments[slotIndex];
            if (slotAttachments) {
                for (var name_5 in slotAttachments) {
                    var attachment = slotAttachments[name_5];
                    if (attachment)
                        attachments.push(new SkinEntry(slotIndex, name_5, attachment));
                }
            }
        };
        Skin.prototype.clear = function () {
            this.attachments.length = 0;
            this.bones.length = 0;
            this.constraints.length = 0;
        };
        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;
    }());
    spine.Skin = Skin;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var Slot = (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 spine.Color();
            this.darkColor = data.darkColor == null ? null : new spine.Color();
            this.setToSetupPose();
        }
        Slot.prototype.getSkeleton = function () {
            return this.bone.skeleton;
        };
        Slot.prototype.getAttachment = function () {
            return this.attachment;
        };
        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;
        };
        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;
    }());
    spine.Slot = Slot;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var SlotData = (function () {
        function SlotData(index, name, boneData) {
            this.color = new spine.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;
    }());
    spine.SlotData = SlotData;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var Texture = (function () {
        function Texture(image) {
            this._image = image;
        }
        Texture.prototype.getImage = function () {
            return this._image;
        };
        Texture.filterFromString = function (text) {
            switch (text.toLowerCase()) {
                case "nearest": return TextureFilter.Nearest;
                case "linear": return TextureFilter.Linear;
                case "mipmap": return TextureFilter.MipMap;
                case "mipmapnearestnearest": return TextureFilter.MipMapNearestNearest;
                case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest;
                case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear;
                case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear;
                default: throw new Error("Unknown texture filter ".concat(text));
            }
        };
        Texture.wrapFromString = function (text) {
            switch (text.toLowerCase()) {
                case "mirroredtepeat": return TextureWrap.MirroredRepeat;
                case "clamptoedge": return TextureWrap.ClampToEdge;
                case "repeat": return TextureWrap.Repeat;
                default: throw new Error("Unknown texture wrap ".concat(text));
            }
        };
        return Texture;
    }());
    spine.Texture = Texture;
    var TextureFilter;
    (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";
    })(TextureFilter = spine.TextureFilter || (spine.TextureFilter = {}));
    var TextureWrap;
    (function (TextureWrap) {
        TextureWrap[TextureWrap["MirroredRepeat"] = 33648] = "MirroredRepeat";
        TextureWrap[TextureWrap["ClampToEdge"] = 33071] = "ClampToEdge";
        TextureWrap[TextureWrap["Repeat"] = 10497] = "Repeat";
    })(TextureWrap = spine.TextureWrap || (spine.TextureWrap = {}));
    var TextureRegion = (function () {
        function TextureRegion() {
            this.u = 0;
            this.v = 0;
            this.u2 = 0;
            this.v2 = 0;
            this.width = 0;
            this.height = 0;
            this.rotate = false;
            this.offsetX = 0;
            this.offsetY = 0;
            this.originalWidth = 0;
            this.originalHeight = 0;
        }
        return TextureRegion;
    }());
    spine.TextureRegion = TextureRegion;
    var FakeTexture = (function (_super) {
        __extends(FakeTexture, _super);
        function FakeTexture() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        FakeTexture.prototype.setFilters = function (minFilter, magFilter) { };
        FakeTexture.prototype.setWraps = function (uWrap, vWrap) { };
        FakeTexture.prototype.dispose = function () { };
        return FakeTexture;
    }(Texture));
    spine.FakeTexture = FakeTexture;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var TextureAtlas = (function () {
        function TextureAtlas(atlasText, textureLoader) {
            this.pages = new Array();
            this.regions = new Array();
            this.load(atlasText, textureLoader);
        }
        TextureAtlas.prototype.load = function (atlasText, textureLoader) {
            if (textureLoader == null)
                throw new Error("textureLoader cannot be null.");
            var reader = new TextureAtlasReader(atlasText);
            var tuple = new Array(4);
            var page = null;
            while (true) {
                var line = reader.readLine();
                if (line == null)
                    break;
                line = line.trim();
                if (line.length == 0)
                    page = null;
                else if (!page) {
                    page = new TextureAtlasPage();
                    page.name = line;
                    if (reader.readTuple(tuple) == 2) {
                        page.width = parseInt(tuple[0]);
                        page.height = parseInt(tuple[1]);
                        reader.readTuple(tuple);
                    }
                    reader.readTuple(tuple);
                    page.minFilter = spine.Texture.filterFromString(tuple[0]);
                    page.magFilter = spine.Texture.filterFromString(tuple[1]);
                    var direction = reader.readValue();
                    page.uWrap = spine.TextureWrap.ClampToEdge;
                    page.vWrap = spine.TextureWrap.ClampToEdge;
                    if (direction == "x")
                        page.uWrap = spine.TextureWrap.Repeat;
                    else if (direction == "y")
                        page.vWrap = spine.TextureWrap.Repeat;
                    else if (direction == "xy")
                        page.uWrap = page.vWrap = spine.TextureWrap.Repeat;
                    page.texture = textureLoader(line);
                    page.texture.setFilters(page.minFilter, page.magFilter);
                    page.texture.setWraps(page.uWrap, page.vWrap);
                    page.width = page.texture.getImage().width;
                    page.height = page.texture.getImage().height;
                    this.pages.push(page);
                }
                else {
                    var region = new TextureAtlasRegion();
                    region.name = line;
                    region.page = page;
                    var rotateValue = reader.readValue();
                    if (rotateValue.toLocaleLowerCase() == "true") {
                        region.degrees = 90;
                    }
                    else if (rotateValue.toLocaleLowerCase() == "false") {
                        region.degrees = 0;
                    }
                    else {
                        region.degrees = parseFloat(rotateValue);
                    }
                    region.rotate = region.degrees == 90;
                    reader.readTuple(tuple);
                    var x = parseInt(tuple[0]);
                    var y = parseInt(tuple[1]);
                    reader.readTuple(tuple);
                    var width = parseInt(tuple[0]);
                    var height = parseInt(tuple[1]);
                    region.u = x / page.width;
                    region.v = y / page.height;
                    if (region.rotate) {
                        region.u2 = (x + height) / page.width;
                        region.v2 = (y + width) / page.height;
                    }
                    else {
                        region.u2 = (x + width) / page.width;
                        region.v2 = (y + height) / page.height;
                    }
                    region.x = x;
                    region.y = y;
                    region.width = Math.abs(width);
                    region.height = Math.abs(height);
                    if (reader.readTuple(tuple) == 4) {
                        if (reader.readTuple(tuple) == 4) {
                            reader.readTuple(tuple);
                        }
                    }
                    region.originalWidth = parseInt(tuple[0]);
                    region.originalHeight = parseInt(tuple[1]);
                    reader.readTuple(tuple);
                    region.offsetX = parseInt(tuple[0]);
                    region.offsetY = parseInt(tuple[1]);
                    region.index = parseInt(reader.readValue());
                    region.texture = page.texture;
                    this.regions.push(region);
                }
            }
        };
        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].texture.dispose();
            }
        };
        return TextureAtlas;
    }());
    spine.TextureAtlas = TextureAtlas;
    var TextureAtlasReader = (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.readValue = function () {
            var line = this.readLine();
            var colon = line.indexOf(":");
            if (colon == -1)
                throw new Error("Invalid line: " + line);
            return line.substring(colon + 1).trim();
        };
        TextureAtlasReader.prototype.readTuple = function (tuple) {
            var line = this.readLine();
            var colon = line.indexOf(":");
            if (colon == -1)
                throw new Error("Invalid line: " + line);
            var i = 0, lastMatch = colon + 1;
            for (; i < 3; i++) {
                var comma = line.indexOf(",", lastMatch);
                if (comma == -1)
                    break;
                tuple[i] = line.substr(lastMatch, comma - lastMatch).trim();
                lastMatch = comma + 1;
            }
            tuple[i] = line.substring(lastMatch).trim();
            return i + 1;
        };
        return TextureAtlasReader;
    }());
    var TextureAtlasPage = (function () {
        function TextureAtlasPage() {
        }
        return TextureAtlasPage;
    }());
    spine.TextureAtlasPage = TextureAtlasPage;
    var TextureAtlasRegion = (function (_super) {
        __extends(TextureAtlasRegion, _super);
        function TextureAtlasRegion() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        return TextureAtlasRegion;
    }(spine.TextureRegion));
    spine.TextureAtlasRegion = TextureAtlasRegion;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var TransformConstraint = (function () {
        function TransformConstraint(data, skeleton) {
            this.rotateMix = 0;
            this.translateMix = 0;
            this.scaleMix = 0;
            this.shearMix = 0;
            this.temp = new spine.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 ta = target.a, tb = target.b, tc = target.c, td = target.d;
            var degRadReflect = ta * td - tb * tc > 0 ? spine.MathUtils.degRad : -spine.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;
                if (rotateMix != 0) {
                    var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
                    var r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation;
                    if (r > spine.MathUtils.PI)
                        r -= spine.MathUtils.PI2;
                    else if (r < -spine.MathUtils.PI)
                        r += spine.MathUtils.PI2;
                    r *= rotateMix;
                    var cos = Math.cos(r), sin = Math.sin(r);
                    bone.a = cos * a - sin * c;
                    bone.b = cos * b - sin * d;
                    bone.c = sin * a + cos * c;
                    bone.d = sin * b + cos * d;
                    modified = true;
                }
                if (translateMix != 0) {
                    var temp = this.temp;
                    target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY));
                    bone.worldX += (temp.x - bone.worldX) * translateMix;
                    bone.worldY += (temp.y - bone.worldY) * translateMix;
                    modified = true;
                }
                if (scaleMix > 0) {
                    var s = Math.sqrt(bone.a * bone.a + bone.c * bone.c);
                    var ts = Math.sqrt(ta * ta + tc * tc);
                    if (s > 0.00001)
                        s = (s + (ts - s + this.data.offsetScaleX) * scaleMix) / s;
                    bone.a *= s;
                    bone.c *= s;
                    s = Math.sqrt(bone.b * bone.b + bone.d * bone.d);
                    ts = Math.sqrt(tb * tb + td * td);
                    if (s > 0.00001)
                        s = (s + (ts - s + this.data.offsetScaleY) * scaleMix) / s;
                    bone.b *= s;
                    bone.d *= s;
                    modified = true;
                }
                if (shearMix > 0) {
                    var b = bone.b, d = bone.d;
                    var by = Math.atan2(d, b);
                    var r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(bone.c, bone.a));
                    if (r > spine.MathUtils.PI)
                        r -= spine.MathUtils.PI2;
                    else if (r < -spine.MathUtils.PI)
                        r += spine.MathUtils.PI2;
                    r = by + (r + offsetShearY) * shearMix;
                    var s = Math.sqrt(b * b + d * d);
                    bone.b = Math.cos(r) * s;
                    bone.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 ta = target.a, tb = target.b, tc = target.c, td = target.d;
            var degRadReflect = ta * td - tb * tc > 0 ? spine.MathUtils.degRad : -spine.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;
                if (rotateMix != 0) {
                    var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
                    var r = Math.atan2(tc, ta) + offsetRotation;
                    if (r > spine.MathUtils.PI)
                        r -= spine.MathUtils.PI2;
                    else if (r < -spine.MathUtils.PI)
                        r += spine.MathUtils.PI2;
                    r *= rotateMix;
                    var cos = Math.cos(r), sin = Math.sin(r);
                    bone.a = cos * a - sin * c;
                    bone.b = cos * b - sin * d;
                    bone.c = sin * a + cos * c;
                    bone.d = sin * b + cos * d;
                    modified = true;
                }
                if (translateMix != 0) {
                    var temp = this.temp;
                    target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY));
                    bone.worldX += temp.x * translateMix;
                    bone.worldY += temp.y * translateMix;
                    modified = true;
                }
                if (scaleMix > 0) {
                    var s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * scaleMix + 1;
                    bone.a *= s;
                    bone.c *= s;
                    s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1;
                    bone.b *= s;
                    bone.d *= s;
                    modified = true;
                }
                if (shearMix > 0) {
                    var r = Math.atan2(td, tb) - Math.atan2(tc, ta);
                    if (r > spine.MathUtils.PI)
                        r -= spine.MathUtils.PI2;
                    else if (r < -spine.MathUtils.PI)
                        r += spine.MathUtils.PI2;
                    var b = bone.b, d = bone.d;
                    r = Math.atan2(d, b) + (r - spine.MathUtils.PI / 2 + offsetShearY) * shearMix;
                    var s = Math.sqrt(b * b + d * d);
                    bone.b = Math.cos(r) * s;
                    bone.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;
    }());
    spine.TransformConstraint = TransformConstraint;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var TransformConstraintData = (function (_super) {
        __extends(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;
    }(spine.ConstraintData));
    spine.TransformConstraintData = TransformConstraintData;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var Triangulator = (function () {
        function Triangulator() {
            this.convexPolygons = new Array();
            this.convexPolygonsIndices = new Array();
            this.indicesArray = new Array();
            this.isConcaveArray = new Array();
            this.triangles = new Array();
            this.polygonPool = new spine.Pool(function () {
                return new Array();
            });
            this.polygonIndicesPool = new spine.Pool(function () {
                return new Array();
            });
        }
        Triangulator.prototype.triangulate = function (verticesArray) {
            var vertices = verticesArray;
            var vertexCount = verticesArray.length >> 1;
            var indices = this.indicesArray;
            indices.length = 0;
            for (var i = 0; i < vertexCount; i++)
                indices[i] = i;
            var isConcave = this.isConcaveArray;
            isConcave.length = 0;
            for (var i = 0, n = vertexCount; i < n; ++i)
                isConcave[i] = Triangulator.isConcave(i, vertexCount, vertices, indices);
            var triangles = this.triangles;
            triangles.length = 0;
            while (vertexCount > 3) {
                var previous = vertexCount - 1, i = 0, next = 1;
                while (true) {
                    outer: if (!isConcave[i]) {
                        var p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;
                        var p1x = vertices[p1], p1y = vertices[p1 + 1];
                        var p2x = vertices[p2], p2y = vertices[p2 + 1];
                        var p3x = vertices[p3], p3y = vertices[p3 + 1];
                        for (var ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) {
                            if (!isConcave[ii])
                                continue;
                            var v = indices[ii] << 1;
                            var vx = vertices[v], vy = vertices[v + 1];
                            if (Triangulator.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) {
                                if (Triangulator.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) {
                                    if (Triangulator.positiveArea(p2x, p2y, p3x, p3y, vx, vy))
                                        break outer;
                                }
                            }
                        }
                        break;
                    }
                    if (next == 0) {
                        do {
                            if (!isConcave[i])
                                break;
                            i--;
                        } while (i > 0);
                        break;
                    }
                    previous = i;
                    i = next;
                    next = (next + 1) % vertexCount;
                }
                triangles.push(indices[(vertexCount + i - 1) % vertexCount]);
                triangles.push(indices[i]);
                triangles.push(indices[(i + 1) % vertexCount]);
                indices.splice(i, 1);
                isConcave.splice(i, 1);
                vertexCount--;
                var previousIndex = (vertexCount + i - 1) % vertexCount;
                var nextIndex = i == vertexCount ? 0 : i;
                isConcave[previousIndex] = Triangulator.isConcave(previousIndex, vertexCount, vertices, indices);
                isConcave[nextIndex] = Triangulator.isConcave(nextIndex, vertexCount, vertices, indices);
            }
            if (vertexCount == 3) {
                triangles.push(indices[2]);
                triangles.push(indices[0]);
                triangles.push(indices[1]);
            }
            return triangles;
        };
        Triangulator.prototype.decompose = function (verticesArray, triangles) {
            var vertices = verticesArray;
            var convexPolygons = this.convexPolygons;
            this.polygonPool.freeAll(convexPolygons);
            convexPolygons.length = 0;
            var convexPolygonsIndices = this.convexPolygonsIndices;
            this.polygonIndicesPool.freeAll(convexPolygonsIndices);
            convexPolygonsIndices.length = 0;
            var polygonIndices = this.polygonIndicesPool.obtain();
            polygonIndices.length = 0;
            var polygon = this.polygonPool.obtain();
            polygon.length = 0;
            var fanBaseIndex = -1, lastWinding = 0;
            for (var i = 0, n = triangles.length; i < n; i += 3) {
                var t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1;
                var x1 = vertices[t1], y1 = vertices[t1 + 1];
                var x2 = vertices[t2], y2 = vertices[t2 + 1];
                var x3 = vertices[t3], y3 = vertices[t3 + 1];
                var merged = false;
                if (fanBaseIndex == t1) {
                    var o = polygon.length - 4;
                    var winding1 = Triangulator.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3);
                    var winding2 = Triangulator.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]);
                    if (winding1 == lastWinding && winding2 == lastWinding) {
                        polygon.push(x3);
                        polygon.push(y3);
                        polygonIndices.push(t3);
                        merged = true;
                    }
                }
                if (!merged) {
                    if (polygon.length > 0) {
                        convexPolygons.push(polygon);
                        convexPolygonsIndices.push(polygonIndices);
                    }
                    else {
                        this.polygonPool.free(polygon);
                        this.polygonIndicesPool.free(polygonIndices);
                    }
                    polygon = this.polygonPool.obtain();
                    polygon.length = 0;
                    polygon.push(x1);
                    polygon.push(y1);
                    polygon.push(x2);
                    polygon.push(y2);
                    polygon.push(x3);
                    polygon.push(y3);
                    polygonIndices = this.polygonIndicesPool.obtain();
                    polygonIndices.length = 0;
                    polygonIndices.push(t1);
                    polygonIndices.push(t2);
                    polygonIndices.push(t3);
                    lastWinding = Triangulator.winding(x1, y1, x2, y2, x3, y3);
                    fanBaseIndex = t1;
                }
            }
            if (polygon.length > 0) {
                convexPolygons.push(polygon);
                convexPolygonsIndices.push(polygonIndices);
            }
            for (var i = 0, n = convexPolygons.length; i < n; i++) {
                polygonIndices = convexPolygonsIndices[i];
                if (polygonIndices.length == 0)
                    continue;
                var firstIndex = polygonIndices[0];
                var lastIndex = polygonIndices[polygonIndices.length - 1];
                polygon = convexPolygons[i];
                var o = polygon.length - 4;
                var prevPrevX = polygon[o], prevPrevY = polygon[o + 1];
                var prevX = polygon[o + 2], prevY = polygon[o + 3];
                var firstX = polygon[0], firstY = polygon[1];
                var secondX = polygon[2], secondY = polygon[3];
                var winding = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY);
                for (var ii = 0; ii < n; ii++) {
                    if (ii == i)
                        continue;
                    var otherIndices = convexPolygonsIndices[ii];
                    if (otherIndices.length != 3)
                        continue;
                    var otherFirstIndex = otherIndices[0];
                    var otherSecondIndex = otherIndices[1];
                    var otherLastIndex = otherIndices[2];
                    var otherPoly = convexPolygons[ii];
                    var x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1];
                    if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex)
                        continue;
                    var winding1 = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3);
                    var winding2 = Triangulator.winding(x3, y3, firstX, firstY, secondX, secondY);
                    if (winding1 == winding && winding2 == winding) {
                        otherPoly.length = 0;
                        otherIndices.length = 0;
                        polygon.push(x3);
                        polygon.push(y3);
                        polygonIndices.push(otherLastIndex);
                        prevPrevX = prevX;
                        prevPrevY = prevY;
                        prevX = x3;
                        prevY = y3;
                        ii = 0;
                    }
                }
            }
            for (var i = convexPolygons.length - 1; i >= 0; i--) {
                polygon = convexPolygons[i];
                if (polygon.length == 0) {
                    convexPolygons.splice(i, 1);
                    this.polygonPool.free(polygon);
                    polygonIndices = convexPolygonsIndices[i];
                    convexPolygonsIndices.splice(i, 1);
                    this.polygonIndicesPool.free(polygonIndices);
                }
            }
            return convexPolygons;
        };
        Triangulator.isConcave = function (index, vertexCount, vertices, indices) {
            var previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
            var current = indices[index] << 1;
            var next = indices[(index + 1) % vertexCount] << 1;
            return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]);
        };
        Triangulator.positiveArea = function (p1x, p1y, p2x, p2y, p3x, p3y) {
            return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0;
        };
        Triangulator.winding = function (p1x, p1y, p2x, p2y, p3x, p3y) {
            var px = p2x - p1x, py = p2y - p1y;
            return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1;
        };
        return Triangulator;
    }());
    spine.Triangulator = Triangulator;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var IntSet = (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;
    }());
    spine.IntSet = IntSet;
    var Color = (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;
            this.clamp();
            return this;
        };
        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.0;
            this.g = parseInt(hex.substr(2, 2), 16) / 255.0;
            this.b = parseInt(hex.substr(4, 2), 16) / 255.0;
            this.a = (hex.length != 8 ? 255 : parseInt(hex.substr(6, 2), 16)) / 255.0;
            return this;
        };
        Color.prototype.add = function (r, g, b, a) {
            this.r += r;
            this.g += g;
            this.b += b;
            this.a += a;
            this.clamp();
            return this;
        };
        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.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;
    }());
    spine.Color = Color;
    var MathUtils = (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.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;
    }());
    spine.MathUtils = MathUtils;
    var Interpolation = (function () {
        function Interpolation() {
        }
        Interpolation.prototype.apply = function (start, end, a) {
            return start + (end - start) * this.applyInternal(a);
        };
        return Interpolation;
    }());
    spine.Interpolation = Interpolation;
    var Pow = (function (_super) {
        __extends(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));
    spine.Pow = Pow;
    var PowOut = (function (_super) {
        __extends(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));
    spine.PowOut = PowOut;
    var Utils = (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.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 ? Math.fround(value) : value;
        };
        Utils.webkit602BugfixHelper = function (alpha, blend) {
        };
        Utils.contains = function (array, element, identity) {
            if (identity === void 0) { identity = true; }
            for (var i = 0; i < array.length; i++) {
                if (array[i] == element)
                    return true;
            }
            return false;
        };
        Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined";
        return Utils;
    }());
    spine.Utils = Utils;
    var DebugUtils = (function () {
        function DebugUtils() {
        }
        DebugUtils.logBones = function (skeleton) {
            for (var i = 0; i < skeleton.bones.length; i++) {
                var bone = skeleton.bones[i];
                console.log(bone.data.name + ", " + bone.a + ", " + bone.b + ", " + bone.c + ", " + bone.d + ", " + bone.worldX + ", " + bone.worldY);
            }
        };
        return DebugUtils;
    }());
    spine.DebugUtils = DebugUtils;
    var Pool = (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;
    }());
    spine.Pool = Pool;
    var Vector2 = (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;
    }());
    spine.Vector2 = Vector2;
    var TimeKeeper = (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;
    }());
    spine.TimeKeeper = TimeKeeper;
    var WindowedMean = (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;
            }
            else {
                return 0;
            }
        };
        return WindowedMean;
    }());
    spine.WindowedMean = WindowedMean;
})(spine || (spine = {}));
(function () {
    if (!Math.fround) {
        Math.fround = (function (array) {
            return function (x) {
                return array[0] = x, array[0];
            };
        })(new Float32Array(1));
    }
})();
var spine;
(function (spine) {
    var Attachment = (function () {
        function Attachment(name) {
            if (name == null)
                throw new Error("name cannot be null.");
            this.name = name;
        }
        return Attachment;
    }());
    spine.Attachment = Attachment;
    var VertexAttachment = (function (_super) {
        __extends(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.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 bone = slot.bone;
                var x = bone.worldX;
                var y = bone.worldY;
                var a = bone.a, b = bone.b, c = bone.c, d = bone.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 bone = skeletonBones[bones[v]];
                        var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2];
                        wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
                        wy += (vx * bone.c + vy * bone.d + bone.worldY) * 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 bone = skeletonBones[bones[v]];
                        var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2];
                        wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
                        wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
                    }
                    worldVertices[w] = wx;
                    worldVertices[w + 1] = wy;
                }
            }
        };
        VertexAttachment.prototype.copyTo = function (attachment) {
            if (this.bones != null) {
                attachment.bones = new Array(this.bones.length);
                spine.Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length);
            }
            else
                attachment.bones = null;
            if (this.vertices != null) {
                attachment.vertices = spine.Utils.newFloatArray(this.vertices.length);
                spine.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));
    spine.VertexAttachment = VertexAttachment;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var AttachmentType;
    (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";
    })(AttachmentType = spine.AttachmentType || (spine.AttachmentType = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var BoundingBoxAttachment = (function (_super) {
        __extends(BoundingBoxAttachment, _super);
        function BoundingBoxAttachment(name) {
            var _this = _super.call(this, name) || this;
            _this.color = new spine.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;
    }(spine.VertexAttachment));
    spine.BoundingBoxAttachment = BoundingBoxAttachment;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var ClippingAttachment = (function (_super) {
        __extends(ClippingAttachment, _super);
        function ClippingAttachment(name) {
            var _this = _super.call(this, name) || this;
            _this.color = new spine.Color(0.2275, 0.2275, 0.8078, 1);
            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;
    }(spine.VertexAttachment));
    spine.ClippingAttachment = ClippingAttachment;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var MeshAttachment = (function (_super) {
        __extends(MeshAttachment, _super);
        function MeshAttachment(name) {
            var _this = _super.call(this, name) || this;
            _this.color = new spine.Color(1, 1, 1, 1);
            _this.tempColor = new spine.Color(0, 0, 0, 0);
            return _this;
        }
        MeshAttachment.prototype.updateUVs = function () {
            var regionUVs = this.regionUVs;
            if (this.uvs == null || this.uvs.length != regionUVs.length)
                this.uvs = spine.Utils.newFloatArray(regionUVs.length);
            var uvs = this.uvs;
            var n = this.uvs.length;
            var u = this.region.u, v = this.region.v, width = 0, height = 0;
            if (this.region instanceof spine.TextureAtlasRegion) {
                var region = this.region;
                var textureWidth = region.texture.getImage().width, textureHeight = region.texture.getImage().height;
                switch (region.degrees) {
                    case 90:
                        u -= (region.originalHeight - region.offsetY - region.height) / textureWidth;
                        v -= (region.originalWidth - region.offsetX - region.width) / textureHeight;
                        width = region.originalHeight / textureWidth;
                        height = region.originalWidth / textureHeight;
                        for (var i = 0; i < n; i += 2) {
                            uvs[i] = u + regionUVs[i + 1] * width;
                            uvs[i + 1] = v + (1 - regionUVs[i]) * height;
                        }
                        return;
                    case 180:
                        u -= (region.originalWidth - region.offsetX - region.width) / textureWidth;
                        v -= region.offsetY / textureHeight;
                        width = region.originalWidth / textureWidth;
                        height = region.originalHeight / textureHeight;
                        for (var i = 0; i < n; i += 2) {
                            uvs[i] = u + (1 - regionUVs[i]) * width;
                            uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height;
                        }
                        return;
                    case 270:
                        u -= region.offsetY / textureWidth;
                        v -= region.offsetX / textureHeight;
                        width = region.originalHeight / textureWidth;
                        height = region.originalWidth / textureHeight;
                        for (var i = 0; i < n; i += 2) {
                            uvs[i] = u + (1 - regionUVs[i + 1]) * width;
                            uvs[i + 1] = v + regionUVs[i] * height;
                        }
                        return;
                }
                u -= region.offsetX / textureWidth;
                v -= (region.originalHeight - region.offsetY - region.height) / textureHeight;
                width = region.originalWidth / textureWidth;
                height = region.originalHeight / textureHeight;
            }
            else if (this.region == null) {
                u = v = 0;
                width = height = 1;
            }
            else {
                width = this.region.u2 - u;
                height = this.region.v2 - v;
            }
            for (var i = 0; i < n; i += 2) {
                uvs[i] = u + regionUVs[i] * width;
                uvs[i + 1] = v + regionUVs[i + 1] * height;
            }
        };
        MeshAttachment.prototype.getParentMesh = function () {
            return this.parentMesh;
        };
        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 Array(this.regionUVs.length);
            spine.Utils.arrayCopy(this.regionUVs, 0, copy.regionUVs, 0, this.regionUVs.length);
            copy.uvs = new Array(this.uvs.length);
            spine.Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, this.uvs.length);
            copy.triangles = new Array(this.triangles.length);
            spine.Utils.arrayCopy(this.triangles, 0, copy.triangles, 0, this.triangles.length);
            copy.hullLength = this.hullLength;
            if (this.edges != null) {
                copy.edges = new Array(this.edges.length);
                spine.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;
    }(spine.VertexAttachment));
    spine.MeshAttachment = MeshAttachment;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var PathAttachment = (function (_super) {
        __extends(PathAttachment, _super);
        function PathAttachment(name) {
            var _this = _super.call(this, name) || this;
            _this.closed = false;
            _this.constantSpeed = false;
            _this.color = new spine.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);
            spine.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;
    }(spine.VertexAttachment));
    spine.PathAttachment = PathAttachment;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var PointAttachment = (function (_super) {
        __extends(PointAttachment, _super);
        function PointAttachment(name) {
            var _this = _super.call(this, name) || this;
            _this.color = new spine.Color(0.38, 0.94, 0, 1);
            return _this;
        }
        PointAttachment.prototype.computeWorldPosition = function (bone, point) {
            point.x = this.x * bone.a + this.y * bone.b + bone.worldX;
            point.y = this.x * bone.c + this.y * bone.d + bone.worldY;
            return point;
        };
        PointAttachment.prototype.computeWorldRotation = function (bone) {
            var cos = spine.MathUtils.cosDeg(this.rotation), sin = spine.MathUtils.sinDeg(this.rotation);
            var x = cos * bone.a + sin * bone.b;
            var y = cos * bone.c + sin * bone.d;
            return Math.atan2(y, x) * spine.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;
    }(spine.VertexAttachment));
    spine.PointAttachment = PointAttachment;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var RegionAttachment = (function (_super) {
        __extends(RegionAttachment, _super);
        function RegionAttachment(name) {
            var _this = _super.call(this, name) || this;
            _this.x = 0;
            _this.y = 0;
            _this.scaleX = 1;
            _this.scaleY = 1;
            _this.rotation = 0;
            _this.width = 0;
            _this.height = 0;
            _this.color = new spine.Color(1, 1, 1, 1);
            _this.offset = spine.Utils.newFloatArray(8);
            _this.uvs = spine.Utils.newFloatArray(8);
            _this.tempColor = new spine.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 x = bone.worldX, y = bone.worldY;
            var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
            var offsetX = 0, offsetY = 0;
            offsetX = vertexOffset[RegionAttachment.OX1];
            offsetY = vertexOffset[RegionAttachment.OY1];
            worldVertices[offset] = offsetX * a + offsetY * b + x;
            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;
            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;
            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;
            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;
            spine.Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, 8);
            spine.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;
    }(spine.Attachment));
    spine.RegionAttachment = RegionAttachment;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var JitterEffect = (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 += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY);
            position.y += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY);
        };
        JitterEffect.prototype.end = function () {
        };
        return JitterEffect;
    }());
    spine.JitterEffect = JitterEffect;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var SwirlEffect = (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 * spine.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 spine.PowOut(2);
        return SwirlEffect;
    }());
    spine.SwirlEffect = SwirlEffect;
})(spine || (spine = {}));
var spine;
(function (spine) {
    var canvas;
    (function (canvas) {
        var AssetManager = (function (_super) {
            __extends(AssetManager, _super);
            function AssetManager(pathPrefix) {
                if (pathPrefix === void 0) { pathPrefix = ""; }
                return _super.call(this, function (image) { return new spine.canvas.CanvasTexture(image); }, pathPrefix) || this;
            }
            return AssetManager;
        }(spine.AssetManager));
        canvas.AssetManager = AssetManager;
    })(canvas = spine.canvas || (spine.canvas = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var canvas;
    (function (canvas) {
        var CanvasTexture = (function (_super) {
            __extends(CanvasTexture, _super);
            function CanvasTexture(image) {
                return _super.call(this, image) || this;
            }
            CanvasTexture.prototype.setFilters = function (minFilter, magFilter) { };
            CanvasTexture.prototype.setWraps = function (uWrap, vWrap) { };
            CanvasTexture.prototype.dispose = function () { };
            return CanvasTexture;
        }(spine.Texture));
        canvas.CanvasTexture = CanvasTexture;
    })(canvas = spine.canvas || (spine.canvas = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var canvas;
    (function (canvas) {
        var SkeletonRenderer = (function () {
            function SkeletonRenderer(context) {
                this.triangleRendering = false;
                this.debugRendering = false;
                this.vertices = spine.Utils.newFloatArray(8 * 1024);
                this.tempColor = new spine.Color();
                this.ctx = context;
            }
            SkeletonRenderer.prototype.draw = function (skeleton) {
                if (this.triangleRendering)
                    this.drawTriangles(skeleton);
                else
                    this.drawImages(skeleton);
            };
            SkeletonRenderer.prototype.drawImages = function (skeleton) {
                var ctx = this.ctx;
                var drawOrder = skeleton.drawOrder;
                if (this.debugRendering)
                    ctx.strokeStyle = "green";
                ctx.save();
                for (var i = 0, n = drawOrder.length; i < n; i++) {
                    var slot = drawOrder[i];
                    if (!slot.bone.active)
                        continue;
                    var attachment = slot.getAttachment();
                    var regionAttachment = null;
                    var region = null;
                    var image = null;
                    if (attachment instanceof spine.RegionAttachment) {
                        regionAttachment = attachment;
                        region = regionAttachment.region;
                        image = region.texture.getImage();
                    }
                    else
                        continue;
                    var skeleton_1 = slot.bone.skeleton;
                    var skeletonColor = skeleton_1.color;
                    var slotColor = slot.color;
                    var regionColor = regionAttachment.color;
                    var alpha = skeletonColor.a * slotColor.a * regionColor.a;
                    var color = this.tempColor;
                    color.set(skeletonColor.r * slotColor.r * regionColor.r, skeletonColor.g * slotColor.g * regionColor.g, skeletonColor.b * slotColor.b * regionColor.b, alpha);
                    var att = attachment;
                    var bone = slot.bone;
                    var w = region.width;
                    var h = region.height;
                    ctx.save();
                    ctx.transform(bone.a, bone.c, bone.b, bone.d, bone.worldX, bone.worldY);
                    ctx.translate(attachment.offset[0], attachment.offset[1]);
                    ctx.rotate(attachment.rotation * Math.PI / 180);
                    var atlasScale = att.width / w;
                    ctx.scale(atlasScale * attachment.scaleX, atlasScale * attachment.scaleY);
                    ctx.translate(w / 2, h / 2);
                    if (attachment.region.rotate) {
                        var t = w;
                        w = h;
                        h = t;
                        ctx.rotate(-Math.PI / 2);
                    }
                    ctx.scale(1, -1);
                    ctx.translate(-w / 2, -h / 2);
                    ctx.globalAlpha = color.a;
                    ctx.drawImage(image, region.x, region.y, w, h, 0, 0, w, h);
                    if (this.debugRendering)
                        ctx.strokeRect(0, 0, w, h);
                    ctx.restore();
                }
                ctx.restore();
            };
            SkeletonRenderer.prototype.drawTriangles = function (skeleton) {
                var blendMode = null;
                var vertices = this.vertices;
                var triangles = null;
                var drawOrder = skeleton.drawOrder;
                for (var i = 0, n = drawOrder.length; i < n; i++) {
                    var slot = drawOrder[i];
                    var attachment = slot.getAttachment();
                    var texture = null;
                    var region = null;
                    if (attachment instanceof spine.RegionAttachment) {
                        var regionAttachment = attachment;
                        vertices = this.computeRegionVertices(slot, regionAttachment, false);
                        triangles = SkeletonRenderer.QUAD_TRIANGLES;
                        region = regionAttachment.region;
                        texture = region.texture.getImage();
                    }
                    else if (attachment instanceof spine.MeshAttachment) {
                        var mesh = attachment;
                        vertices = this.computeMeshVertices(slot, mesh, false);
                        triangles = mesh.triangles;
                        texture = mesh.region.renderObject.texture.getImage();
                    }
                    else
                        continue;
                    if (texture != null) {
                        var slotBlendMode = slot.data.blendMode;
                        if (slotBlendMode != blendMode) {
                            blendMode = slotBlendMode;
                        }
                        var skeleton_2 = slot.bone.skeleton;
                        var skeletonColor = skeleton_2.color;
                        var slotColor = slot.color;
                        var attachmentColor = attachment.color;
                        var alpha = skeletonColor.a * slotColor.a * attachmentColor.a;
                        var color = this.tempColor;
                        color.set(skeletonColor.r * slotColor.r * attachmentColor.r, skeletonColor.g * slotColor.g * attachmentColor.g, skeletonColor.b * slotColor.b * attachmentColor.b, alpha);
                        var ctx = this.ctx;
                        ctx.globalAlpha = color.a;
                        for (var j = 0; j < triangles.length; j += 3) {
                            var t1 = triangles[j] * 8, t2 = triangles[j + 1] * 8, t3 = triangles[j + 2] * 8;
                            var x0 = vertices[t1], y0 = vertices[t1 + 1], u0 = vertices[t1 + 6], v0 = vertices[t1 + 7];
                            var x1 = vertices[t2], y1 = vertices[t2 + 1], u1 = vertices[t2 + 6], v1 = vertices[t2 + 7];
                            var x2 = vertices[t3], y2 = vertices[t3 + 1], u2 = vertices[t3 + 6], v2 = vertices[t3 + 7];
                            this.drawTriangle(texture, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
                            if (this.debugRendering) {
                                ctx.strokeStyle = "green";
                                ctx.beginPath();
                                ctx.moveTo(x0, y0);
                                ctx.lineTo(x1, y1);
                                ctx.lineTo(x2, y2);
                                ctx.lineTo(x0, y0);
                                ctx.stroke();
                            }
                        }
                    }
                }
                this.ctx.globalAlpha = 1;
            };
            SkeletonRenderer.prototype.drawTriangle = function (img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2) {
                var ctx = this.ctx;
                u0 *= img.width;
                v0 *= img.height;
                u1 *= img.width;
                v1 *= img.height;
                u2 *= img.width;
                v2 *= img.height;
                ctx.beginPath();
                ctx.moveTo(x0, y0);
                ctx.lineTo(x1, y1);
                ctx.lineTo(x2, y2);
                ctx.closePath();
                x1 -= x0;
                y1 -= y0;
                x2 -= x0;
                y2 -= y0;
                u1 -= u0;
                v1 -= v0;
                u2 -= u0;
                v2 -= v0;
                var det = 1 / (u1 * v2 - u2 * v1), a = (v2 * x1 - v1 * x2) * det, b = (v2 * y1 - v1 * y2) * det, c = (u1 * x2 - u2 * x1) * det, d = (u1 * y2 - u2 * y1) * det, e = x0 - a * u0 - c * v0, f = y0 - b * u0 - d * v0;
                ctx.save();
                ctx.transform(a, b, c, d, e, f);
                ctx.clip();
                ctx.drawImage(img, 0, 0);
                ctx.restore();
            };
            SkeletonRenderer.prototype.computeRegionVertices = function (slot, region, pma) {
                var skeleton = slot.bone.skeleton;
                var skeletonColor = skeleton.color;
                var slotColor = slot.color;
                var regionColor = region.color;
                var alpha = skeletonColor.a * slotColor.a * regionColor.a;
                var multiplier = pma ? alpha : 1;
                var color = this.tempColor;
                color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
                region.computeWorldVertices(slot.bone, this.vertices, 0, SkeletonRenderer.VERTEX_SIZE);
                var vertices = this.vertices;
                var uvs = region.uvs;
                vertices[spine.RegionAttachment.C1R] = color.r;
                vertices[spine.RegionAttachment.C1G] = color.g;
                vertices[spine.RegionAttachment.C1B] = color.b;
                vertices[spine.RegionAttachment.C1A] = color.a;
                vertices[spine.RegionAttachment.U1] = uvs[0];
                vertices[spine.RegionAttachment.V1] = uvs[1];
                vertices[spine.RegionAttachment.C2R] = color.r;
                vertices[spine.RegionAttachment.C2G] = color.g;
                vertices[spine.RegionAttachment.C2B] = color.b;
                vertices[spine.RegionAttachment.C2A] = color.a;
                vertices[spine.RegionAttachment.U2] = uvs[2];
                vertices[spine.RegionAttachment.V2] = uvs[3];
                vertices[spine.RegionAttachment.C3R] = color.r;
                vertices[spine.RegionAttachment.C3G] = color.g;
                vertices[spine.RegionAttachment.C3B] = color.b;
                vertices[spine.RegionAttachment.C3A] = color.a;
                vertices[spine.RegionAttachment.U3] = uvs[4];
                vertices[spine.RegionAttachment.V3] = uvs[5];
                vertices[spine.RegionAttachment.C4R] = color.r;
                vertices[spine.RegionAttachment.C4G] = color.g;
                vertices[spine.RegionAttachment.C4B] = color.b;
                vertices[spine.RegionAttachment.C4A] = color.a;
                vertices[spine.RegionAttachment.U4] = uvs[6];
                vertices[spine.RegionAttachment.V4] = uvs[7];
                return vertices;
            };
            SkeletonRenderer.prototype.computeMeshVertices = function (slot, mesh, pma) {
                var skeleton = slot.bone.skeleton;
                var skeletonColor = skeleton.color;
                var slotColor = slot.color;
                var regionColor = mesh.color;
                var alpha = skeletonColor.a * slotColor.a * regionColor.a;
                var multiplier = pma ? alpha : 1;
                var color = this.tempColor;
                color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
                var numVertices = mesh.worldVerticesLength / 2;
                if (this.vertices.length < mesh.worldVerticesLength) {
                    this.vertices = spine.Utils.newFloatArray(mesh.worldVerticesLength);
                }
                var vertices = this.vertices;
                mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, SkeletonRenderer.VERTEX_SIZE);
                var uvs = mesh.uvs;
                for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
                    vertices[v++] = color.r;
                    vertices[v++] = color.g;
                    vertices[v++] = color.b;
                    vertices[v++] = color.a;
                    vertices[v++] = uvs[u++];
                    vertices[v++] = uvs[u++];
                    v += 2;
                }
                return vertices;
            };
            SkeletonRenderer.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
            SkeletonRenderer.VERTEX_SIZE = 2 + 2 + 4;
            return SkeletonRenderer;
        }());
        canvas.SkeletonRenderer = SkeletonRenderer;
    })(canvas = spine.canvas || (spine.canvas = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var AssetManager = (function (_super) {
            __extends(AssetManager, _super);
            function AssetManager(context, pathPrefix) {
                if (pathPrefix === void 0) { pathPrefix = ""; }
                return _super.call(this, function (image) {
                    return new spine.webgl.GLTexture(context, image);
                }, pathPrefix) || this;
            }
            return AssetManager;
        }(spine.AssetManager));
        webgl.AssetManager = AssetManager;
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var OrthoCamera = (function () {
            function OrthoCamera(viewportWidth, viewportHeight) {
                this.position = new webgl.Vector3(0, 0, 0);
                this.direction = new webgl.Vector3(0, 0, -1);
                this.up = new webgl.Vector3(0, 1, 0);
                this.near = 0;
                this.far = 100;
                this.zoom = 1;
                this.viewportWidth = 0;
                this.viewportHeight = 0;
                this.projectionView = new webgl.Matrix4();
                this.inverseProjectionView = new webgl.Matrix4();
                this.projection = new webgl.Matrix4();
                this.view = new webgl.Matrix4();
                this.tmp = new webgl.Vector3();
                this.viewportWidth = viewportWidth;
                this.viewportHeight = viewportHeight;
                this.update();
            }
            OrthoCamera.prototype.update = function () {
                var projection = this.projection;
                var view = this.view;
                var projectionView = this.projectionView;
                var inverseProjectionView = this.inverseProjectionView;
                var zoom = this.zoom, viewportWidth = this.viewportWidth, viewportHeight = this.viewportHeight;
                projection.ortho(zoom * (-viewportWidth / 2), zoom * (viewportWidth / 2), zoom * (-viewportHeight / 2), zoom * (viewportHeight / 2), this.near, this.far);
                view.lookAt(this.position, this.direction, this.up);
                projectionView.set(projection.values);
                projectionView.multiply(view);
                inverseProjectionView.set(projectionView.values).invert();
            };
            OrthoCamera.prototype.screenToWorld = function (screenCoords, screenWidth, screenHeight) {
                var x = screenCoords.x, y = screenHeight - screenCoords.y - 1;
                var tmp = this.tmp;
                tmp.x = (2 * x) / screenWidth - 1;
                tmp.y = (2 * y) / screenHeight - 1;
                tmp.z = (2 * screenCoords.z) - 1;
                tmp.project(this.inverseProjectionView);
                screenCoords.set(tmp.x, tmp.y, tmp.z);
                return screenCoords;
            };
            OrthoCamera.prototype.setViewport = function (viewportWidth, viewportHeight) {
                this.viewportWidth = viewportWidth;
                this.viewportHeight = viewportHeight;
            };
            return OrthoCamera;
        }());
        webgl.OrthoCamera = OrthoCamera;
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var GLTexture = (function (_super) {
            __extends(GLTexture, _super);
            function GLTexture(context, image, useMipMaps) {
                if (useMipMaps === void 0) { useMipMaps = false; }
                var _this = _super.call(this, image) || this;
                _this.texture = null;
                _this.boundUnit = 0;
                _this.useMipMaps = false;
                _this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
                _this.useMipMaps = useMipMaps;
                _this.restore();
                _this.context.addRestorable(_this);
                return _this;
            }
            GLTexture.prototype.setFilters = function (minFilter, magFilter) {
                var gl = this.context.gl;
                this.bind();
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, GLTexture.validateMagFilter(magFilter));
            };
            GLTexture.validateMagFilter = function (magFilter) {
                switch (magFilter) {
                    case spine.TextureFilter.MipMap:
                    case spine.TextureFilter.MipMapLinearLinear:
                    case spine.TextureFilter.MipMapLinearNearest:
                    case spine.TextureFilter.MipMapNearestLinear:
                    case spine.TextureFilter.MipMapNearestNearest:
                        return spine.TextureFilter.Linear;
                    default:
                        return magFilter;
                }
            };
            GLTexture.prototype.setWraps = function (uWrap, vWrap) {
                var gl = this.context.gl;
                this.bind();
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, uWrap);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, vWrap);
            };
            GLTexture.prototype.update = function (useMipMaps) {
                var gl = this.context.gl;
                if (!this.texture) {
                    this.texture = this.context.gl.createTexture();
                }
                this.bind();
                if (GLTexture.DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL)
                    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
                gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._image);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, useMipMaps ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
                if (useMipMaps)
                    gl.generateMipmap(gl.TEXTURE_2D);
            };
            GLTexture.prototype.restore = function () {
                this.texture = null;
                this.update(this.useMipMaps);
            };
            GLTexture.prototype.bind = function (unit) {
                if (unit === void 0) { unit = 0; }
                var gl = this.context.gl;
                this.boundUnit = unit;
                gl.activeTexture(gl.TEXTURE0 + unit);
                gl.bindTexture(gl.TEXTURE_2D, this.texture);
            };
            GLTexture.prototype.unbind = function () {
                var gl = this.context.gl;
                gl.activeTexture(gl.TEXTURE0 + this.boundUnit);
                gl.bindTexture(gl.TEXTURE_2D, null);
            };
            GLTexture.prototype.dispose = function () {
                this.context.removeRestorable(this);
                var gl = this.context.gl;
                gl.deleteTexture(this.texture);
            };
            GLTexture.DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL = false;
            return GLTexture;
        }(spine.Texture));
        webgl.GLTexture = GLTexture;
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        webgl.M00 = 0;
        webgl.M01 = 4;
        webgl.M02 = 8;
        webgl.M03 = 12;
        webgl.M10 = 1;
        webgl.M11 = 5;
        webgl.M12 = 9;
        webgl.M13 = 13;
        webgl.M20 = 2;
        webgl.M21 = 6;
        webgl.M22 = 10;
        webgl.M23 = 14;
        webgl.M30 = 3;
        webgl.M31 = 7;
        webgl.M32 = 11;
        webgl.M33 = 15;
        var Matrix4 = (function () {
            function Matrix4() {
                this.temp = new Float32Array(16);
                this.values = new Float32Array(16);
                var v = this.values;
                v[webgl.M00] = 1;
                v[webgl.M11] = 1;
                v[webgl.M22] = 1;
                v[webgl.M33] = 1;
            }
            Matrix4.prototype.set = function (values) {
                this.values.set(values);
                return this;
            };
            Matrix4.prototype.transpose = function () {
                var t = this.temp;
                var v = this.values;
                t[webgl.M00] = v[webgl.M00];
                t[webgl.M01] = v[webgl.M10];
                t[webgl.M02] = v[webgl.M20];
                t[webgl.M03] = v[webgl.M30];
                t[webgl.M10] = v[webgl.M01];
                t[webgl.M11] = v[webgl.M11];
                t[webgl.M12] = v[webgl.M21];
                t[webgl.M13] = v[webgl.M31];
                t[webgl.M20] = v[webgl.M02];
                t[webgl.M21] = v[webgl.M12];
                t[webgl.M22] = v[webgl.M22];
                t[webgl.M23] = v[webgl.M32];
                t[webgl.M30] = v[webgl.M03];
                t[webgl.M31] = v[webgl.M13];
                t[webgl.M32] = v[webgl.M23];
                t[webgl.M33] = v[webgl.M33];
                return this.set(t);
            };
            Matrix4.prototype.identity = function () {
                var v = this.values;
                v[webgl.M00] = 1;
                v[webgl.M01] = 0;
                v[webgl.M02] = 0;
                v[webgl.M03] = 0;
                v[webgl.M10] = 0;
                v[webgl.M11] = 1;
                v[webgl.M12] = 0;
                v[webgl.M13] = 0;
                v[webgl.M20] = 0;
                v[webgl.M21] = 0;
                v[webgl.M22] = 1;
                v[webgl.M23] = 0;
                v[webgl.M30] = 0;
                v[webgl.M31] = 0;
                v[webgl.M32] = 0;
                v[webgl.M33] = 1;
                return this;
            };
            Matrix4.prototype.invert = function () {
                var v = this.values;
                var t = this.temp;
                var l_det = v[webgl.M30] * v[webgl.M21] * v[webgl.M12] * v[webgl.M03] - v[webgl.M20] * v[webgl.M31] * v[webgl.M12] * v[webgl.M03] - v[webgl.M30] * v[webgl.M11] * v[webgl.M22] * v[webgl.M03]
                    + v[webgl.M10] * v[webgl.M31] * v[webgl.M22] * v[webgl.M03] + v[webgl.M20] * v[webgl.M11] * v[webgl.M32] * v[webgl.M03] - v[webgl.M10] * v[webgl.M21] * v[webgl.M32] * v[webgl.M03]
                    - v[webgl.M30] * v[webgl.M21] * v[webgl.M02] * v[webgl.M13] + v[webgl.M20] * v[webgl.M31] * v[webgl.M02] * v[webgl.M13] + v[webgl.M30] * v[webgl.M01] * v[webgl.M22] * v[webgl.M13]
                    - v[webgl.M00] * v[webgl.M31] * v[webgl.M22] * v[webgl.M13] - v[webgl.M20] * v[webgl.M01] * v[webgl.M32] * v[webgl.M13] + v[webgl.M00] * v[webgl.M21] * v[webgl.M32] * v[webgl.M13]
                    + v[webgl.M30] * v[webgl.M11] * v[webgl.M02] * v[webgl.M23] - v[webgl.M10] * v[webgl.M31] * v[webgl.M02] * v[webgl.M23] - v[webgl.M30] * v[webgl.M01] * v[webgl.M12] * v[webgl.M23]
                    + v[webgl.M00] * v[webgl.M31] * v[webgl.M12] * v[webgl.M23] + v[webgl.M10] * v[webgl.M01] * v[webgl.M32] * v[webgl.M23] - v[webgl.M00] * v[webgl.M11] * v[webgl.M32] * v[webgl.M23]
                    - v[webgl.M20] * v[webgl.M11] * v[webgl.M02] * v[webgl.M33] + v[webgl.M10] * v[webgl.M21] * v[webgl.M02] * v[webgl.M33] + v[webgl.M20] * v[webgl.M01] * v[webgl.M12] * v[webgl.M33]
                    - v[webgl.M00] * v[webgl.M21] * v[webgl.M12] * v[webgl.M33] - v[webgl.M10] * v[webgl.M01] * v[webgl.M22] * v[webgl.M33] + v[webgl.M00] * v[webgl.M11] * v[webgl.M22] * v[webgl.M33];
                if (l_det == 0)
                    throw new Error("non-invertible matrix");
                var inv_det = 1.0 / l_det;
                t[webgl.M00] = v[webgl.M12] * v[webgl.M23] * v[webgl.M31] - v[webgl.M13] * v[webgl.M22] * v[webgl.M31] + v[webgl.M13] * v[webgl.M21] * v[webgl.M32]
                    - v[webgl.M11] * v[webgl.M23] * v[webgl.M32] - v[webgl.M12] * v[webgl.M21] * v[webgl.M33] + v[webgl.M11] * v[webgl.M22] * v[webgl.M33];
                t[webgl.M01] = v[webgl.M03] * v[webgl.M22] * v[webgl.M31] - v[webgl.M02] * v[webgl.M23] * v[webgl.M31] - v[webgl.M03] * v[webgl.M21] * v[webgl.M32]
                    + v[webgl.M01] * v[webgl.M23] * v[webgl.M32] + v[webgl.M02] * v[webgl.M21] * v[webgl.M33] - v[webgl.M01] * v[webgl.M22] * v[webgl.M33];
                t[webgl.M02] = v[webgl.M02] * v[webgl.M13] * v[webgl.M31] - v[webgl.M03] * v[webgl.M12] * v[webgl.M31] + v[webgl.M03] * v[webgl.M11] * v[webgl.M32]
                    - v[webgl.M01] * v[webgl.M13] * v[webgl.M32] - v[webgl.M02] * v[webgl.M11] * v[webgl.M33] + v[webgl.M01] * v[webgl.M12] * v[webgl.M33];
                t[webgl.M03] = v[webgl.M03] * v[webgl.M12] * v[webgl.M21] - v[webgl.M02] * v[webgl.M13] * v[webgl.M21] - v[webgl.M03] * v[webgl.M11] * v[webgl.M22]
                    + v[webgl.M01] * v[webgl.M13] * v[webgl.M22] + v[webgl.M02] * v[webgl.M11] * v[webgl.M23] - v[webgl.M01] * v[webgl.M12] * v[webgl.M23];
                t[webgl.M10] = v[webgl.M13] * v[webgl.M22] * v[webgl.M30] - v[webgl.M12] * v[webgl.M23] * v[webgl.M30] - v[webgl.M13] * v[webgl.M20] * v[webgl.M32]
                    + v[webgl.M10] * v[webgl.M23] * v[webgl.M32] + v[webgl.M12] * v[webgl.M20] * v[webgl.M33] - v[webgl.M10] * v[webgl.M22] * v[webgl.M33];
                t[webgl.M11] = v[webgl.M02] * v[webgl.M23] * v[webgl.M30] - v[webgl.M03] * v[webgl.M22] * v[webgl.M30] + v[webgl.M03] * v[webgl.M20] * v[webgl.M32]
                    - v[webgl.M00] * v[webgl.M23] * v[webgl.M32] - v[webgl.M02] * v[webgl.M20] * v[webgl.M33] + v[webgl.M00] * v[webgl.M22] * v[webgl.M33];
                t[webgl.M12] = v[webgl.M03] * v[webgl.M12] * v[webgl.M30] - v[webgl.M02] * v[webgl.M13] * v[webgl.M30] - v[webgl.M03] * v[webgl.M10] * v[webgl.M32]
                    + v[webgl.M00] * v[webgl.M13] * v[webgl.M32] + v[webgl.M02] * v[webgl.M10] * v[webgl.M33] - v[webgl.M00] * v[webgl.M12] * v[webgl.M33];
                t[webgl.M13] = v[webgl.M02] * v[webgl.M13] * v[webgl.M20] - v[webgl.M03] * v[webgl.M12] * v[webgl.M20] + v[webgl.M03] * v[webgl.M10] * v[webgl.M22]
                    - v[webgl.M00] * v[webgl.M13] * v[webgl.M22] - v[webgl.M02] * v[webgl.M10] * v[webgl.M23] + v[webgl.M00] * v[webgl.M12] * v[webgl.M23];
                t[webgl.M20] = v[webgl.M11] * v[webgl.M23] * v[webgl.M30] - v[webgl.M13] * v[webgl.M21] * v[webgl.M30] + v[webgl.M13] * v[webgl.M20] * v[webgl.M31]
                    - v[webgl.M10] * v[webgl.M23] * v[webgl.M31] - v[webgl.M11] * v[webgl.M20] * v[webgl.M33] + v[webgl.M10] * v[webgl.M21] * v[webgl.M33];
                t[webgl.M21] = v[webgl.M03] * v[webgl.M21] * v[webgl.M30] - v[webgl.M01] * v[webgl.M23] * v[webgl.M30] - v[webgl.M03] * v[webgl.M20] * v[webgl.M31]
                    + v[webgl.M00] * v[webgl.M23] * v[webgl.M31] + v[webgl.M01] * v[webgl.M20] * v[webgl.M33] - v[webgl.M00] * v[webgl.M21] * v[webgl.M33];
                t[webgl.M22] = v[webgl.M01] * v[webgl.M13] * v[webgl.M30] - v[webgl.M03] * v[webgl.M11] * v[webgl.M30] + v[webgl.M03] * v[webgl.M10] * v[webgl.M31]
                    - v[webgl.M00] * v[webgl.M13] * v[webgl.M31] - v[webgl.M01] * v[webgl.M10] * v[webgl.M33] + v[webgl.M00] * v[webgl.M11] * v[webgl.M33];
                t[webgl.M23] = v[webgl.M03] * v[webgl.M11] * v[webgl.M20] - v[webgl.M01] * v[webgl.M13] * v[webgl.M20] - v[webgl.M03] * v[webgl.M10] * v[webgl.M21]
                    + v[webgl.M00] * v[webgl.M13] * v[webgl.M21] + v[webgl.M01] * v[webgl.M10] * v[webgl.M23] - v[webgl.M00] * v[webgl.M11] * v[webgl.M23];
                t[webgl.M30] = v[webgl.M12] * v[webgl.M21] * v[webgl.M30] - v[webgl.M11] * v[webgl.M22] * v[webgl.M30] - v[webgl.M12] * v[webgl.M20] * v[webgl.M31]
                    + v[webgl.M10] * v[webgl.M22] * v[webgl.M31] + v[webgl.M11] * v[webgl.M20] * v[webgl.M32] - v[webgl.M10] * v[webgl.M21] * v[webgl.M32];
                t[webgl.M31] = v[webgl.M01] * v[webgl.M22] * v[webgl.M30] - v[webgl.M02] * v[webgl.M21] * v[webgl.M30] + v[webgl.M02] * v[webgl.M20] * v[webgl.M31]
                    - v[webgl.M00] * v[webgl.M22] * v[webgl.M31] - v[webgl.M01] * v[webgl.M20] * v[webgl.M32] + v[webgl.M00] * v[webgl.M21] * v[webgl.M32];
                t[webgl.M32] = v[webgl.M02] * v[webgl.M11] * v[webgl.M30] - v[webgl.M01] * v[webgl.M12] * v[webgl.M30] - v[webgl.M02] * v[webgl.M10] * v[webgl.M31]
                    + v[webgl.M00] * v[webgl.M12] * v[webgl.M31] + v[webgl.M01] * v[webgl.M10] * v[webgl.M32] - v[webgl.M00] * v[webgl.M11] * v[webgl.M32];
                t[webgl.M33] = v[webgl.M01] * v[webgl.M12] * v[webgl.M20] - v[webgl.M02] * v[webgl.M11] * v[webgl.M20] + v[webgl.M02] * v[webgl.M10] * v[webgl.M21]
                    - v[webgl.M00] * v[webgl.M12] * v[webgl.M21] - v[webgl.M01] * v[webgl.M10] * v[webgl.M22] + v[webgl.M00] * v[webgl.M11] * v[webgl.M22];
                v[webgl.M00] = t[webgl.M00] * inv_det;
                v[webgl.M01] = t[webgl.M01] * inv_det;
                v[webgl.M02] = t[webgl.M02] * inv_det;
                v[webgl.M03] = t[webgl.M03] * inv_det;
                v[webgl.M10] = t[webgl.M10] * inv_det;
                v[webgl.M11] = t[webgl.M11] * inv_det;
                v[webgl.M12] = t[webgl.M12] * inv_det;
                v[webgl.M13] = t[webgl.M13] * inv_det;
                v[webgl.M20] = t[webgl.M20] * inv_det;
                v[webgl.M21] = t[webgl.M21] * inv_det;
                v[webgl.M22] = t[webgl.M22] * inv_det;
                v[webgl.M23] = t[webgl.M23] * inv_det;
                v[webgl.M30] = t[webgl.M30] * inv_det;
                v[webgl.M31] = t[webgl.M31] * inv_det;
                v[webgl.M32] = t[webgl.M32] * inv_det;
                v[webgl.M33] = t[webgl.M33] * inv_det;
                return this;
            };
            Matrix4.prototype.determinant = function () {
                var v = this.values;
                return v[webgl.M30] * v[webgl.M21] * v[webgl.M12] * v[webgl.M03] - v[webgl.M20] * v[webgl.M31] * v[webgl.M12] * v[webgl.M03] - v[webgl.M30] * v[webgl.M11] * v[webgl.M22] * v[webgl.M03]
                    + v[webgl.M10] * v[webgl.M31] * v[webgl.M22] * v[webgl.M03] + v[webgl.M20] * v[webgl.M11] * v[webgl.M32] * v[webgl.M03] - v[webgl.M10] * v[webgl.M21] * v[webgl.M32] * v[webgl.M03]
                    - v[webgl.M30] * v[webgl.M21] * v[webgl.M02] * v[webgl.M13] + v[webgl.M20] * v[webgl.M31] * v[webgl.M02] * v[webgl.M13] + v[webgl.M30] * v[webgl.M01] * v[webgl.M22] * v[webgl.M13]
                    - v[webgl.M00] * v[webgl.M31] * v[webgl.M22] * v[webgl.M13] - v[webgl.M20] * v[webgl.M01] * v[webgl.M32] * v[webgl.M13] + v[webgl.M00] * v[webgl.M21] * v[webgl.M32] * v[webgl.M13]
                    + v[webgl.M30] * v[webgl.M11] * v[webgl.M02] * v[webgl.M23] - v[webgl.M10] * v[webgl.M31] * v[webgl.M02] * v[webgl.M23] - v[webgl.M30] * v[webgl.M01] * v[webgl.M12] * v[webgl.M23]
                    + v[webgl.M00] * v[webgl.M31] * v[webgl.M12] * v[webgl.M23] + v[webgl.M10] * v[webgl.M01] * v[webgl.M32] * v[webgl.M23] - v[webgl.M00] * v[webgl.M11] * v[webgl.M32] * v[webgl.M23]
                    - v[webgl.M20] * v[webgl.M11] * v[webgl.M02] * v[webgl.M33] + v[webgl.M10] * v[webgl.M21] * v[webgl.M02] * v[webgl.M33] + v[webgl.M20] * v[webgl.M01] * v[webgl.M12] * v[webgl.M33]
                    - v[webgl.M00] * v[webgl.M21] * v[webgl.M12] * v[webgl.M33] - v[webgl.M10] * v[webgl.M01] * v[webgl.M22] * v[webgl.M33] + v[webgl.M00] * v[webgl.M11] * v[webgl.M22] * v[webgl.M33];
            };
            Matrix4.prototype.translate = function (x, y, z) {
                var v = this.values;
                v[webgl.M03] += x;
                v[webgl.M13] += y;
                v[webgl.M23] += z;
                return this;
            };
            Matrix4.prototype.copy = function () {
                return new Matrix4().set(this.values);
            };
            Matrix4.prototype.projection = function (near, far, fovy, aspectRatio) {
                this.identity();
                var l_fd = (1.0 / Math.tan((fovy * (Math.PI / 180)) / 2.0));
                var l_a1 = (far + near) / (near - far);
                var l_a2 = (2 * far * near) / (near - far);
                var v = this.values;
                v[webgl.M00] = l_fd / aspectRatio;
                v[webgl.M10] = 0;
                v[webgl.M20] = 0;
                v[webgl.M30] = 0;
                v[webgl.M01] = 0;
                v[webgl.M11] = l_fd;
                v[webgl.M21] = 0;
                v[webgl.M31] = 0;
                v[webgl.M02] = 0;
                v[webgl.M12] = 0;
                v[webgl.M22] = l_a1;
                v[webgl.M32] = -1;
                v[webgl.M03] = 0;
                v[webgl.M13] = 0;
                v[webgl.M23] = l_a2;
                v[webgl.M33] = 0;
                return this;
            };
            Matrix4.prototype.ortho2d = function (x, y, width, height) {
                return this.ortho(x, x + width, y, y + height, 0, 1);
            };
            Matrix4.prototype.ortho = function (left, right, bottom, top, near, far) {
                this.identity();
                var x_orth = 2 / (right - left);
                var y_orth = 2 / (top - bottom);
                var z_orth = -2 / (far - near);
                var tx = -(right + left) / (right - left);
                var ty = -(top + bottom) / (top - bottom);
                var tz = -(far + near) / (far - near);
                var v = this.values;
                v[webgl.M00] = x_orth;
                v[webgl.M10] = 0;
                v[webgl.M20] = 0;
                v[webgl.M30] = 0;
                v[webgl.M01] = 0;
                v[webgl.M11] = y_orth;
                v[webgl.M21] = 0;
                v[webgl.M31] = 0;
                v[webgl.M02] = 0;
                v[webgl.M12] = 0;
                v[webgl.M22] = z_orth;
                v[webgl.M32] = 0;
                v[webgl.M03] = tx;
                v[webgl.M13] = ty;
                v[webgl.M23] = tz;
                v[webgl.M33] = 1;
                return this;
            };
            Matrix4.prototype.multiply = function (matrix) {
                var t = this.temp;
                var v = this.values;
                var m = matrix.values;
                t[webgl.M00] = v[webgl.M00] * m[webgl.M00] + v[webgl.M01] * m[webgl.M10] + v[webgl.M02] * m[webgl.M20] + v[webgl.M03] * m[webgl.M30];
                t[webgl.M01] = v[webgl.M00] * m[webgl.M01] + v[webgl.M01] * m[webgl.M11] + v[webgl.M02] * m[webgl.M21] + v[webgl.M03] * m[webgl.M31];
                t[webgl.M02] = v[webgl.M00] * m[webgl.M02] + v[webgl.M01] * m[webgl.M12] + v[webgl.M02] * m[webgl.M22] + v[webgl.M03] * m[webgl.M32];
                t[webgl.M03] = v[webgl.M00] * m[webgl.M03] + v[webgl.M01] * m[webgl.M13] + v[webgl.M02] * m[webgl.M23] + v[webgl.M03] * m[webgl.M33];
                t[webgl.M10] = v[webgl.M10] * m[webgl.M00] + v[webgl.M11] * m[webgl.M10] + v[webgl.M12] * m[webgl.M20] + v[webgl.M13] * m[webgl.M30];
                t[webgl.M11] = v[webgl.M10] * m[webgl.M01] + v[webgl.M11] * m[webgl.M11] + v[webgl.M12] * m[webgl.M21] + v[webgl.M13] * m[webgl.M31];
                t[webgl.M12] = v[webgl.M10] * m[webgl.M02] + v[webgl.M11] * m[webgl.M12] + v[webgl.M12] * m[webgl.M22] + v[webgl.M13] * m[webgl.M32];
                t[webgl.M13] = v[webgl.M10] * m[webgl.M03] + v[webgl.M11] * m[webgl.M13] + v[webgl.M12] * m[webgl.M23] + v[webgl.M13] * m[webgl.M33];
                t[webgl.M20] = v[webgl.M20] * m[webgl.M00] + v[webgl.M21] * m[webgl.M10] + v[webgl.M22] * m[webgl.M20] + v[webgl.M23] * m[webgl.M30];
                t[webgl.M21] = v[webgl.M20] * m[webgl.M01] + v[webgl.M21] * m[webgl.M11] + v[webgl.M22] * m[webgl.M21] + v[webgl.M23] * m[webgl.M31];
                t[webgl.M22] = v[webgl.M20] * m[webgl.M02] + v[webgl.M21] * m[webgl.M12] + v[webgl.M22] * m[webgl.M22] + v[webgl.M23] * m[webgl.M32];
                t[webgl.M23] = v[webgl.M20] * m[webgl.M03] + v[webgl.M21] * m[webgl.M13] + v[webgl.M22] * m[webgl.M23] + v[webgl.M23] * m[webgl.M33];
                t[webgl.M30] = v[webgl.M30] * m[webgl.M00] + v[webgl.M31] * m[webgl.M10] + v[webgl.M32] * m[webgl.M20] + v[webgl.M33] * m[webgl.M30];
                t[webgl.M31] = v[webgl.M30] * m[webgl.M01] + v[webgl.M31] * m[webgl.M11] + v[webgl.M32] * m[webgl.M21] + v[webgl.M33] * m[webgl.M31];
                t[webgl.M32] = v[webgl.M30] * m[webgl.M02] + v[webgl.M31] * m[webgl.M12] + v[webgl.M32] * m[webgl.M22] + v[webgl.M33] * m[webgl.M32];
                t[webgl.M33] = v[webgl.M30] * m[webgl.M03] + v[webgl.M31] * m[webgl.M13] + v[webgl.M32] * m[webgl.M23] + v[webgl.M33] * m[webgl.M33];
                return this.set(this.temp);
            };
            Matrix4.prototype.multiplyLeft = function (matrix) {
                var t = this.temp;
                var v = this.values;
                var m = matrix.values;
                t[webgl.M00] = m[webgl.M00] * v[webgl.M00] + m[webgl.M01] * v[webgl.M10] + m[webgl.M02] * v[webgl.M20] + m[webgl.M03] * v[webgl.M30];
                t[webgl.M01] = m[webgl.M00] * v[webgl.M01] + m[webgl.M01] * v[webgl.M11] + m[webgl.M02] * v[webgl.M21] + m[webgl.M03] * v[webgl.M31];
                t[webgl.M02] = m[webgl.M00] * v[webgl.M02] + m[webgl.M01] * v[webgl.M12] + m[webgl.M02] * v[webgl.M22] + m[webgl.M03] * v[webgl.M32];
                t[webgl.M03] = m[webgl.M00] * v[webgl.M03] + m[webgl.M01] * v[webgl.M13] + m[webgl.M02] * v[webgl.M23] + m[webgl.M03] * v[webgl.M33];
                t[webgl.M10] = m[webgl.M10] * v[webgl.M00] + m[webgl.M11] * v[webgl.M10] + m[webgl.M12] * v[webgl.M20] + m[webgl.M13] * v[webgl.M30];
                t[webgl.M11] = m[webgl.M10] * v[webgl.M01] + m[webgl.M11] * v[webgl.M11] + m[webgl.M12] * v[webgl.M21] + m[webgl.M13] * v[webgl.M31];
                t[webgl.M12] = m[webgl.M10] * v[webgl.M02] + m[webgl.M11] * v[webgl.M12] + m[webgl.M12] * v[webgl.M22] + m[webgl.M13] * v[webgl.M32];
                t[webgl.M13] = m[webgl.M10] * v[webgl.M03] + m[webgl.M11] * v[webgl.M13] + m[webgl.M12] * v[webgl.M23] + m[webgl.M13] * v[webgl.M33];
                t[webgl.M20] = m[webgl.M20] * v[webgl.M00] + m[webgl.M21] * v[webgl.M10] + m[webgl.M22] * v[webgl.M20] + m[webgl.M23] * v[webgl.M30];
                t[webgl.M21] = m[webgl.M20] * v[webgl.M01] + m[webgl.M21] * v[webgl.M11] + m[webgl.M22] * v[webgl.M21] + m[webgl.M23] * v[webgl.M31];
                t[webgl.M22] = m[webgl.M20] * v[webgl.M02] + m[webgl.M21] * v[webgl.M12] + m[webgl.M22] * v[webgl.M22] + m[webgl.M23] * v[webgl.M32];
                t[webgl.M23] = m[webgl.M20] * v[webgl.M03] + m[webgl.M21] * v[webgl.M13] + m[webgl.M22] * v[webgl.M23] + m[webgl.M23] * v[webgl.M33];
                t[webgl.M30] = m[webgl.M30] * v[webgl.M00] + m[webgl.M31] * v[webgl.M10] + m[webgl.M32] * v[webgl.M20] + m[webgl.M33] * v[webgl.M30];
                t[webgl.M31] = m[webgl.M30] * v[webgl.M01] + m[webgl.M31] * v[webgl.M11] + m[webgl.M32] * v[webgl.M21] + m[webgl.M33] * v[webgl.M31];
                t[webgl.M32] = m[webgl.M30] * v[webgl.M02] + m[webgl.M31] * v[webgl.M12] + m[webgl.M32] * v[webgl.M22] + m[webgl.M33] * v[webgl.M32];
                t[webgl.M33] = m[webgl.M30] * v[webgl.M03] + m[webgl.M31] * v[webgl.M13] + m[webgl.M32] * v[webgl.M23] + m[webgl.M33] * v[webgl.M33];
                return this.set(this.temp);
            };
            Matrix4.prototype.lookAt = function (position, direction, up) {
                Matrix4.initTemps();
                var xAxis = Matrix4.xAxis, yAxis = Matrix4.yAxis, zAxis = Matrix4.zAxis;
                zAxis.setFrom(direction).normalize();
                xAxis.setFrom(direction).normalize();
                xAxis.cross(up).normalize();
                yAxis.setFrom(xAxis).cross(zAxis).normalize();
                this.identity();
                var val = this.values;
                val[webgl.M00] = xAxis.x;
                val[webgl.M01] = xAxis.y;
                val[webgl.M02] = xAxis.z;
                val[webgl.M10] = yAxis.x;
                val[webgl.M11] = yAxis.y;
                val[webgl.M12] = yAxis.z;
                val[webgl.M20] = -zAxis.x;
                val[webgl.M21] = -zAxis.y;
                val[webgl.M22] = -zAxis.z;
                Matrix4.tmpMatrix.identity();
                Matrix4.tmpMatrix.values[webgl.M03] = -position.x;
                Matrix4.tmpMatrix.values[webgl.M13] = -position.y;
                Matrix4.tmpMatrix.values[webgl.M23] = -position.z;
                this.multiply(Matrix4.tmpMatrix);
                return this;
            };
            Matrix4.initTemps = function () {
                if (Matrix4.xAxis === null)
                    Matrix4.xAxis = new webgl.Vector3();
                if (Matrix4.yAxis === null)
                    Matrix4.yAxis = new webgl.Vector3();
                if (Matrix4.zAxis === null)
                    Matrix4.zAxis = new webgl.Vector3();
            };
            Matrix4.xAxis = null;
            Matrix4.yAxis = null;
            Matrix4.zAxis = null;
            Matrix4.tmpMatrix = new Matrix4();
            return Matrix4;
        }());
        webgl.Matrix4 = Matrix4;
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var Mesh = (function () {
            function Mesh(context, attributes, maxVertices, maxIndices) {
                this.attributes = attributes;
                this.verticesLength = 0;
                this.dirtyVertices = false;
                this.indicesLength = 0;
                this.dirtyIndices = false;
                this.elementsPerVertex = 0;
                this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
                this.elementsPerVertex = 0;
                for (var i = 0; i < attributes.length; i++) {
                    this.elementsPerVertex += attributes[i].numElements;
                }
                this.vertices = new Float32Array(maxVertices * this.elementsPerVertex);
                this.indices = new Uint16Array(maxIndices);
                this.context.addRestorable(this);
            }
            Mesh.prototype.getAttributes = function () { return this.attributes; };
            Mesh.prototype.maxVertices = function () { return this.vertices.length / this.elementsPerVertex; };
            Mesh.prototype.numVertices = function () { return this.verticesLength / this.elementsPerVertex; };
            Mesh.prototype.setVerticesLength = function (length) {
                this.dirtyVertices = true;
                this.verticesLength = length;
            };
            Mesh.prototype.getVertices = function () { return this.vertices; };
            Mesh.prototype.maxIndices = function () { return this.indices.length; };
            Mesh.prototype.numIndices = function () { return this.indicesLength; };
            Mesh.prototype.setIndicesLength = function (length) {
                this.dirtyIndices = true;
                this.indicesLength = length;
            };
            Mesh.prototype.getIndices = function () { return this.indices; };
            ;
            Mesh.prototype.getVertexSizeInFloats = function () {
                var size = 0;
                for (var i = 0; i < this.attributes.length; i++) {
                    var attribute = this.attributes[i];
                    size += attribute.numElements;
                }
                return size;
            };
            Mesh.prototype.setVertices = function (vertices) {
                this.dirtyVertices = true;
                if (vertices.length > this.vertices.length)
                    throw Error("Mesh can't store more than " + this.maxVertices() + " vertices");
                this.vertices.set(vertices, 0);
                this.verticesLength = vertices.length;
            };
            Mesh.prototype.setIndices = function (indices) {
                this.dirtyIndices = true;
                if (indices.length > this.indices.length)
                    throw Error("Mesh can't store more than " + this.maxIndices() + " indices");
                this.indices.set(indices, 0);
                this.indicesLength = indices.length;
            };
            Mesh.prototype.draw = function (shader, primitiveType) {
                this.drawWithOffset(shader, primitiveType, 0, this.indicesLength > 0 ? this.indicesLength : this.verticesLength / this.elementsPerVertex);
            };
            Mesh.prototype.drawWithOffset = function (shader, primitiveType, offset, count) {
                var gl = this.context.gl;
                if (this.dirtyVertices || this.dirtyIndices)
                    this.update();
                this.bind(shader);
                if (this.indicesLength > 0) {
                    gl.drawElements(primitiveType, count, gl.UNSIGNED_SHORT, offset * 2);
                }
                else {
                    gl.drawArrays(primitiveType, offset, count);
                }
                this.unbind(shader);
            };
            Mesh.prototype.bind = function (shader) {
                var gl = this.context.gl;
                gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
                var offset = 0;
                for (var i = 0; i < this.attributes.length; i++) {
                    var attrib = this.attributes[i];
                    var location_1 = shader.getAttributeLocation(attrib.name);
                    gl.enableVertexAttribArray(location_1);
                    gl.vertexAttribPointer(location_1, attrib.numElements, gl.FLOAT, false, this.elementsPerVertex * 4, offset * 4);
                    offset += attrib.numElements;
                }
                if (this.indicesLength > 0)
                    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
            };
            Mesh.prototype.unbind = function (shader) {
                var gl = this.context.gl;
                for (var i = 0; i < this.attributes.length; i++) {
                    var attrib = this.attributes[i];
                    var location_2 = shader.getAttributeLocation(attrib.name);
                    gl.disableVertexAttribArray(location_2);
                }
                gl.bindBuffer(gl.ARRAY_BUFFER, null);
                if (this.indicesLength > 0)
                    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
            };
            Mesh.prototype.update = function () {
                var gl = this.context.gl;
                if (this.dirtyVertices) {
                    if (!this.verticesBuffer) {
                        this.verticesBuffer = gl.createBuffer();
                    }
                    gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
                    gl.bufferData(gl.ARRAY_BUFFER, this.vertices.subarray(0, this.verticesLength), gl.DYNAMIC_DRAW);
                    this.dirtyVertices = false;
                }
                if (this.dirtyIndices) {
                    if (!this.indicesBuffer) {
                        this.indicesBuffer = gl.createBuffer();
                    }
                    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
                    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices.subarray(0, this.indicesLength), gl.DYNAMIC_DRAW);
                    this.dirtyIndices = false;
                }
            };
            Mesh.prototype.restore = function () {
                this.verticesBuffer = null;
                this.indicesBuffer = null;
                this.update();
            };
            Mesh.prototype.dispose = function () {
                this.context.removeRestorable(this);
                var gl = this.context.gl;
                gl.deleteBuffer(this.verticesBuffer);
                gl.deleteBuffer(this.indicesBuffer);
            };
            return Mesh;
        }());
        webgl.Mesh = Mesh;
        var VertexAttribute = (function () {
            function VertexAttribute(name, type, numElements) {
                this.name = name;
                this.type = type;
                this.numElements = numElements;
            }
            return VertexAttribute;
        }());
        webgl.VertexAttribute = VertexAttribute;
        var Position2Attribute = (function (_super) {
            __extends(Position2Attribute, _super);
            function Position2Attribute() {
                return _super.call(this, webgl.Shader.POSITION, VertexAttributeType.Float, 2) || this;
            }
            return Position2Attribute;
        }(VertexAttribute));
        webgl.Position2Attribute = Position2Attribute;
        var Position3Attribute = (function (_super) {
            __extends(Position3Attribute, _super);
            function Position3Attribute() {
                return _super.call(this, webgl.Shader.POSITION, VertexAttributeType.Float, 3) || this;
            }
            return Position3Attribute;
        }(VertexAttribute));
        webgl.Position3Attribute = Position3Attribute;
        var TexCoordAttribute = (function (_super) {
            __extends(TexCoordAttribute, _super);
            function TexCoordAttribute(unit) {
                if (unit === void 0) { unit = 0; }
                return _super.call(this, webgl.Shader.TEXCOORDS + (unit == 0 ? "" : unit), VertexAttributeType.Float, 2) || this;
            }
            return TexCoordAttribute;
        }(VertexAttribute));
        webgl.TexCoordAttribute = TexCoordAttribute;
        var ColorAttribute = (function (_super) {
            __extends(ColorAttribute, _super);
            function ColorAttribute() {
                return _super.call(this, webgl.Shader.COLOR, VertexAttributeType.Float, 4) || this;
            }
            return ColorAttribute;
        }(VertexAttribute));
        webgl.ColorAttribute = ColorAttribute;
        var Color2Attribute = (function (_super) {
            __extends(Color2Attribute, _super);
            function Color2Attribute() {
                return _super.call(this, webgl.Shader.COLOR2, VertexAttributeType.Float, 4) || this;
            }
            return Color2Attribute;
        }(VertexAttribute));
        webgl.Color2Attribute = Color2Attribute;
        var VertexAttributeType;
        (function (VertexAttributeType) {
            VertexAttributeType[VertexAttributeType["Float"] = 0] = "Float";
        })(VertexAttributeType = webgl.VertexAttributeType || (webgl.VertexAttributeType = {}));
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var PolygonBatcher = (function () {
            function PolygonBatcher(context, twoColorTint, maxVertices) {
                if (twoColorTint === void 0) { twoColorTint = true; }
                if (maxVertices === void 0) { maxVertices = 10920; }
                this.isDrawing = false;
                this.shader = null;
                this.lastTexture = null;
                this.verticesLength = 0;
                this.indicesLength = 0;
                if (maxVertices > 10920)
                    throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
                this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
                var attributes = twoColorTint ?
                    [new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute(), new webgl.Color2Attribute()] :
                    [new webgl.Position2Attribute(), new webgl.ColorAttribute(), new webgl.TexCoordAttribute()];
                this.mesh = new webgl.Mesh(context, attributes, maxVertices, maxVertices * 3);
                this.srcBlend = this.context.gl.SRC_ALPHA;
                this.dstBlend = this.context.gl.ONE_MINUS_SRC_ALPHA;
            }
            PolygonBatcher.prototype.begin = function (shader) {
                var gl = this.context.gl;
                if (this.isDrawing)
                    throw new Error("PolygonBatch is already drawing. Call PolygonBatch.end() before calling PolygonBatch.begin()");
                this.drawCalls = 0;
                this.shader = shader;
                this.lastTexture = null;
                this.isDrawing = true;
                gl.enable(gl.BLEND);
                gl.blendFunc(this.srcBlend, this.dstBlend);
            };
            PolygonBatcher.prototype.setBlendMode = function (srcBlend, dstBlend) {
                var gl = this.context.gl;
                this.srcBlend = srcBlend;
                this.dstBlend = dstBlend;
                if (this.isDrawing) {
                    this.flush();
                    gl.blendFunc(this.srcBlend, this.dstBlend);
                }
            };
            PolygonBatcher.prototype.draw = function (texture, vertices, indices) {
                if (texture != this.lastTexture) {
                    this.flush();
                    this.lastTexture = texture;
                }
                else if (this.verticesLength + vertices.length > this.mesh.getVertices().length ||
                    this.indicesLength + indices.length > this.mesh.getIndices().length) {
                    this.flush();
                }
                var indexStart = this.mesh.numVertices();
                this.mesh.getVertices().set(vertices, this.verticesLength);
                this.verticesLength += vertices.length;
                this.mesh.setVerticesLength(this.verticesLength);
                var indicesArray = this.mesh.getIndices();
                for (var i = this.indicesLength, j = 0; j < indices.length; i++, j++)
                    indicesArray[i] = indices[j] + indexStart;
                this.indicesLength += indices.length;
                this.mesh.setIndicesLength(this.indicesLength);
            };
            PolygonBatcher.prototype.flush = function () {
                var gl = this.context.gl;
                if (this.verticesLength == 0)
                    return;
                this.lastTexture.bind();
                this.mesh.draw(this.shader, gl.TRIANGLES);
                this.verticesLength = 0;
                this.indicesLength = 0;
                this.mesh.setVerticesLength(0);
                this.mesh.setIndicesLength(0);
                this.drawCalls++;
            };
            PolygonBatcher.prototype.end = function () {
                var gl = this.context.gl;
                if (!this.isDrawing)
                    throw new Error("PolygonBatch is not drawing. Call PolygonBatch.begin() before calling PolygonBatch.end()");
                if (this.verticesLength > 0 || this.indicesLength > 0)
                    this.flush();
                this.shader = null;
                this.lastTexture = null;
                this.isDrawing = false;
                gl.disable(gl.BLEND);
            };
            PolygonBatcher.prototype.getDrawCalls = function () { return this.drawCalls; };
            PolygonBatcher.prototype.dispose = function () {
                this.mesh.dispose();
            };
            return PolygonBatcher;
        }());
        webgl.PolygonBatcher = PolygonBatcher;
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var SceneRenderer = (function () {
            function SceneRenderer(canvas, context, twoColorTint) {
                if (twoColorTint === void 0) { twoColorTint = true; }
                this.twoColorTint = false;
                this.activeRenderer = null;
                this.QUAD = [
                    0, 0, 1, 1, 1, 1, 0, 0,
                    0, 0, 1, 1, 1, 1, 0, 0,
                    0, 0, 1, 1, 1, 1, 0, 0,
                    0, 0, 1, 1, 1, 1, 0, 0,
                ];
                this.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
                this.WHITE = new spine.Color(1, 1, 1, 1);
                this.canvas = canvas;
                this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
                this.twoColorTint = twoColorTint;
                this.camera = new webgl.OrthoCamera(canvas.width, canvas.height);
                this.batcherShader = twoColorTint ? webgl.Shader.newTwoColoredTextured(this.context) : webgl.Shader.newColoredTextured(this.context);
                this.batcher = new webgl.PolygonBatcher(this.context, twoColorTint);
                this.shapesShader = webgl.Shader.newColored(this.context);
                this.shapes = new webgl.ShapeRenderer(this.context);
                this.skeletonRenderer = new webgl.SkeletonRenderer(this.context, twoColorTint);
                this.skeletonDebugRenderer = new webgl.SkeletonDebugRenderer(this.context);
            }
            SceneRenderer.prototype.begin = function () {
                this.camera.update();
                this.enableRenderer(this.batcher);
            };
            SceneRenderer.prototype.drawSkeleton = function (skeleton, premultipliedAlpha, slotRangeStart, slotRangeEnd) {
                if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
                if (slotRangeStart === void 0) { slotRangeStart = -1; }
                if (slotRangeEnd === void 0) { slotRangeEnd = -1; }
                this.enableRenderer(this.batcher);
                this.skeletonRenderer.premultipliedAlpha = premultipliedAlpha;
                this.skeletonRenderer.draw(this.batcher, skeleton, slotRangeStart, slotRangeEnd);
            };
            SceneRenderer.prototype.drawSkeletonDebug = function (skeleton, premultipliedAlpha, ignoredBones) {
                if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
                if (ignoredBones === void 0) { ignoredBones = null; }
                this.enableRenderer(this.shapes);
                this.skeletonDebugRenderer.premultipliedAlpha = premultipliedAlpha;
                this.skeletonDebugRenderer.draw(this.shapes, skeleton, ignoredBones);
            };
            SceneRenderer.prototype.drawTexture = function (texture, x, y, width, height, color) {
                if (color === void 0) { color = null; }
                this.enableRenderer(this.batcher);
                if (color === null)
                    color = this.WHITE;
                var quad = this.QUAD;
                var i = 0;
                quad[i++] = x;
                quad[i++] = y;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = 0;
                quad[i++] = 1;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x + width;
                quad[i++] = y;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = 1;
                quad[i++] = 1;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x + width;
                quad[i++] = y + height;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = 1;
                quad[i++] = 0;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x;
                quad[i++] = y + height;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = 0;
                quad[i++] = 0;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                this.batcher.draw(texture, quad, this.QUAD_TRIANGLES);
            };
            SceneRenderer.prototype.drawTextureUV = function (texture, x, y, width, height, u, v, u2, v2, color) {
                if (color === void 0) { color = null; }
                this.enableRenderer(this.batcher);
                if (color === null)
                    color = this.WHITE;
                var quad = this.QUAD;
                var i = 0;
                quad[i++] = x;
                quad[i++] = y;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = u;
                quad[i++] = v;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x + width;
                quad[i++] = y;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = u2;
                quad[i++] = v;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x + width;
                quad[i++] = y + height;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = u2;
                quad[i++] = v2;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x;
                quad[i++] = y + height;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = u;
                quad[i++] = v2;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                this.batcher.draw(texture, quad, this.QUAD_TRIANGLES);
            };
            SceneRenderer.prototype.drawTextureRotated = function (texture, x, y, width, height, pivotX, pivotY, angle, color, premultipliedAlpha) {
                if (color === void 0) { color = null; }
                if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
                this.enableRenderer(this.batcher);
                if (color === null)
                    color = this.WHITE;
                var quad = this.QUAD;
                var worldOriginX = x + pivotX;
                var worldOriginY = y + pivotY;
                var fx = -pivotX;
                var fy = -pivotY;
                var fx2 = width - pivotX;
                var fy2 = height - pivotY;
                var p1x = fx;
                var p1y = fy;
                var p2x = fx;
                var p2y = fy2;
                var p3x = fx2;
                var p3y = fy2;
                var p4x = fx2;
                var p4y = fy;
                var x1 = 0;
                var y1 = 0;
                var x2 = 0;
                var y2 = 0;
                var x3 = 0;
                var y3 = 0;
                var x4 = 0;
                var y4 = 0;
                if (angle != 0) {
                    var cos = spine.MathUtils.cosDeg(angle);
                    var sin = spine.MathUtils.sinDeg(angle);
                    x1 = cos * p1x - sin * p1y;
                    y1 = sin * p1x + cos * p1y;
                    x4 = cos * p2x - sin * p2y;
                    y4 = sin * p2x + cos * p2y;
                    x3 = cos * p3x - sin * p3y;
                    y3 = sin * p3x + cos * p3y;
                    x2 = x3 + (x1 - x4);
                    y2 = y3 + (y1 - y4);
                }
                else {
                    x1 = p1x;
                    y1 = p1y;
                    x4 = p2x;
                    y4 = p2y;
                    x3 = p3x;
                    y3 = p3y;
                    x2 = p4x;
                    y2 = p4y;
                }
                x1 += worldOriginX;
                y1 += worldOriginY;
                x2 += worldOriginX;
                y2 += worldOriginY;
                x3 += worldOriginX;
                y3 += worldOriginY;
                x4 += worldOriginX;
                y4 += worldOriginY;
                var i = 0;
                quad[i++] = x1;
                quad[i++] = y1;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = 0;
                quad[i++] = 1;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x2;
                quad[i++] = y2;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = 1;
                quad[i++] = 1;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x3;
                quad[i++] = y3;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = 1;
                quad[i++] = 0;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x4;
                quad[i++] = y4;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = 0;
                quad[i++] = 0;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                this.batcher.draw(texture, quad, this.QUAD_TRIANGLES);
            };
            SceneRenderer.prototype.drawRegion = function (region, x, y, width, height, color, premultipliedAlpha) {
                if (color === void 0) { color = null; }
                if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
                this.enableRenderer(this.batcher);
                if (color === null)
                    color = this.WHITE;
                var quad = this.QUAD;
                var i = 0;
                quad[i++] = x;
                quad[i++] = y;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = region.u;
                quad[i++] = region.v2;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x + width;
                quad[i++] = y;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = region.u2;
                quad[i++] = region.v2;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x + width;
                quad[i++] = y + height;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = region.u2;
                quad[i++] = region.v;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                quad[i++] = x;
                quad[i++] = y + height;
                quad[i++] = color.r;
                quad[i++] = color.g;
                quad[i++] = color.b;
                quad[i++] = color.a;
                quad[i++] = region.u;
                quad[i++] = region.v;
                if (this.twoColorTint) {
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                    quad[i++] = 0;
                }
                this.batcher.draw(region.texture, quad, this.QUAD_TRIANGLES);
            };
            SceneRenderer.prototype.line = function (x, y, x2, y2, color, color2) {
                if (color === void 0) { color = null; }
                if (color2 === void 0) { color2 = null; }
                this.enableRenderer(this.shapes);
                this.shapes.line(x, y, x2, y2, color);
            };
            SceneRenderer.prototype.triangle = function (filled, x, y, x2, y2, x3, y3, color, color2, color3) {
                if (color === void 0) { color = null; }
                if (color2 === void 0) { color2 = null; }
                if (color3 === void 0) { color3 = null; }
                this.enableRenderer(this.shapes);
                this.shapes.triangle(filled, x, y, x2, y2, x3, y3, color, color2, color3);
            };
            SceneRenderer.prototype.quad = function (filled, x, y, x2, y2, x3, y3, x4, y4, color, color2, color3, color4) {
                if (color === void 0) { color = null; }
                if (color2 === void 0) { color2 = null; }
                if (color3 === void 0) { color3 = null; }
                if (color4 === void 0) { color4 = null; }
                this.enableRenderer(this.shapes);
                this.shapes.quad(filled, x, y, x2, y2, x3, y3, x4, y4, color, color2, color3, color4);
            };
            SceneRenderer.prototype.rect = function (filled, x, y, width, height, color) {
                if (color === void 0) { color = null; }
                this.enableRenderer(this.shapes);
                this.shapes.rect(filled, x, y, width, height, color);
            };
            SceneRenderer.prototype.rectLine = function (filled, x1, y1, x2, y2, width, color) {
                if (color === void 0) { color = null; }
                this.enableRenderer(this.shapes);
                this.shapes.rectLine(filled, x1, y1, x2, y2, width, color);
            };
            SceneRenderer.prototype.polygon = function (polygonVertices, offset, count, color) {
                if (color === void 0) { color = null; }
                this.enableRenderer(this.shapes);
                this.shapes.polygon(polygonVertices, offset, count, color);
            };
            SceneRenderer.prototype.circle = function (filled, x, y, radius, color, segments) {
                if (color === void 0) { color = null; }
                if (segments === void 0) { segments = 0; }
                this.enableRenderer(this.shapes);
                this.shapes.circle(filled, x, y, radius, color, segments);
            };
            SceneRenderer.prototype.curve = function (x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color) {
                if (color === void 0) { color = null; }
                this.enableRenderer(this.shapes);
                this.shapes.curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color);
            };
            SceneRenderer.prototype.end = function () {
                if (this.activeRenderer === this.batcher)
                    this.batcher.end();
                else if (this.activeRenderer === this.shapes)
                    this.shapes.end();
                this.activeRenderer = null;
            };
            SceneRenderer.prototype.resize = function (resizeMode) {
                var canvas = this.canvas;
                var w = canvas.clientWidth;
                var h = canvas.clientHeight;
                if (canvas.width != w || canvas.height != h) {
                    canvas.width = w;
                    canvas.height = h;
                }
                this.context.gl.viewport(0, 0, canvas.width, canvas.height);
                if (resizeMode === ResizeMode.Stretch) {
                }
                else if (resizeMode === ResizeMode.Expand) {
                    this.camera.setViewport(w, h);
                }
                else if (resizeMode === ResizeMode.Fit) {
                    var sourceWidth = canvas.width, sourceHeight = canvas.height;
                    var targetWidth = this.camera.viewportWidth, targetHeight = this.camera.viewportHeight;
                    var targetRatio = targetHeight / targetWidth;
                    var sourceRatio = sourceHeight / sourceWidth;
                    var scale = targetRatio < sourceRatio ? targetWidth / sourceWidth : targetHeight / sourceHeight;
                    this.camera.viewportWidth = sourceWidth * scale;
                    this.camera.viewportHeight = sourceHeight * scale;
                }
                this.camera.update();
            };
            SceneRenderer.prototype.enableRenderer = function (renderer) {
                if (this.activeRenderer === renderer)
                    return;
                this.end();
                if (renderer instanceof webgl.PolygonBatcher) {
                    this.batcherShader.bind();
                    this.batcherShader.setUniform4x4f(webgl.Shader.MVP_MATRIX, this.camera.projectionView.values);
                    this.batcherShader.setUniformi("u_texture", 0);
                    this.batcher.begin(this.batcherShader);
                    this.activeRenderer = this.batcher;
                }
                else if (renderer instanceof webgl.ShapeRenderer) {
                    this.shapesShader.bind();
                    this.shapesShader.setUniform4x4f(webgl.Shader.MVP_MATRIX, this.camera.projectionView.values);
                    this.shapes.begin(this.shapesShader);
                    this.activeRenderer = this.shapes;
                }
                else {
                    this.activeRenderer = this.skeletonDebugRenderer;
                }
            };
            SceneRenderer.prototype.dispose = function () {
                this.batcher.dispose();
                this.batcherShader.dispose();
                this.shapes.dispose();
                this.shapesShader.dispose();
                this.skeletonDebugRenderer.dispose();
            };
            return SceneRenderer;
        }());
        webgl.SceneRenderer = SceneRenderer;
        var ResizeMode;
        (function (ResizeMode) {
            ResizeMode[ResizeMode["Stretch"] = 0] = "Stretch";
            ResizeMode[ResizeMode["Expand"] = 1] = "Expand";
            ResizeMode[ResizeMode["Fit"] = 2] = "Fit";
        })(ResizeMode = webgl.ResizeMode || (webgl.ResizeMode = {}));
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var Shader = (function () {
            function Shader(context, vertexShader, fragmentShader) {
                this.vertexShader = vertexShader;
                this.fragmentShader = fragmentShader;
                this.vs = null;
                this.fs = null;
                this.program = null;
                this.tmp2x2 = new Float32Array(2 * 2);
                this.tmp3x3 = new Float32Array(3 * 3);
                this.tmp4x4 = new Float32Array(4 * 4);
                this.vsSource = vertexShader;
                this.fsSource = fragmentShader;
                this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
                this.context.addRestorable(this);
                this.compile();
            }
            Shader.prototype.getProgram = function () { return this.program; };
            Shader.prototype.getVertexShader = function () { return this.vertexShader; };
            Shader.prototype.getFragmentShader = function () { return this.fragmentShader; };
            Shader.prototype.getVertexShaderSource = function () { return this.vsSource; };
            Shader.prototype.getFragmentSource = function () { return this.fsSource; };
            Shader.prototype.compile = function () {
                var gl = this.context.gl;
                try {
                    this.vs = this.compileShader(gl.VERTEX_SHADER, this.vertexShader);
                    this.fs = this.compileShader(gl.FRAGMENT_SHADER, this.fragmentShader);
                    this.program = this.compileProgram(this.vs, this.fs);
                }
                catch (e) {
                    this.dispose();
                    throw e;
                }
            };
            Shader.prototype.compileShader = function (type, source) {
                var gl = this.context.gl;
                var shader = gl.createShader(type);
                gl.shaderSource(shader, source);
                gl.compileShader(shader);
                if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                    var error = "Couldn't compile shader: " + gl.getShaderInfoLog(shader);
                    gl.deleteShader(shader);
                    if (!gl.isContextLost())
                        throw new Error(error);
                }
                return shader;
            };
            Shader.prototype.compileProgram = function (vs, fs) {
                var gl = this.context.gl;
                var program = gl.createProgram();
                gl.attachShader(program, vs);
                gl.attachShader(program, fs);
                gl.linkProgram(program);
                if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
                    var error = "Couldn't compile shader program: " + gl.getProgramInfoLog(program);
                    gl.deleteProgram(program);
                    if (!gl.isContextLost())
                        throw new Error(error);
                }
                return program;
            };
            Shader.prototype.restore = function () {
                this.compile();
            };
            Shader.prototype.bind = function () {
                this.context.gl.useProgram(this.program);
            };
            Shader.prototype.unbind = function () {
                this.context.gl.useProgram(null);
            };
            Shader.prototype.setUniformi = function (uniform, value) {
                this.context.gl.uniform1i(this.getUniformLocation(uniform), value);
            };
            Shader.prototype.setUniformf = function (uniform, value) {
                this.context.gl.uniform1f(this.getUniformLocation(uniform), value);
            };
            Shader.prototype.setUniform2f = function (uniform, value, value2) {
                this.context.gl.uniform2f(this.getUniformLocation(uniform), value, value2);
            };
            Shader.prototype.setUniform3f = function (uniform, value, value2, value3) {
                this.context.gl.uniform3f(this.getUniformLocation(uniform), value, value2, value3);
            };
            Shader.prototype.setUniform4f = function (uniform, value, value2, value3, value4) {
                this.context.gl.uniform4f(this.getUniformLocation(uniform), value, value2, value3, value4);
            };
            Shader.prototype.setUniform2x2f = function (uniform, value) {
                var gl = this.context.gl;
                this.tmp2x2.set(value);
                gl.uniformMatrix2fv(this.getUniformLocation(uniform), false, this.tmp2x2);
            };
            Shader.prototype.setUniform3x3f = function (uniform, value) {
                var gl = this.context.gl;
                this.tmp3x3.set(value);
                gl.uniformMatrix3fv(this.getUniformLocation(uniform), false, this.tmp3x3);
            };
            Shader.prototype.setUniform4x4f = function (uniform, value) {
                var gl = this.context.gl;
                this.tmp4x4.set(value);
                gl.uniformMatrix4fv(this.getUniformLocation(uniform), false, this.tmp4x4);
            };
            Shader.prototype.getUniformLocation = function (uniform) {
                var gl = this.context.gl;
                var location = gl.getUniformLocation(this.program, uniform);
                if (!location && !gl.isContextLost())
                    throw new Error("Couldn't find location for uniform ".concat(uniform));
                return location;
            };
            Shader.prototype.getAttributeLocation = function (attribute) {
                var gl = this.context.gl;
                var location = gl.getAttribLocation(this.program, attribute);
                if (location == -1 && !gl.isContextLost())
                    throw new Error("Couldn't find location for attribute ".concat(attribute));
                return location;
            };
            Shader.prototype.dispose = function () {
                this.context.removeRestorable(this);
                var gl = this.context.gl;
                if (this.vs) {
                    gl.deleteShader(this.vs);
                    this.vs = null;
                }
                if (this.fs) {
                    gl.deleteShader(this.fs);
                    this.fs = null;
                }
                if (this.program) {
                    gl.deleteProgram(this.program);
                    this.program = null;
                }
            };
            Shader.newColoredTextured = function (context) {
                var vs = "\n\t\t\t\tattribute vec4 ".concat(Shader.POSITION, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR, ";\n\t\t\t\tattribute vec2 ").concat(Shader.TEXCOORDS, ";\n\t\t\t\tuniform mat4 ").concat(Shader.MVP_MATRIX, ";\n\t\t\t\tvarying vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = ").concat(Shader.COLOR, ";\n\t\t\t\t\tv_texCoords = ").concat(Shader.TEXCOORDS, ";\n\t\t\t\t\tgl_Position = ").concat(Shader.MVP_MATRIX, " * ").concat(Shader.POSITION, ";\n\t\t\t\t}\n\t\t\t");
                var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n\t\t\t\t}\n\t\t\t";
                return new Shader(context, vs, fs);
            };
            Shader.newTwoColoredTextured = function (context) {
                var vs = "\n\t\t\t\tattribute vec4 ".concat(Shader.POSITION, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR2, ";\n\t\t\t\tattribute vec2 ").concat(Shader.TEXCOORDS, ";\n\t\t\t\tuniform mat4 ").concat(Shader.MVP_MATRIX, ";\n\t\t\t\tvarying vec4 v_light;\n\t\t\t\tvarying vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_light = ").concat(Shader.COLOR, ";\n\t\t\t\t\tv_dark = ").concat(Shader.COLOR2, ";\n\t\t\t\t\tv_texCoords = ").concat(Shader.TEXCOORDS, ";\n\t\t\t\t\tgl_Position = ").concat(Shader.MVP_MATRIX, " * ").concat(Shader.POSITION, ";\n\t\t\t\t}\n\t\t\t");
                var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_light;\n\t\t\t\tvarying LOWP vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tvec4 texColor = texture2D(u_texture, v_texCoords);\n\t\t\t\t\tgl_FragColor.a = texColor.a * v_light.a;\n\t\t\t\t\tgl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n\t\t\t\t}\n\t\t\t";
                return new Shader(context, vs, fs);
            };
            Shader.newColored = function (context) {
                var vs = "\n\t\t\t\tattribute vec4 ".concat(Shader.POSITION, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR, ";\n\t\t\t\tuniform mat4 ").concat(Shader.MVP_MATRIX, ";\n\t\t\t\tvarying vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = ").concat(Shader.COLOR, ";\n\t\t\t\t\tgl_Position = ").concat(Shader.MVP_MATRIX, " * ").concat(Shader.POSITION, ";\n\t\t\t\t}\n\t\t\t");
                var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color;\n\t\t\t\t}\n\t\t\t";
                return new Shader(context, vs, fs);
            };
            Shader.MVP_MATRIX = "u_projTrans";
            Shader.POSITION = "a_position";
            Shader.COLOR = "a_color";
            Shader.COLOR2 = "a_color2";
            Shader.TEXCOORDS = "a_texCoords";
            Shader.SAMPLER = "u_texture";
            return Shader;
        }());
        webgl.Shader = Shader;
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var ShapeRenderer = (function () {
            function ShapeRenderer(context, maxVertices) {
                if (maxVertices === void 0) { maxVertices = 10920; }
                this.isDrawing = false;
                this.shapeType = ShapeType.Filled;
                this.color = new spine.Color(1, 1, 1, 1);
                this.vertexIndex = 0;
                this.tmp = new spine.Vector2();
                if (maxVertices > 10920)
                    throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
                this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
                this.mesh = new webgl.Mesh(context, [new webgl.Position2Attribute(), new webgl.ColorAttribute()], maxVertices, 0);
                this.srcBlend = this.context.gl.SRC_ALPHA;
                this.dstBlend = this.context.gl.ONE_MINUS_SRC_ALPHA;
            }
            ShapeRenderer.prototype.begin = function (shader) {
                if (this.isDrawing)
                    throw new Error("ShapeRenderer.begin() has already been called");
                this.shader = shader;
                this.vertexIndex = 0;
                this.isDrawing = true;
                var gl = this.context.gl;
                gl.enable(gl.BLEND);
                gl.blendFunc(this.srcBlend, this.dstBlend);
            };
            ShapeRenderer.prototype.setBlendMode = function (srcBlend, dstBlend) {
                var gl = this.context.gl;
                this.srcBlend = srcBlend;
                this.dstBlend = dstBlend;
                if (this.isDrawing) {
                    this.flush();
                    gl.blendFunc(this.srcBlend, this.dstBlend);
                }
            };
            ShapeRenderer.prototype.setColor = function (color) {
                this.color.setFromColor(color);
            };
            ShapeRenderer.prototype.setColorWith = function (r, g, b, a) {
                this.color.set(r, g, b, a);
            };
            ShapeRenderer.prototype.point = function (x, y, color) {
                if (color === void 0) { color = null; }
                this.check(ShapeType.Point, 1);
                if (color === null)
                    color = this.color;
                this.vertex(x, y, color);
            };
            ShapeRenderer.prototype.line = function (x, y, x2, y2, color) {
                if (color === void 0) { color = null; }
                this.check(ShapeType.Line, 2);
                var vertices = this.mesh.getVertices();
                var idx = this.vertexIndex;
                if (color === null)
                    color = this.color;
                this.vertex(x, y, color);
                this.vertex(x2, y2, color);
            };
            ShapeRenderer.prototype.triangle = function (filled, x, y, x2, y2, x3, y3, color, color2, color3) {
                if (color === void 0) { color = null; }
                if (color2 === void 0) { color2 = null; }
                if (color3 === void 0) { color3 = null; }
                this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
                var vertices = this.mesh.getVertices();
                var idx = this.vertexIndex;
                if (color === null)
                    color = this.color;
                if (color2 === null)
                    color2 = this.color;
                if (color3 === null)
                    color3 = this.color;
                if (filled) {
                    this.vertex(x, y, color);
                    this.vertex(x2, y2, color2);
                    this.vertex(x3, y3, color3);
                }
                else {
                    this.vertex(x, y, color);
                    this.vertex(x2, y2, color2);
                    this.vertex(x2, y2, color);
                    this.vertex(x3, y3, color2);
                    this.vertex(x3, y3, color);
                    this.vertex(x, y, color2);
                }
            };
            ShapeRenderer.prototype.quad = function (filled, x, y, x2, y2, x3, y3, x4, y4, color, color2, color3, color4) {
                if (color === void 0) { color = null; }
                if (color2 === void 0) { color2 = null; }
                if (color3 === void 0) { color3 = null; }
                if (color4 === void 0) { color4 = null; }
                this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
                var vertices = this.mesh.getVertices();
                var idx = this.vertexIndex;
                if (color === null)
                    color = this.color;
                if (color2 === null)
                    color2 = this.color;
                if (color3 === null)
                    color3 = this.color;
                if (color4 === null)
                    color4 = this.color;
                if (filled) {
                    this.vertex(x, y, color);
                    this.vertex(x2, y2, color2);
                    this.vertex(x3, y3, color3);
                    this.vertex(x3, y3, color3);
                    this.vertex(x4, y4, color4);
                    this.vertex(x, y, color);
                }
                else {
                    this.vertex(x, y, color);
                    this.vertex(x2, y2, color2);
                    this.vertex(x2, y2, color2);
                    this.vertex(x3, y3, color3);
                    this.vertex(x3, y3, color3);
                    this.vertex(x4, y4, color4);
                    this.vertex(x4, y4, color4);
                    this.vertex(x, y, color);
                }
            };
            ShapeRenderer.prototype.rect = function (filled, x, y, width, height, color) {
                if (color === void 0) { color = null; }
                this.quad(filled, x, y, x + width, y, x + width, y + height, x, y + height, color, color, color, color);
            };
            ShapeRenderer.prototype.rectLine = function (filled, x1, y1, x2, y2, width, color) {
                if (color === void 0) { color = null; }
                this.check(filled ? ShapeType.Filled : ShapeType.Line, 8);
                if (color === null)
                    color = this.color;
                var t = this.tmp.set(y2 - y1, x1 - x2);
                t.normalize();
                width *= 0.5;
                var tx = t.x * width;
                var ty = t.y * width;
                if (!filled) {
                    this.vertex(x1 + tx, y1 + ty, color);
                    this.vertex(x1 - tx, y1 - ty, color);
                    this.vertex(x2 + tx, y2 + ty, color);
                    this.vertex(x2 - tx, y2 - ty, color);
                    this.vertex(x2 + tx, y2 + ty, color);
                    this.vertex(x1 + tx, y1 + ty, color);
                    this.vertex(x2 - tx, y2 - ty, color);
                    this.vertex(x1 - tx, y1 - ty, color);
                }
                else {
                    this.vertex(x1 + tx, y1 + ty, color);
                    this.vertex(x1 - tx, y1 - ty, color);
                    this.vertex(x2 + tx, y2 + ty, color);
                    this.vertex(x2 - tx, y2 - ty, color);
                    this.vertex(x2 + tx, y2 + ty, color);
                    this.vertex(x1 - tx, y1 - ty, color);
                }
            };
            ShapeRenderer.prototype.x = function (x, y, size) {
                this.line(x - size, y - size, x + size, y + size);
                this.line(x - size, y + size, x + size, y - size);
            };
            ShapeRenderer.prototype.polygon = function (polygonVertices, offset, count, color) {
                if (color === void 0) { color = null; }
                if (count < 3)
                    throw new Error("Polygon must contain at least 3 vertices");
                this.check(ShapeType.Line, count * 2);
                if (color === null)
                    color = this.color;
                var vertices = this.mesh.getVertices();
                var idx = this.vertexIndex;
                offset <<= 1;
                count <<= 1;
                var firstX = polygonVertices[offset];
                var firstY = polygonVertices[offset + 1];
                var last = offset + count;
                for (var i = offset, n = offset + count - 2; i < n; i += 2) {
                    var x1 = polygonVertices[i];
                    var y1 = polygonVertices[i + 1];
                    var x2 = 0;
                    var y2 = 0;
                    if (i + 2 >= last) {
                        x2 = firstX;
                        y2 = firstY;
                    }
                    else {
                        x2 = polygonVertices[i + 2];
                        y2 = polygonVertices[i + 3];
                    }
                    this.vertex(x1, y1, color);
                    this.vertex(x2, y2, color);
                }
            };
            ShapeRenderer.prototype.circle = function (filled, x, y, radius, color, segments) {
                if (color === void 0) { color = null; }
                if (segments === void 0) { segments = 0; }
                if (segments === 0)
                    segments = Math.max(1, (6 * spine.MathUtils.cbrt(radius)) | 0);
                if (segments <= 0)
                    throw new Error("segments must be > 0.");
                if (color === null)
                    color = this.color;
                var angle = 2 * spine.MathUtils.PI / segments;
                var cos = Math.cos(angle);
                var sin = Math.sin(angle);
                var cx = radius, cy = 0;
                if (!filled) {
                    this.check(ShapeType.Line, segments * 2 + 2);
                    for (var i = 0; i < segments; i++) {
                        this.vertex(x + cx, y + cy, color);
                        var temp_1 = cx;
                        cx = cos * cx - sin * cy;
                        cy = sin * temp_1 + cos * cy;
                        this.vertex(x + cx, y + cy, color);
                    }
                    this.vertex(x + cx, y + cy, color);
                }
                else {
                    this.check(ShapeType.Filled, segments * 3 + 3);
                    segments--;
                    for (var i = 0; i < segments; i++) {
                        this.vertex(x, y, color);
                        this.vertex(x + cx, y + cy, color);
                        var temp_2 = cx;
                        cx = cos * cx - sin * cy;
                        cy = sin * temp_2 + cos * cy;
                        this.vertex(x + cx, y + cy, color);
                    }
                    this.vertex(x, y, color);
                    this.vertex(x + cx, y + cy, color);
                }
                var temp = cx;
                cx = radius;
                cy = 0;
                this.vertex(x + cx, y + cy, color);
            };
            ShapeRenderer.prototype.curve = function (x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color) {
                if (color === void 0) { color = null; }
                this.check(ShapeType.Line, segments * 2 + 2);
                if (color === null)
                    color = this.color;
                var subdiv_step = 1 / segments;
                var subdiv_step2 = subdiv_step * subdiv_step;
                var subdiv_step3 = subdiv_step * subdiv_step * subdiv_step;
                var pre1 = 3 * subdiv_step;
                var pre2 = 3 * subdiv_step2;
                var pre4 = 6 * subdiv_step2;
                var pre5 = 6 * subdiv_step3;
                var tmp1x = x1 - cx1 * 2 + cx2;
                var tmp1y = y1 - cy1 * 2 + cy2;
                var tmp2x = (cx1 - cx2) * 3 - x1 + x2;
                var tmp2y = (cy1 - cy2) * 3 - y1 + y2;
                var fx = x1;
                var fy = y1;
                var dfx = (cx1 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
                var dfy = (cy1 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
                var ddfx = tmp1x * pre4 + tmp2x * pre5;
                var ddfy = tmp1y * pre4 + tmp2y * pre5;
                var dddfx = tmp2x * pre5;
                var dddfy = tmp2y * pre5;
                while (segments-- > 0) {
                    this.vertex(fx, fy, color);
                    fx += dfx;
                    fy += dfy;
                    dfx += ddfx;
                    dfy += ddfy;
                    ddfx += dddfx;
                    ddfy += dddfy;
                    this.vertex(fx, fy, color);
                }
                this.vertex(fx, fy, color);
                this.vertex(x2, y2, color);
            };
            ShapeRenderer.prototype.vertex = function (x, y, color) {
                var idx = this.vertexIndex;
                var vertices = this.mesh.getVertices();
                vertices[idx++] = x;
                vertices[idx++] = y;
                vertices[idx++] = color.r;
                vertices[idx++] = color.g;
                vertices[idx++] = color.b;
                vertices[idx++] = color.a;
                this.vertexIndex = idx;
            };
            ShapeRenderer.prototype.end = function () {
                if (!this.isDrawing)
                    throw new Error("ShapeRenderer.begin() has not been called");
                this.flush();
                this.context.gl.disable(this.context.gl.BLEND);
                this.isDrawing = false;
            };
            ShapeRenderer.prototype.flush = function () {
                if (this.vertexIndex == 0)
                    return;
                this.mesh.setVerticesLength(this.vertexIndex);
                this.mesh.draw(this.shader, this.shapeType);
                this.vertexIndex = 0;
            };
            ShapeRenderer.prototype.check = function (shapeType, numVertices) {
                if (!this.isDrawing)
                    throw new Error("ShapeRenderer.begin() has not been called");
                if (this.shapeType == shapeType) {
                    if (this.mesh.maxVertices() - this.mesh.numVertices() < numVertices)
                        this.flush();
                    else
                        return;
                }
                else {
                    this.flush();
                    this.shapeType = shapeType;
                }
            };
            ShapeRenderer.prototype.dispose = function () {
                this.mesh.dispose();
            };
            return ShapeRenderer;
        }());
        webgl.ShapeRenderer = ShapeRenderer;
        var ShapeType;
        (function (ShapeType) {
            ShapeType[ShapeType["Point"] = 0] = "Point";
            ShapeType[ShapeType["Line"] = 1] = "Line";
            ShapeType[ShapeType["Filled"] = 4] = "Filled";
        })(ShapeType = webgl.ShapeType || (webgl.ShapeType = {}));
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var SkeletonDebugRenderer = (function () {
            function SkeletonDebugRenderer(context) {
                this.boneLineColor = new spine.Color(1, 0, 0, 1);
                this.boneOriginColor = new spine.Color(0, 1, 0, 1);
                this.attachmentLineColor = new spine.Color(0, 0, 1, 0.5);
                this.triangleLineColor = new spine.Color(1, 0.64, 0, 0.5);
                this.pathColor = new spine.Color().setFromString("FF7F00");
                this.clipColor = new spine.Color(0.8, 0, 0, 2);
                this.aabbColor = new spine.Color(0, 1, 0, 0.5);
                this.drawBones = true;
                this.drawRegionAttachments = true;
                this.drawBoundingBoxes = true;
                this.drawMeshHull = true;
                this.drawMeshTriangles = true;
                this.drawPaths = true;
                this.drawSkeletonXY = false;
                this.drawClipping = true;
                this.premultipliedAlpha = false;
                this.scale = 1;
                this.boneWidth = 2;
                this.bounds = new spine.SkeletonBounds();
                this.temp = new Array();
                this.vertices = spine.Utils.newFloatArray(2 * 1024);
                this.context = context instanceof webgl.ManagedWebGLRenderingContext ? context : new webgl.ManagedWebGLRenderingContext(context);
            }
            SkeletonDebugRenderer.prototype.draw = function (shapes, skeleton, ignoredBones) {
                if (ignoredBones === void 0) { ignoredBones = null; }
                var skeletonX = skeleton.x;
                var skeletonY = skeleton.y;
                var gl = this.context.gl;
                var srcFunc = this.premultipliedAlpha ? gl.ONE : gl.SRC_ALPHA;
                shapes.setBlendMode(srcFunc, gl.ONE_MINUS_SRC_ALPHA);
                var bones = skeleton.bones;
                if (this.drawBones) {
                    shapes.setColor(this.boneLineColor);
                    for (var i = 0, n = bones.length; i < n; i++) {
                        var bone = bones[i];
                        if (ignoredBones && ignoredBones.indexOf(bone.data.name) > -1)
                            continue;
                        if (bone.parent == null)
                            continue;
                        var x = skeletonX + bone.data.length * bone.a + bone.worldX;
                        var y = skeletonY + bone.data.length * bone.c + bone.worldY;
                        shapes.rectLine(true, skeletonX + bone.worldX, skeletonY + bone.worldY, x, y, this.boneWidth * this.scale);
                    }
                    if (this.drawSkeletonXY)
                        shapes.x(skeletonX, skeletonY, 4 * this.scale);
                }
                if (this.drawRegionAttachments) {
                    shapes.setColor(this.attachmentLineColor);
                    var slots = skeleton.slots;
                    for (var i = 0, n = slots.length; i < n; i++) {
                        var slot = slots[i];
                        var attachment = slot.getAttachment();
                        if (attachment instanceof spine.RegionAttachment) {
                            var regionAttachment = attachment;
                            var vertices = this.vertices;
                            regionAttachment.computeWorldVertices(slot.bone, vertices, 0, 2);
                            shapes.line(vertices[0], vertices[1], vertices[2], vertices[3]);
                            shapes.line(vertices[2], vertices[3], vertices[4], vertices[5]);
                            shapes.line(vertices[4], vertices[5], vertices[6], vertices[7]);
                            shapes.line(vertices[6], vertices[7], vertices[0], vertices[1]);
                        }
                    }
                }
                if (this.drawMeshHull || this.drawMeshTriangles) {
                    var slots = skeleton.slots;
                    for (var i = 0, n = slots.length; i < n; i++) {
                        var slot = slots[i];
                        if (!slot.bone.active)
                            continue;
                        var attachment = slot.getAttachment();
                        if (!(attachment instanceof spine.MeshAttachment))
                            continue;
                        var mesh = attachment;
                        var vertices = this.vertices;
                        mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, 2);
                        var triangles = mesh.triangles;
                        var hullLength = mesh.hullLength;
                        if (this.drawMeshTriangles) {
                            shapes.setColor(this.triangleLineColor);
                            for (var ii = 0, nn = triangles.length; ii < nn; ii += 3) {
                                var v1 = triangles[ii] * 2, v2 = triangles[ii + 1] * 2, v3 = triangles[ii + 2] * 2;
                                shapes.triangle(false, vertices[v1], vertices[v1 + 1], vertices[v2], vertices[v2 + 1], vertices[v3], vertices[v3 + 1]);
                            }
                        }
                        if (this.drawMeshHull && hullLength > 0) {
                            shapes.setColor(this.attachmentLineColor);
                            hullLength = (hullLength >> 1) * 2;
                            var lastX = vertices[hullLength - 2], lastY = vertices[hullLength - 1];
                            for (var ii = 0, nn = hullLength; ii < nn; ii += 2) {
                                var x = vertices[ii], y = vertices[ii + 1];
                                shapes.line(x, y, lastX, lastY);
                                lastX = x;
                                lastY = y;
                            }
                        }
                    }
                }
                if (this.drawBoundingBoxes) {
                    var bounds = this.bounds;
                    bounds.update(skeleton, true);
                    shapes.setColor(this.aabbColor);
                    shapes.rect(false, bounds.minX, bounds.minY, bounds.getWidth(), bounds.getHeight());
                    var polygons = bounds.polygons;
                    var boxes = bounds.boundingBoxes;
                    for (var i = 0, n = polygons.length; i < n; i++) {
                        var polygon = polygons[i];
                        shapes.setColor(boxes[i].color);
                        shapes.polygon(polygon, 0, polygon.length);
                    }
                }
                if (this.drawPaths) {
                    var slots = skeleton.slots;
                    for (var i = 0, n = slots.length; i < n; i++) {
                        var slot = slots[i];
                        if (!slot.bone.active)
                            continue;
                        var attachment = slot.getAttachment();
                        if (!(attachment instanceof spine.PathAttachment))
                            continue;
                        var path = attachment;
                        var nn = path.worldVerticesLength;
                        var world = this.temp = spine.Utils.setArraySize(this.temp, nn, 0);
                        path.computeWorldVertices(slot, 0, nn, world, 0, 2);
                        var color = this.pathColor;
                        var x1 = world[2], y1 = world[3], x2 = 0, y2 = 0;
                        if (path.closed) {
                            shapes.setColor(color);
                            var cx1 = world[0], cy1 = world[1], cx2 = world[nn - 2], cy2 = world[nn - 1];
                            x2 = world[nn - 4];
                            y2 = world[nn - 3];
                            shapes.curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, 32);
                            shapes.setColor(SkeletonDebugRenderer.LIGHT_GRAY);
                            shapes.line(x1, y1, cx1, cy1);
                            shapes.line(x2, y2, 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];
                            shapes.setColor(color);
                            shapes.curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, 32);
                            shapes.setColor(SkeletonDebugRenderer.LIGHT_GRAY);
                            shapes.line(x1, y1, cx1, cy1);
                            shapes.line(x2, y2, cx2, cy2);
                            x1 = x2;
                            y1 = y2;
                        }
                    }
                }
                if (this.drawBones) {
                    shapes.setColor(this.boneOriginColor);
                    for (var i = 0, n = bones.length; i < n; i++) {
                        var bone = bones[i];
                        if (ignoredBones && ignoredBones.indexOf(bone.data.name) > -1)
                            continue;
                        shapes.circle(true, skeletonX + bone.worldX, skeletonY + bone.worldY, 3 * this.scale, SkeletonDebugRenderer.GREEN, 8);
                    }
                }
                if (this.drawClipping) {
                    var slots = skeleton.slots;
                    shapes.setColor(this.clipColor);
                    for (var i = 0, n = slots.length; i < n; i++) {
                        var slot = slots[i];
                        if (!slot.bone.active)
                            continue;
                        var attachment = slot.getAttachment();
                        if (!(attachment instanceof spine.ClippingAttachment))
                            continue;
                        var clip = attachment;
                        var nn = clip.worldVerticesLength;
                        var world = this.temp = spine.Utils.setArraySize(this.temp, nn, 0);
                        clip.computeWorldVertices(slot, 0, nn, world, 0, 2);
                        for (var i_17 = 0, n_3 = world.length; i_17 < n_3; i_17 += 2) {
                            var x = world[i_17];
                            var y = world[i_17 + 1];
                            var x2 = world[(i_17 + 2) % world.length];
                            var y2 = world[(i_17 + 3) % world.length];
                            shapes.line(x, y, x2, y2);
                        }
                    }
                }
            };
            SkeletonDebugRenderer.prototype.dispose = function () {
            };
            SkeletonDebugRenderer.LIGHT_GRAY = new spine.Color(192 / 255, 192 / 255, 192 / 255, 1);
            SkeletonDebugRenderer.GREEN = new spine.Color(0, 1, 0, 1);
            return SkeletonDebugRenderer;
        }());
        webgl.SkeletonDebugRenderer = SkeletonDebugRenderer;
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var Renderable = (function () {
            function Renderable(vertices, numVertices, numFloats) {
                this.vertices = vertices;
                this.numVertices = numVertices;
                this.numFloats = numFloats;
            }
            return Renderable;
        }());
        ;
        var SkeletonRenderer = (function () {
            function SkeletonRenderer(context, twoColorTint) {
                if (twoColorTint === void 0) { twoColorTint = true; }
                this.premultipliedAlpha = false;
                this.vertexEffect = null;
                this.tempColor = new spine.Color();
                this.tempColor2 = new spine.Color();
                this.vertexSize = 2 + 2 + 4;
                this.twoColorTint = false;
                this.renderable = new Renderable(null, 0, 0);
                this.clipper = new spine.SkeletonClipping();
                this.temp = new spine.Vector2();
                this.temp2 = new spine.Vector2();
                this.temp3 = new spine.Color();
                this.temp4 = new spine.Color();
                this.twoColorTint = twoColorTint;
                if (twoColorTint)
                    this.vertexSize += 4;
                this.vertices = spine.Utils.newFloatArray(this.vertexSize * 1024);
            }
            SkeletonRenderer.prototype.draw = function (batcher, skeleton, slotRangeStart, slotRangeEnd) {
                if (slotRangeStart === void 0) { slotRangeStart = -1; }
                if (slotRangeEnd === void 0) { slotRangeEnd = -1; }
                var clipper = this.clipper;
                var premultipliedAlpha = this.premultipliedAlpha;
                var twoColorTint = this.twoColorTint;
                var blendMode = null;
                var tempPos = this.temp;
                var tempUv = this.temp2;
                var tempLight = this.temp3;
                var tempDark = this.temp4;
                var renderable = this.renderable;
                var uvs = null;
                var triangles = null;
                var drawOrder = skeleton.drawOrder;
                var attachmentColor = null;
                var skeletonColor = skeleton.color;
                var vertexSize = twoColorTint ? 12 : 8;
                var inRange = false;
                if (slotRangeStart == -1)
                    inRange = true;
                for (var i = 0, n = drawOrder.length; i < n; i++) {
                    var clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
                    var slot = drawOrder[i];
                    if (!slot.bone.active) {
                        clipper.clipEndWithSlot(slot);
                        continue;
                    }
                    if (slotRangeStart >= 0 && slotRangeStart == slot.data.index) {
                        inRange = true;
                    }
                    if (!inRange) {
                        clipper.clipEndWithSlot(slot);
                        continue;
                    }
                    if (slotRangeEnd >= 0 && slotRangeEnd == slot.data.index) {
                        inRange = false;
                    }
                    var attachment = slot.getAttachment();
                    var texture = null;
                    if (attachment instanceof spine.RegionAttachment) {
                        var region = attachment;
                        renderable.vertices = this.vertices;
                        renderable.numVertices = 4;
                        renderable.numFloats = clippedVertexSize << 2;
                        region.computeWorldVertices(slot.bone, renderable.vertices, 0, clippedVertexSize);
                        triangles = SkeletonRenderer.QUAD_TRIANGLES;
                        uvs = region.uvs;
                        texture = region.region.renderObject.texture;
                        attachmentColor = region.color;
                    }
                    else if (attachment instanceof spine.MeshAttachment) {
                        var mesh = attachment;
                        renderable.vertices = this.vertices;
                        renderable.numVertices = (mesh.worldVerticesLength >> 1);
                        renderable.numFloats = renderable.numVertices * clippedVertexSize;
                        if (renderable.numFloats > renderable.vertices.length) {
                            renderable.vertices = this.vertices = spine.Utils.newFloatArray(renderable.numFloats);
                        }
                        mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize);
                        triangles = mesh.triangles;
                        texture = mesh.region.renderObject.texture;
                        uvs = mesh.uvs;
                        attachmentColor = mesh.color;
                    }
                    else if (attachment instanceof spine.ClippingAttachment) {
                        var clip = (attachment);
                        clipper.clipStart(slot, clip);
                        continue;
                    }
                    else {
                        clipper.clipEndWithSlot(slot);
                        continue;
                    }
                    if (texture != null) {
                        var slotColor = slot.color;
                        var finalColor = this.tempColor;
                        finalColor.r = skeletonColor.r * slotColor.r * attachmentColor.r;
                        finalColor.g = skeletonColor.g * slotColor.g * attachmentColor.g;
                        finalColor.b = skeletonColor.b * slotColor.b * attachmentColor.b;
                        finalColor.a = skeletonColor.a * slotColor.a * attachmentColor.a;
                        if (premultipliedAlpha) {
                            finalColor.r *= finalColor.a;
                            finalColor.g *= finalColor.a;
                            finalColor.b *= finalColor.a;
                        }
                        var darkColor = this.tempColor2;
                        if (slot.darkColor == null)
                            darkColor.set(0, 0, 0, 1.0);
                        else {
                            if (premultipliedAlpha) {
                                darkColor.r = slot.darkColor.r * finalColor.a;
                                darkColor.g = slot.darkColor.g * finalColor.a;
                                darkColor.b = slot.darkColor.b * finalColor.a;
                            }
                            else {
                                darkColor.setFromColor(slot.darkColor);
                            }
                            darkColor.a = premultipliedAlpha ? 1.0 : 0.0;
                        }
                        var slotBlendMode = slot.data.blendMode;
                        if (slotBlendMode != blendMode) {
                            blendMode = slotBlendMode;
                            batcher.setBlendMode(webgl.WebGLBlendModeConverter.getSourceGLBlendMode(blendMode, premultipliedAlpha), webgl.WebGLBlendModeConverter.getDestGLBlendMode(blendMode));
                        }
                        if (clipper.isClipping()) {
                            clipper.clipTriangles(renderable.vertices, renderable.numFloats, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint);
                            var clippedVertices = new Float32Array(clipper.clippedVertices);
                            var clippedTriangles = clipper.clippedTriangles;
                            if (this.vertexEffect != null) {
                                var vertexEffect = this.vertexEffect;
                                var verts = clippedVertices;
                                if (!twoColorTint) {
                                    for (var v = 0, n_4 = clippedVertices.length; v < n_4; v += vertexSize) {
                                        tempPos.x = verts[v];
                                        tempPos.y = verts[v + 1];
                                        tempLight.set(verts[v + 2], verts[v + 3], verts[v + 4], verts[v + 5]);
                                        tempUv.x = verts[v + 6];
                                        tempUv.y = verts[v + 7];
                                        tempDark.set(0, 0, 0, 0);
                                        vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
                                        verts[v] = tempPos.x;
                                        verts[v + 1] = tempPos.y;
                                        verts[v + 2] = tempLight.r;
                                        verts[v + 3] = tempLight.g;
                                        verts[v + 4] = tempLight.b;
                                        verts[v + 5] = tempLight.a;
                                        verts[v + 6] = tempUv.x;
                                        verts[v + 7] = tempUv.y;
                                    }
                                }
                                else {
                                    for (var v = 0, n_5 = clippedVertices.length; v < n_5; v += vertexSize) {
                                        tempPos.x = verts[v];
                                        tempPos.y = verts[v + 1];
                                        tempLight.set(verts[v + 2], verts[v + 3], verts[v + 4], verts[v + 5]);
                                        tempUv.x = verts[v + 6];
                                        tempUv.y = verts[v + 7];
                                        tempDark.set(verts[v + 8], verts[v + 9], verts[v + 10], verts[v + 11]);
                                        vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
                                        verts[v] = tempPos.x;
                                        verts[v + 1] = tempPos.y;
                                        verts[v + 2] = tempLight.r;
                                        verts[v + 3] = tempLight.g;
                                        verts[v + 4] = tempLight.b;
                                        verts[v + 5] = tempLight.a;
                                        verts[v + 6] = tempUv.x;
                                        verts[v + 7] = tempUv.y;
                                        verts[v + 8] = tempDark.r;
                                        verts[v + 9] = tempDark.g;
                                        verts[v + 10] = tempDark.b;
                                        verts[v + 11] = tempDark.a;
                                    }
                                }
                            }
                            batcher.draw(texture, clippedVertices, clippedTriangles);
                        }
                        else {
                            var verts = renderable.vertices;
                            if (this.vertexEffect != null) {
                                var vertexEffect = this.vertexEffect;
                                if (!twoColorTint) {
                                    for (var v = 0, u = 0, n_6 = renderable.numFloats; v < n_6; v += vertexSize, u += 2) {
                                        tempPos.x = verts[v];
                                        tempPos.y = verts[v + 1];
                                        tempUv.x = uvs[u];
                                        tempUv.y = uvs[u + 1];
                                        tempLight.setFromColor(finalColor);
                                        tempDark.set(0, 0, 0, 0);
                                        vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
                                        verts[v] = tempPos.x;
                                        verts[v + 1] = tempPos.y;
                                        verts[v + 2] = tempLight.r;
                                        verts[v + 3] = tempLight.g;
                                        verts[v + 4] = tempLight.b;
                                        verts[v + 5] = tempLight.a;
                                        verts[v + 6] = tempUv.x;
                                        verts[v + 7] = tempUv.y;
                                    }
                                }
                                else {
                                    for (var v = 0, u = 0, n_7 = renderable.numFloats; v < n_7; v += vertexSize, u += 2) {
                                        tempPos.x = verts[v];
                                        tempPos.y = verts[v + 1];
                                        tempUv.x = uvs[u];
                                        tempUv.y = uvs[u + 1];
                                        tempLight.setFromColor(finalColor);
                                        tempDark.setFromColor(darkColor);
                                        vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
                                        verts[v] = tempPos.x;
                                        verts[v + 1] = tempPos.y;
                                        verts[v + 2] = tempLight.r;
                                        verts[v + 3] = tempLight.g;
                                        verts[v + 4] = tempLight.b;
                                        verts[v + 5] = tempLight.a;
                                        verts[v + 6] = tempUv.x;
                                        verts[v + 7] = tempUv.y;
                                        verts[v + 8] = tempDark.r;
                                        verts[v + 9] = tempDark.g;
                                        verts[v + 10] = tempDark.b;
                                        verts[v + 11] = tempDark.a;
                                    }
                                }
                            }
                            else {
                                if (!twoColorTint) {
                                    for (var v = 2, u = 0, n_8 = renderable.numFloats; v < n_8; v += vertexSize, u += 2) {
                                        verts[v] = finalColor.r;
                                        verts[v + 1] = finalColor.g;
                                        verts[v + 2] = finalColor.b;
                                        verts[v + 3] = finalColor.a;
                                        verts[v + 4] = uvs[u];
                                        verts[v + 5] = uvs[u + 1];
                                    }
                                }
                                else {
                                    for (var v = 2, u = 0, n_9 = renderable.numFloats; v < n_9; v += vertexSize, u += 2) {
                                        verts[v] = finalColor.r;
                                        verts[v + 1] = finalColor.g;
                                        verts[v + 2] = finalColor.b;
                                        verts[v + 3] = finalColor.a;
                                        verts[v + 4] = uvs[u];
                                        verts[v + 5] = uvs[u + 1];
                                        verts[v + 6] = darkColor.r;
                                        verts[v + 7] = darkColor.g;
                                        verts[v + 8] = darkColor.b;
                                        verts[v + 9] = darkColor.a;
                                    }
                                }
                            }
                            var view = renderable.vertices.subarray(0, renderable.numFloats);
                            batcher.draw(texture, view, triangles);
                        }
                    }
                    clipper.clipEndWithSlot(slot);
                }
                clipper.clipEnd();
            };
            SkeletonRenderer.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
            return SkeletonRenderer;
        }());
        webgl.SkeletonRenderer = SkeletonRenderer;
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var Vector3 = (function () {
            function Vector3(x, y, z) {
                if (x === void 0) { x = 0; }
                if (y === void 0) { y = 0; }
                if (z === void 0) { z = 0; }
                this.x = 0;
                this.y = 0;
                this.z = 0;
                this.x = x;
                this.y = y;
                this.z = z;
            }
            Vector3.prototype.setFrom = function (v) {
                this.x = v.x;
                this.y = v.y;
                this.z = v.z;
                return this;
            };
            Vector3.prototype.set = function (x, y, z) {
                this.x = x;
                this.y = y;
                this.z = z;
                return this;
            };
            Vector3.prototype.add = function (v) {
                this.x += v.x;
                this.y += v.y;
                this.z += v.z;
                return this;
            };
            Vector3.prototype.sub = function (v) {
                this.x -= v.x;
                this.y -= v.y;
                this.z -= v.z;
                return this;
            };
            Vector3.prototype.scale = function (s) {
                this.x *= s;
                this.y *= s;
                this.z *= s;
                return this;
            };
            Vector3.prototype.normalize = function () {
                var len = this.length();
                if (len == 0)
                    return this;
                len = 1 / len;
                this.x *= len;
                this.y *= len;
                this.z *= len;
                return this;
            };
            Vector3.prototype.cross = function (v) {
                return this.set(this.y * v.z - this.z * v.y, this.z * v.x - this.x * v.z, this.x * v.y - this.y * v.x);
            };
            Vector3.prototype.multiply = function (matrix) {
                var l_mat = matrix.values;
                return this.set(this.x * l_mat[webgl.M00] + this.y * l_mat[webgl.M01] + this.z * l_mat[webgl.M02] + l_mat[webgl.M03], this.x * l_mat[webgl.M10] + this.y * l_mat[webgl.M11] + this.z * l_mat[webgl.M12] + l_mat[webgl.M13], this.x * l_mat[webgl.M20] + this.y * l_mat[webgl.M21] + this.z * l_mat[webgl.M22] + l_mat[webgl.M23]);
            };
            Vector3.prototype.project = function (matrix) {
                var l_mat = matrix.values;
                var l_w = 1 / (this.x * l_mat[webgl.M30] + this.y * l_mat[webgl.M31] + this.z * l_mat[webgl.M32] + l_mat[webgl.M33]);
                return this.set((this.x * l_mat[webgl.M00] + this.y * l_mat[webgl.M01] + this.z * l_mat[webgl.M02] + l_mat[webgl.M03]) * l_w, (this.x * l_mat[webgl.M10] + this.y * l_mat[webgl.M11] + this.z * l_mat[webgl.M12] + l_mat[webgl.M13]) * l_w, (this.x * l_mat[webgl.M20] + this.y * l_mat[webgl.M21] + this.z * l_mat[webgl.M22] + l_mat[webgl.M23]) * l_w);
            };
            Vector3.prototype.dot = function (v) {
                return this.x * v.x + this.y * v.y + this.z * v.z;
            };
            Vector3.prototype.length = function () {
                return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
            };
            Vector3.prototype.distance = function (v) {
                var a = v.x - this.x;
                var b = v.y - this.y;
                var c = v.z - this.z;
                return Math.sqrt(a * a + b * b + c * c);
            };
            return Vector3;
        }());
        webgl.Vector3 = Vector3;
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
var spine;
(function (spine) {
    var webgl;
    (function (webgl) {
        var ManagedWebGLRenderingContext = (function () {
            function ManagedWebGLRenderingContext(canvasOrContext, contextConfig) {
                if (contextConfig === void 0) { contextConfig = { alpha: "true" }; }
                this.restorables = new Array();
                if (!((canvasOrContext instanceof WebGLRenderingContext) || (canvasOrContext instanceof WebGL2RenderingContext))) {
                    this.setupCanvas(canvasOrContext, contextConfig);
                }
                else {
                    this.gl = canvasOrContext;
                    this.canvas = this.gl.canvas;
                }
            }
            ManagedWebGLRenderingContext.prototype.setupCanvas = function (canvas, contextConfig) {
                var _this = this;
                this.gl = (canvas.getContext("webgl2", contextConfig) || canvas.getContext("webgl", contextConfig));
                this.canvas = canvas;
                canvas.addEventListener("webglcontextlost", function (e) {
                    var event = e;
                    if (e) {
                        e.preventDefault();
                    }
                });
                canvas.addEventListener("webglcontextrestored", function (e) {
                    for (var i = 0, n = _this.restorables.length; i < n; i++) {
                        _this.restorables[i].restore();
                    }
                });
            };
            ManagedWebGLRenderingContext.prototype.addRestorable = function (restorable) {
                this.restorables.push(restorable);
            };
            ManagedWebGLRenderingContext.prototype.removeRestorable = function (restorable) {
                var index = this.restorables.indexOf(restorable);
                if (index > -1)
                    this.restorables.splice(index, 1);
            };
            return ManagedWebGLRenderingContext;
        }());
        webgl.ManagedWebGLRenderingContext = ManagedWebGLRenderingContext;
        var WebGLBlendModeConverter = (function () {
            function WebGLBlendModeConverter() {
            }
            WebGLBlendModeConverter.getDestGLBlendMode = function (blendMode) {
                switch (blendMode) {
                    case spine.BlendMode.Normal: return WebGLBlendModeConverter.ONE_MINUS_SRC_ALPHA;
                    case spine.BlendMode.Additive: return WebGLBlendModeConverter.ONE;
                    case spine.BlendMode.Multiply: return WebGLBlendModeConverter.ONE_MINUS_SRC_ALPHA;
                    case spine.BlendMode.Screen: return WebGLBlendModeConverter.ONE_MINUS_SRC_ALPHA;
                    default: throw new Error("Unknown blend mode: " + blendMode);
                }
            };
            WebGLBlendModeConverter.getSourceGLBlendMode = function (blendMode, premultipliedAlpha) {
                if (premultipliedAlpha === void 0) { premultipliedAlpha = false; }
                switch (blendMode) {
                    case spine.BlendMode.Normal: return premultipliedAlpha ? WebGLBlendModeConverter.ONE : WebGLBlendModeConverter.SRC_ALPHA;
                    case spine.BlendMode.Additive: return premultipliedAlpha ? WebGLBlendModeConverter.ONE : WebGLBlendModeConverter.SRC_ALPHA;
                    case spine.BlendMode.Multiply: return WebGLBlendModeConverter.DST_COLOR;
                    case spine.BlendMode.Screen: return WebGLBlendModeConverter.ONE;
                    default: throw new Error("Unknown blend mode: " + blendMode);
                }
            };
            WebGLBlendModeConverter.ZERO = 0;
            WebGLBlendModeConverter.ONE = 1;
            WebGLBlendModeConverter.SRC_COLOR = 0x0300;
            WebGLBlendModeConverter.ONE_MINUS_SRC_COLOR = 0x0301;
            WebGLBlendModeConverter.SRC_ALPHA = 0x0302;
            WebGLBlendModeConverter.ONE_MINUS_SRC_ALPHA = 0x0303;
            WebGLBlendModeConverter.DST_ALPHA = 0x0304;
            WebGLBlendModeConverter.ONE_MINUS_DST_ALPHA = 0x0305;
            WebGLBlendModeConverter.DST_COLOR = 0x0306;
            return WebGLBlendModeConverter;
        }());
        webgl.WebGLBlendModeConverter = WebGLBlendModeConverter;
    })(webgl = spine.webgl || (spine.webgl = {}));
})(spine || (spine = {}));
//# sourceMappingURL=spine-both.js.map
/*** EXPORTS FROM exports-loader ***/
module.exports = spine;

}.call(window));


/***/ }),

/***/ 3524:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var Class = __webpack_require__(7473);
var GetFastValue = __webpack_require__(4597);
var ImageFile = __webpack_require__(6732);
var IsPlainObject = __webpack_require__(2482);
var JSONFile = __webpack_require__(704);
var MultiFile = __webpack_require__(3137);
var TextFile = __webpack_require__(1192);

/**
 * @typedef {object} Phaser.Loader.FileTypes.SpineFileConfig
 *
 * @property {string} key - The key of the file. Must be unique within both the Loader and the Texture Manager.
 * @property {string|string[]} [jsonURL] - The absolute or relative URL to load the JSON file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json".
 * @property {string} [atlasURL] - The absolute or relative URL to load the texture atlas data file from. If undefined or `null` it will be set to `<key>.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt".
 * @property {boolean} [preMultipliedAlpha=false] - Do the textures contain pre-multiplied alpha or not?
 * @property {XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings.
 * @property {XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas data file. Used in replacement of the Loaders default XHR Settings.
 */

/**
 * @classdesc
 * A Spine File suitable for loading by the Loader.
 *
 * These are created when you use the Phaser.Loader.LoaderPlugin#spine method and are not typically created directly.
 *
 * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#spine.
 *
 * @class SpineFile
 * @extends Phaser.Loader.MultiFile
 * @memberof Phaser.Loader.FileTypes
 * @constructor
 *
 * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
 * @param {(string|Phaser.Loader.FileTypes.SpineFileConfig)} key - The key to use for this file, or a file configuration object.
 * @param {string|string[]} [jsonURL] - The absolute or relative URL to load the JSON file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json".
 * @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas data file from. If undefined or `null` it will be set to `<key>.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt".
 * @param {boolean} [preMultipliedAlpha=false] - Do the textures contain pre-multiplied alpha or not?
 * @param {XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings.
 * @param {XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas data file. Used in replacement of the Loaders default XHR Settings.
 */
var SpineFile = new Class({

    Extends: MultiFile,

    initialize:

    function SpineFile (loader, key, jsonURL, atlasURL, preMultipliedAlpha, jsonXhrSettings, atlasXhrSettings)
    {
        var i;
        var json;
        var atlas;
        var files = [];
        var cache = loader.cacheManager.custom.spine;

        //  atlas can be an array of atlas files, not just a single one

        if (IsPlainObject(key))
        {
            var config = key;

            key = GetFastValue(config, 'key');

            json = new JSONFile(loader, {
                key: key,
                url: GetFastValue(config, 'jsonURL'),
                extension: GetFastValue(config, 'jsonExtension', 'json'),
                xhrSettings: GetFastValue(config, 'jsonXhrSettings')
            });

            atlasURL = GetFastValue(config, 'atlasURL');
            preMultipliedAlpha = GetFastValue(config, 'preMultipliedAlpha');

            if (!Array.isArray(atlasURL))
            {
                atlasURL = [ atlasURL ];
            }

            for (i = 0; i < atlasURL.length; i++)
            {
                atlas = new TextFile(loader, {
                    key: key + '!' + i,
                    url: atlasURL[i],
                    extension: GetFastValue(config, 'atlasExtension', 'atlas'),
                    xhrSettings: GetFastValue(config, 'atlasXhrSettings')
                });

                atlas.cache = cache;

                files.push(atlas);
            }
        }
        else
        {
            json = new JSONFile(loader, key, jsonURL, jsonXhrSettings);

            if (!Array.isArray(atlasURL))
            {
                atlasURL = [ atlasURL ];
            }

            for (i = 0; i < atlasURL.length; i++)
            {
                atlas = new TextFile(loader, key + '!' + i, atlasURL[i], atlasXhrSettings);
                atlas.cache = cache;

                files.push(atlas);
            }
        }

        files.unshift(json);

        MultiFile.call(this, loader, 'spine', key, files);

        this.config.preMultipliedAlpha = preMultipliedAlpha;
    },

    /**
     * Called by each File when it finishes loading.
     *
     * @method Phaser.Loader.FileTypes.SpineFile#onFileComplete
     * @since 3.19.0
     *
     * @param {Phaser.Loader.File} file - The File that has completed processing.
     */
    onFileComplete: function (file)
    {
        var index = this.files.indexOf(file);

        if (index !== -1)
        {
            this.pending--;

            if (file.type === 'text')
            {
                //  Inspect the data for the files to now load
                var content = file.data.split('\n');

                //  Extract the textures
                var textures = [];

                for (var t = 0; t < content.length; t++)
                {
                    var line = content[t];

                    if (line.trim() === '' && t < content.length - 1)
                    {
                        line = content[t + 1];

                        textures.push(line);
                    }
                }

                var config = this.config;
                var loader = this.loader;

                var currentBaseURL = loader.baseURL;
                var currentPath = loader.path;
                var currentPrefix = loader.prefix;

                var baseURL = GetFastValue(config, 'baseURL', this.baseURL);
                var path = GetFastValue(config, 'path', file.src.match(/^.*\//))[0];
                var prefix = GetFastValue(config, 'prefix', this.prefix);
                var textureXhrSettings = GetFastValue(config, 'textureXhrSettings');

                loader.setBaseURL(baseURL);
                loader.setPath(path);
                loader.setPrefix(prefix);

                for (var i = 0; i < textures.length; i++)
                {
                    var textureURL = textures[i];

                    var key = this.key + ':' + textureURL;

                    var image = new ImageFile(loader, key, textureURL, textureXhrSettings);

                    if (!loader.keyExists(image))
                    {
                        this.addToMultiFile(image);

                        loader.addFile(image);
                    }
                }

                //  Reset the loader settings
                loader.setBaseURL(currentBaseURL);
                loader.setPath(currentPath);
                loader.setPrefix(currentPrefix);
            }
        }
    },

    /**
     * Adds this file to its target cache upon successful loading and processing.
     *
     * @method Phaser.Loader.FileTypes.SpineFile#addToCache
     * @since 3.19.0
     */
    addToCache: function ()
    {
        if (this.isReadyToProcess())
        {
            var fileJSON = this.files[0];

            fileJSON.addToCache();

            var atlasCache;
            var atlasKey = '';
            var combinedAtlasData = '';
            var preMultipliedAlpha = (this.config.preMultipliedAlpha) ? true : false;
            var textureManager = this.loader.textureManager;

            for (var i = 1; i < this.files.length; i++)
            {
                var file = this.files[i];

                if (file.type === 'text')
                {
                    atlasKey = file.key.replace(/![\d]$/, '');

                    atlasCache = file.cache;

                    combinedAtlasData = combinedAtlasData.concat(file.data);
                }
                else
                {
                    var src = file.key.trim();
                    var pos = src.indexOf('!');
                    var key = src.substr(pos + 1);

                    if (!textureManager.exists(key))
                    {
                        textureManager.addImage(key, file.data);
                    }
                }

                file.pendingDestroy();
            }

            atlasCache.add(atlasKey, { preMultipliedAlpha: preMultipliedAlpha, data: combinedAtlasData, prefix: this.prefix });

            this.complete = true;
        }
    }

});

module.exports = SpineFile;


/***/ }),

/***/ 4513:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var BuildGameObject = __webpack_require__(2494);
var Class = __webpack_require__(7473);
var GetValue = __webpack_require__(5851);
var ResizeEvent = __webpack_require__(3527);
var ScenePlugin = __webpack_require__(5722);
var Spine = __webpack_require__(1847);
var SpineFile = __webpack_require__(3524);
var SpineGameObject = __webpack_require__(8332);
var SpineContainer = __webpack_require__(5782);
var NOOP = __webpack_require__(1984);

/**
 * @classdesc
 * The Spine Plugin is a Scene based plugin that handles the creation and rendering of Spine Game Objects.
 *
 * Find more details about Spine itself at http://esotericsoftware.com/.
 *
 * All rendering and object creation is handled via the official Spine Runtimes. This version of the plugin
 * uses the Spine 3.8.95 runtimes. Please note that due to the way the Spine runtimes use semver, you will
 * get breaking changes in point-releases. Therefore, files created in a different version of Spine may not
 * work as a result, without you first updating the runtimes and rebuilding the plugin.
 *
 * Esoteric themselves recommend that you freeze your Spine editor version against the runtime versions.
 * You can find more information about this here: http://esotericsoftware.com/spine-settings#Version
 *
 * Please note that you require a Spine license in order to use Spine Runtimes in your games.
 *
 * You can install this plugin into your Phaser game by either importing it, if you're using ES6:
 *
 * ```javascript
 * import * as SpinePlugin from './SpinePlugin.js';
 * ```
 *
 * and then adding it to your Phaser Game configuration:
 *
 * ```javascript
 * plugins: {
 *     scene: [
 *         { key: 'SpinePlugin', plugin: window.SpinePlugin, mapping: 'spine' }
 *     ]
 * }
 * ```
 *
 * If you're using ES5 then you can load the Spine Plugin in a Scene files payload, _within_ your
 * Game Configuration object, like this:
 *
 * ```javascript
 * scene: {
 *     preload: preload,
 *     create: create,
 *     pack: {
 *         files: [
 *             { type: 'scenePlugin', key: 'SpinePlugin', url: 'plugins/SpinePlugin.js', sceneKey: 'spine' }
 *         ]
 *     }
 * }
 * ```
 *
 * Loading it like this allows you to then use commands such as `this.load.spine` from within the
 * same Scene. Alternatively, you can use the method `this.load.plugin` to load the plugin via the normal
 * Phaser Loader. However, doing so will not add it to the current Scene. It will be available from any
 * subsequent Scenes.
 *
 * ## A note about inlined data:
 *
 * If you need to load Spine assets from inline / base64 encoded data, then you should not use the Loader
 * at all. Instead, call the functions directly as required:
 *
 * scene.cache.json.add
 * scene.cache.custom.spine.add
 * scene.textures.addBase64
 *
 * ## Using the plugin
 *
 * Assuming a default environment you access it from within a Scene by using the `this.spine` reference.
 *
 * When this plugin is installed into a Scene it will add a Loader File Type, allowing you to load
 * Spine files directly, i.e.:
 *
 * ```javascript
 * this.load.spine('stretchyman', 'stretchyman-pro.json', [ 'stretchyman-pma.atlas' ], true);
 * ```
 *
 * It also installs two Game Object Factory methods, allowing you to create Spine Game Objects
 * and Spine Containers:
 *
 * ```javascript
 * const man = this.add.spine(512, 650, 'stretchyman');
 *
 * const container = this.add.spineContainer();
 *
 * container.add(man);
 * ```
 *
 * The first argument is the key which you used when importing the Spine data. There are lots of
 * things you can specify, such as the animation name, skeleton, slot attachments and more. Please
 * see the respective documentation and examples for further details.
 *
 * Phaser expects the Spine data to be exported from the Spine application in a JSON format, not binary.
 * The associated atlas files are scanned for any texture files present in them, which are then loaded.
 * If you have exported your Spine data with preMultipliedAlpha set, then you should enable this in the
 * load arguments, or you may see black outlines around skeleton textures.
 *
 * The Spine plugin is local to the Scene in which it is installed. This means a change to something,
 * such as the Skeleton Debug Renderer, in this Scene, will not impact the renderer in any other Scene.
 * The only exception to this is with the caches this plugin creates. Spine atlas and texture data are
 * stored in their own caches, which are global, meaning they're accessible from any Scene in your
 * game, regardless if the Scene loaded the Spine data or not.
 *
 * When destroying a Phaser Game instance, if you need to re-create it again on the same page without
 * reloading, you must remember to remove the Spine Plugin as part of your tear-down process:
 *
 * ```javascript
 * this.plugins.removeScenePlugin('SpinePlugin');
 * ```
 *
 * For details about the Spine Runtime API see http://esotericsoftware.com/spine-api-reference
 *
 * @class SpinePlugin
 * @extends Phaser.Plugins.ScenePlugin
 * @constructor
 * @since 3.19.0
 *
 * @param {Phaser.Scene} scene - A reference to the Scene that has installed this plugin.
 * @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Phaser Plugin Manager.
 * @param {string} pluginKey - The key under which this plugin has been installed into the Scene Systems.
 */
var SpinePlugin = new Class({

    Extends: ScenePlugin,

    initialize:

    function SpinePlugin (scene, pluginManager, pluginKey)
    {
        ScenePlugin.call(this, scene, pluginManager, pluginKey);

        var game = pluginManager.game;

        /**
         * A read-only flag that indicates if the game is running under WebGL or Canvas.
         *
         * @name SpinePlugin#isWebGL
         * @type {boolean}
         * @readonly
         * @since 3.19.0
         */
        this.isWebGL = (game.config.renderType === 2);

        /**
         * A custom cache that stores the Spine atlas data.
         *
         * This cache is global across your game, allowing you to access Spine data loaded from other Scenes,
         * no matter which Scene you are in.
         *
         * @name SpinePlugin#cache
         * @type {Phaser.Cache.BaseCache}
         * @since 3.19.0
         */
        this.cache = game.cache.addCustom('spine');

        /**
         * A custom cache that stores the Spine Textures.
         *
         * This cache is global across your game, allowing you to access Spine data loaded from other Scenes,
         * no matter which Scene you are in.
         *
         * @name SpinePlugin#spineTextures
         * @type {Phaser.Cache.BaseCache}
         * @since 3.19.0
         */
        this.spineTextures = game.cache.addCustom('spineTextures');

        /**
         * A reference to the global JSON Cache.
         *
         * @name SpinePlugin#json
         * @type {Phaser.Cache.BaseCache}
         * @since 3.19.0
         */
        this.json = game.cache.json;

        /**
         * A reference to the global Texture Manager.
         *
         * @name SpinePlugin#textures
         * @type {Phaser.Textures.TextureManager}
         * @since 3.19.0
         */
        this.textures = game.textures;

        /**
         * A flag that sets if the Skeleton Renderers will render debug information over the top
         * of the skeleton or not.
         *
         * @name SpinePlugin#drawDebug
         * @type {boolean}
         * @since 3.19.0
         */
        this.drawDebug = false;

        /**
         * The underlying WebGL context of the Phaser renderer.
         *
         * Only set if running in WebGL mode.
         *
         * @name SpinePlugin#gl
         * @type {WebGLRenderingContext}
         * @since 3.19.0
         */
        this.gl;

        /**
         * A reference to either the Canvas or WebGL Renderer that this Game is using.
         *
         * @name SpinePlugin#renderer
         * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)}
         * @since 3.19.0
         */
        this.renderer;

        /**
         * An instance of the Spine WebGL Scene Renderer.
         *
         * There is only one instance of the Scene Renderer shared across the whole plugin.
         *
         * Only set if running in WebGL mode.
         *
         * @name SpinePlugin#sceneRenderer
         * @type {spine.webgl.SceneRenderer}
         * @since 3.19.0
         */
        this.sceneRenderer;

        /**
         * An instance of the Spine Skeleton Renderer.
         *
         * @name SpinePlugin#skeletonRenderer
         * @type {(spine.canvas.SkeletonRenderer|spine.webgl.SkeletonRenderer)}
         * @since 3.19.0
         */
        this.skeletonRenderer;

        /**
         * An instance of the Spine Skeleton Debug Renderer.
         *
         * Only set if running in WebGL mode.
         *
         * @name SpinePlugin#skeletonDebugRenderer
         * @type {spine.webgl.skeletonDebugRenderer}
         * @since 3.19.0
         */
        this.skeletonDebugRenderer;

        /**
         * A reference to the Spine runtime.
         * This is the runtime created by Esoteric Software.
         *
         * @name SpinePlugin#plugin
         * @type {spine}
         * @since 3.19.0
         */
        this.plugin = Spine;

        /**
         * An internal vector3 used by the screen to world method.
         *
         * @name SpinePlugin#temp1
         * @private
         * @type {spine.webgl.Vector3}
         * @since 3.19.0
         */
        this.temp1;

        /**
         * An internal vector3 used by the screen to world method.
         *
         * @name SpinePlugin#temp2
         * @private
         * @type {spine.webgl.Vector3}
         * @since 3.19.0
         */
        this.temp2;

        if (this.isWebGL)
        {
            this.runtime = Spine.webgl;

            this.renderer = game.renderer;
            this.gl = game.renderer.gl;

            this.getAtlas = this.getAtlasWebGL;
        }
        else
        {
            this.runtime = Spine.canvas;

            this.renderer = game.renderer;

            this.getAtlas = this.getAtlasCanvas;
        }

        //  Headless mode?
        if (!this.renderer)
        {
            this.renderer = {
                width: game.scale.width,
                height: game.scale.height,
                preRender: NOOP,
                postRender: NOOP,
                render: NOOP,
                destroy: NOOP
            };
        }

        var isWebGL = this.isWebGL;

        var add = function (x, y, key, animationName, loop)
        {
            if (isWebGL)
            {
                this.scene.sys.renderer.pipelines.clear();
            }

            var spinePlugin = this.scene.sys[pluginKey];
            var spineGO = new SpineGameObject(this.scene, spinePlugin, x, y, key, animationName, loop);

            this.displayList.add(spineGO);
            this.updateList.add(spineGO);

            if (isWebGL)
            {
                this.scene.sys.renderer.pipelines.rebind();
            }

            return spineGO;
        };

        var make = function (config, addToScene)
        {
            if (config === undefined) { config = {}; }

            if (isWebGL)
            {
                this.scene.sys.renderer.pipelines.clear();
            }

            var key = GetValue(config, 'key', null);
            var animationName = GetValue(config, 'animationName', null);
            var loop = GetValue(config, 'loop', false);

            var spinePlugin = this.scene.sys[pluginKey];
            var spineGO = new SpineGameObject(this.scene, spinePlugin, 0, 0, key, animationName, loop);

            if (addToScene !== undefined)
            {
                config.add = addToScene;
            }

            BuildGameObject(this.scene, spineGO, config);

            //  Spine specific
            var skinName = GetValue(config, 'skinName', false);

            if (skinName)
            {
                spineGO.setSkinByName(skinName);
            }

            var slotName = GetValue(config, 'slotName', false);
            var attachmentName = GetValue(config, 'attachmentName', null);

            if (slotName)
            {
                spineGO.setAttachment(slotName, attachmentName);
            }

            if (isWebGL)
            {
                this.scene.sys.renderer.pipelines.rebind();
            }

            return spineGO.refresh();
        };

        var addContainer = function (x, y, children)
        {
            var spinePlugin = this.scene.sys[pluginKey];
            var spineGO = new SpineContainer(this.scene, spinePlugin, x, y, children);

            this.displayList.add(spineGO);

            return spineGO;
        };

        var makeContainer = function (config, addToScene)
        {
            if (config === undefined) { config = {}; }

            var x = GetValue(config, 'x', 0);
            var y = GetValue(config, 'y', 0);
            var children = GetValue(config, 'children', null);

            var spinePlugin = this.scene.sys[pluginKey];
            var container = new SpineContainer(this.scene, spinePlugin, x, y, children);

            if (addToScene !== undefined)
            {
                config.add = addToScene;
            }

            BuildGameObject(this.scene, container, config);

            return container;
        };

        pluginManager.registerFileType('spine', this.spineFileCallback, scene);
        pluginManager.registerGameObject('spine', add, make);
        pluginManager.registerGameObject('spineContainer', addContainer, makeContainer);
    },

    /**
     * Internal boot handler.
     *
     * @method SpinePlugin#boot
     * @private
     * @since 3.19.0
     */
    boot: function ()
    {
        if (this.isWebGL)
        {
            this.bootWebGL();
            this.onResize();
            this.game.scale.on(ResizeEvent, this.onResize, this);
        }
        else
        {
            this.bootCanvas();
        }

        var eventEmitter = this.systems.events;

        eventEmitter.once('shutdown', this.shutdown, this);
        eventEmitter.once('destroy', this.destroy, this);

        this.game.events.once('destroy', this.gameDestroy, this);
    },

    /**
     * Internal boot handler for the Canvas Renderer.
     *
     * @method SpinePlugin#bootCanvas
     * @private
     * @since 3.19.0
     */
    bootCanvas: function ()
    {
        this.skeletonRenderer = new Spine.canvas.SkeletonRenderer(this.scene.sys.context);
    },

    /**
     * Internal boot handler for the WebGL Renderer.
     *
     * @method SpinePlugin#bootWebGL
     * @private
     * @since 3.19.0
     */
    bootWebGL: function ()
    {
        //  Monkeypatch the Spine setBlendMode functions, or batching is destroyed!

        var setBlendMode = function (srcBlend, dstBlend)
        {
            if (srcBlend !== this.srcBlend || dstBlend !== this.dstBlend)
            {
                var gl = this.context.gl;

                this.srcBlend = srcBlend;
                this.dstBlend = dstBlend;

                if (this.isDrawing)
                {
                    this.flush();
                    gl.blendFunc(this.srcBlend, this.dstBlend);
                }
            }
        };

        var sceneRenderer = this.renderer.spineSceneRenderer;

        if (!sceneRenderer)
        {
            sceneRenderer = new Spine.webgl.SceneRenderer(this.renderer.canvas, this.gl, true);
            sceneRenderer.batcher.setBlendMode = setBlendMode;
            sceneRenderer.shapes.setBlendMode = setBlendMode;

            this.renderer.spineSceneRenderer = sceneRenderer;
        }

        //  All scene share the same instance
        this.sceneRenderer = sceneRenderer;
        this.skeletonRenderer = sceneRenderer.skeletonRenderer;
        this.skeletonDebugRenderer = sceneRenderer.skeletonDebugRenderer;

        this.temp1 = new Spine.webgl.Vector3(0, 0, 0);
        this.temp2 = new Spine.webgl.Vector3(0, 0, 0);
    },

    /**
     * Gets a loaded Spine Atlas from the cache and creates a new Spine Texture Atlas,
     * then returns it. You do not normally need to invoke this method directly.
     *
     * @method SpinePlugin#getAtlasCanvas
     * @since 3.19.0
     *
     * @param {string} key - The key of the Spine Atlas to create.
     *
     * @return {spine.TextureAtlas} The Spine Texture Atlas, or undefined if the given key wasn't found.
     */
    getAtlasCanvas: function (key)
    {
        var atlasEntry = this.cache.get(key);

        if (!atlasEntry)
        {
            console.warn('No atlas data for: ' + key);
            return;
        }

        var atlas;
        var spineTextures = this.spineTextures;

        if (spineTextures.has(key))
        {
            atlas = spineTextures.get(key);
        }
        else
        {
            var textures = this.textures;

            atlas = new Spine.TextureAtlas(atlasEntry.data, function (path)
            {
                return new Spine.canvas.CanvasTexture(textures.get(atlasEntry.prefix + key + ':' + path).getSourceImage());
            });
        }

        return atlas;
    },

    /**
     * Gets a loaded Spine Atlas from the cache and creates a new Spine Texture Atlas,
     * then returns it. You do not normally need to invoke this method directly.
     *
     * @method SpinePlugin#getAtlasWebGL
     * @since 3.19.0
     *
     * @param {string} key - The key of the Spine Atlas to create.
     *
     * @return {spine.TextureAtlas} The Spine Texture Atlas, or undefined if the given key wasn't found.
     */
    getAtlasWebGL: function (key)
    {
        var atlasEntry = this.cache.get(key);

        if (!atlasEntry)
        {
            console.warn('No atlas data for: ' + key);
            return;
        }

        var atlas;
        var spineTextures = this.spineTextures;

        if (spineTextures.has(key))
        {
            atlas = spineTextures.get(key);
        }
        else
        {
            var textures = this.textures;

            var gl = this.sceneRenderer.context.gl;

            gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);

            atlas = new Spine.TextureAtlas(atlasEntry.data, function (path)
            {
                return new Spine.webgl.GLTexture(gl, textures.get(atlasEntry.prefix + key + ':' + path).getSourceImage(), false);
            });
        }

        return atlas;
    },

    /**
     * Adds a Spine Skeleton and Atlas file, or array of files, to the current load queue.
     *
     * You can call this method from within your Scene's `preload`, along with any other files you wish to load:
     *
     * ```javascript
     * function preload ()
     * {
     *     this.load.spine('spineBoy', 'boy.json', 'boy.atlas', true);
     * }
     * ```
     *
     * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
     * or if it's already running, when the next free load slot becomes available. This happens automatically if you
     * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
     * it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
     * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
     * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
     * loaded.
     *
     * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring
     * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details.
     *
     * Phaser expects the Spine data to be exported from the Spine application in a JSON format, not binary. The associated
     * atlas files are scanned for any texture files present in them, which are then loaded. If you have exported
     * your Spine data with preMultipliedAlpha set, then you should enable this in the arguments, or you may see black
     * outlines around skeleton textures.
     *
     * The key must be a unique String. It is used to add the file to the global Spine cache upon a successful load.
     * The key should be unique both in terms of files being loaded and files already present in the Spine cache.
     * Loading a file using a key that is already taken will result in a warning.
     *
     * Instead of passing arguments you can pass a configuration object, such as:
     *
     * ```javascript
     * this.load.spine({
     *     key: 'mainmenu',
     *     jsonURL: 'boy.json',
     *     atlasURL: 'boy.atlas',
     *     preMultipliedAlpha: true
     * });
     * ```
     *
     * If you need to load multiple Spine atlas files, provide them as an array:
     *
     * ```javascript
     * function preload ()
     * {
     *     this.load.spine('demos', 'demos.json', [ 'atlas1.atlas', 'atlas2.atlas' ], true);
     * }
     * ```
     *
     * See the documentation for `Phaser.Types.Loader.FileTypes.SpineFileConfig` for more details.
     *
     * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files
     * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and
     * this is what you would use to retrieve the data from the Spine plugin.
     *
     * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
     *
     * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien"
     * and no URL is given then the Loader will set the URL to be "alien.json". It will always add `.json` as the extension, although
     * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
     *
     * Note: The ability to load this type of file will only be available if the Spine Plugin has been built or loaded into Phaser.
     *
     * @method Phaser.Loader.LoaderPlugin#spine
     * @fires Phaser.Loader.Events#ADD
     * @since 3.19.0
     *
     * @param {(string|Phaser.Types.Loader.FileTypes.JSONFileConfig|Phaser.Types.Loader.FileTypes.JSONFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
     * @param {string} jsonURL - The absolute or relative URL to load the Spine json file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json".
     * @param {string|string[]} atlasURL - The absolute or relative URL to load the Spine atlas file from. If undefined or `null` it will be set to `<key>.atlas`, i.e. if `key` was "alien" then the URL will be "alien.atlas".
     * @param {boolean} [preMultipliedAlpha=false] - Do the texture files include pre-multiplied alpha or not?
     * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the Spine json file. Used in replacement of the Loaders default XHR Settings.
     * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the Spine atlas file. Used in replacement of the Loaders default XHR Settings.
     * @param {object} [settings] - An external Settings configuration object { prefix: '' }
     *
     * @return {Phaser.Loader.LoaderPlugin} The Loader instance.
     */
    spineFileCallback: function (key, jsonURL, atlasURL, preMultipliedAlpha, jsonXhrSettings, atlasXhrSettings, settings)
    {
        var multifile;
        settings = settings || {};

        if (Array.isArray(key))
        {
            for (var i = 0; i < key.length; i++)
            {
                multifile = new SpineFile(this, key[i]);

                // Support prefix key
                multifile.prefix = multifile.prefix || settings.prefix || '';

                this.addFile(multifile.files);
            }
        }
        else
        {
            multifile = new SpineFile(this, key, jsonURL, atlasURL, preMultipliedAlpha, jsonXhrSettings, atlasXhrSettings);

            // Support prefix key
            multifile.prefix = multifile.prefix || settings.prefix || '';

            this.addFile(multifile.files);
        }

        return this;
    },

    /**
     * Converts the given x and y screen coordinates into the world space of the given Skeleton.
     *
     * Only works in WebGL.
     *
     * @method SpinePlugin#worldToLocal
     * @since 3.19.0
     *
     * @param {number} x - The screen space x coordinate to convert.
     * @param {number} y - The screen space y coordinate to convert.
     * @param {spine.Skeleton} skeleton - The Spine Skeleton to convert into.
     * @param {spine.Bone} [bone] - Optional bone of the Skeleton to convert into.
     *
     * @return {spine.Vector2} A Vector2 containing the translated point.
     */
    worldToLocal: function (x, y, skeleton, bone)
    {
        var temp1 = this.temp1;
        var temp2 = this.temp2;
        var camera = this.sceneRenderer.camera;

        temp1.set(x + skeleton.x, y - skeleton.y, 0);

        var width = camera.viewportWidth;
        var height = camera.viewportHeight;

        camera.screenToWorld(temp1, width, height);

        if (bone && bone.parent !== null)
        {
            bone.parent.worldToLocal(temp2.set(temp1.x - skeleton.x, temp1.y - skeleton.y, 0));

            return new Spine.Vector2(temp2.x, temp2.y);
        }
        else if (bone)
        {
            return new Spine.Vector2(temp1.x - skeleton.x, temp1.y - skeleton.y);
        }
        else
        {
            return new Spine.Vector2(temp1.x, temp1.y);
        }
    },

    /**
     * Returns a Spine Vector2 based on the given x and y values.
     *
     * @method SpinePlugin#getVector2
     * @since 3.19.0
     *
     * @param {number} x - The Vector x value.
     * @param {number} y - The Vector y value.
     *
     * @return {spine.Vector2} A Spine Vector2 based on the given values.
     */
    getVector2: function (x, y)
    {
        return new Spine.Vector2(x, y);
    },

    /**
     * Returns a Spine Vector2 based on the given x, y and z values.
     *
     * Only works in WebGL.
     *
     * @method SpinePlugin#getVector3
     * @since 3.19.0
     *
     * @param {number} x - The Vector x value.
     * @param {number} y - The Vector y value.
     * @param {number} z - The Vector z value.
     *
     * @return {spine.Vector2} A Spine Vector2 based on the given values.
     */
    getVector3: function (x, y, z)
    {
        return new Spine.webgl.Vector3(x, y, z);
    },

    /**
     * Sets `drawBones` in the Spine Skeleton Debug Renderer.
     *
     * Only works in WebGL.
     *
     * @method SpinePlugin#setDebugBones
     * @since 3.19.0
     *
     * @param {boolean} [value=true] - The value to set in the debug property.
     *
     * @return {this} This Spine Plugin.
     */
    setDebugBones: function (value)
    {
        if (value === undefined) { value = true; }

        this.skeletonDebugRenderer.drawBones = value;

        return this;
    },

    /**
     * Sets `drawRegionAttachments` in the Spine Skeleton Debug Renderer.
     *
     * Only works in WebGL.
     *
     * @method SpinePlugin#setDebugRegionAttachments
     * @since 3.19.0
     *
     * @param {boolean} [value=true] - The value to set in the debug property.
     *
     * @return {this} This Spine Plugin.
     */
    setDebugRegionAttachments: function (value)
    {
        if (value === undefined) { value = true; }

        this.skeletonDebugRenderer.drawRegionAttachments = value;

        return this;
    },

    /**
     * Sets `drawBoundingBoxes` in the Spine Skeleton Debug Renderer.
     *
     * Only works in WebGL.
     *
     * @method SpinePlugin#setDebugBoundingBoxes
     * @since 3.19.0
     *
     * @param {boolean} [value=true] - The value to set in the debug property.
     *
     * @return {this} This Spine Plugin.
     */
    setDebugBoundingBoxes: function (value)
    {
        if (value === undefined) { value = true; }

        this.skeletonDebugRenderer.drawBoundingBoxes = value;

        return this;
    },

    /**
     * Sets `drawMeshHull` in the Spine Skeleton Debug Renderer.
     *
     * Only works in WebGL.
     *
     * @method SpinePlugin#setDebugMeshHull
     * @since 3.19.0
     *
     * @param {boolean} [value=true] - The value to set in the debug property.
     *
     * @return {this} This Spine Plugin.
     */
    setDebugMeshHull: function (value)
    {
        if (value === undefined) { value = true; }

        this.skeletonDebugRenderer.drawMeshHull = value;

        return this;
    },

    /**
     * Sets `drawMeshTriangles` in the Spine Skeleton Debug Renderer.
     *
     * Only works in WebGL.
     *
     * @method SpinePlugin#setDebugMeshTriangles
     * @since 3.19.0
     *
     * @param {boolean} [value=true] - The value to set in the debug property.
     *
     * @return {this} This Spine Plugin.
     */
    setDebugMeshTriangles: function (value)
    {
        if (value === undefined) { value = true; }

        this.skeletonDebugRenderer.drawMeshTriangles = value;

        return this;
    },

    /**
     * Sets `drawPaths` in the Spine Skeleton Debug Renderer.
     *
     * Only works in WebGL.
     *
     * @method SpinePlugin#setDebugPaths
     * @since 3.19.0
     *
     * @param {boolean} [value=true] - The value to set in the debug property.
     *
     * @return {this} This Spine Plugin.
     */
    setDebugPaths: function (value)
    {
        if (value === undefined) { value = true; }

        this.skeletonDebugRenderer.drawPaths = value;

        return this;
    },

    /**
     * Sets `drawSkeletonXY` in the Spine Skeleton Debug Renderer.
     *
     * Only works in WebGL.
     *
     * @method SpinePlugin#setDebugSkeletonXY
     * @since 3.19.0
     *
     * @param {boolean} [value=true] - The value to set in the debug property.
     *
     * @return {this} This Spine Plugin.
     */
    setDebugSkeletonXY: function (value)
    {
        if (value === undefined) { value = true; }

        this.skeletonDebugRenderer.drawSkeletonXY = value;

        return this;
    },

    /**
     * Sets `drawClipping` in the Spine Skeleton Debug Renderer.
     *
     * Only works in WebGL.
     *
     * @method SpinePlugin#setDebugClipping
     * @since 3.19.0
     *
     * @param {boolean} [value=true] - The value to set in the debug property.
     *
     * @return {this} This Spine Plugin.
     */
    setDebugClipping: function (value)
    {
        if (value === undefined) { value = true; }

        this.skeletonDebugRenderer.drawClipping = value;

        return this;
    },

    /**
     * Sets the given vertex effect on the Spine Skeleton Renderer.
     *
     * Only works in WebGL.
     *
     * @method SpinePlugin#setEffect
     * @since 3.19.0
     *
     * @param {spine.VertexEffect} [effect] - The vertex effect to set on the Skeleton Renderer.
     *
     * @return {this} This Spine Plugin.
     */
    setEffect: function (effect)
    {
        this.sceneRenderer.skeletonRenderer.vertexEffect = effect;

        return this;
    },

    /**
     * Creates a Spine Skeleton based on the given key and optional Skeleton JSON data.
     *
     * The Skeleton data should have already been loaded before calling this method.
     *
     * @method SpinePlugin#createSkeleton
     * @since 3.19.0
     *
     * @param {string} key - The key of the Spine skeleton data, as loaded by the plugin. If the Spine JSON contains multiple skeletons, reference them with a period, i.e. `set.spineBoy`.
     * @param {object} [skeletonJSON] - Optional Skeleton JSON data to use, instead of getting it from the cache.
     *
     * @return {(any|null)} This Spine Skeleton data object, or `null` if the key was invalid.
     */
    createSkeleton: function (key, skeletonJSON)
    {
        var atlasKey = key;
        var jsonKey = key;
        var split = (key.indexOf('.') !== -1);

        if (split)
        {
            var parts = key.split('.');

            atlasKey = parts.shift();
            jsonKey = parts.join('.');
        }

        var atlasData = this.cache.get(atlasKey);
        var atlas = this.getAtlas(atlasKey);

        if (!atlas)
        {
            return null;
        }

        if (!this.spineTextures.has(atlasKey))
        {
            this.spineTextures.add(atlasKey, atlas);
        }

        var preMultipliedAlpha = atlasData.preMultipliedAlpha;

        var atlasLoader = new Spine.AtlasAttachmentLoader(atlas);

        var skeletonJson = new Spine.SkeletonJson(atlasLoader);

        var data;

        if (skeletonJSON)
        {
            data = skeletonJSON;
        }
        else
        {
            var json = this.json.get(atlasKey);

            data = (split) ? GetValue(json, jsonKey) : json;
        }

        if (data)
        {
            var skeletonData = skeletonJson.readSkeletonData(data);

            var skeleton = new Spine.Skeleton(skeletonData);

            return { skeletonData: skeletonData, skeleton: skeleton, preMultipliedAlpha: preMultipliedAlpha };
        }
        else
        {
            return null;
        }
    },

    /**
     * Creates a new Animation State and Animation State Data for the given skeleton.
     *
     * The returned object contains two properties: `state` and `stateData` respectively.
     *
     * @method SpinePlugin#createAnimationState
     * @since 3.19.0
     *
     * @param {spine.Skeleton} skeleton - The Skeleton to create the Animation State for.
     *
     * @return {any} An object containing the Animation State and Animation State Data instances.
     */
    createAnimationState: function (skeleton)
    {
        var stateData = new Spine.AnimationStateData(skeleton.data);

        var state = new Spine.AnimationState(stateData);

        return { stateData: stateData, state: state };
    },

    /**
     * Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
     *
     * The returned object contains two properties: `offset` and `size`:
     *
     * `offset` - The distance from the skeleton origin to the bottom left corner of the AABB.
     * `size` - The width and height of the AABB.
     *
     * @method SpinePlugin#getBounds
     * @since 3.19.0
     *
     * @param {spine.Skeleton} skeleton - The Skeleton to get the bounds from.
     *
     * @return {any} The bounds object.
     */
    getBounds: function (skeleton)
    {
        var offset = new Spine.Vector2();
        var size = new Spine.Vector2();

        skeleton.getBounds(offset, size, []);

        return { offset: offset, size: size };
    },

    /**
     * Internal handler for when the renderer resizes.
     *
     * Only called if running in WebGL.
     *
     * @method SpinePlugin#onResize
     * @since 3.19.0
     */
    onResize: function ()
    {
        var renderer = this.renderer;
        var sceneRenderer = this.sceneRenderer;

        var viewportWidth = renderer.width;
        var viewportHeight = renderer.height;

        sceneRenderer.camera.position.x = viewportWidth / 2;
        sceneRenderer.camera.position.y = viewportHeight / 2;

        sceneRenderer.camera.setViewport(viewportWidth, viewportHeight);
    },

    /**
     * The Scene that owns this plugin is shutting down.
     *
     * We need to kill and reset all internal properties as well as stop listening to Scene events.
     *
     * @method SpinePlugin#shutdown
     * @private
     * @since 3.19.0
     */
    shutdown: function ()
    {
        var eventEmitter = this.systems.events;

        eventEmitter.off('shutdown', this.shutdown, this);

        if (this.isWebGL)
        {
            this.game.scale.off(ResizeEvent, this.onResize, this);
        }
    },

    /**
     * The Scene that owns this plugin is being destroyed.
     *
     * We need to shutdown and then kill off all external references.
     *
     * @method SpinePlugin#destroy
     * @private
     * @since 3.19.0
     */
    destroy: function ()
    {
        this.shutdown();

        this.game = null;
        this.scene = null;
        this.systems = null;

        this.cache = null;
        this.spineTextures = null;
        this.json = null;
        this.textures = null;
        this.skeletonRenderer = null;
        this.gl = null;
    },

    /**
     * The Game that owns this plugin is being destroyed.
     *
     * Dispose of the Scene Renderer and remove the Game Objects.
     *
     * @method SpinePlugin#gameDestroy
     * @private
     * @since 3.50.0
     */
    gameDestroy: function ()
    {
        this.pluginManager.removeGameObject('spine', true, true);
        this.pluginManager.removeGameObject('spineContainer', true, true);

        this.pluginManager = null;

        var sceneRenderer = this.renderer.spineSceneRenderer;

        if (sceneRenderer)
        {
            sceneRenderer.dispose();
        }

        this.renderer.spineSceneRenderer = null;
        this.sceneRenderer = null;
    }

});

SpinePlugin.SpineGameObject = SpineGameObject;
SpinePlugin.SpineContainer = SpineContainer;

/**
 * Creates a new Spine Game Object and adds it to the Scene.
 *
 * The x and y coordinate given is used to set the placement of the root Spine bone, which can vary from
 * skeleton to skeleton. All rotation and scaling happens from the root bone placement. Spine Game Objects
 * do not have a Phaser origin.
 *
 * If the Spine JSON file exported multiple Skeletons within it, then you can specify them by using a period
 * character in the key. For example, if you loaded a Spine JSON using the key `monsters` and it contains
 * multiple Skeletons, including one called `goblin` then you would use the key `monsters.goblin` to reference
 * that.
 *
 * ```javascript
 * let jelly = this.add.spine(512, 550, 'jelly', 'jelly-think', true);
 * ```
 *
 * The key is optional. If not passed here, you need to call `SpineGameObject.setSkeleton()` to use it.
 *
 * The animation name is also optional and can be set later via `SpineGameObject.setAnimation`.
 *
 * Should you wish for more control over the object creation, such as setting a slot attachment or skin
 * name, then use `SpinePlugin.make` instead.
 *
 * @method SpinePlugin#add
 * @since 3.19.0
 *
 * @param {number} x - The horizontal position of this Game Object in the world.
 * @param {number} y - The vertical position of this Game Object in the world.
 * @param {string} [key] - The key of the Spine Skeleton this Game Object will use, as stored in the Spine Plugin.
 * @param {string} [animationName] - The name of the animation to set on this Skeleton.
 * @param {boolean} [loop=false] - Should the animation playback be looped or not?
 *
 * @return {SpineGameObject} The Game Object that was created.
 */

/**
 * Creates a new Spine Game Object from the given configuration file and optionally adds it to the Scene.
 *
 * The x and y coordinate given is used to set the placement of the root Spine bone, which can vary from
 * skeleton to skeleton. All rotation and scaling happens from the root bone placement. Spine Game Objects
 * do not have a Phaser origin.
 *
 * If the Spine JSON file exported multiple Skeletons within it, then you can specify them by using a period
 * character in the key. For example, if you loaded a Spine JSON using the key `monsters` and it contains
 * multiple Skeletons, including one called `goblin` then you would use the key `monsters.goblin` to reference
 * that.
 *
 * ```javascript
 * let jelly = this.make.spine({
 *     x: 500, y: 500, key: 'jelly',
 *     scale: 1.5,
 *     skinName: 'square_Green',
 *     animationName: 'jelly-idle', loop: true,
 *     slotName: 'hat', attachmentName: 'images/La_14'
 * });
 * ```
 *
 * @method SpinePlugin#make
 * @since 3.19.0
 *
 * @param {any} config - The configuration object this Game Object will use to create itself.
 * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object.
 *
 * @return {SpineGameObject} The Game Object that was created.
 */

module.exports = SpinePlugin;


/***/ }),

/***/ 5782:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var Class = __webpack_require__(7473);
var Container = __webpack_require__(7361);
var SpineContainerRender = __webpack_require__(7738);

/**
 * @classdesc
 * A Spine Container is a special kind of Container created specifically for Spine Game Objects.
 *
 * You have all of the same features of a standard Container, but the rendering functions are optimized specifically
 * for Spine Game Objects. You must only add ever Spine Game Objects, or other Spine Containers, to this type of Container.
 * Although Phaser will not prevent you from adding other types, they will not render and are likely to throw runtime errors.
 *
 * To create one in a Scene, use the factory methods:
 *
 * ```javascript
 * this.add.spineContainer();
 * ```
 *
 * or
 *
 * ```javascript
 * this.make.spineContainer();
 * ```
 *
 * Note that you should not nest Spine Containers inside regular Containers if you wish to use masks on the
 * container children. You can, however, mask children of Spine Containers if they are embedded within other
 * Spine Containers. In short, if you need masking, don't mix and match the types.
 *
 * See the Container documentation for further details about what Containers can do.
 *
 * @class SpineContainer
 * @extends Phaser.GameObjects.Container
 * @constructor
 * @since 3.50.0
 *
 * @param {Phaser.Scene} scene - A reference to the Scene that this Game Object belongs to.
 * @param {SpinePlugin} pluginManager - A reference to the Phaser Spine Plugin.
 * @param {number} x - The horizontal position of this Game Object in the world.
 * @param {number} y - The vertical position of this Game Object in the world.
 * @param {SpineGameObject[]} [children] - An optional array of Spine Game Objects to add to this Container.
 */
var SpineContainer = new Class({

    Extends: Container,

    Mixins: [
        SpineContainerRender
    ],

    initialize:

    function SpineContainer (scene, plugin, x, y, children)
    {
        Container.call(this, scene, x, y, children);

        //  Same as SpineGameObject, to prevent the renderer from mis-typing it when batching
        this.type = 'Spine';

        /**
         * A reference to the Spine Plugin.
         *
         * @name SpineContainer#plugin
         * @type {SpinePlugin}
         * @since 3.50.0
         */
        this.plugin = plugin;
    },

    /**
     * Internal destroy handler, called as part of the destroy process.
     *
     * @method SpineContainer#preDestroy
     * @protected
     * @since 3.50.0
     */
    preDestroy: function ()
    {
        this.removeAll(!!this.exclusive);

        this.localTransform.destroy();
        this.tempTransformMatrix.destroy();

        this.list = [];
        this._displayList = null;
        this.plugin = null;
    }

});

module.exports = SpineContainer;


/***/ }),

/***/ 8064:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Renders this Game Object with the Canvas Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method Phaser.GameObjects.Container#renderCanvas
 * @since 3.4.0
 * @private
 *
 * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer.
 * @param {Phaser.GameObjects.Container} container - The Game Object being rendered in this call.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
 */
var SpineContainerCanvasRenderer = function (renderer, container, camera, parentMatrix)
{
    var children = container.list;

    if (children.length === 0)
    {
        return;
    }

    camera.addToRenderList(container);

    var transformMatrix = container.localTransform;

    if (parentMatrix)
    {
        transformMatrix.loadIdentity();
        transformMatrix.multiply(parentMatrix);
        transformMatrix.translate(container.x, container.y);
        transformMatrix.rotate(container.rotation);
        transformMatrix.scale(container.scaleX, container.scaleY);
    }
    else
    {
        transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY);
    }

    var containerHasBlendMode = (container.blendMode !== -1);

    if (!containerHasBlendMode)
    {
        //  If Container is SKIP_TEST then set blend mode to be Normal
        renderer.setBlendMode(0);
    }

    var alpha = container._alpha;
    var scrollFactorX = container.scrollFactorX;
    var scrollFactorY = container.scrollFactorY;

    if (container.mask)
    {
        container.mask.preRenderCanvas(renderer, null, camera);
    }

    for (var i = 0; i < children.length; i++)
    {
        var child = children[i];

        if (!child.willRender(camera))
        {
            continue;
        }

        var childAlpha = child.alpha;
        var childScrollFactorX = child.scrollFactorX;
        var childScrollFactorY = child.scrollFactorY;

        if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode)
        {
            //  If Container doesn't have its own blend mode, then a child can have one
            renderer.setBlendMode(child.blendMode);
        }

        //  Set parent values
        child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY);
        child.setAlpha(childAlpha * alpha);

        //  Render
        child.renderCanvas(renderer, child, camera, transformMatrix);

        //  Restore original values
        child.setAlpha(childAlpha);
        child.setScrollFactor(childScrollFactorX, childScrollFactorY);
    }

    if (container.mask)
    {
        container.mask.postRenderCanvas(renderer);
    }
};

module.exports = SpineContainerCanvasRenderer;


/***/ }),

/***/ 7738:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var renderWebGL = __webpack_require__(1984);
var renderCanvas = __webpack_require__(1984);

if (true)
{
    renderWebGL = __webpack_require__(434);
}

if (true)
{
    renderCanvas = __webpack_require__(8064);
}

module.exports = {

    renderWebGL: renderWebGL,
    renderCanvas: renderCanvas

};


/***/ }),

/***/ 434:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Renders this Game Object with the WebGL Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method SpineContainerWebGLRenderer#renderWebGL
 * @since 3.50.0
 * @private
 *
 * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
 * @param {SpineContainer} container - The Game Object being rendered in this call.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
 */
var SpineContainerWebGLRenderer = function (renderer, container, camera, parentMatrix)
{
    var plugin = container.plugin;
    var sceneRenderer = plugin.sceneRenderer;
    var children = container.list;

    if (children.length === 0)
    {
        if (sceneRenderer.batcher.isDrawing && renderer.finalType)
        {
            sceneRenderer.end();

            renderer.pipelines.rebind();
        }

        return;
    }

    camera.addToRenderList(container);

    var transformMatrix = container.localTransform;

    if (parentMatrix)
    {
        transformMatrix.loadIdentity();
        transformMatrix.multiply(parentMatrix);
        transformMatrix.translate(container.x, container.y);
        transformMatrix.rotate(container.rotation);
        transformMatrix.scale(container.scaleX, container.scaleY);
    }
    else
    {
        transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY);
    }

    if (renderer.newType)
    {
        //  flush + clear if this is a new type
        renderer.pipelines.clear();

        sceneRenderer.begin();
    }

    var rendererNextType = renderer.nextTypeMatch;

    //  Force these to avoid batch flushing during SpineGameObject.renderWebGL
    renderer.nextTypeMatch = true;
    renderer.newType = false;

    for (var i = 0; i < children.length; i++)
    {
        var child = children[i];

        if (child.willRender(camera, container))
        {
            var mask = child.mask;

            if (mask)
            {
                sceneRenderer.end();

                renderer.pipelines.rebind();

                mask.preRenderWebGL(renderer, child, camera);

                renderer.pipelines.clear();

                sceneRenderer.begin();
            }

            child.renderWebGL(renderer, child, camera, transformMatrix, container);

            if (mask)
            {
                sceneRenderer.end();

                renderer.pipelines.rebind();

                mask.postRenderWebGL(renderer, camera);

                renderer.pipelines.clear();

                sceneRenderer.begin();
            }
        }
    }

    renderer.nextTypeMatch = rendererNextType;

    if (!rendererNextType || container.mask)
    {
        //  The next object in the display list is not a Spine Game Object or Spine Container, so we end the batch
        sceneRenderer.end();

        //  And rebind the previous pipeline
        renderer.pipelines.rebind();
    }
};

module.exports = SpineContainerWebGLRenderer;


/***/ }),

/***/ 6576:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Complete Event.
 *
 * @event SpinePluginEvents#COMPLETE
 * @since 3.19.0
 */
module.exports = 'complete';


/***/ }),

/***/ 8621:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Dispose Event.
 *
 * @event SpinePluginEvents#DISPOSE
 * @since 3.19.0
 */
module.exports = 'dispose';


/***/ }),

/***/ 8944:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The End Event.
 *
 * @event SpinePluginEvents#END
 * @since 3.19.0
 */
module.exports = 'end';


/***/ }),

/***/ 7494:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Custom Event Event.
 *
 * @event SpinePluginEvents#EVENT
 * @since 3.19.0
 */
module.exports = 'event';


/***/ }),

/***/ 1908:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Interrupted Event.
 *
 * @event SpinePluginEvents#INTERRUPTED
 * @since 3.19.0
 */
module.exports = 'interrupted';


/***/ }),

/***/ 5591:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Start Event.
 *
 * @event SpinePluginEvents#START
 * @since 3.19.0
 */
module.exports = 'start';


/***/ }),

/***/ 5146:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace SpinePluginEvents
 */

module.exports = {

    COMPLETE: __webpack_require__(6576),
    DISPOSE: __webpack_require__(8621),
    END: __webpack_require__(8944),
    EVENT: __webpack_require__(7494),
    INTERRUPTED: __webpack_require__(1908),
    START: __webpack_require__(5591)

};


/***/ }),

/***/ 8332:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var AngleBetween = __webpack_require__(6412);
var Clamp = __webpack_require__(2915);
var Class = __webpack_require__(7473);
var ComponentsComputedSize = __webpack_require__(1991);
var ComponentsDepth = __webpack_require__(3131);
var ComponentsFlip = __webpack_require__(9660);
var ComponentsScrollFactor = __webpack_require__(4627);
var ComponentsTransform = __webpack_require__(3212);
var ComponentsVisible = __webpack_require__(8414);
var CounterClockwise = __webpack_require__(3426);
var DegToRad = __webpack_require__(7149);
var GameObject = __webpack_require__(2273);
var RadToDeg = __webpack_require__(4208);
var SpineEvents = __webpack_require__(5146);
var SpineGameObjectRender = __webpack_require__(2762);

/**
 * @classdesc
 * A Spine Game Object is a Phaser level object that can be added to your Phaser Scenes. It encapsulates
 * a Spine Skeleton with Spine Animation Data and Animation State, with helper methods to allow you to
 * easily change the skin, slot attachment, bone positions and more.
 *
 * Spine Game Objects can be created via the Game Object Factory, Game Object Creator, or directly.
 * You can only create them if the Spine plugin has been loaded into Phaser.
 *
 * The quickest way is the Game Object Factory:
 *
 * ```javascript
 * let jelly = this.add.spine(512, 550, 'jelly', 'jelly-think', true);
 * ```
 *
 * Here we are creating a new Spine Game Object positioned at 512 x 550. It's using the `jelly`
 * Spine data, which has previously been loaded into your Scene. The `jelly-think` argument is
 * an optional animation to start playing on the skeleton. The final argument `true` sets the
 * animation to loop. Look at the documentation for further details on each of these options.
 *
 * For more control, you can use the Game Object Creator, passing in a Spine Game Object
 * Configuration object:
 *
 * ```javascript
 * let jelly = this.make.spine({
 *     x: 512, y: 550, key: 'jelly',
 *     scale: 1.5,
 *     skinName: 'square_Green',
 *     animationName: 'jelly-think', loop: true,
 *     slotName: 'hat', attachmentName: 'images/La_14'
 * });
 * ```
 *
 * Here, you've got the ability to specify extra details, such as the slot name, attachments or
 * overall scale.
 *
 * If you wish to instantiate a Spine Game Object directly you can do so, but in order for it to
 * update and render, it must be added to the display and update lists of your Scene:
 *
 * ```javascript
 * let jelly = new SpineGameObject(this, this.spine, 512, 550, 'jelly', 'jelly-think', true);
 * this.sys.displayList.add(jelly);
 * this.sys.updateList.add(jelly);
 * ```
 *
 * It's possible to enable Spine Game Objects for input, but you should be aware that it will use
 * the bounds of the skeletons current pose to create the hit area from. Ensure that your setup
 * post in the Spine Editor does _not_ have everything turned off, or the runtimes will be unable
 * to get an accurate bounds. You can make use of the `InputPlugin.enableDebug` method to view the
 * input shape being created. If it's not suitable, provide your own shape to the `setInteractive` method.
 *
 * Due to the way Spine handles scaling, it's not recommended to enable a Spine Game Object for
 * physics directly. Instead, you should look at creating a proxy body and syncing the Spine Game
 * Object position with it. See the examples for further details.
 *
 * If your Spine Game Object has black outlines around the different parts of the texture when it
 * renders then you have exported the files from Spine with pre-multiplied alpha enabled, but have
 * forgotten to set that flag when loading the Spine data. Please see the loader docs for more details.
 *
 * @class SpineGameObject
 * @extends Phaser.GameObjects.GameObject
 * @constructor
 * @since 3.19.0
 *
 * @param {Phaser.Scene} scene - A reference to the Scene that this Game Object belongs to.
 * @param {SpinePlugin} pluginManager - A reference to the Phaser Spine Plugin.
 * @param {number} x - The horizontal position of this Game Object in the world.
 * @param {number} y - The vertical position of this Game Object in the world.
 * @param {string} [key] - The key of the Spine Skeleton this Game Object will use, as stored in the Spine Plugin.
 * @param {string} [animationName] - The name of the animation to set on this Skeleton.
 * @param {boolean} [loop=false] - Should the animation playback be looped or not?
 */
var SpineGameObject = new Class({

    Extends: GameObject,

    Mixins: [
        ComponentsComputedSize,
        ComponentsDepth,
        ComponentsFlip,
        ComponentsScrollFactor,
        ComponentsTransform,
        ComponentsVisible,
        SpineGameObjectRender
    ],

    initialize:

    function SpineGameObject (scene, plugin, x, y, key, animationName, loop)
    {
        GameObject.call(this, scene, 'Spine');

        /**
         * A reference to the Spine Plugin.
         *
         * @name SpineGameObject#plugin
         * @type {SpinePlugin}
         * @since 3.19.0
         */
        this.plugin = plugin;

        /**
         * The Spine Skeleton this Game Object is using.
         *
         * @name SpineGameObject#skeleton
         * @type {spine.Skeleton}
         * @since 3.19.0
         */
        this.skeleton = null;

        /**
         * The Spine Skeleton Data associated with the Skeleton this Game Object is using.
         *
         * @name SpineGameObject#skeletonData
         * @type {spine.SkeletonData}
         * @since 3.19.0
         */
        this.skeletonData = null;

        /**
         * The Spine Animation State this Game Object is using.
         *
         * @name SpineGameObject#state
         * @type {spine.AnimationState}
         * @since 3.19.0
         */
        this.state = null;

        /**
         * The Spine Animation State Data associated with the Animation State this Game Object is using.
         *
         * @name SpineGameObject#stateData
         * @type {spine.AnimationStateData}
         * @since 3.19.0
         */
        this.stateData = null;

        /**
         * A reference to the root bone of the Skeleton.
         *
         * @name SpineGameObject#root
         * @type {spine.Bone}
         * @since 3.19.0
         */
        this.root = null;

        /**
         * This object holds the calculated bounds of the current
         * pose, as set when a new Skeleton is applied.
         *
         * @name SpineGameObject#bounds
         * @type {any}
         * @since 3.19.0
         */
        this.bounds = null;

        /**
         * A Game Object level flag that allows you to enable debug drawing
         * to the Skeleton Debug Renderer by toggling it.
         *
         * @name SpineGameObject#drawDebug
         * @type {boolean}
         * @since 3.19.0
         */
        this.drawDebug = false;

        /**
         * The factor to scale the Animation update time by.
         *
         * @name SpineGameObject#timeScale
         * @type {number}
         * @since 3.19.0
         */
        this.timeScale = 1;

        /**
         * The calculated Display Origin of this Game Object.
         *
         * @name SpineGameObject#displayOriginX
         * @type {number}
         * @since 3.19.0
         */
        this.displayOriginX = 0;

        /**
         * The calculated Display Origin of this Game Object.
         *
         * @name SpineGameObject#displayOriginY
         * @type {number}
         * @since 3.19.0
         */
        this.displayOriginY = 0;

        /**
         * A flag that stores if the texture associated with the current
         * Skin being used by this Game Object, has its alpha pre-multiplied
         * into it, or not.
         *
         * @name SpineGameObject#preMultipliedAlpha
         * @type {boolean}
         * @since 3.19.0
         */
        this.preMultipliedAlpha = false;

        /**
         * A default Blend Mode. You cannot change the blend mode of a
         * Spine Game Object.
         *
         * @name SpineGameObject#blendMode
         * @type {number}
         * @readonly
         * @since 3.19.0
         */
        this.blendMode = -1;

        this.setPosition(x, y);

        if (key)
        {
            this.setSkeleton(key, animationName, loop);
        }
    },

    /**
     * Returns `true` if this Spine Game Object both has a skeleton and
     * also passes the render tests for the given Camera.
     *
     * @method SpineGameObject#willRender
     * @since 3.19.0
     *
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
     * @param {SpineContainer} [container] - If this Spine object is in a Spine Container, this is a reference to it.
     *
     * @return {boolean} `true` if this Game Object should be rendered, otherwise `false`.
     */
    willRender: function (camera, container)
    {
        var GameObjectRenderMask = 15;

        var result = (!this.skeleton || !(GameObjectRenderMask !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))));

        if (!container && !result && this.parentContainer)
        {
            var plugin = this.plugin;
            var sceneRenderer = plugin.sceneRenderer;

            if (plugin.gl && sceneRenderer.batcher.isDrawing)
            {
                sceneRenderer.end();

                plugin.renderer.pipelines.rebind();
            }
        }

        return result;
    },

    /**
     * Set the Alpha level for the whole Skeleton of this Game Object.
     *
     * The alpha controls the opacity of the Game Object as it renders.
     *
     * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque.
     *
     * @method SpineGameObject#setAlpha
     * @since 3.19.0
     *
     * @param {number} [value=1] - The alpha value used for the whole Skeleton.
     *
     * @return {this} This Game Object instance.
     */
    setAlpha: function (value, slotName)
    {
        if (value === undefined) { value = 1; }

        if (slotName)
        {
            var slot = this.findSlot(slotName);

            if (slot)
            {
                slot.color.a = Clamp(value, 0, 1);
            }
        }
        else
        {
            this.alpha = value;
        }

        return this;
    },

    /**
     * The alpha value of the Skeleton.
     *
     * A value between 0 and 1.
     *
     * This is a global value, impacting the entire Skeleton, not just a region of it.
     *
     * @name SpineGameObject#alpha
     * @type {number}
     * @since 3.19.0
     */
    alpha: {

        get: function ()
        {
            return this.skeleton.color.a;
        },

        set: function (value)
        {
            var v = Clamp(value, 0, 1);

            if (this.skeleton)
            {
                this.skeleton.color.a = v;
            }

            if (v === 0)
            {
                this.renderFlags &= ~2;
            }
            else
            {
                this.renderFlags |= 2;
            }
        }

    },

    /**
     * The amount of red used when rendering the Skeleton.
     *
     * A value between 0 and 1.
     *
     * This is a global value, impacting the entire Skeleton, not just a region of it.
     *
     * @name SpineGameObject#red
     * @type {number}
     * @since 3.19.0
     */
    red: {

        get: function ()
        {
            return this.skeleton.color.r;
        },

        set: function (value)
        {
            var v = Clamp(value, 0, 1);

            if (this.skeleton)
            {
                this.skeleton.color.r = v;
            }
        }

    },

    /**
     * The amount of green used when rendering the Skeleton.
     *
     * A value between 0 and 1.
     *
     * This is a global value, impacting the entire Skeleton, not just a region of it.
     *
     * @name SpineGameObject#green
     * @type {number}
     * @since 3.19.0
     */
    green: {

        get: function ()
        {
            return this.skeleton.color.g;
        },

        set: function (value)
        {
            var v = Clamp(value, 0, 1);

            if (this.skeleton)
            {
                this.skeleton.color.g = v;
            }
        }

    },

    /**
     * The amount of blue used when rendering the Skeleton.
     *
     * A value between 0 and 1.
     *
     * This is a global value, impacting the entire Skeleton, not just a region of it.
     *
     * @name SpineGameObject#blue
     * @type {number}
     * @since 3.19.0
     */
    blue: {

        get: function ()
        {
            return this.skeleton.color.b;
        },

        set: function (value)
        {
            var v = Clamp(value, 0, 1);

            if (this.skeleton)
            {
                this.skeleton.color.b = v;
            }
        }

    },

    /**
     * Sets the color on the given attachment slot. Or, if no slot is given, on the whole skeleton.
     *
     * @method SpineGameObject#setColor
     * @since 3.19.0
     *
     * @param {integer} [color=0xffffff] - The color being applied to the Skeleton or named Slot. Set to white to disable any previously set color.
     * @param {string} [slotName] - The name of the slot to set the color on. If not give, will be set on the whole skeleton.
     *
     * @return {this} This Game Object instance.
     */
    setColor: function (color, slotName)
    {
        if (color === undefined) { color = 0xffffff; }

        var red = (color >> 16 & 0xFF) / 255;
        var green = (color >> 8 & 0xFF) / 255;
        var blue = (color & 0xFF) / 255;
        var alpha = (color > 16777215) ? (color >>> 24) / 255 : null;

        var target = this.skeleton;

        if (slotName)
        {
            var slot = this.findSlot(slotName);

            if (slot)
            {
                target = slot;
            }
        }

        target.color.r = red;
        target.color.g = green;
        target.color.b = blue;

        if (alpha !== null)
        {
            target.color.a = alpha;
        }

        return this;
    },

    /**
     * Sets this Game Object to use the given Skeleton based on the Atlas Data Key and a provided JSON object
     * that contains the Skeleton data.
     *
     * @method SpineGameObject#setSkeletonFromJSON
     * @since 3.19.0
     *
     * @param {string} atlasDataKey - The key of the Spine data to use for this Skeleton.
     * @param {object} skeletonJSON - The JSON data for the Skeleton.
     * @param {string} [animationName] - Optional name of the animation to set on the Skeleton.
     * @param {boolean} [loop=false] - Should the animation, if set, loop or not?
     *
     * @return {this} This Game Object.
     */
    setSkeletonFromJSON: function (atlasDataKey, skeletonJSON, animationName, loop)
    {
        return this.setSkeleton(atlasDataKey, animationName, loop, skeletonJSON);
    },

    /**
     * Sets this Game Object to use the given Skeleton based on its cache key.
     *
     * Typically, once set, the Skeleton doesn't change. Instead, you change the skin,
     * or slot attachment, or any other property to adjust it.
     *
     * @method SpineGameObject#setSkeleton
     * @since 3.19.0
     *
     * @param {string} atlasDataKey - The key of the Spine data to use for this Skeleton.
     * @param {string} [animationName] - Optional name of the animation to set on the Skeleton.
     * @param {boolean} [loop=false] - Should the animation, if set, loop or not?
     * @param {object} [skeletonJSON] - The JSON data for the Skeleton.
     *
     * @return {this} This Game Object.
     */
    setSkeleton: function (atlasDataKey, animationName, loop, skeletonJSON)
    {
        if (this.state)
        {
            this.state.clearListeners();
            this.state.clearListenerNotifications();
        }

        var data = this.plugin.createSkeleton(atlasDataKey, skeletonJSON);

        this.skeletonData = data.skeletonData;

        this.preMultipliedAlpha = data.preMultipliedAlpha;

        var skeleton = data.skeleton;

        skeleton.setSkin();
        skeleton.setToSetupPose();

        this.skeleton = skeleton;

        //  AnimationState
        data = this.plugin.createAnimationState(skeleton);

        if (this.state)
        {
            this.state.clearListeners();
            this.state.clearListenerNotifications();
        }

        this.state = data.state;
        this.stateData = data.stateData;

        this.state.addListener({
            event: this.onEvent.bind(this),
            complete: this.onComplete.bind(this),
            start: this.onStart.bind(this),
            end: this.onEnd.bind(this),
            dispose: this.onDispose.bind(this),
            interrupted: this.onInterrupted.bind(this)
        });

        if (animationName)
        {
            this.setAnimation(0, animationName, loop);
        }

        this.root = this.getRootBone();

        if (this.root)
        {
            //  +90 degrees to account for the difference in Spine vs. Phaser rotation
            this.root.rotation = RadToDeg(CounterClockwise(this.rotation)) + 90;
        }

        this.state.apply(skeleton);

        skeleton.updateCache();

        return this.updateSize();
    },

    /**
     * Internal event handler that emits the Spine onComplete event via this Game Object.
     *
     * @method SpineGameObject#onComplete
     * @fires SpinePluginEvents#COMPLETE
     * @private
     * @since 3.19.0
     *
     * @param {any} entry - The event data from Spine.
     */
    onComplete: function (entry)
    {
        this.emit(SpineEvents.COMPLETE, entry);
    },

    /**
     * Internal event handler that emits the Spine onDispose event via this Game Object.
     *
     * @method SpineGameObject#onDispose
     * @fires SpinePluginEvents#DISPOSE
     * @private
     * @since 3.19.0
     *
     * @param {any} entry - The event data from Spine.
     */
    onDispose: function (entry)
    {
        this.emit(SpineEvents.DISPOSE, entry);
    },

    /**
     * Internal event handler that emits the Spine onEnd event via this Game Object.
     *
     * @method SpineGameObject#onEnd
     * @fires SpinePluginEvents#END
     * @private
     * @since 3.19.0
     *
     * @param {any} entry - The event data from Spine.
     */
    onEnd: function (entry)
    {
        this.emit(SpineEvents.END, entry);
    },

    /**
     * Internal event handler that emits the Spine Event event via this Game Object.
     *
     * @method SpineGameObject#onEvent
     * @fires SpinePluginEvents#EVENT
     * @private
     * @since 3.19.0
     *
     * @param {any} entry - The event data from Spine.
     * @param {spine.Event} event - The Spine event.
     */
    onEvent: function (entry, event)
    {
        this.emit(SpineEvents.EVENT, entry, event);
    },

    /**
     * Internal event handler that emits the Spine onInterrupted event via this Game Object.
     *
     * @method SpineGameObject#onInterrupted
     * @fires SpinePluginEvents#INTERRUPTED
     * @private
     * @since 3.19.0
     *
     * @param {any} entry - The event data from Spine.
     */
    onInterrupted: function (entry)
    {
        this.emit(SpineEvents.INTERRUPTED, entry);
    },

    /**
     * Internal event handler that emits the Spine onStart event via this Game Object.
     *
     * @method SpineGameObject#onStart
     * @fires SpinePluginEvents#START
     * @private
     * @since 3.19.0
     *
     * @param {any} entry - The event data from Spine.
     */
    onStart: function (entry)
    {
        this.emit(SpineEvents.START, entry);
    },

    /**
     * Refreshes the data about the current Skeleton.
     *
     * This will reset the rotation, position and size of the Skeleton to match this Game Object.
     *
     * Call this method if you need to access the Skeleton data directly, and it may have changed
     * recently.
     *
     * @method SpineGameObject#refresh
     * @since 3.19.0
     *
     * @return {this} This Game Object.
     */
    refresh: function ()
    {
        if (this.root)
        {
            //  +90 degrees to account for the difference in Spine vs. Phaser rotation
            this.root.rotation = RadToDeg(CounterClockwise(this.rotation)) + 90;
        }

        this.updateSize();

        this.skeleton.updateCache();

        return this;
    },

    /**
     * Sets the size of this Game Object.
     *
     * If no arguments are given it uses the current skeleton data dimensions.
     *
     * You can use this method to set a fixed size of this Game Object, such as for input detection,
     * when the skeleton data doesn't match what is required in-game.
     *
     * @method SpineGameObject#setSize
     * @since 3.19.0
     *
     * @param {number} [width] - The width of the Skeleton. If not given it defaults to the Skeleton Data width.
     * @param {number} [height] - The height of the Skeleton. If not given it defaults to the Skeleton Data height.
     * @param {number} [offsetX=0] - The horizontal offset of the Skeleton from its x and y coordinate.
     * @param {number} [offsetY=0] - The vertical offset of the Skeleton from its x and y coordinate.
     *
     * @return {this} This Game Object.
     */
    setSize: function (width, height, offsetX, offsetY)
    {
        var skeleton = this.skeleton;

        if (width === undefined) { width = skeleton.data.width; }
        if (height === undefined) { height = skeleton.data.height; }
        if (offsetX === undefined) { offsetX = 0; }
        if (offsetY === undefined) { offsetY = 0; }

        this.width = width;
        this.height = height;

        this.displayOriginX = skeleton.x - offsetX;
        this.displayOriginY = skeleton.y - offsetY;

        return this;
    },

    /**
     * Sets the offset of this Game Object from the Skeleton position.
     *
     * You can use this method to adjust how the position of this Game Object relates to the Skeleton it is using.
     *
     * @method SpineGameObject#setOffset
     * @since 3.19.0
     *
     * @param {number} [offsetX=0] - The horizontal offset of the Skeleton from its x and y coordinate.
     * @param {number} [offsetY=0] - The vertical offset of the Skeleton from its x and y coordinate.
     *
     * @return {this} This Game Object.
     */
    setOffset: function (offsetX, offsetY)
    {
        var skeleton = this.skeleton;

        if (offsetX === undefined) { offsetX = 0; }
        if (offsetY === undefined) { offsetY = 0; }

        this.displayOriginX = skeleton.x - offsetX;
        this.displayOriginY = skeleton.y - offsetY;

        return this;
    },

    /**
     * Internal method that syncs all of the Game Object position and scale data to the Skeleton.
     * It then syncs the skeleton bounds back to this Game Object.
     *
     * This method is called automatically as needed internally, however, it's also exposed should
     * you require overriding the size settings.
     *
     * @method SpineGameObject#updateSize
     * @since 3.19.0
     *
     * @return {this} This Game Object.
     */
    updateSize: function ()
    {
        var skeleton = this.skeleton;
        var renderer = this.plugin.renderer;

        var height = renderer.height;

        var oldScaleX = this.scaleX;
        var oldScaleY = this.scaleY;

        skeleton.x = this.x;
        skeleton.y = height - this.y;
        skeleton.scaleX = 1;
        skeleton.scaleY = 1;

        skeleton.updateWorldTransform();

        var bounds = this.getBounds();

        this.width = bounds.size.x;
        this.height = bounds.size.y;

        this.displayOriginX = this.x - bounds.offset.x;
        this.displayOriginY = this.y - (height - (this.height + bounds.offset.y));

        skeleton.scaleX = oldScaleX;
        skeleton.scaleY = oldScaleY;

        skeleton.updateWorldTransform();

        return this;
    },

    /**
     * The horizontal scale of this Game Object, as applied to the Skeleton it is using.
     *
     * @name SpineGameObject#scaleX
     * @type {number}
     * @default 1
     * @since 3.19.0
     */
    scaleX: {

        get: function ()
        {
            return this._scaleX;
        },

        set: function (value)
        {
            this._scaleX = value;

            this.refresh();
        }

    },

    /**
     * The vertical scale of this Game Object, as applied to the Skeleton it is using.
     *
     * @name SpineGameObject#scaleY
     * @type {number}
     * @default 1
     * @since 3.19.0
     */
    scaleY: {

        get: function ()
        {
            return this._scaleY;
        },

        set: function (value)
        {
            this._scaleY = value;

            this.refresh();
        }

    },

    /**
     * Returns an array containing the names of all the bones in the Skeleton Data.
     *
     * @method SpineGameObject#getBoneList
     * @since 3.19.0
     *
     * @return {string[]} An array containing the names of all the bones in the Skeleton Data.
     */
    getBoneList: function ()
    {
        var output = [];

        var skeletonData = this.skeletonData;

        if (skeletonData)
        {
            for (var i = 0; i < skeletonData.bones.length; i++)
            {
                output.push(skeletonData.bones[i].name);
            }
        }

        return output;
    },

    /**
     * Returns an array containing the names of all the skins in the Skeleton Data.
     *
     * @method SpineGameObject#getSkinList
     * @since 3.19.0
     *
     * @return {string[]} An array containing the names of all the skins in the Skeleton Data.
     */
    getSkinList: function ()
    {
        var output = [];

        var skeletonData = this.skeletonData;

        if (skeletonData)
        {
            for (var i = 0; i < skeletonData.skins.length; i++)
            {
                output.push(skeletonData.skins[i].name);
            }
        }

        return output;
    },

    /**
     * Returns an array containing the names of all the slots in the Skeleton.
     *
     * @method SpineGameObject#getSlotList
     * @since 3.19.0
     *
     * @return {string[]} An array containing the names of all the slots in the Skeleton.
     */
    getSlotList: function ()
    {
        var output = [];

        var skeleton = this.skeleton;

        for (var i = 0; i < skeleton.slots.length; i++)
        {
            output.push(skeleton.slots[i].data.name);
        }

        return output;
    },

    /**
     * Returns an array containing the names of all the animations in the Skeleton Data.
     *
     * @method SpineGameObject#getAnimationList
     * @since 3.19.0
     *
     * @return {string[]} An array containing the names of all the animations in the Skeleton Data.
     */
    getAnimationList: function ()
    {
        var output = [];

        var skeletonData = this.skeletonData;

        if (skeletonData)
        {
            for (var i = 0; i < skeletonData.animations.length; i++)
            {
                output.push(skeletonData.animations[i].name);
            }
        }

        return output;
    },

    /**
     * Returns the current animation being played on the given track, if any.
     *
     * @method SpineGameObject#getCurrentAnimation
     * @since 3.19.0
     *
     * @param {integer} [trackIndex=0] - The track to return the current animation on.
     *
     * @return {?spine.Animation} The current Animation on the given track, or `undefined` if there is no current animation.
     */
    getCurrentAnimation: function (trackIndex)
    {
        if (trackIndex === undefined) { trackIndex = 0; }

        var current = this.state.getCurrent(trackIndex);

        if (current)
        {
            return current.animation;
        }
    },

    /**
     * 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).
     *
     * Animations are referenced by a unique string-based key, as defined in the Spine software.
     *
     * @method SpineGameObject#play
     * @fires SpinePluginEvents#START
     * @since 3.19.0
     *
     * @param {string} animationName - The string-based key of the animation to play.
     * @param {boolean} [loop=false] - Should the animation be looped when played?
     * @param {boolean} [ignoreIfPlaying=false] - If this animation is already playing then ignore this call.
     *
     * @return {this} This Game Object. If you need the TrackEntry, see `setAnimation` instead.
     */
    play: function (animationName, loop, ignoreIfPlaying)
    {
        this.setAnimation(0, animationName, loop, ignoreIfPlaying);

        return this;
    },

    /**
     * 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).
     *
     * Animations are referenced by a unique string-based key, as defined in the Spine software.
     *
     * @method SpineGameObject#setAnimation
     * @fires SpinePluginEvents#START
     * @since 3.19.0
     *
     * @param {integer} trackIndex - The track index to play the animation on.
     * @param {string} animationName - The string-based key of the animation to play.
     * @param {boolean} [loop=false] - Should the animation be looped when played?
     * @param {boolean} [ignoreIfPlaying=false] - If the animation specified by the track index is already playing then ignore this call.
     *
     * @return {spine.TrackEntry} A track entry to allow further customization of animation playback.
     */
    setAnimation: function (trackIndex, animationName, loop, ignoreIfPlaying)
    {
        if (loop === undefined) { loop = false; }
        if (ignoreIfPlaying === undefined) { ignoreIfPlaying = false; }

        if (ignoreIfPlaying && this.state)
        {
            var currentTrack = this.state.getCurrent(trackIndex);

            if (currentTrack && currentTrack.animation.name === animationName && !currentTrack.isComplete())
            {
                return;
            }
        }

        if (this.findAnimation(animationName))
        {
            return this.state.setAnimation(trackIndex, animationName, loop);
        }
    },

    /**
     * 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 setAnimation.
     *
     * Animations are referenced by a unique string-based key, as defined in the Spine software.
     *
     * The delay is a float. If > 0, sets delay. If <= 0, the delay set is the duration of the previous
     * track entry minus any mix duration (from the 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.
     *
     * @method SpineGameObject#addAnimation
     * @since 3.19.0
     *
     * @param {integer} trackIndex - The track index to add the animation to.
     * @param {string} animationName - The string-based key of the animation to add.
     * @param {boolean} [loop=false] - Should the animation be looped when played?
     * @param {integer} [delay=0] - A delay, in ms, before which this animation will start when played.
     *
     * @return {spine.TrackEntry} A track entry to allow further customization of animation playback.
     */
    addAnimation: function (trackIndex, animationName, loop, delay)
    {
        if (loop === undefined) { loop = false; }
        if (delay === undefined) { delay = 0; }

        return this.state.addAnimation(trackIndex, animationName, loop, delay);
    },

    /**
     * Sets an empty animation for a track, discarding any queued animations, and sets the track
     * entry's 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 setEmptyAnimation,
     * setEmptyAnimations, or 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 addAnimation
     * and on the returned track entry, set the mixDuration. 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.
     *
     * @method SpineGameObject#setEmptyAnimation
     * @since 3.19.0
     *
     * @param {integer} trackIndex - The track index to add the animation to.
     * @param {integer} [mixDuration] - Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData getMix based on the animation before this animation (if any).
     *
     * @return {spine.TrackEntry} The returned Track Entry.
     */
    setEmptyAnimation: function (trackIndex, mixDuration)
    {
        return this.state.setEmptyAnimation(trackIndex, mixDuration);
    },

    /**
     * Removes all animations from the track, leaving skeletons in their current pose.
     *
     * It may be desired to use setEmptyAnimation to mix the skeletons back to the setup pose,
     * rather than leaving them in their current pose.
     *
     * @method SpineGameObject#clearTrack
     * @since 3.19.0
     *
     * @param {integer} trackIndex - The track index to add the animation to.
     *
     * @return {this} This Game Object.
     */
    clearTrack: function (trackIndex)
    {
        this.state.clearTrack(trackIndex);

        return this;
    },

    /**
     * Removes all animations from all tracks, leaving skeletons in their current pose.
     *
     * It may be desired to use setEmptyAnimation to mix the skeletons back to the setup pose,
     * rather than leaving them in their current pose.
     *
     * @method SpineGameObject#clearTracks
     * @since 3.19.0
     *
     * @return {this} This Game Object.
     */
    clearTracks: function ()
    {
        this.state.clearTracks();

        return this;
    },

    /**
     * Sets the skin used to look up attachments before looking in the defaultSkin.
     *
     * 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 setSlotsToSetupPose. Also, often 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.
     *
     * @method SpineGameObject#setSkinByName
     * @since 3.19.0
     *
     * @param {string} skinName - The name of the skin to set.
     *
     * @return {this} This Game Object.
     */
    setSkinByName: function (skinName)
    {
        var skeleton = this.skeleton;

        skeleton.setSkinByName(skinName);

        skeleton.setSlotsToSetupPose();

        this.state.apply(skeleton);

        return this;
    },

    /**
     * Sets the skin used to look up attachments before looking in the defaultSkin.
     *
     * 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 setSlotsToSetupPose. Also, often 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.
     *
     * @method SpineGameObject#setSkin
     * @since 3.19.0
     *
     * @param {?spine.Skin} newSkin - The Skin to set. May be `null`.
     *
     * @return {this} This Game Object.
     */
    setSkin: function (newSkin)
    {
        var skeleton = this.skeleton;

        skeleton.setSkin(newSkin);

        skeleton.setSlotsToSetupPose();

        this.state.apply(skeleton);

        return this;
    },

    /**
     * Sets the mix duration when changing from the specified animation to the other.
     *
     * @method SpineGameObject#setMix
     * @since 3.19.0
     *
     * @param {string} fromName - The animation to mix from.
     * @param {string} toName - The animation to mix to.
     * @param {number} [duration] - Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData getMix based on the animation before this animation (if any).
     *
     * @return {this} This Game Object.
     */
    setMix: function (fromName, toName, duration)
    {
        this.stateData.setMix(fromName, toName, duration);

        return this;
    },

    /**
     * Finds an attachment by looking in the skin and 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.
     *
     * @method SpineGameObject#getAttachment
     * @since 3.19.0
     *
     * @param {integer} slotIndex - The slot index to search.
     * @param {string} attachmentName - The attachment name to look for.
     *
     * @return {?spine.Attachment} The Attachment, if found. May be null.
     */
    getAttachment: function (slotIndex, attachmentName)
    {
        return this.skeleton.getAttachment(slotIndex, attachmentName);
    },

    /**
     * Finds an attachment by looking in the skin and defaultSkin using the slot name and attachment name.
     *
     * @method SpineGameObject#getAttachmentByName
     * @since 3.19.0
     *
     * @param {string} slotName - The slot name to search.
     * @param {string} attachmentName - The attachment name to look for.
     *
     * @return {?spine.Attachment} The Attachment, if found. May be null.
     */
    getAttachmentByName: function (slotName, attachmentName)
    {
        return this.skeleton.getAttachmentByName(slotName, attachmentName);
    },

    /**
     * A convenience method to set an attachment by finding the slot with findSlot,
     * finding the attachment with getAttachment, then setting the slot's attachment.
     *
     * @method SpineGameObject#setAttachment
     * @since 3.19.0
     *
     * @param {string} slotName - The slot name to add the attachment to.
     * @param {string} attachmentName - The attachment name to add.
     *
     * @return {this} This Game Object.
     */
    setAttachment: function (slotName, attachmentName)
    {
        if (Array.isArray(slotName) && Array.isArray(attachmentName) && slotName.length === attachmentName.length)
        {
            for (var i = 0; i < slotName.length; i++)
            {
                this.skeleton.setAttachment(slotName[i], attachmentName[i]);
            }
        }
        else
        {
            this.skeleton.setAttachment(slotName, attachmentName);
        }

        return this;
    },

    /**
     * Sets the bones, constraints, slots, and draw order to their setup pose values.
     *
     * @method SpineGameObject#setToSetupPose
     * @since 3.19.0
     *
     * @return {this} This Game Object.
     */
    setToSetupPose: function ()
    {
        this.skeleton.setToSetupPose();

        return this;
    },

    /**
     * Sets the slots and draw order to their setup pose values.
     *
     * @method SpineGameObject#setSlotsToSetupPose
     * @since 3.19.0
     *
     * @return {this} This Game Object.
     */
    setSlotsToSetupPose: function ()
    {
        this.skeleton.setSlotsToSetupPose();

        return this;
    },

    /**
     * Sets the bones and constraints to their setup pose values.
     *
     * @method SpineGameObject#setBonesToSetupPose
     * @since 3.19.0
     *
     * @return {this} This Game Object.
     */
    setBonesToSetupPose: function ()
    {
        this.skeleton.setBonesToSetupPose();

        return this;
    },

    /**
     * Gets the root bone, or null.
     *
     * @method SpineGameObject#getRootBone
     * @since 3.19.0
     *
     * @return {spine.Bone} The root bone, or null.
     */
    getRootBone: function ()
    {
        return this.skeleton.getRootBone();
    },

    /**
     * Takes a Bone object and a position in world space and rotates the Bone so it is angled
     * towards the given position. You can set an optional angle offset, should the bone be
     * designed at a specific angle already. You can also set a minimum and maximum range for the angle.
     *
     * @method SpineGameObject#angleBoneToXY
     * @since 3.19.0
     *
     * @param {spine.Bone} bone - The bone to rotate towards the world position.
     * @param {number} worldX - The world x coordinate to rotate the bone towards.
     * @param {number} worldY - The world y coordinate to rotate the bone towards.
     * @param {number} [offset=0] - An offset to add to the rotation angle.
     * @param {number} [minAngle=0] - The minimum range of the rotation angle.
     * @param {number} [maxAngle=360] - The maximum range of the rotation angle.
     *
     * @return {this} This Game Object.
     */
    angleBoneToXY: function (bone, worldX, worldY, offset, minAngle, maxAngle)
    {
        if (offset === undefined) { offset = 0; }
        if (minAngle === undefined) { minAngle = 0; }
        if (maxAngle === undefined) { maxAngle = 360; }

        var renderer = this.plugin.renderer;
        var height = renderer.height;

        var angle = CounterClockwise(AngleBetween(bone.worldX, height - bone.worldY, worldX, worldY) + DegToRad(offset));

        bone.rotation = Clamp(RadToDeg(angle), minAngle, maxAngle);

        return this;
    },

    /**
     * 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.
     *
     * @method SpineGameObject#findBone
     * @since 3.19.0
     *
     * @param {string} boneName - The name of the bone to find.
     *
     * @return {spine.Bone} The bone, or null.
     */
    findBone: function (boneName)
    {
        return this.skeleton.findBone(boneName);
    },

    /**
     * Finds the index of 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.
     *
     * @method SpineGameObject#findBoneIndex
     * @since 3.19.0
     *
     * @param {string} boneName - The name of the bone to find.
     *
     * @return {integer} The bone index. Or -1 if the bone was not found.
     */
    findBoneIndex: function (boneName)
    {
        return this.skeleton.findBoneIndex(boneName);
    },

    /**
     * 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.
     *
     * @method SpineGameObject#findSlot
     * @since 3.19.0
     *
     * @param {string} slotName - The name of the slot to find.
     *
     * @return {spine.Slot} The Slot. May be null.
     */
    findSlot: function (slotName)
    {
        return this.skeleton.findSlot(slotName);
    },

    /**
     * Finds the index of 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.
     *
     * @method SpineGameObject#findSlotIndex
     * @since 3.19.0
     *
     * @param {string} slotName - The name of the slot to find.
     *
     * @return {integer} The slot index. Or -1 if the Slot was not found.
     */
    findSlotIndex: function (slotName)
    {
        return this.skeleton.findSlotIndex(slotName);
    },

    /**
     * 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.
     *
     * @method SpineGameObject#findSkin
     * @since 3.19.0
     *
     * @param {string} skinName - The name of the skin to find.
     *
     * @return {spine.Skin} The Skin. May be null.
     */
    findSkin: function (skinName)
    {
        return this.skeletonData.findSkin(skinName);
    },

    /**
     * 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.
     *
     * @method SpineGameObject#findEvent
     * @since 3.19.0
     *
     * @param {string} eventDataName - The name of the event to find.
     *
     * @return {spine.EventData} The Event Data. May be null.
     */
    findEvent: function (eventDataName)
    {
        return this.skeletonData.findEvent(eventDataName);
    },

    /**
     * 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.
     *
     * @method SpineGameObject#findAnimation
     * @since 3.19.0
     *
     * @param {string} animationName - The name of the animation to find.
     *
     * @return {spine.Animation} The Animation. May be null.
     */
    findAnimation: function (animationName)
    {
        return this.skeletonData.findAnimation(animationName);
    },

    /**
     * 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.
     *
     * @method SpineGameObject#findIkConstraint
     * @since 3.19.0
     *
     * @param {string} constraintName - The name of the constraint to find.
     *
     * @return {spine.IkConstraintData} The IK constraint. May be null.
     */
    findIkConstraint: function (constraintName)
    {
        return this.skeletonData.findIkConstraint(constraintName);
    },

    /**
     * Finds an 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.
     *
     * @method SpineGameObject#findTransformConstraint
     * @since 3.19.0
     *
     * @param {string} constraintName - The name of the constraint to find.
     *
     * @return {spine.TransformConstraintData} The transform constraint. May be null.
     */
    findTransformConstraint: function (constraintName)
    {
        return this.skeletonData.findTransformConstraint(constraintName);
    },

    /**
     * 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.
     *
     * @method SpineGameObject#findPathConstraint
     * @since 3.19.0
     *
     * @param {string} constraintName - The name of the constraint to find.
     *
     * @return {spine.PathConstraintData} The path constraint. May be null.
     */
    findPathConstraint: function (constraintName)
    {
        return this.skeletonData.findPathConstraint(constraintName);
    },

    /**
     * Finds the index of 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.
     *
     * @method SpineGameObject#findPathConstraintIndex
     * @since 3.19.0
     *
     * @param {string} constraintName - The name of the constraint to find.
     *
     * @return {integer} The constraint index. Or -1 if the constraint was not found.
     */
    findPathConstraintIndex: function (constraintName)
    {
        return this.skeletonData.findPathConstraintIndex(constraintName);
    },

    /**
     * Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
     *
     * The returned object contains two properties: `offset` and `size`:
     *
     * `offset` - The distance from the skeleton origin to the bottom left corner of the AABB.
     * `size` - The width and height of the AABB.
     *
     * @method SpineGameObject#getBounds
     * @since 3.19.0
     *
     * @return {any} The bounds object.
     */
    getBounds: function ()
    {
        return this.plugin.getBounds(this.skeleton);
    },

    /**
     * Internal update handler.
     *
     * @method SpineGameObject#preUpdate
     * @protected
     * @since 3.19.0
     *
     * @param {number} time - The current timestamp.
     * @param {number} delta - The delta time, in ms, elapsed since the last frame.
     */
    preUpdate: function (time, delta)
    {
        var skeleton = this.skeleton;

        this.state.update((delta / 1000) * this.timeScale);

        this.state.apply(skeleton);
    },

    /**
     * Internal destroy handler, called as part of the destroy process.
     *
     * @method SpineGameObject#preDestroy
     * @protected
     * @since 3.19.0
     */
    preDestroy: function ()
    {
        if (this.state)
        {
            this.state.clearListeners();
            this.state.clearListenerNotifications();
        }

        this.plugin = null;

        this.skeleton = null;
        this.skeletonData = null;

        this.state = null;
        this.stateData = null;
    }

});

module.exports = SpineGameObject;


/***/ }),

/***/ 2753:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var CounterClockwise = __webpack_require__(3426);
var RadToDeg = __webpack_require__(4208);
var Wrap = __webpack_require__(8445);

/**
 * Renders this Game Object with the Canvas Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method SpineGameObject#renderCanvas
 * @since 3.19.0
 * @private
 *
 * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer.
 * @param {SpineGameObject} src - The Game Object being rendered in this call.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
 */
var SpineGameObjectCanvasRenderer = function (renderer, src, camera, parentMatrix)
{
    var context = renderer.currentContext;

    var plugin = src.plugin;
    var skeleton = src.skeleton;
    var skeletonRenderer = plugin.skeletonRenderer;

    var camMatrix = renderer._tempMatrix1;
    var spriteMatrix = renderer._tempMatrix2;
    var calcMatrix = renderer._tempMatrix3;

    camera.addToRenderList(src);

    spriteMatrix.applyITRS(src.x, src.y, src.rotation, Math.abs(src.scaleX), Math.abs(src.scaleY));

    camMatrix.copyFrom(camera.matrix);

    if (parentMatrix)
    {
        //  Multiply the camera by the parent matrix
        camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY);

        //  Undo the camera scroll
        spriteMatrix.e = src.x;
        spriteMatrix.f = src.y;

        //  Multiply by the Sprite matrix, store result in calcMatrix
        camMatrix.multiply(spriteMatrix, calcMatrix);
    }
    else
    {
        spriteMatrix.e -= camera.scrollX * src.scrollFactorX;
        spriteMatrix.f -= camera.scrollY * src.scrollFactorY;

        //  Multiply by the Sprite matrix, store result in calcMatrix
        camMatrix.multiply(spriteMatrix, calcMatrix);
    }

    skeleton.x = calcMatrix.tx;
    skeleton.y = calcMatrix.ty;

    skeleton.scaleX = calcMatrix.scaleX;

    //  Inverse or we get upside-down skeletons
    skeleton.scaleY = calcMatrix.scaleY * -1;

    if (src.scaleX < 0)
    {
        skeleton.scaleX *= -1;

        src.root.rotation = RadToDeg(calcMatrix.rotationNormalized);
    }
    else
    {
        //  +90 degrees to account for the difference in Spine vs. Phaser rotation
        src.root.rotation = Wrap(RadToDeg(CounterClockwise(calcMatrix.rotationNormalized)) + 90, 0, 360);
    }

    if (src.scaleY < 0)
    {
        skeleton.scaleY *= -1;

        if (src.scaleX < 0)
        {
            src.root.rotation -= (RadToDeg(calcMatrix.rotationNormalized) * 2);
        }
        else
        {
            src.root.rotation += (RadToDeg(calcMatrix.rotationNormalized) * 2);
        }
    }

    if (camera.renderToTexture)
    {
        skeleton.y = calcMatrix.ty;
        skeleton.scaleY *= -1;
    }

    skeleton.updateWorldTransform();

    skeletonRenderer.ctx = context;
    skeletonRenderer.debugRendering = (plugin.drawDebug || src.drawDebug);

    context.save();

    skeletonRenderer.draw(skeleton);

    context.restore();
};

module.exports = SpineGameObjectCanvasRenderer;


/***/ }),

/***/ 2762:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var renderWebGL = __webpack_require__(1984);
var renderCanvas = __webpack_require__(1984);
var renderDirect = __webpack_require__(1984);

if (true)
{
    renderWebGL = __webpack_require__(4290);
    renderDirect = __webpack_require__(780);
}

if (true)
{
    renderCanvas = __webpack_require__(2753);
}

module.exports = {

    renderWebGL: renderWebGL,
    renderCanvas: renderCanvas,
    renderDirect: renderDirect

};


/***/ }),

/***/ 780:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var Clamp = __webpack_require__(2915);
var CounterClockwise = __webpack_require__(3426);
var GetCalcMatrix = __webpack_require__(2208);
var RadToDeg = __webpack_require__(4208);
var Wrap = __webpack_require__(8445);

/**
 * Directly renders this Game Object with the WebGL Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method SpineGameObject#renderDirect
 * @since 3.50.0
 * @private
 *
 * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
 * @param {SpineGameObject} src - The Game Object being rendered in this call.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
 * @param {SpineContainer} [container] - If this Spine object is in a Spine Container, this is a reference to it.
 */
var SpineGameObjectWebGLDirect = function (renderer, src, camera, parentMatrix, container)
{
    var plugin = src.plugin;
    var skeleton = src.skeleton;
    var sceneRenderer = plugin.sceneRenderer;

    //  flush + clear previous pipeline if this is a new type
    renderer.pipelines.clear();

    sceneRenderer.begin();

    var scrollFactorX = src.scrollFactorX;
    var scrollFactorY = src.scrollFactorY;
    var alpha = skeleton.color.a;

    if (container)
    {
        src.scrollFactorX = container.scrollFactorX;
        src.scrollFactorY = container.scrollFactorY;

        skeleton.color.a = Clamp(alpha * container.alpha, 0, 1);
    }

    camera.addToRenderList(src);

    var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;

    var viewportHeight = renderer.height;

    skeleton.x = calcMatrix.tx;
    skeleton.y = viewportHeight - calcMatrix.ty;

    skeleton.scaleX = calcMatrix.scaleX;
    skeleton.scaleY = calcMatrix.scaleY;

    if (src.scaleX < 0)
    {
        skeleton.scaleX *= -1;

        //  -180 degrees to account for the difference in Spine vs. Phaser rotation when inversely scaled
        src.root.rotation = Wrap(RadToDeg(calcMatrix.rotationNormalized) - 180, 0, 360);
    }
    else
    {
        //  +90 degrees to account for the difference in Spine vs. Phaser rotation
        src.root.rotation = Wrap(RadToDeg(CounterClockwise(calcMatrix.rotationNormalized)) + 90, 0, 360);
    }

    if (src.scaleY < 0)
    {
        skeleton.scaleY *= -1;

        if (src.scaleX < 0)
        {
            src.root.rotation -= (RadToDeg(calcMatrix.rotationNormalized) * 2);
        }
        else
        {
            src.root.rotation += (RadToDeg(calcMatrix.rotationNormalized) * 2);
        }
    }

    /*
    if (renderer.currentFramebuffer !== null)
    {
        skeleton.y = calcMatrix.ty;
        skeleton.scaleY *= -1;
    }
    */

    skeleton.updateWorldTransform();

    //  Draw the current skeleton

    sceneRenderer.drawSkeleton(skeleton, src.preMultipliedAlpha);

    if (container)
    {
        src.scrollFactorX = scrollFactorX;
        src.scrollFactorY = scrollFactorY;
        skeleton.color.a = alpha;
    }

    if (plugin.drawDebug || src.drawDebug)
    {
        //  Because if we don't, the bones render positions are completely wrong (*sigh*)
        var oldX = skeleton.x;
        var oldY = skeleton.y;

        skeleton.x = 0;
        skeleton.y = 0;

        sceneRenderer.drawSkeletonDebug(skeleton, src.preMultipliedAlpha);

        skeleton.x = oldX;
        skeleton.y = oldY;
    }

    //  The next object in the display list is not a Spine Game Object or Spine Container, so we end the batch
    sceneRenderer.end();

    //  And rebind the previous pipeline
    renderer.pipelines.rebind();
};

module.exports = SpineGameObjectWebGLDirect;


/***/ }),

/***/ 4290:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var Clamp = __webpack_require__(2915);
var CounterClockwise = __webpack_require__(3426);
var GetCalcMatrix = __webpack_require__(2208);
var RadToDeg = __webpack_require__(4208);
var Wrap = __webpack_require__(8445);

/**
 * Renders this Game Object with the WebGL Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method SpineGameObject#renderWebGL
 * @since 3.19.0
 * @private
 *
 * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
 * @param {SpineGameObject} src - The Game Object being rendered in this call.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
 * @param {SpineContainer} [container] - If this Spine object is in a Spine Container, this is a reference to it.
 */
var SpineGameObjectWebGLRenderer = function (renderer, src, camera, parentMatrix, container)
{
    var plugin = src.plugin;
    var skeleton = src.skeleton;
    var sceneRenderer = plugin.sceneRenderer;

    if (renderer.newType)
    {
        //  flush + clear previous pipeline if this is a new type
        renderer.pipelines.clear();

        sceneRenderer.begin();
    }

    var scrollFactorX = src.scrollFactorX;
    var scrollFactorY = src.scrollFactorY;
    var alpha = skeleton.color.a;

    if (container)
    {
        src.scrollFactorX = container.scrollFactorX;
        src.scrollFactorY = container.scrollFactorY;

        skeleton.color.a = Clamp(alpha * container.alpha, 0, 1);
    }

    camera.addToRenderList(src);

    var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;

    var viewportHeight = renderer.height;

    skeleton.x = calcMatrix.tx;
    skeleton.y = viewportHeight - calcMatrix.ty;

    skeleton.scaleX = calcMatrix.scaleX;
    skeleton.scaleY = calcMatrix.scaleY;

    if (src.scaleX < 0)
    {
        skeleton.scaleX *= -1;

        //  -180 degrees to account for the difference in Spine vs. Phaser rotation when inversely scaled
        src.root.rotation = Wrap(RadToDeg(calcMatrix.rotationNormalized) - 180, 0, 360);
    }
    else
    {
        //  +90 degrees to account for the difference in Spine vs. Phaser rotation
        src.root.rotation = Wrap(RadToDeg(CounterClockwise(calcMatrix.rotationNormalized)) + 90, 0, 360);
    }

    if (src.scaleY < 0)
    {
        skeleton.scaleY *= -1;

        if (src.scaleX < 0)
        {
            src.root.rotation -= (RadToDeg(calcMatrix.rotationNormalized) * 2);
        }
        else
        {
            src.root.rotation += (RadToDeg(calcMatrix.rotationNormalized) * 2);
        }
    }

    /*
    if (renderer.currentFramebuffer !== null)
    {
        skeleton.y = calcMatrix.ty;
        skeleton.scaleY *= -1;
    }
    */

    skeleton.updateWorldTransform();

    //  Draw the current skeleton

    sceneRenderer.drawSkeleton(skeleton, src.preMultipliedAlpha);

    if (container)
    {
        src.scrollFactorX = scrollFactorX;
        src.scrollFactorY = scrollFactorY;
        skeleton.color.a = alpha;
    }

    if (plugin.drawDebug || src.drawDebug)
    {
        //  Because if we don't, the bones render positions are completely wrong (*sigh*)
        var oldX = skeleton.x;
        var oldY = skeleton.y;

        skeleton.x = 0;
        skeleton.y = 0;

        sceneRenderer.drawSkeletonDebug(skeleton, src.preMultipliedAlpha);

        skeleton.x = oldX;
        skeleton.y = oldY;

        //  The Spine debug draw has reset the batcher, so we need to do this regardless:
        sceneRenderer.end();
        renderer.pipelines.rebind();
    }
    else if (!renderer.nextTypeMatch)
    {
        //  The next object in the display list is not a Spine Game Object or Spine Container, so we end the batch
        sceneRenderer.end();

        //  And rebind the previous pipeline
        renderer.pipelines.rebind();
    }
};

module.exports = SpineGameObjectWebGLRenderer;


/***/ }),

/***/ 9454:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Global constants.
 *
 * @ignore
 */

var CONST = {

    /**
     * Phaser Release Version
     *
     * @name Phaser.VERSION
     * @const
     * @type {string}
     * @since 3.0.0
     */
    VERSION: '3.70.0',

    BlendModes: __webpack_require__(8351),

    ScaleModes: __webpack_require__(8196),

    /**
     * This setting will auto-detect if the browser is capable of suppporting WebGL.
     * If it is, it will use the WebGL Renderer. If not, it will fall back to the Canvas Renderer.
     *
     * @name Phaser.AUTO
     * @const
     * @type {number}
     * @since 3.0.0
     */
    AUTO: 0,

    /**
     * Forces Phaser to only use the Canvas Renderer, regardless if the browser supports
     * WebGL or not.
     *
     * @name Phaser.CANVAS
     * @const
     * @type {number}
     * @since 3.0.0
     */
    CANVAS: 1,

    /**
     * Forces Phaser to use the WebGL Renderer. If the browser does not support it, there is
     * no fallback to Canvas with this setting, so you should trap it and display a suitable
     * message to the user.
     *
     * @name Phaser.WEBGL
     * @const
     * @type {number}
     * @since 3.0.0
     */
    WEBGL: 2,

    /**
     * A Headless Renderer doesn't create either a Canvas or WebGL Renderer. However, it still
     * absolutely relies on the DOM being present and available. This mode is meant for unit testing,
     * not for running Phaser on the server, which is something you really shouldn't do.
     *
     * @name Phaser.HEADLESS
     * @const
     * @type {number}
     * @since 3.0.0
     */
    HEADLESS: 3,

    /**
     * In Phaser the value -1 means 'forever' in lots of cases, this const allows you to use it instead
     * to help you remember what the value is doing in your code.
     *
     * @name Phaser.FOREVER
     * @const
     * @type {number}
     * @since 3.0.0
     */
    FOREVER: -1,

    /**
     * Direction constant.
     *
     * @name Phaser.NONE
     * @const
     * @type {number}
     * @since 3.0.0
     */
    NONE: 4,

    /**
     * Direction constant.
     *
     * @name Phaser.UP
     * @const
     * @type {number}
     * @since 3.0.0
     */
    UP: 5,

    /**
     * Direction constant.
     *
     * @name Phaser.DOWN
     * @const
     * @type {number}
     * @since 3.0.0
     */
    DOWN: 6,

    /**
     * Direction constant.
     *
     * @name Phaser.LEFT
     * @const
     * @type {number}
     * @since 3.0.0
     */
    LEFT: 7,

    /**
     * Direction constant.
     *
     * @name Phaser.RIGHT
     * @const
     * @type {number}
     * @since 3.0.0
     */
    RIGHT: 8

};

module.exports = CONST;


/***/ }),

/***/ 1081:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Events = __webpack_require__(6748);

/**
 * @callback DataEachCallback
 *
 * @param {*} parent - The parent object of the DataManager.
 * @param {string} key - The key of the value.
 * @param {*} value - The value.
 * @param {...*} [args] - Additional arguments that will be passed to the callback, after the game object, key, and data.
 */

/**
 * @classdesc
 * The Data Manager Component features a means to store pieces of data specific to a Game Object, System or Plugin.
 * You can then search, query it, and retrieve the data. The parent must either extend EventEmitter,
 * or have a property called `events` that is an instance of it.
 *
 * @class DataManager
 * @memberof Phaser.Data
 * @constructor
 * @since 3.0.0
 *
 * @param {object} parent - The object that this DataManager belongs to.
 * @param {Phaser.Events.EventEmitter} [eventEmitter] - The DataManager's event emitter.
 */
var DataManager = new Class({

    initialize:

    function DataManager (parent, eventEmitter)
    {
        /**
         * The object that this DataManager belongs to.
         *
         * @name Phaser.Data.DataManager#parent
         * @type {*}
         * @since 3.0.0
         */
        this.parent = parent;

        /**
         * The DataManager's event emitter.
         *
         * @name Phaser.Data.DataManager#events
         * @type {Phaser.Events.EventEmitter}
         * @since 3.0.0
         */
        this.events = eventEmitter;

        if (!eventEmitter)
        {
            this.events = (parent.events) ? parent.events : parent;
        }

        /**
         * The data list.
         *
         * @name Phaser.Data.DataManager#list
         * @type {Object.<string, *>}
         * @default {}
         * @since 3.0.0
         */
        this.list = {};

        /**
         * The public values list. You can use this to access anything you have stored
         * in this Data Manager. For example, if you set a value called `gold` you can
         * access it via:
         *
         * ```javascript
         * this.data.values.gold;
         * ```
         *
         * You can also modify it directly:
         *
         * ```javascript
         * this.data.values.gold += 1000;
         * ```
         *
         * Doing so will emit a `setdata` event from the parent of this Data Manager.
         *
         * Do not modify this object directly. Adding properties directly to this object will not
         * emit any events. Always use `DataManager.set` to create new items the first time around.
         *
         * @name Phaser.Data.DataManager#values
         * @type {Object.<string, *>}
         * @default {}
         * @since 3.10.0
         */
        this.values = {};

        /**
         * Whether setting data is frozen for this DataManager.
         *
         * @name Phaser.Data.DataManager#_frozen
         * @type {boolean}
         * @private
         * @default false
         * @since 3.0.0
         */
        this._frozen = false;

        if (!parent.hasOwnProperty('sys') && this.events)
        {
            this.events.once(Events.DESTROY, this.destroy, this);
        }
    },

    /**
     * Retrieves the value for the given key, or undefined if it doesn't exist.
     *
     * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either:
     *
     * ```javascript
     * this.data.get('gold');
     * ```
     *
     * Or access the value directly:
     *
     * ```javascript
     * this.data.values.gold;
     * ```
     *
     * You can also pass in an array of keys, in which case an array of values will be returned:
     *
     * ```javascript
     * this.data.get([ 'gold', 'armor', 'health' ]);
     * ```
     *
     * This approach is useful for destructuring arrays in ES6.
     *
     * @method Phaser.Data.DataManager#get
     * @since 3.0.0
     *
     * @param {(string|string[])} key - The key of the value to retrieve, or an array of keys.
     *
     * @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array.
     */
    get: function (key)
    {
        var list = this.list;

        if (Array.isArray(key))
        {
            var output = [];

            for (var i = 0; i < key.length; i++)
            {
                output.push(list[key[i]]);
            }

            return output;
        }
        else
        {
            return list[key];
        }
    },

    /**
     * Retrieves all data values in a new object.
     *
     * @method Phaser.Data.DataManager#getAll
     * @since 3.0.0
     *
     * @return {Object.<string, *>} All data values.
     */
    getAll: function ()
    {
        var results = {};

        for (var key in this.list)
        {
            if (this.list.hasOwnProperty(key))
            {
                results[key] = this.list[key];
            }
        }

        return results;
    },

    /**
     * Queries the DataManager for the values of keys matching the given regular expression.
     *
     * @method Phaser.Data.DataManager#query
     * @since 3.0.0
     *
     * @param {RegExp} search - A regular expression object. If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj).
     *
     * @return {Object.<string, *>} The values of the keys matching the search string.
     */
    query: function (search)
    {
        var results = {};

        for (var key in this.list)
        {
            if (this.list.hasOwnProperty(key) && key.match(search))
            {
                results[key] = this.list[key];
            }
        }

        return results;
    },

    /**
     * Sets a value for the given key. If the key doesn't already exist in the Data Manager then it is created.
     *
     * ```javascript
     * data.set('name', 'Red Gem Stone');
     * ```
     *
     * You can also pass in an object of key value pairs as the first argument:
     *
     * ```javascript
     * data.set({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 });
     * ```
     *
     * To get a value back again you can call `get`:
     *
     * ```javascript
     * data.get('gold');
     * ```
     *
     * Or you can access the value directly via the `values` property, where it works like any other variable:
     *
     * ```javascript
     * data.values.gold += 50;
     * ```
     *
     * When the value is first set, a `setdata` event is emitted.
     *
     * If the key already exists, a `changedata` event is emitted instead, along an event named after the key.
     * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`.
     * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter.
     *
     * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings.
     * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager.
     *
     * @method Phaser.Data.DataManager#set
     * @fires Phaser.Data.Events#SET_DATA
     * @fires Phaser.Data.Events#CHANGE_DATA
     * @fires Phaser.Data.Events#CHANGE_DATA_KEY
     * @since 3.0.0
     *
     * @generic {any} T
     * @genericUse {(string|T)} - [key]
     *
     * @param {(string|object)} key - The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored.
     * @param {*} [data] - The value to set for the given key. If an object is provided as the key this argument is ignored.
     *
     * @return {this} This Data Manager instance.
     */
    set: function (key, data)
    {
        if (this._frozen)
        {
            return this;
        }

        if (typeof key === 'string')
        {
            return this.setValue(key, data);
        }
        else
        {
            for (var entry in key)
            {
                this.setValue(entry, key[entry]);
            }
        }

        return this;
    },

    /**
     * Increase a value for the given key. If the key doesn't already exist in the Data Manager then it is increased from 0.
     *
     * When the value is first set, a `setdata` event is emitted.
     *
     * @method Phaser.Data.DataManager#inc
     * @fires Phaser.Data.Events#SET_DATA
     * @fires Phaser.Data.Events#CHANGE_DATA
     * @fires Phaser.Data.Events#CHANGE_DATA_KEY
     * @since 3.23.0
     *
     * @param {string} key - The key to change the value for.
     * @param {number} [amount=1] - The amount to increase the given key by. Pass a negative value to decrease the key.
     *
     * @return {this} This Data Manager instance.
     */
    inc: function (key, amount)
    {
        if (this._frozen)
        {
            return this;
        }

        if (amount === undefined)
        {
            amount = 1;
        }

        var value = this.get(key);

        if (value === undefined)
        {
            value = 0;
        }

        this.set(key, (value + amount));

        return this;
    },

    /**
     * Toggle a boolean value for the given key. If the key doesn't already exist in the Data Manager then it is toggled from false.
     *
     * When the value is first set, a `setdata` event is emitted.
     *
     * @method Phaser.Data.DataManager#toggle
     * @fires Phaser.Data.Events#SET_DATA
     * @fires Phaser.Data.Events#CHANGE_DATA
     * @fires Phaser.Data.Events#CHANGE_DATA_KEY
     * @since 3.23.0
     *
     * @param {string} key - The key to toggle the value for.
     *
     * @return {this} This Data Manager instance.
     */
    toggle: function (key)
    {
        if (this._frozen)
        {
            return this;
        }

        this.set(key, !this.get(key));

        return this;
    },

    /**
     * Internal value setter, called automatically by the `set` method.
     *
     * @method Phaser.Data.DataManager#setValue
     * @fires Phaser.Data.Events#SET_DATA
     * @fires Phaser.Data.Events#CHANGE_DATA
     * @fires Phaser.Data.Events#CHANGE_DATA_KEY
     * @private
     * @since 3.10.0
     *
     * @param {string} key - The key to set the value for.
     * @param {*} data - The value to set.
     *
     * @return {this} This Data Manager instance.
     */
    setValue: function (key, data)
    {
        if (this._frozen)
        {
            return this;
        }

        if (this.has(key))
        {
            //  Hit the key getter, which will in turn emit the events.
            this.values[key] = data;
        }
        else
        {
            var _this = this;
            var list = this.list;
            var events = this.events;
            var parent = this.parent;

            Object.defineProperty(this.values, key, {

                enumerable: true,

                configurable: true,

                get: function ()
                {
                    return list[key];
                },

                set: function (value)
                {
                    if (!_this._frozen)
                    {
                        var previousValue = list[key];
                        list[key] = value;

                        events.emit(Events.CHANGE_DATA, parent, key, value, previousValue);
                        events.emit(Events.CHANGE_DATA_KEY + key, parent, value, previousValue);
                    }
                }

            });

            list[key] = data;

            events.emit(Events.SET_DATA, parent, key, data);
        }

        return this;
    },

    /**
     * Passes all data entries to the given callback.
     *
     * @method Phaser.Data.DataManager#each
     * @since 3.0.0
     *
     * @param {DataEachCallback} callback - The function to call.
     * @param {*} [context] - Value to use as `this` when executing callback.
     * @param {...*} [args] - Additional arguments that will be passed to the callback, after the game object, key, and data.
     *
     * @return {this} This Data Manager instance.
     */
    each: function (callback, context)
    {
        var args = [ this.parent, null, undefined ];

        for (var i = 1; i < arguments.length; i++)
        {
            args.push(arguments[i]);
        }

        for (var key in this.list)
        {
            args[1] = key;
            args[2] = this.list[key];

            callback.apply(context, args);
        }

        return this;
    },

    /**
     * Merge the given object of key value pairs into this DataManager.
     *
     * Any newly created values will emit a `setdata` event. Any updated values (see the `overwrite` argument)
     * will emit a `changedata` event.
     *
     * @method Phaser.Data.DataManager#merge
     * @fires Phaser.Data.Events#SET_DATA
     * @fires Phaser.Data.Events#CHANGE_DATA
     * @fires Phaser.Data.Events#CHANGE_DATA_KEY
     * @since 3.0.0
     *
     * @param {Object.<string, *>} data - The data to merge.
     * @param {boolean} [overwrite=true] - Whether to overwrite existing data. Defaults to true.
     *
     * @return {this} This Data Manager instance.
     */
    merge: function (data, overwrite)
    {
        if (overwrite === undefined) { overwrite = true; }

        //  Merge data from another component into this one
        for (var key in data)
        {
            if (data.hasOwnProperty(key) && (overwrite || (!overwrite && !this.has(key))))
            {
                this.setValue(key, data[key]);
            }
        }

        return this;
    },

    /**
     * Remove the value for the given key.
     *
     * If the key is found in this Data Manager it is removed from the internal lists and a
     * `removedata` event is emitted.
     *
     * You can also pass in an array of keys, in which case all keys in the array will be removed:
     *
     * ```javascript
     * this.data.remove([ 'gold', 'armor', 'health' ]);
     * ```
     *
     * @method Phaser.Data.DataManager#remove
     * @fires Phaser.Data.Events#REMOVE_DATA
     * @since 3.0.0
     *
     * @param {(string|string[])} key - The key to remove, or an array of keys to remove.
     *
     * @return {this} This Data Manager instance.
     */
    remove: function (key)
    {
        if (this._frozen)
        {
            return this;
        }

        if (Array.isArray(key))
        {
            for (var i = 0; i < key.length; i++)
            {
                this.removeValue(key[i]);
            }
        }
        else
        {
            return this.removeValue(key);
        }

        return this;
    },

    /**
     * Internal value remover, called automatically by the `remove` method.
     *
     * @method Phaser.Data.DataManager#removeValue
     * @private
     * @fires Phaser.Data.Events#REMOVE_DATA
     * @since 3.10.0
     *
     * @param {string} key - The key to set the value for.
     *
     * @return {this} This Data Manager instance.
     */
    removeValue: function (key)
    {
        if (this.has(key))
        {
            var data = this.list[key];

            delete this.list[key];
            delete this.values[key];

            this.events.emit(Events.REMOVE_DATA, this.parent, key, data);
        }

        return this;
    },

    /**
     * Retrieves the data associated with the given 'key', deletes it from this Data Manager, then returns it.
     *
     * @method Phaser.Data.DataManager#pop
     * @fires Phaser.Data.Events#REMOVE_DATA
     * @since 3.0.0
     *
     * @param {string} key - The key of the value to retrieve and delete.
     *
     * @return {*} The value of the given key.
     */
    pop: function (key)
    {
        var data = undefined;

        if (!this._frozen && this.has(key))
        {
            data = this.list[key];

            delete this.list[key];
            delete this.values[key];

            this.events.emit(Events.REMOVE_DATA, this.parent, key, data);
        }

        return data;
    },

    /**
     * Determines whether the given key is set in this Data Manager.
     *
     * Please note that the keys are case-sensitive and must be valid JavaScript Object property strings.
     * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager.
     *
     * @method Phaser.Data.DataManager#has
     * @since 3.0.0
     *
     * @param {string} key - The key to check.
     *
     * @return {boolean} Returns `true` if the key exists, otherwise `false`.
     */
    has: function (key)
    {
        return this.list.hasOwnProperty(key);
    },

    /**
     * Freeze or unfreeze this Data Manager. A frozen Data Manager will block all attempts
     * to create new values or update existing ones.
     *
     * @method Phaser.Data.DataManager#setFreeze
     * @since 3.0.0
     *
     * @param {boolean} value - Whether to freeze or unfreeze the Data Manager.
     *
     * @return {this} This Data Manager instance.
     */
    setFreeze: function (value)
    {
        this._frozen = value;

        return this;
    },

    /**
     * Delete all data in this Data Manager and unfreeze it.
     *
     * @method Phaser.Data.DataManager#reset
     * @since 3.0.0
     *
     * @return {this} This Data Manager instance.
     */
    reset: function ()
    {
        for (var key in this.list)
        {
            delete this.list[key];
            delete this.values[key];
        }

        this._frozen = false;

        return this;
    },

    /**
     * Destroy this data manager.
     *
     * @method Phaser.Data.DataManager#destroy
     * @since 3.0.0
     */
    destroy: function ()
    {
        this.reset();

        this.events.off(Events.CHANGE_DATA);
        this.events.off(Events.SET_DATA);
        this.events.off(Events.REMOVE_DATA);

        this.parent = null;
    },

    /**
     * Gets or sets the frozen state of this Data Manager.
     * A frozen Data Manager will block all attempts to create new values or update existing ones.
     *
     * @name Phaser.Data.DataManager#freeze
     * @type {boolean}
     * @since 3.0.0
     */
    freeze: {

        get: function ()
        {
            return this._frozen;
        },

        set: function (value)
        {
            this._frozen = (value) ? true : false;
        }

    },

    /**
     * Return the total number of entries in this Data Manager.
     *
     * @name Phaser.Data.DataManager#count
     * @type {number}
     * @since 3.0.0
     */
    count: {

        get: function ()
        {
            var i = 0;

            for (var key in this.list)
            {
                if (this.list[key] !== undefined)
                {
                    i++;
                }
            }

            return i;
        }

    }

});

module.exports = DataManager;


/***/ }),

/***/ 9044:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Change Data Event.
 *
 * This event is dispatched by a Data Manager when an item in the data store is changed.
 *
 * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for
 * a change data event from a Game Object you would use: `sprite.on('changedata', listener)`.
 *
 * This event is dispatched for all items that change in the Data Manager.
 * To listen for the change of a specific item, use the `CHANGE_DATA_KEY_EVENT` event.
 *
 * @event Phaser.Data.Events#CHANGE_DATA
 * @type {string}
 * @since 3.0.0
 *
 * @param {any} parent - A reference to the object that the Data Manager responsible for this event belongs to.
 * @param {string} key - The unique key of the data item within the Data Manager.
 * @param {any} value - The new value of the item in the Data Manager.
 * @param {any} previousValue - The previous value of the item in the Data Manager.
 */
module.exports = 'changedata';


/***/ }),

/***/ 7801:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Change Data Key Event.
 *
 * This event is dispatched by a Data Manager when an item in the data store is changed.
 *
 * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for
 * the change of a specific data item from a Game Object you would use: `sprite.on('changedata-key', listener)`,
 * where `key` is the unique string key of the data item. For example, if you have a data item stored called `gold`
 * then you can listen for `sprite.on('changedata-gold')`.
 *
 * @event Phaser.Data.Events#CHANGE_DATA_KEY
 * @type {string}
 * @since 3.16.1
 *
 * @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event.
 * @param {any} value - The item that was updated in the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance.
 * @param {any} previousValue - The previous item that was updated in the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance.
 */
module.exports = 'changedata-';


/***/ }),

/***/ 4873:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Data Manager Destroy Event.
 *
 * The Data Manager will listen for the destroy event from its parent, and then close itself down.
 *
 * @event Phaser.Data.Events#DESTROY
 * @type {string}
 * @since 3.50.0
 */
module.exports = 'destroy';


/***/ }),

/***/ 9966:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Remove Data Event.
 *
 * This event is dispatched by a Data Manager when an item is removed from it.
 *
 * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for
 * the removal of a data item on a Game Object you would use: `sprite.on('removedata', listener)`.
 *
 * @event Phaser.Data.Events#REMOVE_DATA
 * @type {string}
 * @since 3.0.0
 *
 * @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event.
 * @param {string} key - The unique key of the data item within the Data Manager.
 * @param {any} data - The item that was removed from the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance.
 */
module.exports = 'removedata';


/***/ }),

/***/ 4586:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Set Data Event.
 *
 * This event is dispatched by a Data Manager when a new item is added to the data store.
 *
 * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for
 * the addition of a new data item on a Game Object you would use: `sprite.on('setdata', listener)`.
 *
 * @event Phaser.Data.Events#SET_DATA
 * @type {string}
 * @since 3.0.0
 *
 * @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event.
 * @param {string} key - The unique key of the data item within the Data Manager.
 * @param {any} data - The item that was added to the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance.
 */
module.exports = 'setdata';


/***/ }),

/***/ 6748:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Data.Events
 */

module.exports = {

    CHANGE_DATA: __webpack_require__(9044),
    CHANGE_DATA_KEY: __webpack_require__(7801),
    DESTROY: __webpack_require__(4873),
    REMOVE_DATA: __webpack_require__(9966),
    SET_DATA: __webpack_require__(4586)

};


/***/ }),

/***/ 3004:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Browser = __webpack_require__(2776);

/**
 * Determines the audio playback capabilities of the device running this Phaser Game instance.
 * These values are read-only and populated during the boot sequence of the game.
 * They are then referenced by internal game systems and are available for you to access
 * via `this.sys.game.device.audio` from within any Scene.
 *
 * @typedef {object} Phaser.Device.Audio
 * @since 3.0.0
 *
 * @property {boolean} audioData - Can this device play HTML Audio tags?
 * @property {boolean} dolby - Can this device play EC-3 Dolby Digital Plus files?
 * @property {boolean} m4a - Can this device can play m4a files.
 * @property {boolean} aac - Can this device can play aac files.
 * @property {boolean} flac - Can this device can play flac files.
 * @property {boolean} mp3 - Can this device play mp3 files?
 * @property {boolean} ogg - Can this device play ogg files?
 * @property {boolean} opus - Can this device play opus files?
 * @property {boolean} wav - Can this device play wav files?
 * @property {boolean} webAudio - Does this device have the Web Audio API?
 * @property {boolean} webm - Can this device play webm files?
 */
var Audio = {

    flac: false,
    aac: false,
    audioData: false,
    dolby: false,
    m4a: false,
    mp3: false,
    ogg: false,
    opus: false,
    wav: false,
    webAudio: false,
    webm: false

};

function init ()
{
    if (typeof importScripts === 'function')
    {
        return Audio;
    }

    Audio.audioData = !!(window['Audio']);

    Audio.webAudio = !!(window['AudioContext'] || window['webkitAudioContext']);

    var audioElement = document.createElement('audio');
    var result = !!audioElement.canPlayType;

    try
    {
        if (result)
        {
            var CanPlay = function (type1, type2)
            {
                var canPlayType1 = audioElement.canPlayType('audio/' + type1).replace(/^no$/, '');

                if (type2)
                {
                    return Boolean(canPlayType1 || audioElement.canPlayType('audio/' + type2).replace(/^no$/, ''));
                }
                else
                {
                    return Boolean(canPlayType1);
                }
            };

            //  wav Mimetypes accepted:
            //  developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements

            Audio.ogg = CanPlay('ogg; codecs="vorbis"');
            Audio.opus = CanPlay('ogg; codecs="opus"', 'opus');
            Audio.mp3 = CanPlay('mpeg');
            Audio.wav = CanPlay('wav');
            Audio.m4a = CanPlay('x-m4a');
            Audio.aac = CanPlay('aac');
            Audio.flac = CanPlay('flac', 'x-flac');
            Audio.webm = CanPlay('webm; codecs="vorbis"');

            if (audioElement.canPlayType('audio/mp4; codecs="ec-3"') !== '')
            {
                if (Browser.edge)
                {
                    Audio.dolby = true;
                }
                else if (Browser.safari && Browser.safariVersion >= 9)
                {
                    if ((/Mac OS X (\d+)_(\d+)/).test(navigator.userAgent))
                    {
                        var major = parseInt(RegExp.$1, 10);
                        var minor = parseInt(RegExp.$2, 10);

                        if ((major === 10 && minor >= 11) || major > 10)
                        {
                            Audio.dolby = true;
                        }
                    }
                }
            }
        }
    }
    catch (e)
    {
        //  Nothing to do here
    }

    return Audio;
}

module.exports = init();


/***/ }),

/***/ 2776:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var OS = __webpack_require__(5203);

/**
 * Determines the browser type and version running this Phaser Game instance.
 * These values are read-only and populated during the boot sequence of the game.
 * They are then referenced by internal game systems and are available for you to access
 * via `this.sys.game.device.browser` from within any Scene.
 *
 * @typedef {object} Phaser.Device.Browser
 * @since 3.0.0
 *
 * @property {boolean} chrome - Set to true if running in Chrome.
 * @property {boolean} edge - Set to true if running in Microsoft Edge browser.
 * @property {boolean} firefox - Set to true if running in Firefox.
 * @property {boolean} ie - Set to true if running in Internet Explorer 11 or less (not Edge).
 * @property {boolean} mobileSafari - Set to true if running in Mobile Safari.
 * @property {boolean} opera - Set to true if running in Opera.
 * @property {boolean} safari - Set to true if running in Safari.
 * @property {boolean} silk - Set to true if running in the Silk browser (as used on the Amazon Kindle)
 * @property {boolean} trident - Set to true if running a Trident version of Internet Explorer (IE11+)
 * @property {number} chromeVersion - If running in Chrome this will contain the major version number.
 * @property {number} firefoxVersion - If running in Firefox this will contain the major version number.
 * @property {number} ieVersion - If running in Internet Explorer this will contain the major version number. Beyond IE10 you should use Browser.trident and Browser.tridentVersion.
 * @property {number} safariVersion - If running in Safari this will contain the major version number.
 * @property {number} tridentVersion - If running in Internet Explorer 11 this will contain the major version number. See {@link http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx}
 */
var Browser = {

    chrome: false,
    chromeVersion: 0,
    edge: false,
    firefox: false,
    firefoxVersion: 0,
    ie: false,
    ieVersion: 0,
    mobileSafari: false,
    opera: false,
    safari: false,
    safariVersion: 0,
    silk: false,
    trident: false,
    tridentVersion: 0,
    es2019: false

};

function init ()
{
    var ua = navigator.userAgent;

    if ((/Edg\/\d+/).test(ua))
    {
        Browser.edge = true;
        Browser.es2019 = true;
    }
    else if ((/OPR/).test(ua))
    {
        Browser.opera = true;
        Browser.es2019 = true;
    }
    else if ((/Chrome\/(\d+)/).test(ua) && !OS.windowsPhone)
    {
        Browser.chrome = true;
        Browser.chromeVersion = parseInt(RegExp.$1, 10);
        Browser.es2019 = (Browser.chromeVersion > 69);
    }
    else if ((/Firefox\D+(\d+)/).test(ua))
    {
        Browser.firefox = true;
        Browser.firefoxVersion = parseInt(RegExp.$1, 10);
        Browser.es2019 = (Browser.firefoxVersion > 10);
    }
    else if ((/AppleWebKit/).test(ua) && OS.iOS)
    {
        Browser.mobileSafari = true;
        Browser.es2019 = true;
    }
    else if ((/MSIE (\d+\.\d+);/).test(ua))
    {
        Browser.ie = true;
        Browser.ieVersion = parseInt(RegExp.$1, 10);
    }
    else if ((/Version\/(\d+\.\d+) Safari/).test(ua) && !OS.windowsPhone)
    {
        Browser.safari = true;
        Browser.safariVersion = parseInt(RegExp.$1, 10);
        Browser.es2019 = (Browser.safariVersion > 10);
    }
    else if ((/Trident\/(\d+\.\d+)(.*)rv:(\d+\.\d+)/).test(ua))
    {
        Browser.ie = true;
        Browser.trident = true;
        Browser.tridentVersion = parseInt(RegExp.$1, 10);
        Browser.ieVersion = parseInt(RegExp.$3, 10);
    }

    //  Silk gets its own if clause because its ua also contains 'Safari'
    if ((/Silk/).test(ua))
    {
        Browser.silk = true;
    }

    return Browser;
}

module.exports = init();


/***/ }),

/***/ 6505:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var CanvasPool = __webpack_require__(8073);

/**
 * Determines the canvas features of the browser running this Phaser Game instance.
 * These values are read-only and populated during the boot sequence of the game.
 * They are then referenced by internal game systems and are available for you to access
 * via `this.sys.game.device.canvasFeatures` from within any Scene.
 *
 * @typedef {object} Phaser.Device.CanvasFeatures
 * @since 3.0.0
 *
 * @property {boolean} supportInverseAlpha - Set to true if the browser supports inversed alpha.
 * @property {boolean} supportNewBlendModes - Set to true if the browser supports new canvas blend modes.
 */
var CanvasFeatures = {

    supportInverseAlpha: false,
    supportNewBlendModes: false

};

function checkBlendMode ()
{
    var pngHead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/';
    var pngEnd = 'AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==';

    var magenta = new Image();

    magenta.onload = function ()
    {
        var yellow = new Image();

        yellow.onload = function ()
        {
            var canvas = CanvasPool.create2D(yellow, 6);
            var context = canvas.getContext('2d', { willReadFrequently: true });

            context.globalCompositeOperation = 'multiply';

            context.drawImage(magenta, 0, 0);
            context.drawImage(yellow, 2, 0);

            if (!context.getImageData(2, 0, 1, 1))
            {
                return false;
            }

            var data = context.getImageData(2, 0, 1, 1).data;

            CanvasPool.remove(yellow);

            CanvasFeatures.supportNewBlendModes = (data[0] === 255 && data[1] === 0 && data[2] === 0);
        };

        yellow.src = pngHead + '/wCKxvRF' + pngEnd;
    };

    magenta.src = pngHead + 'AP804Oa6' + pngEnd;

    return false;
}

function checkInverseAlpha ()
{
    var canvas = CanvasPool.create2D(this, 2);
    var context = canvas.getContext('2d', { willReadFrequently: true });

    context.fillStyle = 'rgba(10, 20, 30, 0.5)';

    //  Draw a single pixel
    context.fillRect(0, 0, 1, 1);

    //  Get the color values
    var s1 = context.getImageData(0, 0, 1, 1);

    if (s1 === null)
    {
        return false;
    }

    //  Plot them to x2
    context.putImageData(s1, 1, 0);

    //  Get those values
    var s2 = context.getImageData(1, 0, 1, 1);

    var result = (s2.data[0] === s1.data[0] && s2.data[1] === s1.data[1] && s2.data[2] === s1.data[2] && s2.data[3] === s1.data[3]);

    CanvasPool.remove(this);

    //  Compare and return
    return result;
}

function init ()
{
    if (typeof importScripts !== 'function' && document !== undefined)
    {
        CanvasFeatures.supportNewBlendModes = checkBlendMode();
        CanvasFeatures.supportInverseAlpha = checkInverseAlpha();
    }

    return CanvasFeatures;
}

module.exports = init();


/***/ }),

/***/ 6543:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var OS = __webpack_require__(5203);
var Browser = __webpack_require__(2776);
var CanvasPool = __webpack_require__(8073);

/**
 * Determines the features of the browser running this Phaser Game instance.
 * These values are read-only and populated during the boot sequence of the game.
 * They are then referenced by internal game systems and are available for you to access
 * via `this.sys.game.device.features` from within any Scene.
 *
 * @typedef {object} Phaser.Device.Features
 * @since 3.0.0
 *
 * @property {boolean} canvas - Is canvas available?
 * @property {?boolean} canvasBitBltShift - True if canvas supports a 'copy' bitblt onto itself when the source and destination regions overlap.
 * @property {boolean} file - Is file available?
 * @property {boolean} fileSystem - Is fileSystem available?
 * @property {boolean} getUserMedia - Does the device support the getUserMedia API?
 * @property {boolean} littleEndian - Is the device big or little endian? (only detected if the browser supports TypedArrays)
 * @property {boolean} localStorage - Is localStorage available?
 * @property {boolean} pointerLock - Is Pointer Lock available?
 * @property {boolean} stableSort - Is Array.sort stable?
 * @property {boolean} support32bit - Does the device context support 32bit pixel manipulation using array buffer views?
 * @property {boolean} vibration - Does the device support the Vibration API?
 * @property {boolean} webGL - Is webGL available?
 * @property {boolean} worker - Is worker available?
 */
var Features = {

    canvas: false,
    canvasBitBltShift: null,
    file: false,
    fileSystem: false,
    getUserMedia: true,
    littleEndian: false,
    localStorage: false,
    pointerLock: false,
    stableSort: false,
    support32bit: false,
    vibration: false,
    webGL: false,
    worker: false

};

// Check Little or Big Endian system.
// @author Matt DesLauriers (@mattdesl)
function checkIsLittleEndian ()
{
    var a = new ArrayBuffer(4);
    var b = new Uint8Array(a);
    var c = new Uint32Array(a);

    b[0] = 0xa1;
    b[1] = 0xb2;
    b[2] = 0xc3;
    b[3] = 0xd4;

    if (c[0] === 0xd4c3b2a1)
    {
        return true;
    }

    if (c[0] === 0xa1b2c3d4)
    {
        return false;
    }
    else
    {
        //  Could not determine endianness
        return null;
    }
}

function init ()
{
    if (typeof importScripts === 'function')
    {
        return Features;
    }

    Features.canvas = !!window['CanvasRenderingContext2D'];

    try
    {
        Features.localStorage = !!localStorage.getItem;
    }
    catch (error)
    {
        Features.localStorage = false;
    }

    Features.file = !!window['File'] && !!window['FileReader'] && !!window['FileList'] && !!window['Blob'];
    Features.fileSystem = !!window['requestFileSystem'];

    var isUint8 = false;

    var testWebGL = function ()
    {
        if (window['WebGLRenderingContext'])
        {
            try
            {
                var canvas = CanvasPool.createWebGL(this);

                var ctx = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');

                var canvas2D = CanvasPool.create2D(this);

                var ctx2D = canvas2D.getContext('2d', { willReadFrequently: true });

                //  Can't be done on a webgl context
                var image = ctx2D.createImageData(1, 1);

                //  Test to see if ImageData uses CanvasPixelArray or Uint8ClampedArray.
                //  @author Matt DesLauriers (@mattdesl)
                isUint8 = image.data instanceof Uint8ClampedArray;

                CanvasPool.remove(canvas);
                CanvasPool.remove(canvas2D);

                return !!ctx;
            }
            catch (e)
            {
                return false;
            }
        }

        return false;
    };

    Features.webGL = testWebGL();

    Features.worker = !!window['Worker'];

    Features.pointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;

    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;

    window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;

    Features.getUserMedia = Features.getUserMedia && !!navigator.getUserMedia && !!window.URL;

    // Older versions of firefox (< 21) apparently claim support but user media does not actually work
    if (Browser.firefox && Browser.firefoxVersion < 21)
    {
        Features.getUserMedia = false;
    }

    // Excludes iOS versions as they generally wrap UIWebView (eg. Safari WebKit) and it
    // is safer to not try and use the fast copy-over method.
    if (!OS.iOS && (Browser.ie || Browser.firefox || Browser.chrome))
    {
        Features.canvasBitBltShift = true;
    }

    // Known not to work
    if (Browser.safari || Browser.mobileSafari)
    {
        Features.canvasBitBltShift = false;
    }

    navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;

    if (navigator.vibrate)
    {
        Features.vibration = true;
    }

    if (typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined' && typeof Uint32Array !== 'undefined')
    {
        Features.littleEndian = checkIsLittleEndian();
    }

    Features.support32bit = (
        typeof ArrayBuffer !== 'undefined' &&
        typeof Uint8ClampedArray !== 'undefined' &&
        typeof Int32Array !== 'undefined' &&
        Features.littleEndian !== null &&
        isUint8
    );

    return Features;
}

module.exports = init();


/***/ }),

/***/ 3922:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Determines the full screen support of the browser running this Phaser Game instance.
 * These values are read-only and populated during the boot sequence of the game.
 * They are then referenced by internal game systems and are available for you to access
 * via `this.sys.game.device.fullscreen` from within any Scene.
 *
 * @typedef {object} Phaser.Device.Fullscreen
 * @since 3.0.0
 *
 * @property {boolean} available - Does the browser support the Full Screen API?
 * @property {boolean} keyboard - Does the browser support access to the Keyboard during Full Screen mode?
 * @property {string} cancel - If the browser supports the Full Screen API this holds the call you need to use to cancel it.
 * @property {string} request - If the browser supports the Full Screen API this holds the call you need to use to activate it.
 */
var Fullscreen = {

    available: false,
    cancel: '',
    keyboard: false,
    request: ''

};

/**
* Checks for support of the Full Screen API.
*
* @ignore
*/
function init ()
{
    if (typeof importScripts === 'function')
    {
        return Fullscreen;
    }

    var i;

    var suffix1 = 'Fullscreen';
    var suffix2 = 'FullScreen';

    var fs = [
        'request' + suffix1,
        'request' + suffix2,
        'webkitRequest' + suffix1,
        'webkitRequest' + suffix2,
        'msRequest' + suffix1,
        'msRequest' + suffix2,
        'mozRequest' + suffix2,
        'mozRequest' + suffix1
    ];

    for (i = 0; i < fs.length; i++)
    {
        if (document.documentElement[fs[i]])
        {
            Fullscreen.available = true;
            Fullscreen.request = fs[i];
            break;
        }
    }

    var cfs = [
        'cancel' + suffix2,
        'exit' + suffix1,
        'webkitCancel' + suffix2,
        'webkitExit' + suffix1,
        'msCancel' + suffix2,
        'msExit' + suffix1,
        'mozCancel' + suffix2,
        'mozExit' + suffix1
    ];

    if (Fullscreen.available)
    {
        for (i = 0; i < cfs.length; i++)
        {
            if (document[cfs[i]])
            {
                Fullscreen.cancel = cfs[i];
                break;
            }
        }
    }

    //  Keyboard Input?
    //  Safari 5.1 says it supports fullscreen keyboard, but is lying.
    if (window['Element'] && Element['ALLOW_KEYBOARD_INPUT'] && !(/ Version\/5\.1(?:\.\d+)? Safari\//).test(navigator.userAgent))
    {
        Fullscreen.keyboard = true;
    }

    Object.defineProperty(Fullscreen, 'active', { get: function () { return !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement); } });

    return Fullscreen;
}

module.exports = init();


/***/ }),

/***/ 1454:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Browser = __webpack_require__(2776);

/**
 * Determines the input support of the browser running this Phaser Game instance.
 * These values are read-only and populated during the boot sequence of the game.
 * They are then referenced by internal game systems and are available for you to access
 * via `this.sys.game.device.input` from within any Scene.
 *
 * @typedef {object} Phaser.Device.Input
 * @since 3.0.0
 *
 * @property {?string} wheelType - The newest type of Wheel/Scroll event supported: 'wheel', 'mousewheel', 'DOMMouseScroll'
 * @property {boolean} gamepads - Is navigator.getGamepads available?
 * @property {boolean} mspointer - Is mspointer available?
 * @property {boolean} touch - Is touch available?
 */
var Input = {

    gamepads: false,
    mspointer: false,
    touch: false,
    wheelEvent: null

};

function init ()
{
    if (typeof importScripts === 'function')
    {
        return Input;
    }

    if ('ontouchstart' in document.documentElement || (navigator.maxTouchPoints && navigator.maxTouchPoints >= 1))
    {
        Input.touch = true;
    }

    if (navigator.msPointerEnabled || navigator.pointerEnabled)
    {
        Input.mspointer = true;
    }

    if (navigator.getGamepads)
    {
        Input.gamepads = true;
    }

    // See https://developer.mozilla.org/en-US/docs/Web/Events/wheel
    if ('onwheel' in window || (Browser.ie && 'WheelEvent' in window))
    {
        // DOM3 Wheel Event: FF 17+, IE 9+, Chrome 31+, Safari 7+
        Input.wheelEvent = 'wheel';
    }
    else if ('onmousewheel' in window)
    {
        // Non-FF legacy: IE 6-9, Chrome 1-31, Safari 5-7.
        Input.wheelEvent = 'mousewheel';
    }
    else if (Browser.firefox && 'MouseScrollEvent' in window)
    {
        // FF prior to 17. This should probably be scrubbed.
        Input.wheelEvent = 'DOMMouseScroll';
    }

    return Input;
}

module.exports = init();


/***/ }),

/***/ 5203:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Determines the operating system of the device running this Phaser Game instance.
 * These values are read-only and populated during the boot sequence of the game.
 * They are then referenced by internal game systems and are available for you to access
 * via `this.sys.game.device.os` from within any Scene.
 *
 * @typedef {object} Phaser.Device.OS
 * @since 3.0.0
 *
 * @property {boolean} android - Is running on android?
 * @property {boolean} chromeOS - Is running on chromeOS?
 * @property {boolean} cordova - Is the game running under Apache Cordova?
 * @property {boolean} crosswalk - Is the game running under the Intel Crosswalk XDK?
 * @property {boolean} desktop - Is running on a desktop?
 * @property {boolean} ejecta - Is the game running under Ejecta?
 * @property {boolean} electron - Is the game running under GitHub Electron?
 * @property {boolean} iOS - Is running on iOS?
 * @property {boolean} iPad - Is running on iPad?
 * @property {boolean} iPhone - Is running on iPhone?
 * @property {boolean} kindle - Is running on an Amazon Kindle?
 * @property {boolean} linux - Is running on linux?
 * @property {boolean} macOS - Is running on macOS?
 * @property {boolean} node - Is the game running under Node.js?
 * @property {boolean} nodeWebkit - Is the game running under Node-Webkit?
 * @property {boolean} webApp - Set to true if running as a WebApp, i.e. within a WebView
 * @property {boolean} windows - Is running on windows?
 * @property {boolean} windowsPhone - Is running on a Windows Phone?
 * @property {number} iOSVersion - If running in iOS this will contain the major version number.
 * @property {number} pixelRatio - PixelRatio of the host device?
 */
var OS = {

    android: false,
    chromeOS: false,
    cordova: false,
    crosswalk: false,
    desktop: false,
    ejecta: false,
    electron: false,
    iOS: false,
    iOSVersion: 0,
    iPad: false,
    iPhone: false,
    kindle: false,
    linux: false,
    macOS: false,
    node: false,
    nodeWebkit: false,
    pixelRatio: 1,
    webApp: false,
    windows: false,
    windowsPhone: false

};

function init ()
{
    if (typeof importScripts === 'function')
    {
        return OS;
    }

    var ua = navigator.userAgent;

    if ((/Windows/).test(ua))
    {
        OS.windows = true;
    }
    else if ((/Mac OS/).test(ua) && !((/like Mac OS/).test(ua)))
    {
        //  Because iOS 13 identifies as Mac OS:
        if (navigator.maxTouchPoints && navigator.maxTouchPoints > 2)
        {
            OS.iOS = true;
            OS.iPad = true;

            (navigator.appVersion).match(/Version\/(\d+)/);

            OS.iOSVersion = parseInt(RegExp.$1, 10);
        }
        else
        {
            OS.macOS = true;
        }
    }
    else if ((/Android/).test(ua))
    {
        OS.android = true;
    }
    else if ((/Linux/).test(ua))
    {
        OS.linux = true;
    }
    else if ((/iP[ao]d|iPhone/i).test(ua))
    {
        OS.iOS = true;

        (navigator.appVersion).match(/OS (\d+)/);

        OS.iOSVersion = parseInt(RegExp.$1, 10);

        OS.iPhone = ua.toLowerCase().indexOf('iphone') !== -1;
        OS.iPad = ua.toLowerCase().indexOf('ipad') !== -1;
    }
    else if ((/Kindle/).test(ua) || (/\bKF[A-Z][A-Z]+/).test(ua) || (/Silk.*Mobile Safari/).test(ua))
    {
        OS.kindle = true;

        // This will NOT detect early generations of Kindle Fire, I think there is no reliable way...
        // E.g. "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-80) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true"
    }
    else if ((/CrOS/).test(ua))
    {
        OS.chromeOS = true;
    }

    if ((/Windows Phone/i).test(ua) || (/IEMobile/i).test(ua))
    {
        OS.android = false;
        OS.iOS = false;
        OS.macOS = false;
        OS.windows = true;
        OS.windowsPhone = true;
    }

    var silk = (/Silk/).test(ua);

    if (OS.windows || OS.macOS || (OS.linux && !silk) || OS.chromeOS)
    {
        OS.desktop = true;
    }

    //  Windows Phone / Table reset
    if (OS.windowsPhone || (((/Windows NT/i).test(ua)) && ((/Touch/i).test(ua))))
    {
        OS.desktop = false;
    }

    //  WebApp mode in iOS
    if (navigator.standalone)
    {
        OS.webApp = true;
    }

    if (typeof importScripts !== 'function')
    {
        if (window.cordova !== undefined)
        {
            OS.cordova = true;
        }

        if (window.ejecta !== undefined)
        {
            OS.ejecta = true;
        }
    }

    if (typeof process !== 'undefined' && process.versions && process.versions.node)
    {
        OS.node = true;
    }

    if (OS.node && typeof process.versions === 'object')
    {
        OS.nodeWebkit = !!process.versions['node-webkit'];

        OS.electron = !!process.versions.electron;
    }

    if ((/Crosswalk/).test(ua))
    {
        OS.crosswalk = true;
    }

    OS.pixelRatio = window['devicePixelRatio'] || 1;

    return OS;
}

module.exports = init();


/***/ }),

/***/ 2131:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var GetFastValue = __webpack_require__(4597);

/**
 * Determines the video support of the browser running this Phaser Game instance.
 *
 * These values are read-only and populated during the boot sequence of the game.
 *
 * They are then referenced by internal game systems and are available for you to access
 * via `this.sys.game.device.video` from within any Scene.
 *
 * In Phaser 3.20 the properties were renamed to drop the 'Video' suffix.
 *
 * @typedef {object} Phaser.Device.Video
 * @since 3.0.0
 *
 * @property {boolean} h264 - Can this device play h264 mp4 video files?
 * @property {boolean} hls - Can this device play hls video files?
 * @property {boolean} mp4 - Can this device play h264 mp4 video files?
 * @property {boolean} m4v - Can this device play m4v (typically mp4) video files?
 * @property {boolean} ogg - Can this device play ogg video files?
 * @property {boolean} vp9 - Can this device play vp9 video files?
 * @property {boolean} webm - Can this device play webm video files?
 * @property {function} getVideoURL - Returns the first video URL that can be played by this browser.
 */
var Video = {

    h264: false,
    hls: false,
    mp4: false,
    m4v: false,
    ogg: false,
    vp9: false,
    webm: false,
    hasRequestVideoFrame: false

};

function init ()
{
    if (typeof importScripts === 'function')
    {
        return Video;
    }

    var videoElement = document.createElement('video');
    var result = !!videoElement.canPlayType;
    var no = /^no$/;

    try
    {
        if (result)
        {
            if (videoElement.canPlayType('video/ogg; codecs="theora"').replace(no, ''))
            {
                Video.ogg = true;
            }

            if (videoElement.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(no, ''))
            {
                // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
                Video.h264 = true;
                Video.mp4 = true;
            }

            if (videoElement.canPlayType('video/x-m4v').replace(no, ''))
            {
                Video.m4v = true;
            }

            if (videoElement.canPlayType('video/webm; codecs="vp8, vorbis"').replace(no, ''))
            {
                Video.webm = true;
            }

            if (videoElement.canPlayType('video/webm; codecs="vp9"').replace(no, ''))
            {
                Video.vp9 = true;
            }

            if (videoElement.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(no, ''))
            {
                Video.hls = true;
            }
        }
    }
    catch (e)
    {
        //  Nothing to do
    }

    if (videoElement.parentNode)
    {
        videoElement.parentNode.removeChild(videoElement);
    }

    Video.getVideoURL = function (urls)
    {
        if (!Array.isArray(urls))
        {
            urls = [ urls ];
        }

        for (var i = 0; i < urls.length; i++)
        {
            var url = GetFastValue(urls[i], 'url', urls[i]);

            if (url.indexOf('blob:') === 0)
            {
                return {
                    url: url,
                    type: ''
                };
            }

            var videoType;

            if (url.indexOf('data:') === 0)
            {
                videoType = url.split(',')[0].match(/\/(.*?);/);
            }
            else
            {
                videoType = url.match(/\.([a-zA-Z0-9]+)($|\?)/);
            }

            videoType = GetFastValue(urls[i], 'type', (videoType) ? videoType[1] : '').toLowerCase();

            if (Video[videoType])
            {
                return {
                    url: url,
                    type: videoType
                };
            }
        }

        return null;
    };

    return Video;
}

module.exports = init();


/***/ }),

/***/ 9356:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

//  This singleton is instantiated as soon as Phaser loads,
//  before a Phaser.Game instance has even been created.
//  Which means all instances of Phaser Games can share it,
//  without having to re-poll the device all over again

/**
 * @namespace Phaser.Device
 * @since 3.0.0
 */

/**
 * @typedef {object} Phaser.DeviceConf
 *
 * @property {Phaser.Device.OS} os - The OS Device functions.
 * @property {Phaser.Device.Browser} browser - The Browser Device functions.
 * @property {Phaser.Device.Features} features - The Features Device functions.
 * @property {Phaser.Device.Input} input - The Input Device functions.
 * @property {Phaser.Device.Audio} audio - The Audio Device functions.
 * @property {Phaser.Device.Video} video - The Video Device functions.
 * @property {Phaser.Device.Fullscreen} fullscreen - The Fullscreen Device functions.
 * @property {Phaser.Device.CanvasFeatures} canvasFeatures - The Canvas Device functions.
 */

module.exports = {

    os: __webpack_require__(5203),
    browser: __webpack_require__(2776),
    features: __webpack_require__(6543),
    input: __webpack_require__(1454),
    audio: __webpack_require__(3004),
    video: __webpack_require__(2131),
    fullscreen: __webpack_require__(3922),
    canvasFeatures: __webpack_require__(6505)

};


/***/ }),

/***/ 5686:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);

var tempMatrix = new Float32Array(20);

/**
 * @classdesc
 * The ColorMatrix class creates a 5x4 matrix that can be used in shaders and graphics
 * operations. It provides methods required to modify the color values, such as adjusting
 * the brightness, setting a sepia tone, hue rotation and more.
 *
 * Use the method `getData` to return a Float32Array containing the current color values.
 *
 * @class ColorMatrix
 * @memberof Phaser.Display
 * @constructor
 * @since 3.50.0
 */
var ColorMatrix = new Class({

    initialize:

    function ColorMatrix ()
    {
        /**
         * Internal ColorMatrix array.
         *
         * @name Phaser.Display.ColorMatrix#_matrix
         * @type {Float32Array}
         * @private
         * @since 3.50.0
         */
        this._matrix = new Float32Array(20);

        /**
         * The value that determines how much of the original color is used
         * when mixing the colors. A value between 0 (all original) and 1 (all final)
         *
         * @name Phaser.Display.ColorMatrix#alpha
         * @type {number}
         * @since 3.50.0
         */
        this.alpha = 1;

        /**
         * Is the ColorMatrix array dirty?
         *
         * @name Phaser.Display.ColorMatrix#_dirty
         * @type {boolean}
         * @private
         * @since 3.50.0
         */
        this._dirty = true;

        /**
         * The matrix data as a Float32Array.
         *
         * Returned by the `getData` method.
         *
         * @name Phaser.Display.ColorMatrix#data
         * @type {Float32Array}
         * @private
         * @since 3.50.0
         */
        this._data = new Float32Array(20);

        this.reset();
    },

    /**
     * Sets this ColorMatrix from the given array of color values.
     *
     * @method Phaser.Display.ColorMatrix#set
     * @since 3.50.0
     *
     * @param {(number[]|Float32Array)} value - The ColorMatrix values to set. Must have 20 elements.
     *
     * @return {this} This ColorMatrix instance.
     */
    set: function (value)
    {
        this._matrix.set(value);

        this._dirty = true;

        return this;
    },

    /**
     * Resets the ColorMatrix to default values and also resets
     * the `alpha` property back to 1.
     *
     * @method Phaser.Display.ColorMatrix#reset
     * @since 3.50.0
     *
     * @return {this} This ColorMatrix instance.
     */
    reset: function ()
    {
        var m = this._matrix;

        m.fill(0);

        m[0] = 1;
        m[6] = 1;
        m[12] = 1;
        m[18] = 1;

        this.alpha = 1;

        this._dirty = true;

        return this;
    },

    /**
     * Gets the ColorMatrix as a Float32Array.
     *
     * Can be used directly as a 1fv shader uniform value.
     *
     * @method Phaser.Display.ColorMatrix#getData
     * @since 3.50.0
     *
     * @return {Float32Array} The ColorMatrix as a Float32Array.
     */
    getData: function ()
    {
        var data = this._data;

        if (this._dirty)
        {
            data.set(this._matrix);

            data[4] /= 255;
            data[9] /= 255;
            data[14] /= 255;
            data[19] /= 255;

            this._dirty = false;
        }

        return data;
    },

    /**
     * Changes the brightness of this ColorMatrix by the given amount.
     *
     * @method Phaser.Display.ColorMatrix#brightness
     * @since 3.50.0
     *
     * @param {number} [value=0] - The amount of brightness to apply to this ColorMatrix. Between 0 (black) and 1.
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    brightness: function (value, multiply)
    {
        if (value === undefined) { value = 0; }
        if (multiply === undefined) { multiply = false; }

        var b = value;

        return this.multiply([
            b, 0, 0, 0, 0,
            0, b, 0, 0, 0,
            0, 0, b, 0, 0,
            0, 0, 0, 1, 0
        ], multiply);
    },

    /**
     * Changes the saturation of this ColorMatrix by the given amount.
     *
     * @method Phaser.Display.ColorMatrix#saturate
     * @since 3.50.0
     *
     * @param {number} [value=0] - The amount of saturation to apply to this ColorMatrix.
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    saturate: function (value, multiply)
    {
        if (value === undefined) { value = 0; }
        if (multiply === undefined) { multiply = false; }

        var x = (value * 2 / 3) + 1;
        var y = ((x - 1) * -0.5);

        return this.multiply([
            x, y, y, 0, 0,
            y, x, y, 0, 0,
            y, y, x, 0, 0,
            0, 0, 0, 1, 0
        ], multiply);
    },

    /**
     * Desaturates this ColorMatrix (removes color from it).
     *
     * @method Phaser.Display.ColorMatrix#saturation
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    desaturate: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.saturate(-1, multiply);
    },

    /**
     * Rotates the hues of this ColorMatrix by the value given.
     *
     * @method Phaser.Display.ColorMatrix#hue
     * @since 3.50.0
     *
     * @param {number} [rotation=0] - The amount of hue rotation to apply to this ColorMatrix, in degrees.
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    hue: function (rotation, multiply)
    {
        if (rotation === undefined) { rotation = 0; }
        if (multiply === undefined) { multiply = false; }

        rotation = rotation / 180 * Math.PI;

        var cos = Math.cos(rotation);
        var sin = Math.sin(rotation);
        var lumR = 0.213;
        var lumG = 0.715;
        var lumB = 0.072;

        return this.multiply([
            lumR + cos * (1 - lumR) + sin * (-lumR),lumG + cos * (-lumG) + sin * (-lumG),lumB + cos * (-lumB) + sin * (1 - lumB), 0, 0,
            lumR + cos * (-lumR) + sin * (0.143),lumG + cos * (1 - lumG) + sin * (0.140),lumB + cos * (-lumB) + sin * (-0.283), 0, 0,
            lumR + cos * (-lumR) + sin * (-(1 - lumR)),lumG + cos * (-lumG) + sin * (lumG),lumB + cos * (1 - lumB) + sin * (lumB), 0, 0,
            0, 0, 0, 1, 0
        ], multiply);
    },

    /**
     * Sets this ColorMatrix to be grayscale.
     *
     * @method Phaser.Display.ColorMatrix#grayscale
     * @since 3.50.0
     *
     * @param {number} [value=1] - The grayscale scale (0 is black).
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    grayscale: function (value, multiply)
    {
        if (value === undefined) { value = 1; }
        if (multiply === undefined) { multiply = false; }

        return this.saturate(-value, multiply);
    },

    /**
     * Sets this ColorMatrix to be black and white.
     *
     * @method Phaser.Display.ColorMatrix#blackWhite
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    blackWhite: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.multiply(ColorMatrix.BLACK_WHITE, multiply);
    },

    /**
     * Change the contrast of this ColorMatrix by the amount given.
     *
     * @method Phaser.Display.ColorMatrix#contrast
     * @since 3.50.0
     *
     * @param {number} [value=0] - The amount of contrast to apply to this ColorMatrix.
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    contrast: function (value, multiply)
    {
        if (value === undefined) { value = 0; }
        if (multiply === undefined) { multiply = false; }

        var v = value + 1;
        var o = -0.5 * (v - 1);

        return this.multiply([
            v, 0, 0, 0, o,
            0, v, 0, 0, o,
            0, 0, v, 0, o,
            0, 0, 0, 1, 0
        ], multiply);
    },

    /**
     * Converts this ColorMatrix to have negative values.
     *
     * @method Phaser.Display.ColorMatrix#negative
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    negative: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.multiply(ColorMatrix.NEGATIVE, multiply);
    },

    /**
     * Apply a desaturated luminance to this ColorMatrix.
     *
     * @method Phaser.Display.ColorMatrix#desaturateLuminance
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    desaturateLuminance: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.multiply(ColorMatrix.DESATURATE_LUMINANCE, multiply);
    },

    /**
     * Applies a sepia tone to this ColorMatrix.
     *
     * @method Phaser.Display.ColorMatrix#sepia
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    sepia: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.multiply(ColorMatrix.SEPIA, multiply);
    },

    /**
     * Applies a night vision tone to this ColorMatrix.
     *
     * @method Phaser.Display.ColorMatrix#night
     * @since 3.50.0
     *
     * @param {number} [intensity=0.1] - The intensity of this effect.
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    night: function (intensity, multiply)
    {
        if (intensity === undefined) { intensity = 0.1; }
        if (multiply === undefined) { multiply = false; }

        return this.multiply([
            intensity * (-2.0), -intensity, 0, 0, 0,
            -intensity, 0, intensity, 0, 0,
            0, intensity, intensity * 2.0, 0, 0,
            0, 0, 0, 1, 0
        ], multiply);
    },

    /**
     * Applies a trippy color tone to this ColorMatrix.
     *
     * @method Phaser.Display.ColorMatrix#lsd
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    lsd: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.multiply(ColorMatrix.LSD, multiply);
    },

    /**
     * Applies a brown tone to this ColorMatrix.
     *
     * @method Phaser.Display.ColorMatrix#brown
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    brown: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.multiply(ColorMatrix.BROWN, multiply);
    },

    /**
     * Applies a vintage pinhole color effect to this ColorMatrix.
     *
     * @method Phaser.Display.ColorMatrix#vintagePinhole
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    vintagePinhole: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.multiply(ColorMatrix.VINTAGE, multiply);
    },

    /**
     * Applies a kodachrome color effect to this ColorMatrix.
     *
     * @method Phaser.Display.ColorMatrix#kodachrome
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    kodachrome: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.multiply(ColorMatrix.KODACHROME, multiply);
    },

    /**
     * Applies a technicolor color effect to this ColorMatrix.
     *
     * @method Phaser.Display.ColorMatrix#technicolor
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    technicolor: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.multiply(ColorMatrix.TECHNICOLOR, multiply);
    },

    /**
     * Applies a polaroid color effect to this ColorMatrix.
     *
     * @method Phaser.Display.ColorMatrix#polaroid
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    polaroid: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.multiply(ColorMatrix.POLAROID, multiply);
    },

    /**
     * Shifts the values of this ColorMatrix into BGR order.
     *
     * @method Phaser.Display.ColorMatrix#shiftToBGR
     * @since 3.50.0
     *
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    shiftToBGR: function (multiply)
    {
        if (multiply === undefined) { multiply = false; }

        return this.multiply(ColorMatrix.SHIFT_BGR, multiply);
    },

    /**
     * Multiplies the two given matrices.
     *
     * @method Phaser.Display.ColorMatrix#multiply
     * @since 3.50.0
     *
     * @param {number[]} a - The 5x4 array to multiply with ColorMatrix._matrix.
     * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
     *
     * @return {this} This ColorMatrix instance.
     */
    multiply: function (a, multiply)
    {
        if (multiply === undefined) { multiply = false; }

        //  Duplicate _matrix into c

        if (!multiply)
        {
            this.reset();
        }

        var m = this._matrix;
        var c = tempMatrix;

        //  copy _matrix to tempMatrox
        c.set(m);

        m.set([
            //  R
            (c[0] * a[0]) + (c[1] * a[5]) + (c[2] * a[10]) + (c[3] * a[15]),
            (c[0] * a[1]) + (c[1] * a[6]) + (c[2] * a[11]) + (c[3] * a[16]),
            (c[0] * a[2]) + (c[1] * a[7]) + (c[2] * a[12]) + (c[3] * a[17]),
            (c[0] * a[3]) + (c[1] * a[8]) + (c[2] * a[13]) + (c[3] * a[18]),
            (c[0] * a[4]) + (c[1] * a[9]) + (c[2] * a[14]) + (c[3] * a[19]) + c[4],

            //  G
            (c[5] * a[0]) + (c[6] * a[5]) + (c[7] * a[10]) + (c[8] * a[15]),
            (c[5] * a[1]) + (c[6] * a[6]) + (c[7] * a[11]) + (c[8] * a[16]),
            (c[5] * a[2]) + (c[6] * a[7]) + (c[7] * a[12]) + (c[8] * a[17]),
            (c[5] * a[3]) + (c[6] * a[8]) + (c[7] * a[13]) + (c[8] * a[18]),
            (c[5] * a[4]) + (c[6] * a[9]) + (c[7] * a[14]) + (c[8] * a[19]) + c[9],

            //  B
            (c[10] * a[0]) + (c[11] * a[5]) + (c[12] * a[10]) + (c[13] * a[15]),
            (c[10] * a[1]) + (c[11] * a[6]) + (c[12] * a[11]) + (c[13] * a[16]),
            (c[10] * a[2]) + (c[11] * a[7]) + (c[12] * a[12]) + (c[13] * a[17]),
            (c[10] * a[3]) + (c[11] * a[8]) + (c[12] * a[13]) + (c[13] * a[18]),
            (c[10] * a[4]) + (c[11] * a[9]) + (c[12] * a[14]) + (c[13] * a[19]) + c[14],

            //  A
            (c[15] * a[0]) + (c[16] * a[5]) + (c[17] * a[10]) + (c[18] * a[15]),
            (c[15] * a[1]) + (c[16] * a[6]) + (c[17] * a[11]) + (c[18] * a[16]),
            (c[15] * a[2]) + (c[16] * a[7]) + (c[17] * a[12]) + (c[18] * a[17]),
            (c[15] * a[3]) + (c[16] * a[8]) + (c[17] * a[13]) + (c[18] * a[18]),
            (c[15] * a[4]) + (c[16] * a[9]) + (c[17] * a[14]) + (c[18] * a[19]) + c[19]

        ]);

        this._dirty = true;

        return this;
    }

});

/**
 * A constant array used by the ColorMatrix class for black_white operations.
 *
 * @name Phaser.Display.ColorMatrix.BLACK_WHITE
 * @const
 * @type {number[]}
 * @since 3.60.0
 */
ColorMatrix.BLACK_WHITE = [ 0.3, 0.6, 0.1, 0, 0, 0.3, 0.6, 0.1, 0, 0, 0.3, 0.6, 0.1, 0, 0, 0, 0, 0, 1, 0 ];

/**
 * A constant array used by the ColorMatrix class for negative operations.
 *
 * @name Phaser.Display.ColorMatrix.NEGATIVE
 * @const
 * @type {number[]}
 * @since 3.60.0
 */
ColorMatrix.NEGATIVE = [ -1, 0, 0, 1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 1, 0 ];

/**
 * A constant array used by the ColorMatrix class for desatured luminance operations.
 *
 * @name Phaser.Display.ColorMatrix.DESATURATE_LUMINANCE
 * @const
 * @type {number[]}
 * @since 3.60.0
 */
ColorMatrix.DESATURATE_LUMINANCE = [ 0.2764723, 0.9297080, 0.0938197, 0, -37.1, 0.2764723, 0.9297080, 0.0938197, 0, -37.1, 0.2764723, 0.9297080, 0.0938197, 0, -37.1, 0, 0, 0, 1, 0 ];

/**
 * A constant array used by the ColorMatrix class for sepia operations.
 *
 * @name Phaser.Display.ColorMatrix.SEPIA
 * @const
 * @type {number[]}
 * @since 3.60.0
 */
ColorMatrix.SEPIA = [ 0.393, 0.7689999, 0.18899999, 0, 0, 0.349, 0.6859999, 0.16799999, 0, 0, 0.272, 0.5339999, 0.13099999, 0, 0, 0, 0, 0, 1, 0 ];

/**
 * A constant array used by the ColorMatrix class for lsd operations.
 *
 * @name Phaser.Display.ColorMatrix.LSD
 * @const
 * @type {number[]}
 * @since 3.60.0
 */
ColorMatrix.LSD = [ 2, -0.4, 0.5, 0, 0, -0.5, 2, -0.4, 0, 0, -0.4, -0.5, 3, 0, 0, 0, 0, 0, 1, 0 ];

/**
 * A constant array used by the ColorMatrix class for brown operations.
 *
 * @name Phaser.Display.ColorMatrix.BROWN
 * @const
 * @type {number[]}
 * @since 3.60.0
 */
ColorMatrix.BROWN = [ 0.5997023498159715, 0.34553243048391263, -0.2708298674538042, 0, 47.43192855600873, -0.037703249837783157, 0.8609577587992641, 0.15059552388459913, 0, -36.96841498319127, 0.24113635128153335, -0.07441037908422492, 0.44972182064877153, 0, -7.562075277591283, 0, 0, 0, 1, 0 ];

/**
 * A constant array used by the ColorMatrix class for vintage pinhole operations.
 *
 * @name Phaser.Display.ColorMatrix.VINTAGE
 * @const
 * @type {number[]}
 * @since 3.60.0
 */
ColorMatrix.VINTAGE = [ 0.6279345635605994, 0.3202183420819367, -0.03965408211312453, 0, 9.651285835294123, 0.02578397704808868, 0.6441188644374771, 0.03259127616149294, 0, 7.462829176470591, 0.0466055556782719, -0.0851232987247891, 0.5241648018700465, 0, 5.159190588235296, 0, 0, 0, 1, 0 ];

/**
 * A constant array used by the ColorMatrix class for kodachrome operations.
 *
 * @name Phaser.Display.ColorMatrix.KODACHROME
 * @const
 * @type {number[]}
 * @since 3.60.0
 */
ColorMatrix.KODACHROME = [ 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, 0, 0, 0, 1, 0 ];

/**
 * A constant array used by the ColorMatrix class for technicolor operations.
 *
 * @name Phaser.Display.ColorMatrix.TECHNICOLOR
 * @const
 * @type {number[]}
 * @since 3.60.0
 */
ColorMatrix.TECHNICOLOR = [ 1.9125277891456083, -0.8545344976951645, -0.09155508482755585, 0, 11.793603434377337, -0.3087833385928097, 1.7658908555458428, -0.10601743074722245, 0, -70.35205161461398, -0.231103377548616, -0.7501899197440212, 1.847597816108189, 0, 30.950940869491138, 0, 0, 0, 1, 0 ];

/**
 * A constant array used by the ColorMatrix class for polaroid shift operations.
 *
 * @name Phaser.Display.ColorMatrix.POLAROID
 * @const
 * @type {number[]}
 * @since 3.60.0
 */
ColorMatrix.POLAROID = [ 1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016, 1.483, 0, 0, 0, 0, 0, 1, 0 ];

/**
 * A constant array used by the ColorMatrix class for shift BGR operations.
 *
 * @name Phaser.Display.ColorMatrix.SHIFT_BGR
 * @const
 * @type {number[]}
 * @since 3.60.0
 */
ColorMatrix.SHIFT_BGR = [ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 ];

module.exports = ColorMatrix;


/***/ }),

/***/ 8073:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var CONST = __webpack_require__(9454);
var Smoothing = __webpack_require__(2150);

// The pool into which the canvas elements are placed.
var pool = [];

//  Automatically apply smoothing(false) to created Canvas elements
var _disableContextSmoothing = false;

/**
 * The CanvasPool is a global static object, that allows Phaser to recycle and pool 2D Context Canvas DOM elements.
 * It does not pool WebGL Contexts, because once the context options are set they cannot be modified again,
 * which is useless for some of the Phaser pipelines / renderer.
 *
 * This singleton is instantiated as soon as Phaser loads, before a Phaser.Game instance has even been created.
 * Which means all instances of Phaser Games on the same page can share the one single pool.
 *
 * @namespace Phaser.Display.Canvas.CanvasPool
 * @since 3.0.0
 */
var CanvasPool = function ()
{
    /**
     * Creates a new Canvas DOM element, or pulls one from the pool if free.
     *
     * @function Phaser.Display.Canvas.CanvasPool.create
     * @since 3.0.0
     *
     * @param {*} parent - The parent of the Canvas object.
     * @param {number} [width=1] - The width of the Canvas.
     * @param {number} [height=1] - The height of the Canvas.
     * @param {number} [canvasType=Phaser.CANVAS] - The type of the Canvas. Either `Phaser.CANVAS` or `Phaser.WEBGL`.
     * @param {boolean} [selfParent=false] - Use the generated Canvas element as the parent?
     *
     * @return {HTMLCanvasElement} The canvas element that was created or pulled from the pool
     */
    var create = function (parent, width, height, canvasType, selfParent)
    {
        if (width === undefined) { width = 1; }
        if (height === undefined) { height = 1; }
        if (canvasType === undefined) { canvasType = CONST.CANVAS; }
        if (selfParent === undefined) { selfParent = false; }

        var canvas;
        var container = first(canvasType);

        if (container === null)
        {
            container = {
                parent: parent,
                canvas: document.createElement('canvas'),
                type: canvasType
            };

            if (canvasType === CONST.CANVAS)
            {
                pool.push(container);
            }

            canvas = container.canvas;
        }
        else
        {
            container.parent = parent;

            canvas = container.canvas;
        }

        if (selfParent)
        {
            container.parent = canvas;
        }

        canvas.width = width;
        canvas.height = height;

        if (_disableContextSmoothing && canvasType === CONST.CANVAS)
        {
            Smoothing.disable(canvas.getContext('2d', { willReadFrequently: false }));
        }

        return canvas;
    };

    /**
     * Creates a new Canvas DOM element, or pulls one from the pool if free.
     *
     * @function Phaser.Display.Canvas.CanvasPool.create2D
     * @since 3.0.0
     *
     * @param {*} parent - The parent of the Canvas object.
     * @param {number} [width=1] - The width of the Canvas.
     * @param {number} [height=1] - The height of the Canvas.
     *
     * @return {HTMLCanvasElement} The created canvas.
     */
    var create2D = function (parent, width, height)
    {
        return create(parent, width, height, CONST.CANVAS);
    };

    /**
     * Creates a new Canvas DOM element, or pulls one from the pool if free.
     *
     * @function Phaser.Display.Canvas.CanvasPool.createWebGL
     * @since 3.0.0
     *
     * @param {*} parent - The parent of the Canvas object.
     * @param {number} [width=1] - The width of the Canvas.
     * @param {number} [height=1] - The height of the Canvas.
     *
     * @return {HTMLCanvasElement} The created WebGL canvas.
     */
    var createWebGL = function (parent, width, height)
    {
        return create(parent, width, height, CONST.WEBGL);
    };

    /**
     * Gets the first free canvas index from the pool.
     *
     * @function Phaser.Display.Canvas.CanvasPool.first
     * @since 3.0.0
     *
     * @param {number} [canvasType=Phaser.CANVAS] - The type of the Canvas. Either `Phaser.CANVAS` or `Phaser.WEBGL`.
     *
     * @return {HTMLCanvasElement} The first free canvas, or `null` if a WebGL canvas was requested or if the pool doesn't have free canvases.
     */
    var first = function (canvasType)
    {
        if (canvasType === undefined) { canvasType = CONST.CANVAS; }

        if (canvasType === CONST.WEBGL)
        {
            return null;
        }

        for (var i = 0; i < pool.length; i++)
        {
            var container = pool[i];

            if (!container.parent && container.type === canvasType)
            {
                return container;
            }
        }

        return null;
    };

    /**
     * Looks up a canvas based on its parent, and if found puts it back in the pool, freeing it up for re-use.
     * The canvas has its width and height set to 1, and its parent attribute nulled.
     *
     * @function Phaser.Display.Canvas.CanvasPool.remove
     * @since 3.0.0
     *
     * @param {*} parent - The canvas or the parent of the canvas to free.
     */
    var remove = function (parent)
    {
        //  Check to see if the parent is a canvas object
        var isCanvas = parent instanceof HTMLCanvasElement;

        pool.forEach(function (container)
        {
            if ((isCanvas && container.canvas === parent) || (!isCanvas && container.parent === parent))
            {
                container.parent = null;
                container.canvas.width = 1;
                container.canvas.height = 1;
            }
        });
    };

    /**
     * Gets the total number of used canvas elements in the pool.
     *
     * @function Phaser.Display.Canvas.CanvasPool.total
     * @since 3.0.0
     *
     * @return {number} The number of used canvases.
     */
    var total = function ()
    {
        var c = 0;

        pool.forEach(function (container)
        {
            if (container.parent)
            {
                c++;
            }
        });

        return c;
    };

    /**
     * Gets the total number of free canvas elements in the pool.
     *
     * @function Phaser.Display.Canvas.CanvasPool.free
     * @since 3.0.0
     *
     * @return {number} The number of free canvases.
     */
    var free = function ()
    {
        return pool.length - total();
    };

    /**
     * Disable context smoothing on any new Canvas element created.
     *
     * @function Phaser.Display.Canvas.CanvasPool.disableSmoothing
     * @since 3.0.0
     */
    var disableSmoothing = function ()
    {
        _disableContextSmoothing = true;
    };

    /**
     * Enable context smoothing on any new Canvas element created.
     *
     * @function Phaser.Display.Canvas.CanvasPool.enableSmoothing
     * @since 3.0.0
     */
    var enableSmoothing = function ()
    {
        _disableContextSmoothing = false;
    };

    return {
        create2D: create2D,
        create: create,
        createWebGL: createWebGL,
        disableSmoothing: disableSmoothing,
        enableSmoothing: enableSmoothing,
        first: first,
        free: free,
        pool: pool,
        remove: remove,
        total: total
    };
};

//  If we export the called function here, it'll only be invoked once (not every time it's required).
module.exports = CanvasPool();


/***/ }),

/***/ 2150:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

//  Browser specific prefix, so not going to change between contexts, only between browsers
var prefix = '';

/**
 * @namespace Phaser.Display.Canvas.Smoothing
 * @since 3.0.0
 */
var Smoothing = function ()
{
    /**
     * Gets the Smoothing Enabled vendor prefix being used on the given context, or null if not set.
     *
     * @function Phaser.Display.Canvas.Smoothing.getPrefix
     * @since 3.0.0
     *
     * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The canvas context to check.
     *
     * @return {string} The name of the property on the context which controls image smoothing (either `imageSmoothingEnabled` or a vendor-prefixed version thereof), or `null` if not supported.
     */
    var getPrefix = function (context)
    {
        var vendors = [ 'i', 'webkitI', 'msI', 'mozI', 'oI' ];

        for (var i = 0; i < vendors.length; i++)
        {
            var s = vendors[i] + 'mageSmoothingEnabled';

            if (s in context)
            {
                return s;
            }
        }

        return null;
    };

    /**
     * Sets the Image Smoothing property on the given context. Set to false to disable image smoothing.
     * By default browsers have image smoothing enabled, which isn't always what you visually want, especially
     * when using pixel art in a game. Note that this sets the property on the context itself, so that any image
     * drawn to the context will be affected. This sets the property across all current browsers but support is
     * patchy on earlier browsers, especially on mobile.
     *
     * @function Phaser.Display.Canvas.Smoothing.enable
     * @since 3.0.0
     *
     * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The context on which to enable smoothing.
     *
     * @return {(CanvasRenderingContext2D|WebGLRenderingContext)} The provided context.
     */
    var enable = function (context)
    {
        if (prefix === '')
        {
            prefix = getPrefix(context);
        }

        if (prefix)
        {
            context[prefix] = true;
        }

        return context;
    };

    /**
     * Sets the Image Smoothing property on the given context. Set to false to disable image smoothing.
     * By default browsers have image smoothing enabled, which isn't always what you visually want, especially
     * when using pixel art in a game. Note that this sets the property on the context itself, so that any image
     * drawn to the context will be affected. This sets the property across all current browsers but support is
     * patchy on earlier browsers, especially on mobile.
     *
     * @function Phaser.Display.Canvas.Smoothing.disable
     * @since 3.0.0
     *
     * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The context on which to disable smoothing.
     *
     * @return {(CanvasRenderingContext2D|WebGLRenderingContext)} The provided context.
     */
    var disable = function (context)
    {
        if (prefix === '')
        {
            prefix = getPrefix(context);
        }

        if (prefix)
        {
            context[prefix] = false;
        }

        return context;
    };

    /**
     * Returns `true` if the given context has image smoothing enabled, otherwise returns `false`.
     * Returns null if no smoothing prefix is available.
     *
     * @function Phaser.Display.Canvas.Smoothing.isEnabled
     * @since 3.0.0
     *
     * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The context to check.
     *
     * @return {?boolean} `true` if smoothing is enabled on the context, otherwise `false`. `null` if not supported.
     */
    var isEnabled = function (context)
    {
        return (prefix !== null) ? context[prefix] : null;
    };

    return {
        disable: disable,
        enable: enable,
        getPrefix: getPrefix,
        isEnabled: isEnabled
    };

};

module.exports = Smoothing();


/***/ }),

/***/ 7499:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var GameObjectFactory = __webpack_require__(3649);

/**
 * @classdesc
 * A Bitmap Mask combines the alpha (opacity) of a masked pixel with the alpha of another pixel.
 * Unlike the Geometry Mask, which is a clipping path, a Bitmap Mask behaves like an alpha mask,
 * not a clipping path. It is only available when using the WebGL Renderer.
 *
 * A Bitmap Mask can use any Game Object or Dynamic Texture to determine the alpha of each pixel of the masked Game Object(s).
 * For any given point of a masked Game Object's texture, the pixel's alpha will be multiplied by the alpha
 * of the pixel at the same position in the Bitmap Mask's Game Object. The color of the pixel from the
 * Bitmap Mask doesn't matter.
 *
 * For example, if a pure blue pixel with an alpha of 0.95 is masked with a pure red pixel with an
 * alpha of 0.5, the resulting pixel will be pure blue with an alpha of 0.475. Naturally, this means
 * that a pixel in the mask with an alpha of 0 will hide the corresponding pixel in all masked Game Objects.
 * A pixel with an alpha of 1 in the masked Game Object will receive the same alpha as the
 * corresponding pixel in the mask.
 *
 * Note: You cannot combine Bitmap Masks and Blend Modes on the same Game Object. You can, however,
 * combine Geometry Masks and Blend Modes together.
 *
 * The Bitmap Mask's location matches the location of its Game Object, not the location of the
 * masked objects. Moving or transforming the underlying Game Object will change the mask
 * (and affect the visibility of any masked objects), whereas moving or transforming a masked object
 * will not affect the mask.
 *
 * The Bitmap Mask will not render its Game Object by itself. If the Game Object is not in a
 * Scene's display list, it will only be used for the mask and its full texture will not be directly
 * visible. Adding the underlying Game Object to a Scene will not cause any problems - it will
 * render as a normal Game Object and will also serve as a mask.
 *
 * @class BitmapMask
 * @memberof Phaser.Display.Masks
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Scene} scene - The Scene to which this mask is being added.
 * @param {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)} [maskObject] - The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments.
 * @param {number} [x] - If creating a Game Object, the horizontal position in the world.
 * @param {number} [y] - If creating a Game Object, the vertical position in the world.
 * @param {(string|Phaser.Textures.Texture)} [texture] - If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager.
 * @param {(string|number|Phaser.Textures.Frame)} [frame] - If creating a Game Object, an optional frame from the Texture this Game Object is rendering with.
 */
var BitmapMask = new Class({

    initialize:

    function BitmapMask (scene, maskObject, x, y, texture, frame)
    {
        if (!maskObject)
        {
            maskObject = scene.sys.make.image({ x: x, y: y, key: texture, frame: frame, add: false });
        }

        /**
         * The Game Object that is used as the mask. Must use a texture, such as a Sprite.
         *
         * @name Phaser.Display.Masks.BitmapMask#bitmapMask
         * @type {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)}
         * @since 3.0.0
         */
        this.bitmapMask = maskObject;

        /**
         * Whether to invert the masks alpha.
         *
         * If `true`, the alpha of the masking pixel will be inverted before it's multiplied with the masked pixel.
         *
         * Essentially, this means that a masked area will be visible only if the corresponding area in the mask is invisible.
         *
         * @name Phaser.Display.Masks.BitmapMask#invertAlpha
         * @type {boolean}
         * @since 3.1.2
         */
        this.invertAlpha = false;

        /**
         * Is this mask a stencil mask? This is false by default and should not be changed.
         *
         * @name Phaser.Display.Masks.BitmapMask#isStencil
         * @type {boolean}
         * @readonly
         * @since 3.17.0
         */
        this.isStencil = false;
    },

    /**
     * Sets a new Game Object or Dynamic Texture for this Bitmap Mask to use.
     *
     * If a Game Object it must have a texture, such as a Sprite.
     *
     * You can update the source of the mask as often as you like.
     *
     * @method Phaser.Display.Masks.BitmapMask#setBitmap
     * @since 3.0.0
     *
     * @param {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)} maskObject - The Game Object or Dynamic Texture that will be used as the mask. If a Game Object, it must have a texture, such as a Sprite.
     */
    setBitmap: function (maskObject)
    {
        this.bitmapMask = maskObject;
    },

    /**
     * Prepares the WebGL Renderer to render a Game Object with this mask applied.
     *
     * This renders the masking Game Object to the mask framebuffer and switches to the main framebuffer so that the masked Game Object will be rendered to it instead of being rendered directly to the frame.
     *
     * @method Phaser.Display.Masks.BitmapMask#preRenderWebGL
     * @since 3.0.0
     *
     * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The WebGL Renderer to prepare.
     * @param {Phaser.GameObjects.GameObject} maskedObject - The masked Game Object which will be drawn.
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
     */
    preRenderWebGL: function (renderer, maskedObject, camera)
    {
        renderer.pipelines.BITMAPMASK_PIPELINE.beginMask(this, maskedObject, camera);
    },

    /**
     * Finalizes rendering of a masked Game Object.
     *
     * This resets the previously bound framebuffer and switches the WebGL Renderer to the Bitmap Mask Pipeline, which uses a special fragment shader to apply the masking effect.
     *
     * @method Phaser.Display.Masks.BitmapMask#postRenderWebGL
     * @since 3.0.0
     *
     * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The WebGL Renderer to clean up.
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
     * @param {Phaser.Renderer.WebGL.RenderTarget} [renderTarget] - Optional WebGL RenderTarget.
     */
    postRenderWebGL: function (renderer, camera, renderTarget)
    {
        renderer.pipelines.BITMAPMASK_PIPELINE.endMask(this, camera, renderTarget);
    },

    /**
     * This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer.
     *
     * @method Phaser.Display.Masks.BitmapMask#preRenderCanvas
     * @since 3.0.0
     *
     * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to.
     * @param {Phaser.GameObjects.GameObject} mask - The masked Game Object which would be rendered.
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
     */
    preRenderCanvas: function ()
    {
        // NOOP
    },

    /**
     * This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer.
     *
     * @method Phaser.Display.Masks.BitmapMask#postRenderCanvas
     * @since 3.0.0
     *
     * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to.
     */
    postRenderCanvas: function ()
    {
        // NOOP
    },

    /**
     * Destroys this BitmapMask and nulls any references it holds.
     *
     * Note that if a Game Object is currently using this mask it will _not_ automatically detect you have destroyed it,
     * so be sure to call `clearMask` on any Game Object using it, before destroying it.
     *
     * @method Phaser.Display.Masks.BitmapMask#destroy
     * @since 3.7.0
     */
    destroy: function ()
    {
        this.bitmapMask = null;
    }

});

/**
 * A Bitmap Mask combines the alpha (opacity) of a masked pixel with the alpha of another pixel.
 * Unlike the Geometry Mask, which is a clipping path, a Bitmap Mask behaves like an alpha mask,
 * not a clipping path. It is only available when using the WebGL Renderer.
 *
 * A Bitmap Mask can use any Game Object, or Dynamic Texture, to determine the alpha of each pixel of the masked Game Object(s).
 * For any given point of a masked Game Object's texture, the pixel's alpha will be multiplied by the alpha
 * of the pixel at the same position in the Bitmap Mask's Game Object. The color of the pixel from the
 * Bitmap Mask doesn't matter.
 *
 * For example, if a pure blue pixel with an alpha of 0.95 is masked with a pure red pixel with an
 * alpha of 0.5, the resulting pixel will be pure blue with an alpha of 0.475. Naturally, this means
 * that a pixel in the mask with an alpha of 0 will hide the corresponding pixel in all masked Game Objects
 *  A pixel with an alpha of 1 in the masked Game Object will receive the same alpha as the
 * corresponding pixel in the mask.
 *
 * Note: You cannot combine Bitmap Masks and Blend Modes on the same Game Object. You can, however,
 * combine Geometry Masks and Blend Modes together.
 *
 * The Bitmap Mask's location matches the location of its Game Object, not the location of the
 * masked objects. Moving or transforming the underlying Game Object will change the mask
 * (and affect the visibility of any masked objects), whereas moving or transforming a masked object
 * will not affect the mask.
 *
 * The Bitmap Mask will not render its Game Object by itself. If the Game Object is not in a
 * Scene's display list, it will only be used for the mask and its full texture will not be directly
 * visible. Adding the underlying Game Object to a Scene will not cause any problems - it will
 * render as a normal Game Object and will also serve as a mask.
 *
 * @method Phaser.GameObjects.GameObjectFactory#bitmapMask
 * @since 3.60.0
 *
 * @param {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)} [maskObject] - The Game Object or Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments.
 * @param {number} [x] - If creating a Game Object, the horizontal position in the world.
 * @param {number} [y] - If creating a Game Object, the vertical position in the world.
 * @param {(string|Phaser.Textures.Texture)} [texture] - If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager.
 * @param {(string|number|Phaser.Textures.Frame)} [frame] - If creating a Game Object, an optional frame from the Texture this Game Object is rendering with.
 *
 * @return {Phaser.Display.Masks.BitmapMask} The Bitmap Mask that was created.
 */
GameObjectFactory.register('bitmapMask', function (maskObject, x, y, key, frame)
{
    return new BitmapMask(this.scene, maskObject, x, y, key, frame);
});

module.exports = BitmapMask;


/***/ }),

/***/ 6726:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);

/**
 * @classdesc
 * A Geometry Mask can be applied to a Game Object to hide any pixels of it which don't intersect
 * a visible pixel from the geometry mask. The mask is essentially a clipping path which can only
 * make a masked pixel fully visible or fully invisible without changing its alpha (opacity).
 *
 * A Geometry Mask uses a Graphics Game Object to determine which pixels of the masked Game Object(s)
 * should be clipped. For any given point of a masked Game Object's texture, the pixel will only be displayed
 * if the Graphics Game Object of the Geometry Mask has a visible pixel at the same position. The color and
 * alpha of the pixel from the Geometry Mask do not matter.
 *
 * The Geometry Mask's location matches the location of its Graphics object, not the location of the masked objects.
 * Moving or transforming the underlying Graphics object will change the mask (and affect the visibility
 * of any masked objects), whereas moving or transforming a masked object will not affect the mask.
 * You can think of the Geometry Mask (or rather, of its Graphics object) as an invisible curtain placed
 * in front of all masked objects which has its own visual properties and, naturally, respects the camera's
 * visual properties, but isn't affected by and doesn't follow the masked objects by itself.
 *
 * @class GeometryMask
 * @memberof Phaser.Display.Masks
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Scene} scene - This parameter is not used.
 * @param {Phaser.GameObjects.Graphics} graphicsGeometry - The Graphics Game Object to use for the Geometry Mask. Doesn't have to be in the Display List.
 */
var GeometryMask = new Class({

    initialize:

    function GeometryMask (scene, graphicsGeometry)
    {
        /**
         * The Graphics object which describes the Geometry Mask.
         *
         * @name Phaser.Display.Masks.GeometryMask#geometryMask
         * @type {Phaser.GameObjects.Graphics}
         * @since 3.0.0
         */
        this.geometryMask = graphicsGeometry;

        /**
         * Similar to the BitmapMasks invertAlpha setting this to true will then hide all pixels
         * drawn to the Geometry Mask.
         *
         * This is a WebGL only feature.
         *
         * @name Phaser.Display.Masks.GeometryMask#invertAlpha
         * @type {boolean}
         * @since 3.16.0
         */
        this.invertAlpha = false;

        /**
         * Is this mask a stencil mask?
         *
         * @name Phaser.Display.Masks.GeometryMask#isStencil
         * @type {boolean}
         * @readonly
         * @since 3.17.0
         */
        this.isStencil = true;

        /**
         * The current stencil level. This can change dynamically at runtime
         * and is set in the applyStencil method.
         *
         * @name Phaser.Display.Masks.GeometryMask#level
         * @type {boolean}
         * @since 3.17.0
         */
        this.level = 0;
    },

    /**
     * Sets a new Graphics object for the Geometry Mask.
     *
     * @method Phaser.Display.Masks.GeometryMask#setShape
     * @since 3.0.0
     *
     * @param {Phaser.GameObjects.Graphics} graphicsGeometry - The Graphics object which will be used for the Geometry Mask.
     *
     * @return {this} This Geometry Mask
     */
    setShape: function (graphicsGeometry)
    {
        this.geometryMask = graphicsGeometry;

        return this;
    },

    /**
     * Sets the `invertAlpha` property of this Geometry Mask.
     *
     * Inverting the alpha essentially flips the way the mask works.
     *
     * This is a WebGL only feature.
     *
     * @method Phaser.Display.Masks.GeometryMask#setInvertAlpha
     * @since 3.17.0
     *
     * @param {boolean} [value=true] - Invert the alpha of this mask?
     *
     * @return {this} This Geometry Mask
     */
    setInvertAlpha: function (value)
    {
        if (value === undefined) { value = true; }

        this.invertAlpha = value;

        return this;
    },

    /**
     * Renders the Geometry Mask's underlying Graphics object to the OpenGL stencil buffer and enables the stencil test, which clips rendered pixels according to the mask.
     *
     * @method Phaser.Display.Masks.GeometryMask#preRenderWebGL
     * @since 3.0.0
     *
     * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw to.
     * @param {Phaser.GameObjects.GameObject} child - The Game Object being rendered.
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through.
     */
    preRenderWebGL: function (renderer, child, camera)
    {
        var gl = renderer.gl;

        //  Force flushing before drawing to stencil buffer
        renderer.flush();

        if (renderer.maskStack.length === 0)
        {
            gl.enable(gl.STENCIL_TEST);
            gl.clear(gl.STENCIL_BUFFER_BIT);

            renderer.maskCount = 0;
        }

        if (renderer.currentCameraMask.mask !== this)
        {
            renderer.currentMask.mask = this;
        }

        renderer.maskStack.push({ mask: this, camera: camera });

        this.applyStencil(renderer, camera, true);

        renderer.maskCount++;
    },

    /**
     * Applies the current stencil mask to the renderer.
     *
     * @method Phaser.Display.Masks.GeometryMask#applyStencil
     * @since 3.17.0
     *
     * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw to.
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through.
     * @param {boolean} inc - Is this an INCR stencil or a DECR stencil?
     */
    applyStencil: function (renderer, camera, inc)
    {
        var gl = renderer.gl;
        var geometryMask = this.geometryMask;
        var level = renderer.maskCount;
        var mask = 0xff;

        gl.colorMask(false, false, false, false);

        if (inc)
        {
            gl.stencilFunc(gl.EQUAL, level, mask);
            gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);

            //  Do this _after_ we set the stencilFunc
            level++;
        }
        else
        {
            gl.stencilFunc(gl.EQUAL, level + 1, mask);
            gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR);
        }

        this.level = level;

        //  Write stencil buffer
        geometryMask.renderWebGL(renderer, geometryMask, camera);

        renderer.flush();

        gl.colorMask(true, true, true, true);
        gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);

        if (this.invertAlpha)
        {
            gl.stencilFunc(gl.NOTEQUAL, level, mask);
        }
        else
        {
            gl.stencilFunc(gl.EQUAL, level, mask);
        }
    },

    /**
     * Flushes all rendered pixels and disables the stencil test of a WebGL context, thus disabling the mask for it.
     *
     * @method Phaser.Display.Masks.GeometryMask#postRenderWebGL
     * @since 3.0.0
     *
     * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw flush.
     */
    postRenderWebGL: function (renderer)
    {
        var gl = renderer.gl;

        renderer.maskStack.pop();

        renderer.maskCount--;

        //  Force flush before disabling stencil test
        renderer.flush();

        var current = renderer.currentMask;

        if (renderer.maskStack.length === 0)
        {
            //  If this is the only mask in the stack, flush and disable
            current.mask = null;

            gl.disable(gl.STENCIL_TEST);
        }
        else
        {
            var prev = renderer.maskStack[renderer.maskStack.length - 1];

            prev.mask.applyStencil(renderer, prev.camera, false);

            if (renderer.currentCameraMask.mask !== prev.mask)
            {
                current.mask = prev.mask;
                current.camera = prev.camera;
            }
            else
            {
                current.mask = null;
            }
        }
    },

    /**
     * Sets the clipping path of a 2D canvas context to the Geometry Mask's underlying Graphics object.
     *
     * @method Phaser.Display.Masks.GeometryMask#preRenderCanvas
     * @since 3.0.0
     *
     * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - The Canvas Renderer instance to set the clipping path on.
     * @param {Phaser.GameObjects.GameObject} mask - The Game Object being rendered.
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through.
     */
    preRenderCanvas: function (renderer, mask, camera)
    {
        var geometryMask = this.geometryMask;

        renderer.currentContext.save();

        geometryMask.renderCanvas(renderer, geometryMask, camera, null, null, true);

        renderer.currentContext.clip();
    },

    /**
     * Restore the canvas context's previous clipping path, thus turning off the mask for it.
     *
     * @method Phaser.Display.Masks.GeometryMask#postRenderCanvas
     * @since 3.0.0
     *
     * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - The Canvas Renderer instance being restored.
     */
    postRenderCanvas: function (renderer)
    {
        renderer.currentContext.restore();
    },

    /**
     * Destroys this GeometryMask and nulls any references it holds.
     *
     * Note that if a Game Object is currently using this mask it will _not_ automatically detect you have destroyed it,
     * so be sure to call `clearMask` on any Game Object using it, before destroying it.
     *
     * @method Phaser.Display.Masks.GeometryMask#destroy
     * @since 3.7.0
     */
    destroy: function ()
    {
        this.geometryMask = null;
    }

});

module.exports = GeometryMask;


/***/ }),

/***/ 7340:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Barrel FX Controller.
 *
 * This FX controller manages the barrel distortion effect for a Game Object.
 *
 * A barrel effect allows you to apply either a 'pinch' or 'expand' distortion to
 * a Game Object. The amount of the effect can be modified in real-time.
 *
 * A Barrel effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addBarrel();
 * sprite.postFX.addBarrel();
 * ```
 *
 * @class Barrel
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [amount=1] - The amount of distortion applied to the barrel effect. A value of 1 is no distortion. Typically keep this within +- 1.
 */
var Barrel = new Class({

    Extends: Controller,

    initialize:

    function Barrel (gameObject, amount)
    {
        if (amount === undefined) { amount = 1; }

        Controller.call(this, FX_CONST.BARREL, gameObject);

        /**
         * The amount of distortion applied to the barrel effect.
         *
         * Typically keep this within the range 1 (no distortion) to +- 1.
         *
         * @name Phaser.FX.Barrel#amount
         * @type {number}
         * @since 3.60.0
         */
        this.amount = amount;
    }

});

module.exports = Barrel;


/***/ }),

/***/ 5170:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Bloom FX Controller.
 *
 * This FX controller manages the bloom effect for a Game Object.
 *
 * Bloom is an effect used to reproduce an imaging artifact of real-world cameras.
 * The effect produces fringes of light extending from the borders of bright areas in an image,
 * contributing to the illusion of an extremely bright light overwhelming the
 * camera or eye capturing the scene.
 *
 * A Bloom effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addBloom();
 * sprite.postFX.addBloom();
 * ```
 *
 * @class Bloom
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [color=0xffffff] - The color of the Bloom, as a hex value.
 * @param {number} [offsetX=1] - The horizontal offset of the bloom effect.
 * @param {number} [offsetY=1] - The vertical offset of the bloom effect.
 * @param {number} [blurStrength=1] - The strength of the blur process of the bloom effect.
 * @param {number} [strength=1] - The strength of the blend process of the bloom effect.
 * @param {number} [steps=4] - The number of steps to run the Bloom effect for. This value should always be an integer.
 */
var Bloom = new Class({

    Extends: Controller,

    initialize:

    function Bloom (gameObject, color, offsetX, offsetY, blurStrength, strength, steps)
    {
        if (offsetX === undefined) { offsetX = 1; }
        if (offsetY === undefined) { offsetY = 1; }
        if (blurStrength === undefined) { blurStrength = 1; }
        if (strength === undefined) { strength = 1; }
        if (steps === undefined) { steps = 4; }

        Controller.call(this, FX_CONST.BLOOM, gameObject);

        /**
         * The number of steps to run the Bloom effect for.
         *
         * This value should always be an integer.
         *
         * It defaults to 4. The higher the value, the smoother the Bloom,
         * but at the cost of exponentially more gl operations.
         *
         * Keep this to the lowest possible number you can have it, while
         * still looking correct for your game.
         *
         * @name Phaser.FX.Bloom#steps
         * @type {number}
         * @since 3.60.0
         */
        this.steps = steps;

        /**
         * The horizontal offset of the bloom effect.
         *
         * @name Phaser.FX.Bloom#offsetX
         * @type {number}
         * @since 3.60.0
         */
        this.offsetX = offsetX;

        /**
         * The vertical offset of the bloom effect.
         *
         * @name Phaser.FX.Bloom#offsetY
         * @type {number}
         * @since 3.60.0
         */
        this.offsetY = offsetY;

        /**
         * The strength of the blur process of the bloom effect.
         *
         * @name Phaser.FX.Bloom#blurStrength
         * @type {number}
         * @since 3.60.0
         */
        this.blurStrength = blurStrength;

        /**
         * The strength of the blend process of the bloom effect.
         *
         * @name Phaser.FX.Bloom#strength
         * @type {number}
         * @since 3.60.0
         */
        this.strength = strength;

        /**
         * The internal gl color array.
         *
         * @name Phaser.FX.Bloom#glcolor
         * @type {number[]}
         * @since 3.60.0
         */
        this.glcolor = [ 1, 1, 1 ];

        if (color !== undefined && color !== null)
        {
            this.color = color;
        }
    },

    /**
     * The color of the bloom as a number value.
     *
     * @name Phaser.FX.Bloom#color
     * @type {number}
     * @since 3.60.0
     */
    color: {

        get: function ()
        {
            var color = this.glcolor;

            return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0));
        },

        set: function (value)
        {
            var color = this.glcolor;

            color[0] = ((value >> 16) & 0xFF) / 255;
            color[1] = ((value >> 8) & 0xFF) / 255;
            color[2] = (value & 0xFF) / 255;
        }

    }

});

module.exports = Bloom;


/***/ }),

/***/ 4199:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Blur FX Controller.
 *
 * This FX controller manages the blur effect for a Game Object.
 *
 * A Gaussian blur is the result of blurring an image by a Gaussian function. It is a widely used effect,
 * typically to reduce image noise and reduce detail. The visual effect of this blurring technique is a
 * smooth blur resembling that of viewing the image through a translucent screen, distinctly different
 * from the bokeh effect produced by an out-of-focus lens or the shadow of an object under usual illumination.
 *
 * A Blur effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addBlur();
 * sprite.postFX.addBlur();
 * ```
 *
 * @class Blur
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [quality=0] - The quality of the blur effect. Can be either 0 for Low Quality, 1 for Medium Quality or 2 for High Quality.
 * @param {number} [x=2] - The horizontal offset of the blur effect.
 * @param {number} [y=2] - The vertical offset of the blur effect.
 * @param {number} [strength=1] - The strength of the blur effect.
 * @param {number} [color=0xffffff] - The color of the blur, as a hex value.
 * @param {number} [steps=4] - The number of steps to run the blur effect for. This value should always be an integer.
 */
var Blur = new Class({

    Extends: Controller,

    initialize:

    function Blur (gameObject, quality, x, y, strength, color, steps)
    {
        if (quality === undefined) { quality = 0; }
        if (x === undefined) { x = 2; }
        if (y === undefined) { y = 2; }
        if (strength === undefined) { strength = 1; }
        if (steps === undefined) { steps = 4; }

        Controller.call(this, FX_CONST.BLUR, gameObject);

        /**
         * The quality of the blur effect.
         *
         * This can be:
         *
         * 0 for Low Quality
         * 1 for Medium Quality
         * 2 for High Quality
         *
         * The higher the quality, the more complex shader is used
         * and the more processing time is spent on the GPU calculating
         * the final blur. This value is used in conjunction with the
         * `steps` value, as one has a direct impact on the other.
         *
         * Keep this value as low as you can, while still achieving the
         * desired effect you need for your game.
         *
         * @name Phaser.FX.Blur#quality
         * @type {number}
         * @since 3.60.0
         */
        this.quality = quality;

        /**
         * The horizontal offset of the blur effect.
         *
         * @name Phaser.FX.Blur#x
         * @type {number}
         * @since 3.60.0
         */
        this.x = x;

        /**
         * The vertical offset of the blur effect.
         *
         * @name Phaser.FX.Blur#y
         * @type {number}
         * @since 3.60.0
         */
        this.y = y;

        /**
         * The number of steps to run the Blur effect for.
         *
         * This value should always be an integer.
         *
         * It defaults to 4. The higher the value, the smoother the blur,
         * but at the cost of exponentially more gl operations.
         *
         * Keep this to the lowest possible number you can have it, while
         * still looking correct for your game.
         *
         * @name Phaser.FX.Blur#steps
         * @type {number}
         * @since 3.60.0
         */
        this.steps = steps;

        /**
         * The strength of the blur effect.
         *
         * @name Phaser.FX.Blur#strength
         * @type {number}
         * @since 3.60.0
         */
        this.strength = strength;

        /**
         * The internal gl color array.
         *
         * @name Phaser.FX.Blur#glcolor
         * @type {number[]}
         * @since 3.60.0
         */
        this.glcolor = [ 1, 1, 1 ];

        if (color !== undefined && color !== null)
        {
            this.color = color;
        }
    },

    /**
     * The color of the blur as a number value.
     *
     * @name Phaser.FX.Blur#color
     * @type {number}
     * @since 3.60.0
     */
    color: {

        get: function ()
        {
            var color = this.glcolor;

            return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0));
        },

        set: function (value)
        {
            var color = this.glcolor;

            color[0] = ((value >> 16) & 0xFF) / 255;
            color[1] = ((value >> 8) & 0xFF) / 255;
            color[2] = (value & 0xFF) / 255;
        }

    }

});

module.exports = Blur;


/***/ }),

/***/ 3132:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Bokeh FX Controller.
 *
 * This FX controller manages the bokeh effect for a Game Object.
 *
 * Bokeh refers to a visual effect that mimics the photographic technique of creating a shallow depth of field.
 * This effect is used to emphasize the game's main subject or action, by blurring the background or foreground
 * elements, resulting in a more immersive and visually appealing experience. It is achieved through rendering
 * techniques that simulate the out-of-focus areas, giving a sense of depth and realism to the game's graphics.
 *
 * This effect can also be used to generate a Tilt Shift effect, which is a technique used to create a miniature
 * effect by blurring everything except a small area of the image. This effect is achieved by blurring the
 * top and bottom elements, while keeping the center area in focus.
 *
 * A Bokeh effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addBokeh();
 * sprite.postFX.addBokeh();
 * ```
 *
 * @class Bokeh
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [radius=0.5] - The radius of the bokeh effect.
 * @param {number} [amount=1] - The amount of the bokeh effect.
 * @param {number} [contrast=0.2] - The color contrast of the bokeh effect.
 * @param {boolean} [isTiltShift=false] - Is this a bokeh or Tile Shift effect?
 * @param {number} [blurX=1] - If Tilt Shift, the amount of horizontal blur.
 * @param {number} [blurY=1] - If Tilt Shift, the amount of vertical blur.
 * @param {number} [strength=1] - If Tilt Shift, the strength of the blur.
 */
var Bokeh = new Class({

    Extends: Controller,

    initialize:

    function Bokeh (gameObject, radius, amount, contrast, isTiltShift, blurX, blurY, strength)
    {
        if (radius === undefined) { radius = 0.5; }
        if (amount === undefined) { amount = 1; }
        if (contrast === undefined) { contrast = 0.2; }
        if (isTiltShift === undefined) { isTiltShift = false; }
        if (blurX === undefined) { blurX = 1; }
        if (blurY === undefined) { blurY = 1; }
        if (strength === undefined) { strength = 1; }

        Controller.call(this, FX_CONST.BOKEH, gameObject);

        /**
         * The radius of the bokeh effect.
         *
         * This is a float value, where a radius of 0 will result in no effect being applied,
         * and a radius of 1 will result in a strong bokeh. However, you can exceed this value
         * for even stronger effects.
         *
         * @name Phaser.FX.Bokeh#radius
         * @type {number}
         * @since 3.60.0
         */
        this.radius = radius;

        /**
         * The amount, or strength, of the bokeh effect. Defaults to 1.
         *
         * @name Phaser.FX.Bokeh#amount
         * @type {number}
         * @since 3.60.0
         */
        this.amount = amount;

        /**
         * The color contrast, or brightness, of the bokeh effect. Defaults to 0.2.
         *
         * @name Phaser.FX.Bokeh#contrast
         * @type {number}
         * @since 3.60.0
         */
        this.contrast = contrast;

        /**
         * Is this a Tilt Shift effect or a standard bokeh effect?
         *
         * @name Phaser.FX.Bokeh#isTiltShift
         * @type {boolean}
         * @since 3.60.0
         */
        this.isTiltShift = isTiltShift;

        /**
         * If a Tilt Shift effect this controls the strength of the blur.
         *
         * Setting this value on a non-Tilt Shift effect will have no effect.
         *
         * @name Phaser.FX.Bokeh#strength
         * @type {number}
         * @since 3.60.0
         */
        this.strength = strength;

        /**
         * If a Tilt Shift effect this controls the amount of horizontal blur.
         *
         * Setting this value on a non-Tilt Shift effect will have no effect.
         *
         * @name Phaser.FX.Bokeh#blurX
         * @type {number}
         * @since 3.60.0
         */
        this.blurX = blurX;

        /**
         * If a Tilt Shift effect this controls the amount of vertical blur.
         *
         * Setting this value on a non-Tilt Shift effect will have no effect.
         *
         * @name Phaser.FX.Bokeh#blurY
         * @type {number}
         * @since 3.60.0
         */
        this.blurY = blurY;
    }

});

module.exports = Bokeh;


/***/ }),

/***/ 6610:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Circle FX Controller.
 *
 * This FX controller manages the circle effect for a Game Object.
 *
 * This effect will draw a circle around the texture of the Game Object, effectively masking off
 * any area outside of the circle without the need for an actual mask. You can control the thickness
 * of the circle, the color of the circle and the color of the background, should the texture be
 * transparent. You can also control the feathering applied to the circle, allowing for a harsh or soft edge.
 *
 * Please note that adding this effect to a Game Object will not change the input area or physics body of
 * the Game Object, should it have one.
 *
 * A Circle effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addCircle();
 * sprite.postFX.addCircle();
 * ```
 *
 * @class Circle
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [thickness=8] - The width of the circle around the texture, in pixels.
 * @param {number} [color=0xfeedb6] - The color of the circular ring, given as a number value.
 * @param {number} [backgroundColor=0xff0000] - The color of the background, behind the texture, given as a number value.
 * @param {number} [scale=1] - The scale of the circle. The default scale is 1, which is a circle the full size of the underlying texture.
 * @param {number} [feather=0.005] - The amount of feathering to apply to the circle from the ring.
 */
var Circle = new Class({

    Extends: Controller,

    initialize:

    function Circle (gameObject, thickness, color, backgroundColor, scale, feather)
    {
        if (thickness === undefined) { thickness = 8; }
        if (scale === undefined) { scale = 1; }
        if (feather === undefined) { feather = 0.005; }

        Controller.call(this, FX_CONST.CIRCLE, gameObject);

        /**
         * The scale of the circle. The default scale is 1, which is a circle
         * the full size of the underlying texture. Reduce this value to create
         * a smaller circle, or increase it to create a circle that extends off
         * the edges of the texture.
         *
         * @name Phaser.FX.Circle#scale
         * @type {number}
         * @since 3.60.0
         */
        this.scale = scale;

        /**
         * The amount of feathering to apply to the circle from the ring,
         * extending into the middle of the circle. The default is 0.005,
         * which is a very low amount of feathering just making sure the ring
         * has a smooth edge. Increase this amount to a value such as 0.5
         * or 0.025 for larger amounts of feathering.
         *
         * @name Phaser.FX.Circle#feather
         * @type {number}
         * @since 3.60.0
         */
        this.feather = feather;

        /**
         * The width of the circle around the texture, in pixels. This value
         * doesn't factor in the feather, which can extend the thickness
         * internally depending on its value.
         *
         * @name Phaser.FX.Circle#thickness
         * @type {number}
         * @since 3.60.0
         */
        this.thickness = thickness;

        /**
         * The internal gl color array for the ring color.
         *
         * @name Phaser.FX.Circle#glcolor
         * @type {number[]}
         * @since 3.60.0
         */
        this.glcolor = [ 1, 0.2, 0.7 ];

        /**
         * The internal gl color array for the background color.
         *
         * @name Phaser.FX.Circle#glcolor2
         * @type {number[]}
         * @since 3.60.0
         */
        this.glcolor2 = [ 1, 0, 0, 0.4 ];

        if (color !== undefined && color !== null)
        {
            this.color = color;
        }

        if (backgroundColor !== undefined && backgroundColor !== null)
        {
            this.backgroundColor = backgroundColor;
        }
    },

    /**
     * The color of the circular ring, given as a number value.
     *
     * @name Phaser.FX.Circle#color
     * @type {number}
     * @since 3.60.0
     */
    color: {

        get: function ()
        {
            var color = this.glcolor;

            return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0));
        },

        set: function (value)
        {
            var color = this.glcolor;

            color[0] = ((value >> 16) & 0xFF) / 255;
            color[1] = ((value >> 8) & 0xFF) / 255;
            color[2] = (value & 0xFF) / 255;
        }

    },

    /**
     * The color of the background, behind the texture, given as a number value.
     *
     * @name Phaser.FX.Circle#backgroundColor
     * @type {number}
     * @since 3.60.0
     */
    backgroundColor: {

        get: function ()
        {
            var color = this.glcolor2;

            return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0));
        },

        set: function (value)
        {
            var color = this.glcolor2;

            color[0] = ((value >> 16) & 0xFF) / 255;
            color[1] = ((value >> 8) & 0xFF) / 255;
            color[2] = (value & 0xFF) / 255;
        }

    },

    /**
     * The alpha of the background, behind the texture, given as a number value.
     *
     * @name Phaser.FX.Circle#backgroundAlpha
     * @type {number}
     * @since 3.70.0
     */
    backgroundAlpha: {

        get: function ()
        {
            return this.glcolor2[3];
        },

        set: function (value)
        {
            this.glcolor2[3] = value;
        }

    }
});

module.exports = Circle;


/***/ }),

/***/ 4931:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var BaseColorMatrix = __webpack_require__(5686);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The ColorMatrix FX Controller.
 *
 * This FX controller manages the color matrix effect for a Game Object.
 *
 * The color matrix effect is a visual technique that involves manipulating the colors of an image
 * or scene using a mathematical matrix. This process can adjust hue, saturation, brightness, and contrast,
 * allowing developers to create various stylistic appearances or mood settings within the game.
 * Common applications include simulating different lighting conditions, applying color filters,
 * or achieving a specific visual style.
 *
 * A ColorMatrix effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addColorMatrix();
 * sprite.postFX.addColorMatrix();
 * ```
 *
 * @class ColorMatrix
 * @extends Phaser.Display.ColorMatrix
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 */
var ColorMatrix = new Class({

    Extends: BaseColorMatrix,

    initialize:

    function ColorMatrix (gameObject)
    {
        BaseColorMatrix.call(this);

        /**
         * The FX_CONST type of this effect.
         *
         * @name Phaser.FX.ColorMatrix#type
         * @type {number}
         * @since 3.60.0
         */
        this.type = FX_CONST.COLOR_MATRIX;

        /**
         * A reference to the Game Object that owns this effect.
         *
         * @name Phaser.FX.ColorMatrix#gameObject
         * @type {Phaser.GameObjects.GameObject}
         * @since 3.60.0
         */
        this.gameObject = gameObject;

        /**
         * Toggle this boolean to enable or disable this effect,
         * without removing and adding it from the Game Object.
         *
         * @name Phaser.FX.ColorMatrix#active
         * @type {boolean}
         * @since 3.60.0
         */
        this.active = true;
    },

    destroy: function ()
    {
        this.gameObject = null;
        this._matrix = null;
        this._data = null;
    }

});

module.exports = ColorMatrix;


/***/ }),

/***/ 6128:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);

/**
 * @classdesc
 * FX Controller is the base class that all built-in FX use.
 *
 * You should not normally create an instance of this class directly, but instead use one of the built-in FX that extend it.
 *
 * @class Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {number} type - The FX Type constant.
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 */
var Controller = new Class({

    initialize:

    function Controller (type, gameObject)
    {
        /**
         * The FX_CONST type of this effect.
         *
         * @name Phaser.FX.Controller#type
         * @type {number}
         * @since 3.60.0
         */
        this.type = type;

        /**
         * A reference to the Game Object that owns this effect.
         *
         * @name Phaser.FX.Controller#gameObject
         * @type {Phaser.GameObjects.GameObject}
         * @since 3.60.0
         */
        this.gameObject = gameObject;

        /**
         * Toggle this boolean to enable or disable this effect,
         * without removing and adding it from the Game Object.
         *
         * Only works for Pre FX.
         *
         * Post FX are always active.
         *
         * @name Phaser.FX.Controller#active
         * @type {boolean}
         * @since 3.60.0
         */
        this.active = true;
    },

    /**
     * Sets the active state of this FX Controller.
     *
     * A disabled FX Controller will not be updated.
     *
     * @method Phaser.FX.Controller#setActive
     * @since 3.60.0
     *
     * @param {boolean} value - `true` to enable this FX Controller, or `false` to disable it.
     *
     * @return {this} This FX Controller instance.
     */
    setActive: function (value)
    {
        this.active = value;

        return this;
    },

    /**
     * Destroys this FX Controller.
     *
     * @method Phaser.FX.Controller#destroy
     * @since 3.60.0
     */
    destroy: function ()
    {
        this.gameObject = null;
        this.active = false;
    }

});

module.exports = Controller;


/***/ }),

/***/ 9195:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Displacement FX Controller.
 *
 * This FX controller manages the displacement effect for a Game Object.
 *
 * The displacement effect is a visual technique that alters the position of pixels in an image
 * or texture based on the values of a displacement map. This effect is used to create the illusion
 * of depth, surface irregularities, or distortion in otherwise flat elements. It can be applied to
 * characters, objects, or backgrounds to enhance realism, convey movement, or achieve various
 * stylistic appearances.
 *
 * A Displacement effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addDisplacement();
 * sprite.postFX.addDisplacement();
 * ```
 *
 * @class Displacement
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {string} [texture='__WHITE'] - The unique string-based key of the texture to use for displacement, which must exist in the Texture Manager.
 * @param {number} [x=0.005] - The amount of horizontal displacement to apply. A very small float number, such as 0.005.
 * @param {number} [y=0.005] - The amount of vertical displacement to apply. A very small float number, such as 0.005.
 */
var Displacement = new Class({

    Extends: Controller,

    initialize:

    function Displacement (gameObject, texture, x, y)
    {
        if (texture === undefined) { texture = '__WHITE'; }
        if (x === undefined) { x = 0.005; }
        if (y === undefined) { y = 0.005; }

        Controller.call(this, FX_CONST.DISPLACEMENT, gameObject);

        /**
         * The amount of horizontal displacement to apply.
         *
         * @name Phaser.FX.Displacement#x
         * @type {number}
         * @since 3.60.0
         */
        this.x = x;

        /**
         * The amount of vertical displacement to apply.
         *
         * @name Phaser.FX.Displacement#y
         * @type {number}
         * @since 3.60.0
         */
        this.y = y;

        /**
         * The underlying WebGLTexture used for displacement.
         *
         * @name Phaser.FX.Displacement#glTexture
         * @type {WebGLTexture}
         * @since 3.60.0
         */
        this.glTexture;

        this.setTexture(texture);
    },

    /**
     * Sets the Texture to be used for the displacement effect.
     *
     * You can only use a whole texture, not a frame from a texture atlas or sprite sheet.
     *
     * @method Phaser.GameObjects.Components.FX#setTexture
     * @since 3.60.0
     *
     * @param {string} [texture='__WHITE'] - The unique string-based key of the texture to use for displacement, which must exist in the Texture Manager.
     *
     * @return {this} This FX Controller.
     */
    setTexture: function (texture)
    {
        var phaserTexture = this.gameObject.scene.sys.textures.getFrame(texture);

        if (phaserTexture)
        {
            this.glTexture = phaserTexture.glTexture;
        }

        return this;
    }

});

module.exports = Displacement;


/***/ }),

/***/ 445:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Glow FX Controller.
 *
 * This FX controller manages the glow effect for a Game Object.
 *
 * The glow effect is a visual technique that creates a soft, luminous halo around game objects,
 * characters, or UI elements. This effect is used to emphasize importance, enhance visual appeal,
 * or convey a sense of energy, magic, or otherworldly presence. The effect can also be set on
 * the inside of the Game Object. The color and strength of the glow can be modified.
 *
 * A Glow effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addGlow();
 * sprite.postFX.addGlow();
 * ```
 *
 * @class Glow
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [color=0xffffff] - The color of the glow effect as a number value.
 * @param {number} [outerStrength=4] - The strength of the glow outward from the edge of the Sprite.
 * @param {number} [innerStrength=0] - The strength of the glow inward from the edge of the Sprite.
 * @param {boolean} [knockout=false] - If `true` only the glow is drawn, not the texture itself.
 */
var Glow = new Class({

    Extends: Controller,

    initialize:

    function Glow (gameObject, color, outerStrength, innerStrength, knockout)
    {
        if (outerStrength === undefined) { outerStrength = 4; }
        if (innerStrength === undefined) { innerStrength = 0; }
        if (knockout === undefined) { knockout = false; }

        Controller.call(this, FX_CONST.GLOW, gameObject);

        /**
         * The strength of the glow outward from the edge of the Sprite.
         *
         * @name Phaser.FX.Glow#outerStrength
         * @type {number}
         * @since 3.60.0
         */
        this.outerStrength = outerStrength;

        /**
         * The strength of the glow inward from the edge of the Sprite.
         *
         * @name Phaser.FX.Glow#innerStrength
         * @type {number}
         * @since 3.60.0
         */
        this.innerStrength = innerStrength;

        /**
         * If `true` only the glow is drawn, not the texture itself.
         *
         * @name Phaser.FX.Glow#knockout
         * @type {number}
         * @since 3.60.0
         */
        this.knockout = knockout;

        /**
         * A 4 element array of gl color values.
         *
         * @name Phaser.FX.Glow#glcolor
         * @type {number[]}
         * @since 3.60.0
         */
        this.glcolor = [ 1, 1, 1, 1 ];

        if (color !== undefined)
        {
            this.color = color;
        }
    },

    /**
     * The color of the glow as a number value.
     *
     * @name Phaser.FX.Glow#color
     * @type {number}
     * @since 3.60.0
     */
    color: {

        get: function ()
        {
            var color = this.glcolor;

            return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0));
        },

        set: function (value)
        {
            var color = this.glcolor;

            color[0] = ((value >> 16) & 0xFF) / 255;
            color[1] = ((value >> 8) & 0xFF) / 255;
            color[2] = (value & 0xFF) / 255;
        }

    }

});

module.exports = Glow;


/***/ }),

/***/ 7724:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Gradient FX Controller.
 *
 * This FX controller manages the gradient effect for a Game Object.
 *
 * The gradient overlay effect is a visual technique where a smooth color transition is applied over Game Objects,
 * such as sprites or UI components. This effect is used to enhance visual appeal, emphasize depth, or create
 * stylistic and atmospheric variations. It can also be utilized to convey information, such as representing
 * progress or health status through color changes.
 *
 * A Gradient effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addGradient();
 * sprite.postFX.addGradient();
 * ```
 *
 * @class Gradient
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [color1=0xff0000] - The first gradient color, given as a number value.
 * @param {number} [color2=0x00ff00] - The second gradient color, given as a number value.
 * @param {number} [alpha=0.2] - The alpha value of the gradient effect.
 * @param {number} [fromX=0] - The horizontal position the gradient will start from. This value is normalized, between 0 and 1, and is not in pixels.
 * @param {number} [fromY=0] - The vertical position the gradient will start from. This value is normalized, between 0 and 1, and is not in pixels.
 * @param {number} [toX=0] - The horizontal position the gradient will end at. This value is normalized, between 0 and 1, and is not in pixels.
 * @param {number} [toY=1] - The vertical position the gradient will end at. This value is normalized, between 0 and 1, and is not in pixels.
 * @param {number} [size=0] - How many 'chunks' the gradient is divided in to, as spread over the entire height of the texture. Leave this at zero for a smooth gradient, or set higher for a more retro chunky effect.
 */
var Gradient = new Class({

    Extends: Controller,

    initialize:

    function Gradient (gameObject, color1, color2, alpha, fromX, fromY, toX, toY, size)
    {
        if (alpha === undefined) { alpha = 0.2; }
        if (fromX === undefined) { fromX = 0; }
        if (fromY === undefined) { fromY = 0; }
        if (toX === undefined) { toX = 0; }
        if (toY === undefined) { toY = 1; }
        if (size === undefined) { size = 0; }

        Controller.call(this, FX_CONST.GRADIENT, gameObject);

        /**
         * The alpha value of the gradient effect.
         *
         * @name Phaser.FX.Gradient#alpha
         * @type {number}
         * @since 3.60.0
         */
        this.alpha = alpha;

        /**
         * Sets how many 'chunks' the gradient is divided in to, as spread over the
         * entire height of the texture. Leave this at zero for a smooth gradient,
         * or set to a higher number to split the gradient into that many sections, giving
         * a more banded 'retro' effect.
         *
         * @name Phaser.FX.Gradient#size
         * @type {number}
         * @since 3.60.0
         */
        this.size = size;

        /**
         * The horizontal position the gradient will start from. This value is normalized, between 0 and 1 and is not in pixels.
         *
         * @name Phaser.FX.Gradient#fromX
         * @type {number}
         * @since 3.60.0
         */
        this.fromX = fromX;

        /**
         * The vertical position the gradient will start from. This value is normalized, between 0 and 1 and is not in pixels.
         *
         * @name Phaser.FX.Gradient#fromY
         * @type {number}
         * @since 3.60.0
         */
        this.fromY = fromY;

        /**
         * The horizontal position the gradient will end. This value is normalized, between 0 and 1 and is not in pixels.
         *
         * @name Phaser.FX.Gradient#toX
         * @type {number}
         * @since 3.60.0
         */
        this.toX = toX;

        /**
         * The vertical position the gradient will end. This value is normalized, between 0 and 1 and is not in pixels.
         *
         * @name Phaser.FX.Gradient#toY
         * @type {number}
         * @since 3.60.0
         */
        this.toY = toY;

        /**
         * The internal gl color array for the starting color.
         *
         * @name Phaser.FX.Gradient#glcolor1
         * @type {number[]}
         * @since 3.60.0
         */
        this.glcolor1 = [ 255, 0, 0 ];

        /**
         * The internal gl color array for the ending color.
         *
         * @name Phaser.FX.Gradient#glcolor2
         * @type {number[]}
         * @since 3.60.0
         */
        this.glcolor2 = [ 0, 255, 0 ];

        if (color1 !== undefined && color1 !== null)
        {
            this.color1 = color1;
        }

        if (color2 !== undefined && color2 !== null)
        {
            this.color2 = color2;
        }
    },

    /**
     * The first gradient color, given as a number value.
     *
     * @name Phaser.FX.Gradient#color1
     * @type {number}
     * @since 3.60.0
     */
    color1: {

        get: function ()
        {
            var color = this.glcolor1;

            return (((color[0]) << 16) + ((color[1]) << 8) + (color[2] | 0));
        },

        set: function (value)
        {
            var color = this.glcolor1;

            color[0] = ((value >> 16) & 0xFF);
            color[1] = ((value >> 8) & 0xFF);
            color[2] = (value & 0xFF);
        }

    },

    /**
     * The second gradient color, given as a number value.
     *
     * @name Phaser.FX.Gradient#color2
     * @type {number}
     * @since 3.60.0
     */
    color2: {

        get: function ()
        {
            var color = this.glcolor2;

            return (((color[0]) << 16) + ((color[1]) << 8) + (color[2] | 0));
        },

        set: function (value)
        {
            var color = this.glcolor2;

            color[0] = ((value >> 16) & 0xFF);
            color[1] = ((value >> 8) & 0xFF);
            color[2] = (value & 0xFF);
        }

    }

});

module.exports = Gradient;


/***/ }),

/***/ 4412:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Pixelate FX Controller.
 *
 * This FX controller manages the pixelate effect for a Game Object.
 *
 * The pixelate effect is a visual technique that deliberately reduces the resolution or detail of an image,
 * creating a blocky or mosaic appearance composed of large, visible pixels. This effect can be used for stylistic
 * purposes, as a homage to retro gaming, or as a means to obscure certain elements within the game, such as
 * during a transition or to censor specific content.
 *
 * A Pixelate effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addPixelate();
 * sprite.postFX.addPixelate();
 * ```
 *
 * @class Pixelate
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [amount=1] - The amount of pixelation to apply.
 */
var Pixelate = new Class({

    Extends: Controller,

    initialize:

    function Pixelate (gameObject, amount)
    {
        if (amount === undefined) { amount = 1; }

        Controller.call(this, FX_CONST.PIXELATE, gameObject);

        /**
         * The amount of pixelation to apply.
         *
         * @name Phaser.FX.Pixelate#amount
         * @type {number}
         * @since 3.60.0
         */
        this.amount = amount;
    }

});

module.exports = Pixelate;


/***/ }),

/***/ 75:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Shadow FX Controller.
 *
 * This FX controller manages the shadow effect for a Game Object.
 *
 * The shadow effect is a visual technique used to create the illusion of depth and realism by adding darker,
 * offset silhouettes or shapes beneath game objects, characters, or environments. These simulated shadows
 * help to enhance the visual appeal and immersion, making the 2D game world appear more dynamic and three-dimensional.
 *
 * A Shadow effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addShadow();
 * sprite.postFX.addShadow();
 * ```
 *
 * @class Shadow
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [x=0] - The horizontal offset of the shadow effect.
 * @param {number} [y=0] - The vertical offset of the shadow effect.
 * @param {number} [decay=0.1] - The amount of decay for shadow effect.
 * @param {number} [power=1] - The power of the shadow effect.
 * @param {number} [color=0x000000] - The color of the shadow.
 * @param {number} [samples=6] - The number of samples that the shadow effect will run for. An integer between 1 and 12.
 * @param {number} [intensity=1] - The intensity of the shadow effect.
 */
var Shadow = new Class({

    Extends: Controller,

    initialize:

    function Shadow (gameObject, x, y, decay, power, color, samples, intensity)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = 0; }
        if (decay === undefined) { decay = 0.1; }
        if (power === undefined) { power = 1; }
        if (samples === undefined) { samples = 6; }
        if (intensity === undefined) { intensity = 1; }

        Controller.call(this, FX_CONST.SHADOW, gameObject);

        /**
         * The horizontal offset of the shadow effect.
         *
         * @name Phaser.FX.Shadow#x
         * @type {number}
         * @since 3.60.0
         */
        this.x = x;

        /**
         * The vertical offset of the shadow effect.
         *
         * @name Phaser.FX.Shadow#y
         * @type {number}
         * @since 3.60.0
         */
        this.y = y;

        /**
         * The amount of decay for the shadow effect.
         *
         * @name Phaser.FX.Shadow#decay
         * @type {number}
         * @since 3.60.0
         */
        this.decay = decay;

        /**
         * The power of the shadow effect.
         *
         * @name Phaser.FX.Shadow#power
         * @type {number}
         * @since 3.60.0
         */
        this.power = power;

        /**
         * The internal gl color array.
         *
         * @name Phaser.FX.Shadow#glcolor
         * @type {number[]}
         * @since 3.60.0
         */
        this.glcolor = [ 0, 0, 0, 1 ];

        /**
         * The number of samples that the shadow effect will run for.
         *
         * This should be an integer with a minimum value of 1 and a maximum of 12.
         *
         * @name Phaser.FX.Shadow#samples
         * @type {number}
         * @since 3.60.0
         */
        this.samples = samples;

        /**
         * The intensity of the shadow effect.
         *
         * @name Phaser.FX.Shadow#intensity
         * @type {number}
         * @since 3.60.0
         */
        this.intensity = intensity;

        if (color !== undefined)
        {
            this.color = color;
        }
    },

    /**
     * The color of the shadow.
     *
     * @name Phaser.FX.Shadow#color
     * @type {number}
     * @since 3.60.0
     */
    color: {

        get: function ()
        {
            var color = this.glcolor;

            return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0));
        },

        set: function (value)
        {
            var color = this.glcolor;

            color[0] = ((value >> 16) & 0xFF) / 255;
            color[1] = ((value >> 8) & 0xFF) / 255;
            color[2] = (value & 0xFF) / 255;
        }

    }

});

module.exports = Shadow;


/***/ }),

/***/ 8734:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Shine FX Controller.
 *
 * This FX controller manages the shift effect for a Game Object.
 *
 * The shine effect is a visual technique that simulates the appearance of reflective
 * or glossy surfaces by passing a light beam across a Game Object. This effect is used to
 * enhance visual appeal, emphasize certain features, and create a sense of depth or
 * material properties.
 *
 * A Shine effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addShine();
 * sprite.postFX.addShine();
 * ```
 *
 * @class Shine
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [speed=0.5] - The speed of the Shine effect.
 * @param {number} [lineWidth=0.5] - The line width of the Shine effect.
 * @param {number} [gradient=3] - The gradient of the Shine effect.
 * @param {boolean} [reveal=false] - Does this Shine effect reveal or get added to its target?
 */
var Shine = new Class({

    Extends: Controller,

    initialize:

    function Shine (gameObject, speed, lineWidth, gradient, reveal)
    {
        if (speed === undefined) { speed = 0.5; }
        if (lineWidth === undefined) { lineWidth = 0.5; }
        if (gradient === undefined) { gradient = 3; }
        if (reveal === undefined) { reveal = false; }

        Controller.call(this, FX_CONST.SHINE, gameObject);

        /**
         * The speed of the Shine effect.
         *
         * @name Phaser.FX.Shine#speed
         * @type {number}
         * @since 3.60.0
         */
        this.speed = speed;

        /**
         * The line width of the Shine effect.
         *
         * @name Phaser.FX.Shine#lineWidth
         * @type {number}
         * @since 3.60.0
         */
        this.lineWidth = lineWidth;

        /**
         * The gradient of the Shine effect.
         *
         * @name Phaser.FX.Shine#gradient
         * @type {number}
         * @since 3.60.0
         */
        this.gradient = gradient;

        /**
         * Does this Shine effect reveal or get added to its target?
         *
         * @name Phaser.FX.Shine#reveal
         * @type {boolean}
         * @since 3.60.0
         */
        this.reveal = reveal;
    }

});

module.exports = Shine;


/***/ }),

/***/ 2437:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Vignette FX Controller.
 *
 * This FX controller manages the vignette effect for a Game Object.
 *
 * The vignette effect is a visual technique where the edges of the screen, or a Game Object, gradually darken or blur,
 * creating a frame-like appearance. This effect is used to draw the player's focus towards the central action or subject,
 * enhance immersion, and provide a cinematic or artistic quality to the game's visuals.
 *
 * A Vignette effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addVignette();
 * sprite.postFX.addVignette();
 * ```
 *
 * @class Vignette
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [x=0.5] - The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1.
 * @param {number} [y=0.5] - The vertical offset of the vignette effect. This value is normalized to the range 0 to 1.
 * @param {number} [radius=0.5] - The radius of the vignette effect. This value is normalized to the range 0 to 1.
 * @param {number} [strength=0.5] - The strength of the vignette effect.
 */
var Vignette = new Class({

    Extends: Controller,

    initialize:

    function Vignette (gameObject, x, y, radius, strength)
    {
        if (x === undefined) { x = 0.5; }
        if (y === undefined) { y = 0.5; }
        if (radius === undefined) { radius = 0.5; }
        if (strength === undefined) { strength = 0.5; }

        Controller.call(this, FX_CONST.VIGNETTE, gameObject);

        /**
         * The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1.
         *
         * @name Phaser.FX.Vignette#x
         * @type {number}
         * @since 3.60.0
         */
        this.x = x;

        /**
         * The vertical offset of the vignette effect. This value is normalized to the range 0 to 1.
         *
         * @name Phaser.FX.Vignette#y
         * @type {number}
         * @since 3.60.0
         */
        this.y = y;

        /**
         * The radius of the vignette effect. This value is normalized to the range 0 to 1.
         *
         * @name Phaser.FX.Vignette#radius
         * @type {number}
         * @since 3.60.0
         */
        this.radius = radius;

        /**
         * The strength of the vignette effect.
         *
         * @name Phaser.FX.Vignette#strength
         * @type {number}
         * @since 3.60.0
         */
        this.strength = strength;
    }

});

module.exports = Vignette;


/***/ }),

/***/ 5984:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Controller = __webpack_require__(6128);
var FX_CONST = __webpack_require__(1571);

/**
 * @classdesc
 * The Wipe FX Controller.
 *
 * This FX controller manages the wipe effect for a Game Object.
 *
 * The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements
 * in the game, such as images, text, or scene transitions. This effect is often used to create
 * a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition
 * between game states.
 *
 * You can set both the direction and the axis of the wipe effect. The following combinations are possible:
 *
 * * left to right: direction 0, axis 0
 * * right to left: direction 1, axis 0
 * * top to bottom: direction 1, axis 1
 * * bottom to top: direction 1, axis 0
 *
 * It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect.
 *
 * A Wipe effect is added to a Game Object via the FX component:
 *
 * ```js
 * const sprite = this.add.sprite();
 *
 * sprite.preFX.addWipe();
 * sprite.postFX.addWipe();
 * sprite.preFX.addReveal();
 * sprite.postFX.addReveal();
 * ```
 *
 * @class Wipe
 * @extends Phaser.FX.Controller
 * @memberof Phaser.FX
 * @constructor
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx.
 * @param {number} [wipeWidth=0.1] - The width of the wipe effect. This value is normalized in the range 0 to 1.
 * @param {number} [direction=0] - The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property.
 * @param {number} [axis=0] - The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property.
 * @param {boolean} [reveal=false] - Is this a reveal (true) or a fade (false) effect?
 */
var Wipe = new Class({

    Extends: Controller,

    initialize:

    function Wipe (gameObject, wipeWidth, direction, axis, reveal)
    {
        if (wipeWidth === undefined) { wipeWidth = 0.1; }
        if (direction === undefined) { direction = 0; }
        if (axis === undefined) { axis = 0; }
        if (reveal === undefined) { reveal = false; }

        Controller.call(this, FX_CONST.WIPE, gameObject);

        /**
         * The progress of the Wipe effect. This value is normalized to the range 0 to 1.
         *
         * Adjust this value to make the wipe transition (i.e. via a Tween)
         *
         * @name Phaser.FX.Wipe#progress
         * @type {number}
         * @since 3.60.0
         */
        this.progress = 0;

        /**
         * The width of the wipe effect. This value is normalized in the range 0 to 1.
         *
         * @name Phaser.FX.Wipe#wipeWidth
         * @type {number}
         * @since 3.60.0
         */
        this.wipeWidth = wipeWidth;

        /**
         * The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property.
         *
         * @name Phaser.FX.Wipe#direction
         * @type {number}
         * @since 3.60.0
         */
        this.direction = direction;

        /**
         * The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property.
         *
         * @name Phaser.FX.Wipe#axis
         * @type {number}
         * @since 3.60.0
         */
        this.axis = axis;

        /**
         * Is this a reveal (true) or a fade (false) effect?
         *
         * @name Phaser.FX.Wipe#reveal
         * @type {boolean}
         * @since 3.60.0
         */
        this.reveal = reveal;
    }

});

module.exports = Wipe;


/***/ }),

/***/ 1571:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var FX_CONST = {

    /**
     * The Glow FX.
     *
     * @name Phaser.FX.GLOW
     * @type {number}
     * @const
     * @since 3.60.0
     */
    GLOW: 4,

    /**
     * The Shadow FX.
     *
     * @name Phaser.FX.SHADOW
     * @type {number}
     * @const
     * @since 3.60.0
     */
    SHADOW: 5,

    /**
     * The Pixelate FX.
     *
     * @name Phaser.FX.PIXELATE
     * @type {number}
     * @const
     * @since 3.60.0
     */
    PIXELATE: 6,

    /**
     * The Vignette FX.
     *
     * @name Phaser.FX.VIGNETTE
     * @type {number}
     * @const
     * @since 3.60.0
     */
    VIGNETTE: 7,

    /**
     * The Shine FX.
     *
     * @name Phaser.FX.SHINE
     * @type {number}
     * @const
     * @since 3.60.0
     */
    SHINE: 8,

    /**
     * The Blur FX.
     *
     * @name Phaser.FX.BLUR
     * @type {number}
     * @const
     * @since 3.60.0
     */
    BLUR: 9, // uses 3 shaders, slots 9, 10 and 11

    /**
     * The Gradient FX.
     *
     * @name Phaser.FX.GRADIENT
     * @type {number}
     * @const
     * @since 3.60.0
     */
    GRADIENT: 12,

    /**
     * The Bloom FX.
     *
     * @name Phaser.FX.BLOOM
     * @type {number}
     * @const
     * @since 3.60.0
     */
    BLOOM: 13,

    /**
     * The Color Matrix FX.
     *
     * @name Phaser.FX.COLOR_MATRIX
     * @type {number}
     * @const
     * @since 3.60.0
     */
    COLOR_MATRIX: 14,

    /**
     * The Circle FX.
     *
     * @name Phaser.FX.CIRCLE
     * @type {number}
     * @const
     * @since 3.60.0
     */
    CIRCLE: 15,

    /**
     * The Barrel FX.
     *
     * @name Phaser.FX.BARREL
     * @type {number}
     * @const
     * @since 3.60.0
     */
    BARREL: 16,

    /**
     * The Displacement FX.
     *
     * @name Phaser.FX.DISPLACEMENT
     * @type {number}
     * @const
     * @since 3.60.0
     */
    DISPLACEMENT: 17,

    /**
     * The Wipe FX.
     *
     * @name Phaser.FX.WIPE
     * @type {number}
     * @const
     * @since 3.60.0
     */
    WIPE: 18,

    /**
     * The Bokeh and Tilt Shift FX.
     *
     * @name Phaser.FX.BOKEH
     * @type {number}
     * @const
     * @since 3.60.0
     */
    BOKEH: 19

};

module.exports = FX_CONST;


/***/ }),

/***/ 7347:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Extend = __webpack_require__(1030);
var FX_CONST = __webpack_require__(1571);

/**
 * @namespace Phaser.FX
 */

var FX = {

    Barrel: __webpack_require__(7340),
    Controller: __webpack_require__(6128),
    Bloom: __webpack_require__(5170),
    Blur: __webpack_require__(4199),
    Bokeh: __webpack_require__(3132),
    Circle: __webpack_require__(6610),
    ColorMatrix: __webpack_require__(4931),
    Displacement: __webpack_require__(9195),
    Glow: __webpack_require__(445),
    Gradient: __webpack_require__(7724),
    Pixelate: __webpack_require__(4412),
    Shadow: __webpack_require__(75),
    Shine: __webpack_require__(8734),
    Vignette: __webpack_require__(2437),
    Wipe: __webpack_require__(5984)

};

FX = Extend(false, FX, FX_CONST);

module.exports = FX;


/***/ }),

/***/ 2494:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var BlendModes = __webpack_require__(8351);
var GetAdvancedValue = __webpack_require__(8361);

/**
 * Builds a Game Object using the provided configuration object.
 *
 * @function Phaser.GameObjects.BuildGameObject
 * @since 3.0.0
 *
 * @param {Phaser.Scene} scene - A reference to the Scene.
 * @param {Phaser.GameObjects.GameObject} gameObject - The initial GameObject.
 * @param {Phaser.Types.GameObjects.GameObjectConfig} config - The config to build the GameObject with.
 *
 * @return {Phaser.GameObjects.GameObject} The built Game Object.
 */
var BuildGameObject = function (scene, gameObject, config)
{
    //  Position

    gameObject.x = GetAdvancedValue(config, 'x', 0);
    gameObject.y = GetAdvancedValue(config, 'y', 0);
    gameObject.depth = GetAdvancedValue(config, 'depth', 0);

    //  Flip

    gameObject.flipX = GetAdvancedValue(config, 'flipX', false);
    gameObject.flipY = GetAdvancedValue(config, 'flipY', false);

    //  Scale
    //  Either: { scale: 2 } or { scale: { x: 2, y: 2 }}

    var scale = GetAdvancedValue(config, 'scale', null);

    if (typeof scale === 'number')
    {
        gameObject.setScale(scale);
    }
    else if (scale !== null)
    {
        gameObject.scaleX = GetAdvancedValue(scale, 'x', 1);
        gameObject.scaleY = GetAdvancedValue(scale, 'y', 1);
    }

    //  ScrollFactor
    //  Either: { scrollFactor: 2 } or { scrollFactor: { x: 2, y: 2 }}

    var scrollFactor = GetAdvancedValue(config, 'scrollFactor', null);

    if (typeof scrollFactor === 'number')
    {
        gameObject.setScrollFactor(scrollFactor);
    }
    else if (scrollFactor !== null)
    {
        gameObject.scrollFactorX = GetAdvancedValue(scrollFactor, 'x', 1);
        gameObject.scrollFactorY = GetAdvancedValue(scrollFactor, 'y', 1);
    }

    //  Rotation

    gameObject.rotation = GetAdvancedValue(config, 'rotation', 0);

    var angle = GetAdvancedValue(config, 'angle', null);

    if (angle !== null)
    {
        gameObject.angle = angle;
    }

    //  Alpha

    gameObject.alpha = GetAdvancedValue(config, 'alpha', 1);

    //  Origin
    //  Either: { origin: 0.5 } or { origin: { x: 0.5, y: 0.5 }}

    var origin = GetAdvancedValue(config, 'origin', null);

    if (typeof origin === 'number')
    {
        gameObject.setOrigin(origin);
    }
    else if (origin !== null)
    {
        var ox = GetAdvancedValue(origin, 'x', 0.5);
        var oy = GetAdvancedValue(origin, 'y', 0.5);

        gameObject.setOrigin(ox, oy);
    }

    //  BlendMode

    gameObject.blendMode = GetAdvancedValue(config, 'blendMode', BlendModes.NORMAL);

    //  Visible

    gameObject.visible = GetAdvancedValue(config, 'visible', true);

    //  Add to Scene

    var add = GetAdvancedValue(config, 'add', true);

    if (add)
    {
        scene.sys.displayList.add(gameObject);
    }

    if (gameObject.preUpdate)
    {
        scene.sys.updateList.add(gameObject);
    }

    return gameObject;
};

module.exports = BuildGameObject;


/***/ }),

/***/ 2273:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var ComponentsToJSON = __webpack_require__(6125);
var DataManager = __webpack_require__(1081);
var EventEmitter = __webpack_require__(4399);
var Events = __webpack_require__(3389);
var SceneEvents = __webpack_require__(204);

/**
 * @classdesc
 * The base class that all Game Objects extend.
 * You don't create GameObjects directly and they cannot be added to the display list.
 * Instead, use them as the base for your own custom classes.
 *
 * @class GameObject
 * @memberof Phaser.GameObjects
 * @extends Phaser.Events.EventEmitter
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs.
 * @param {string} type - A textual representation of the type of Game Object, i.e. `sprite`.
 */
var GameObject = new Class({

    Extends: EventEmitter,

    initialize:

    function GameObject (scene, type)
    {
        EventEmitter.call(this);

        /**
         * A reference to the Scene to which this Game Object belongs.
         *
         * Game Objects can only belong to one Scene.
         *
         * You should consider this property as being read-only. You cannot move a
         * Game Object to another Scene by simply changing it.
         *
         * @name Phaser.GameObjects.GameObject#scene
         * @type {Phaser.Scene}
         * @since 3.0.0
         */
        this.scene = scene;

        /**
         * Holds a reference to the Display List that contains this Game Object.
         *
         * This is set automatically when this Game Object is added to a Scene or Layer.
         *
         * You should treat this property as being read-only.
         *
         * @name Phaser.GameObjects.GameObject#displayList
         * @type {(Phaser.GameObjects.DisplayList|Phaser.GameObjects.Layer)}
         * @default null
         * @since 3.50.0
         */
        this.displayList = null;

        /**
         * A textual representation of this Game Object, i.e. `sprite`.
         * Used internally by Phaser but is available for your own custom classes to populate.
         *
         * @name Phaser.GameObjects.GameObject#type
         * @type {string}
         * @since 3.0.0
         */
        this.type = type;

        /**
         * The current state of this Game Object.
         *
         * Phaser itself will never modify this value, although plugins may do so.
         *
         * Use this property to track the state of a Game Object during its lifetime. For example, it could change from
         * a state of 'moving', to 'attacking', to 'dead'. The state value should be an integer (ideally mapped to a constant
         * in your game code), or a string. These are recommended to keep it light and simple, with fast comparisons.
         * If you need to store complex data about your Game Object, look at using the Data Component instead.
         *
         * @name Phaser.GameObjects.GameObject#state
         * @type {(number|string)}
         * @since 3.16.0
         */
        this.state = 0;

        /**
         * The parent Container of this Game Object, if it has one.
         *
         * @name Phaser.GameObjects.GameObject#parentContainer
         * @type {Phaser.GameObjects.Container}
         * @since 3.4.0
         */
        this.parentContainer = null;

        /**
         * The name of this Game Object.
         * Empty by default and never populated by Phaser, this is left for developers to use.
         *
         * @name Phaser.GameObjects.GameObject#name
         * @type {string}
         * @default ''
         * @since 3.0.0
         */
        this.name = '';

        /**
         * The active state of this Game Object.
         * A Game Object with an active state of `true` is processed by the Scenes UpdateList, if added to it.
         * An active object is one which is having its logic and internal systems updated.
         *
         * @name Phaser.GameObjects.GameObject#active
         * @type {boolean}
         * @default true
         * @since 3.0.0
         */
        this.active = true;

        /**
         * The Tab Index of the Game Object.
         * Reserved for future use by plugins and the Input Manager.
         *
         * @name Phaser.GameObjects.GameObject#tabIndex
         * @type {number}
         * @default -1
         * @since 3.0.0
         */
        this.tabIndex = -1;

        /**
         * A Data Manager.
         * It allows you to store, query and get key/value paired information specific to this Game Object.
         * `null` by default. Automatically created if you use `getData` or `setData` or `setDataEnabled`.
         *
         * @name Phaser.GameObjects.GameObject#data
         * @type {Phaser.Data.DataManager}
         * @default null
         * @since 3.0.0
         */
        this.data = null;

        /**
         * The flags that are compared against `RENDER_MASK` to determine if this Game Object will render or not.
         * The bits are 0001 | 0010 | 0100 | 1000 set by the components Visible, Alpha, Transform and Texture respectively.
         * If those components are not used by your custom class then you can use this bitmask as you wish.
         *
         * @name Phaser.GameObjects.GameObject#renderFlags
         * @type {number}
         * @default 15
         * @since 3.0.0
         */
        this.renderFlags = 15;

        /**
         * A bitmask that controls if this Game Object is drawn by a Camera or not.
         * Not usually set directly, instead call `Camera.ignore`, however you can
         * set this property directly using the Camera.id property:
         *
         * @example
         * this.cameraFilter |= camera.id
         *
         * @name Phaser.GameObjects.GameObject#cameraFilter
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.cameraFilter = 0;

        /**
         * If this Game Object is enabled for input then this property will contain an InteractiveObject instance.
         * Not usually set directly. Instead call `GameObject.setInteractive()`.
         *
         * @name Phaser.GameObjects.GameObject#input
         * @type {?Phaser.Types.Input.InteractiveObject}
         * @default null
         * @since 3.0.0
         */
        this.input = null;

        /**
         * If this Game Object is enabled for Arcade or Matter Physics then this property will contain a reference to a Physics Body.
         *
         * @name Phaser.GameObjects.GameObject#body
         * @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|MatterJS.BodyType)}
         * @default null
         * @since 3.0.0
         */
        this.body = null;

        /**
         * This Game Object will ignore all calls made to its destroy method if this flag is set to `true`.
         * This includes calls that may come from a Group, Container or the Scene itself.
         * While it allows you to persist a Game Object across Scenes, please understand you are entirely
         * responsible for managing references to and from this Game Object.
         *
         * @name Phaser.GameObjects.GameObject#ignoreDestroy
         * @type {boolean}
         * @default false
         * @since 3.5.0
         */
        this.ignoreDestroy = false;

        this.on(Events.ADDED_TO_SCENE, this.addedToScene, this);
        this.on(Events.REMOVED_FROM_SCENE, this.removedFromScene, this);

        //  Tell the Scene to re-sort the children
        scene.sys.queueDepthSort();
    },

    /**
     * Sets the `active` property of this Game Object and returns this Game Object for further chaining.
     * A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList.
     *
     * @method Phaser.GameObjects.GameObject#setActive
     * @since 3.0.0
     *
     * @param {boolean} value - True if this Game Object should be set as active, false if not.
     *
     * @return {this} This GameObject.
     */
    setActive: function (value)
    {
        this.active = value;

        return this;
    },

    /**
     * Sets the `name` property of this Game Object and returns this Game Object for further chaining.
     * The `name` property is not populated by Phaser and is presented for your own use.
     *
     * @method Phaser.GameObjects.GameObject#setName
     * @since 3.0.0
     *
     * @param {string} value - The name to be given to this Game Object.
     *
     * @return {this} This GameObject.
     */
    setName: function (value)
    {
        this.name = value;

        return this;
    },

    /**
     * Sets the current state of this Game Object.
     *
     * Phaser itself will never modify the State of a Game Object, although plugins may do so.
     *
     * For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'.
     * The state value should typically be an integer (ideally mapped to a constant
     * in your game code), but could also be a string. It is recommended to keep it light and simple.
     * If you need to store complex data about your Game Object, look at using the Data Component instead.
     *
     * @method Phaser.GameObjects.GameObject#setState
     * @since 3.16.0
     *
     * @param {(number|string)} value - The state of the Game Object.
     *
     * @return {this} This GameObject.
     */
    setState: function (value)
    {
        this.state = value;

        return this;
    },

    /**
     * Adds a Data Manager component to this Game Object.
     *
     * @method Phaser.GameObjects.GameObject#setDataEnabled
     * @since 3.0.0
     * @see Phaser.Data.DataManager
     *
     * @return {this} This GameObject.
     */
    setDataEnabled: function ()
    {
        if (!this.data)
        {
            this.data = new DataManager(this);
        }

        return this;
    },

    /**
     * Allows you to store a key value pair within this Game Objects Data Manager.
     *
     * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled
     * before setting the value.
     *
     * If the key doesn't already exist in the Data Manager then it is created.
     *
     * ```javascript
     * sprite.setData('name', 'Red Gem Stone');
     * ```
     *
     * You can also pass in an object of key value pairs as the first argument:
     *
     * ```javascript
     * sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 });
     * ```
     *
     * To get a value back again you can call `getData`:
     *
     * ```javascript
     * sprite.getData('gold');
     * ```
     *
     * Or you can access the value directly via the `values` property, where it works like any other variable:
     *
     * ```javascript
     * sprite.data.values.gold += 50;
     * ```
     *
     * When the value is first set, a `setdata` event is emitted from this Game Object.
     *
     * If the key already exists, a `changedata` event is emitted instead, along an event named after the key.
     * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`.
     * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter.
     *
     * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings.
     * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager.
     *
     * @method Phaser.GameObjects.GameObject#setData
     * @since 3.0.0
     *
     * @generic {any} T
     * @genericUse {(string|T)} - [key]
     *
     * @param {(string|object)} key - The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored.
     * @param {*} [data] - The value to set for the given key. If an object is provided as the key this argument is ignored.
     *
     * @return {this} This GameObject.
     */
    setData: function (key, value)
    {
        if (!this.data)
        {
            this.data = new DataManager(this);
        }

        this.data.set(key, value);

        return this;
    },

    /**
     * Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0.
     *
     * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled
     * before setting the value.
     *
     * If the key doesn't already exist in the Data Manager then it is created.
     *
     * When the value is first set, a `setdata` event is emitted from this Game Object.
     *
     * @method Phaser.GameObjects.GameObject#incData
     * @since 3.23.0
     *
     * @param {string} key - The key to change the value for.
     * @param {number} [amount=1] - The amount to increase the given key by. Pass a negative value to decrease the key.
     *
     * @return {this} This GameObject.
     */
    incData: function (key, amount)
    {
        if (!this.data)
        {
            this.data = new DataManager(this);
        }

        this.data.inc(key, amount);

        return this;
    },

    /**
     * Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false.
     *
     * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled
     * before setting the value.
     *
     * If the key doesn't already exist in the Data Manager then it is created.
     *
     * When the value is first set, a `setdata` event is emitted from this Game Object.
     *
     * @method Phaser.GameObjects.GameObject#toggleData
     * @since 3.23.0
     *
     * @param {string} key - The key to toggle the value for.
     *
     * @return {this} This GameObject.
     */
    toggleData: function (key)
    {
        if (!this.data)
        {
            this.data = new DataManager(this);
        }

        this.data.toggle(key);

        return this;
    },

    /**
     * Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist.
     *
     * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either:
     *
     * ```javascript
     * sprite.getData('gold');
     * ```
     *
     * Or access the value directly:
     *
     * ```javascript
     * sprite.data.values.gold;
     * ```
     *
     * You can also pass in an array of keys, in which case an array of values will be returned:
     *
     * ```javascript
     * sprite.getData([ 'gold', 'armor', 'health' ]);
     * ```
     *
     * This approach is useful for destructuring arrays in ES6.
     *
     * @method Phaser.GameObjects.GameObject#getData
     * @since 3.0.0
     *
     * @param {(string|string[])} key - The key of the value to retrieve, or an array of keys.
     *
     * @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array.
     */
    getData: function (key)
    {
        if (!this.data)
        {
            this.data = new DataManager(this);
        }

        return this.data.get(key);
    },

    /**
     * Pass this Game Object to the Input Manager to enable it for Input.
     *
     * Input works by using hit areas, these are nearly always geometric shapes, such as rectangles or circles, that act as the hit area
     * for the Game Object. However, you can provide your own hit area shape and callback, should you wish to handle some more advanced
     * input detection.
     *
     * If no arguments are provided it will try and create a rectangle hit area based on the texture frame the Game Object is using. If
     * this isn't a texture-bound object, such as a Graphics or BitmapText object, this will fail, and you'll need to provide a specific
     * shape for it to use.
     *
     * You can also provide an Input Configuration Object as the only argument to this method.
     *
     * @example
     * sprite.setInteractive();
     *
     * @example
     * sprite.setInteractive(new Phaser.Geom.Circle(45, 46, 45), Phaser.Geom.Circle.Contains);
     *
     * @example
     * graphics.setInteractive(new Phaser.Geom.Rectangle(0, 0, 128, 128), Phaser.Geom.Rectangle.Contains);
     *
     * @method Phaser.GameObjects.GameObject#setInteractive
     * @since 3.0.0
     *
     * @param {(Phaser.Types.Input.InputConfiguration|any)} [hitArea] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not given it will try to create a Rectangle based on the texture frame.
     * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The callback that determines if the pointer is within the Hit Area shape or not. If you provide a shape you must also provide a callback.
     * @param {boolean} [dropZone=false] - Should this Game Object be treated as a drop zone target?
     *
     * @return {this} This GameObject.
     */
    setInteractive: function (hitArea, hitAreaCallback, dropZone)
    {
        this.scene.sys.input.enable(this, hitArea, hitAreaCallback, dropZone);

        return this;
    },

    /**
     * If this Game Object has previously been enabled for input, this will disable it.
     *
     * An object that is disabled for input stops processing or being considered for
     * input events, but can be turned back on again at any time by simply calling
     * `setInteractive()` with no arguments provided.
     *
     * If want to completely remove interaction from this Game Object then use `removeInteractive` instead.
     *
     * @method Phaser.GameObjects.GameObject#disableInteractive
     * @since 3.7.0
     *
     * @return {this} This GameObject.
     */
    disableInteractive: function ()
    {
        this.scene.sys.input.disable(this);

        return this;
    },

    /**
     * If this Game Object has previously been enabled for input, this will queue it
     * for removal, causing it to no longer be interactive. The removal happens on
     * the next game step, it is not immediate.
     *
     * The Interactive Object that was assigned to this Game Object will be destroyed,
     * removed from the Input Manager and cleared from this Game Object.
     *
     * If you wish to re-enable this Game Object at a later date you will need to
     * re-create its InteractiveObject by calling `setInteractive` again.
     *
     * If you wish to only temporarily stop an object from receiving input then use
     * `disableInteractive` instead, as that toggles the interactive state, where-as
     * this erases it completely.
     *
     * If you wish to resize a hit area, don't remove and then set it as being
     * interactive. Instead, access the hitarea object directly and resize the shape
     * being used. I.e.: `sprite.input.hitArea.setSize(width, height)` (assuming the
     * shape is a Rectangle, which it is by default.)
     *
     * @method Phaser.GameObjects.GameObject#removeInteractive
     * @since 3.7.0
     *
     * @return {this} This GameObject.
     */
    removeInteractive: function ()
    {
        this.scene.sys.input.clear(this);

        this.input = undefined;

        return this;
    },

    /**
     * This callback is invoked when this Game Object is added to a Scene.
     *
     * Can be overriden by custom Game Objects, but be aware of some Game Objects that
     * will use this, such as Sprites, to add themselves into the Update List.
     *
     * You can also listen for the `ADDED_TO_SCENE` event from this Game Object.
     *
     * @method Phaser.GameObjects.GameObject#addedToScene
     * @since 3.50.0
     */
    addedToScene: function ()
    {
    },

    /**
     * This callback is invoked when this Game Object is removed from a Scene.
     *
     * Can be overriden by custom Game Objects, but be aware of some Game Objects that
     * will use this, such as Sprites, to removed themselves from the Update List.
     *
     * You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object.
     *
     * @method Phaser.GameObjects.GameObject#removedFromScene
     * @since 3.50.0
     */
    removedFromScene: function ()
    {
    },

    /**
     * To be overridden by custom GameObjects. Allows base objects to be used in a Pool.
     *
     * @method Phaser.GameObjects.GameObject#update
     * @since 3.0.0
     *
     * @param {...*} [args] - args
     */
    update: function ()
    {
    },

    /**
     * Returns a JSON representation of the Game Object.
     *
     * @method Phaser.GameObjects.GameObject#toJSON
     * @since 3.0.0
     *
     * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object.
     */
    toJSON: function ()
    {
        return ComponentsToJSON(this);
    },

    /**
     * Compares the renderMask with the renderFlags to see if this Game Object will render or not.
     * Also checks the Game Object against the given Cameras exclusion list.
     *
     * @method Phaser.GameObjects.GameObject#willRender
     * @since 3.0.0
     *
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object.
     *
     * @return {boolean} True if the Game Object should be rendered, otherwise false.
     */
    willRender: function (camera)
    {
        var listWillRender = (this.displayList && this.displayList.active) ? this.displayList.willRender(camera) : true;

        return !(!listWillRender || GameObject.RENDER_MASK !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id)));
    },

    /**
     * Returns an array containing the display list index of either this Game Object, or if it has one,
     * its parent Container. It then iterates up through all of the parent containers until it hits the
     * root of the display list (which is index 0 in the returned array).
     *
     * Used internally by the InputPlugin but also useful if you wish to find out the display depth of
     * this Game Object and all of its ancestors.
     *
     * @method Phaser.GameObjects.GameObject#getIndexList
     * @since 3.4.0
     *
     * @return {number[]} An array of display list position indexes.
     */
    getIndexList: function ()
    {
        // eslint-disable-next-line consistent-this
        var child = this;
        var parent = this.parentContainer;

        var indexes = [];

        while (parent)
        {
            indexes.unshift(parent.getIndex(child));

            child = parent;

            if (!parent.parentContainer)
            {
                break;
            }
            else
            {
                parent = parent.parentContainer;
            }
        }

        if (this.displayList)
        {
            indexes.unshift(this.displayList.getIndex(child));
        }
        else
        {
            indexes.unshift(this.scene.sys.displayList.getIndex(child));
        }

        return indexes;
    },

    /**
     * Adds this Game Object to the given Display List.
     *
     * If no Display List is specified, it will default to the Display List owned by the Scene to which
     * this Game Object belongs.
     *
     * A Game Object can only exist on one Display List at any given time, but may move freely between them.
     *
     * If this Game Object is already on another Display List when this method is called, it will first
     * be removed from it, before being added to the new list.
     *
     * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property.
     *
     * If a Game Object isn't on any display list, it will not be rendered. If you just wish to temporarly
     * disable it from rendering, consider using the `setVisible` method, instead.
     *
     * @method Phaser.GameObjects.GameObject#addToDisplayList
     * @fires Phaser.Scenes.Events#ADDED_TO_SCENE
     * @fires Phaser.GameObjects.Events#ADDED_TO_SCENE
     * @since 3.53.0
     *
     * @param {(Phaser.GameObjects.DisplayList|Phaser.GameObjects.Layer)} [displayList] - The Display List to add to. Defaults to the Scene Display List.
     *
     * @return {this} This Game Object.
     */
    addToDisplayList: function (displayList)
    {
        if (displayList === undefined) { displayList = this.scene.sys.displayList; }

        if (this.displayList && this.displayList !== displayList)
        {
            this.removeFromDisplayList();
        }

        //  Don't repeat if it's already on this list
        if (!displayList.exists(this))
        {
            this.displayList = displayList;

            displayList.add(this, true);

            displayList.queueDepthSort();

            this.emit(Events.ADDED_TO_SCENE, this, this.scene);

            displayList.events.emit(SceneEvents.ADDED_TO_SCENE, this, this.scene);
        }

        return this;
    },

    /**
     * Adds this Game Object to the Update List belonging to the Scene.
     *
     * When a Game Object is added to the Update List it will have its `preUpdate` method called
     * every game frame. This method is passed two parameters: `delta` and `time`.
     *
     * If you wish to run your own logic within `preUpdate` then you should always call
     * `super.preUpdate(delta, time)` within it, or it may fail to process required operations,
     * such as Sprite animations.
     *
     * @method Phaser.GameObjects.GameObject#addToUpdateList
     * @since 3.53.0
     *
     * @return {this} This Game Object.
     */
    addToUpdateList: function ()
    {
        if (this.scene && this.preUpdate)
        {
            this.scene.sys.updateList.add(this);
        }

        return this;
    },

    /**
     * Removes this Game Object from the Display List it is currently on.
     *
     * A Game Object can only exist on one Display List at any given time, but may move freely removed
     * and added back at a later stage.
     *
     * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property.
     *
     * If a Game Object isn't on any Display List, it will not be rendered. If you just wish to temporarly
     * disable it from rendering, consider using the `setVisible` method, instead.
     *
     * @method Phaser.GameObjects.GameObject#removeFromDisplayList
     * @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE
     * @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE
     * @since 3.53.0
     *
     * @return {this} This Game Object.
     */
    removeFromDisplayList: function ()
    {
        var displayList = this.displayList || this.scene.sys.displayList;

        if (displayList && displayList.exists(this))
        {
            displayList.remove(this, true);

            displayList.queueDepthSort();

            this.displayList = null;

            this.emit(Events.REMOVED_FROM_SCENE, this, this.scene);

            displayList.events.emit(SceneEvents.REMOVED_FROM_SCENE, this, this.scene);
        }

        return this;
    },

    /**
     * Removes this Game Object from the Scene's Update List.
     *
     * When a Game Object is on the Update List, it will have its `preUpdate` method called
     * every game frame. Calling this method will remove it from the list, preventing this.
     *
     * Removing a Game Object from the Update List will stop most internal functions working.
     * For example, removing a Sprite from the Update List will prevent it from being able to
     * run animations.
     *
     * @method Phaser.GameObjects.GameObject#removeFromUpdateList
     * @since 3.53.0
     *
     * @return {this} This Game Object.
     */
    removeFromUpdateList: function ()
    {
        if (this.scene && this.preUpdate)
        {
            this.scene.sys.updateList.remove(this);
        }

        return this;
    },

    /**
     * Destroys this Game Object removing it from the Display List and Update List and
     * severing all ties to parent resources.
     *
     * Also removes itself from the Input Manager and Physics Manager if previously enabled.
     *
     * Use this to remove a Game Object from your game if you don't ever plan to use it again.
     * As long as no reference to it exists within your own code it should become free for
     * garbage collection by the browser.
     *
     * If you just want to temporarily disable an object then look at using the
     * Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected.
     *
     * @method Phaser.GameObjects.GameObject#destroy
     * @fires Phaser.GameObjects.Events#DESTROY
     * @since 3.0.0
     *
     * @param {boolean} [fromScene=false] - `True` if this Game Object is being destroyed by the Scene, `false` if not.
     */
    destroy: function (fromScene)
    {
        //  This Game Object has already been destroyed
        if (!this.scene || this.ignoreDestroy)
        {
            return;
        }

        if (fromScene === undefined) { fromScene = false; }

        if (this.preDestroy)
        {
            this.preDestroy.call(this);
        }

        this.emit(Events.DESTROY, this, fromScene);

        this.removeAllListeners();

        if (this.postPipelines)
        {
            this.resetPostPipeline(true);
        }

        this.removeFromDisplayList();
        this.removeFromUpdateList();

        if (this.input)
        {
            this.scene.sys.input.clear(this);

            this.input = undefined;
        }

        if (this.data)
        {
            this.data.destroy();

            this.data = undefined;
        }

        if (this.body)
        {
            this.body.destroy();

            this.body = undefined;
        }

        if (this.preFX)
        {
            this.preFX.destroy();

            this.preFX = undefined;
        }

        if (this.postFX)
        {
            this.postFX.destroy();

            this.postFX = undefined;
        }

        this.active = false;
        this.visible = false;

        this.scene = undefined;
        this.parentContainer = undefined;
    }

});

/**
 * The bitmask that `GameObject.renderFlags` is compared against to determine if the Game Object will render or not.
 *
 * @constant {number} RENDER_MASK
 * @memberof Phaser.GameObjects.GameObject
 * @default
 */
GameObject.RENDER_MASK = 15;

module.exports = GameObject;


/***/ }),

/***/ 3649:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var PluginCache = __webpack_require__(8456);
var SceneEvents = __webpack_require__(204);

/**
 * @classdesc
 * The Game Object Factory is a Scene plugin that allows you to quickly create many common
 * types of Game Objects and have them automatically registered with the Scene.
 *
 * Game Objects directly register themselves with the Factory and inject their own creation
 * methods into the class.
 *
 * @class GameObjectFactory
 * @memberof Phaser.GameObjects
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Scene} scene - The Scene to which this Game Object Factory belongs.
 */
var GameObjectFactory = new Class({

    initialize:

    function GameObjectFactory (scene)
    {
        /**
         * The Scene to which this Game Object Factory belongs.
         *
         * @name Phaser.GameObjects.GameObjectFactory#scene
         * @type {Phaser.Scene}
         * @protected
         * @since 3.0.0
         */
        this.scene = scene;

        /**
         * A reference to the Scene.Systems.
         *
         * @name Phaser.GameObjects.GameObjectFactory#systems
         * @type {Phaser.Scenes.Systems}
         * @protected
         * @since 3.0.0
         */
        this.systems = scene.sys;

        /**
         * A reference to the Scene Event Emitter.
         *
         * @name Phaser.GameObjects.GameObjectFactory#events
         * @type {Phaser.Events.EventEmitter}
         * @protected
         * @since 3.50.0
         */
        this.events = scene.sys.events;

        /**
         * A reference to the Scene Display List.
         *
         * @name Phaser.GameObjects.GameObjectFactory#displayList
         * @type {Phaser.GameObjects.DisplayList}
         * @protected
         * @since 3.0.0
         */
        this.displayList;

        /**
         * A reference to the Scene Update List.
         *
         * @name Phaser.GameObjects.GameObjectFactory#updateList
         * @type {Phaser.GameObjects.UpdateList}
         * @protected
         * @since 3.0.0
         */
        this.updateList;

        this.events.once(SceneEvents.BOOT, this.boot, this);
        this.events.on(SceneEvents.START, this.start, this);
    },

    /**
     * This method is called automatically, only once, when the Scene is first created.
     * Do not invoke it directly.
     *
     * @method Phaser.GameObjects.GameObjectFactory#boot
     * @private
     * @since 3.5.1
     */
    boot: function ()
    {
        this.displayList = this.systems.displayList;
        this.updateList = this.systems.updateList;

        this.events.once(SceneEvents.DESTROY, this.destroy, this);
    },

    /**
     * This method is called automatically by the Scene when it is starting up.
     * It is responsible for creating local systems, properties and listening for Scene events.
     * Do not invoke it directly.
     *
     * @method Phaser.GameObjects.GameObjectFactory#start
     * @private
     * @since 3.5.0
     */
    start: function ()
    {
        this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this);
    },

    /**
     * Adds an existing Game Object to this Scene.
     *
     * If the Game Object renders, it will be added to the Display List.
     * If it has a `preUpdate` method, it will be added to the Update List.
     *
     * @method Phaser.GameObjects.GameObjectFactory#existing
     * @since 3.0.0
     *
     * @generic {(Phaser.GameObjects.GameObject|Phaser.GameObjects.Group|Phaser.GameObjects.Layer)} G - [child,$return]
     *
     * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.Group|Phaser.GameObjects.Layer)} child - The child to be added to this Scene.
     *
     * @return {Phaser.GameObjects.GameObject} The Game Object that was added.
     */
    existing: function (child)
    {
        if (child.renderCanvas || child.renderWebGL)
        {
            this.displayList.add(child);
        }

        //  For when custom objects have overridden `preUpdate` but don't hook into the ADDED_TO_SCENE event:
        //  Adding to the list multiple times is safe, as it won't add duplicates into the list anyway.
        if (child.preUpdate)
        {
            this.updateList.add(child);
        }

        return child;
    },

    /**
     * The Scene that owns this plugin is shutting down.
     * We need to kill and reset all internal properties as well as stop listening to Scene events.
     *
     * @method Phaser.GameObjects.GameObjectFactory#shutdown
     * @private
     * @since 3.0.0
     */
    shutdown: function ()
    {
        this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this);
    },

    /**
     * The Scene that owns this plugin is being destroyed.
     * We need to shutdown and then kill off all external references.
     *
     * @method Phaser.GameObjects.GameObjectFactory#destroy
     * @private
     * @since 3.0.0
     */
    destroy: function ()
    {
        this.shutdown();

        this.events.off(SceneEvents.START, this.start, this);

        this.scene = null;
        this.systems = null;
        this.events = null;

        this.displayList = null;
        this.updateList = null;
    }

});

/**
 * Static method called directly by the Game Object factory functions.
 * With this method you can register a custom GameObject factory in the GameObjectFactory,
 * providing a name (`factoryType`) and the constructor (`factoryFunction`) in order
 * to be called when you call to Phaser.Scene.add[ factoryType ] method.
 *
 * @method Phaser.GameObjects.GameObjectFactory.register
 * @static
 * @since 3.0.0
 *
 * @param {string} factoryType - The key of the factory that you will use to call to Phaser.Scene.add[ factoryType ] method.
 * @param {function} factoryFunction - The constructor function to be called when you invoke to the Phaser.Scene.add method.
 */
GameObjectFactory.register = function (factoryType, factoryFunction)
{
    if (!GameObjectFactory.prototype.hasOwnProperty(factoryType))
    {
        GameObjectFactory.prototype[factoryType] = factoryFunction;
    }
};

/**
 * Static method called directly by the Game Object factory functions.
 * With this method you can remove a custom GameObject factory registered in the GameObjectFactory,
 * providing a its `factoryType`.
 *
 * @method Phaser.GameObjects.GameObjectFactory.remove
 * @static
 * @since 3.0.0
 *
 * @param {string} factoryType - The key of the factory that you want to remove from the GameObjectFactory.
 */
GameObjectFactory.remove = function (factoryType)
{
    if (GameObjectFactory.prototype.hasOwnProperty(factoryType))
    {
        delete GameObjectFactory.prototype[factoryType];
    }
};

PluginCache.register('GameObjectFactory', GameObjectFactory, 'add');

module.exports = GameObjectFactory;


/***/ }),

/***/ 2208:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var TransformMatrix = __webpack_require__(4227);

var tempMatrix1 = new TransformMatrix();
var tempMatrix2 = new TransformMatrix();
var tempMatrix3 = new TransformMatrix();

var result = { camera: tempMatrix1, sprite: tempMatrix2, calc: tempMatrix3 };

/**
 * Calculates the Transform Matrix of the given Game Object and Camera, factoring in
 * the parent matrix if provided.
 *
 * Note that the object this results contains _references_ to the Transform Matrices,
 * not new instances of them. Therefore, you should use their values immediately, or
 * copy them to your own matrix, as they will be replaced as soon as another Game
 * Object is rendered.
 *
 * @function Phaser.GameObjects.GetCalcMatrix
 * @memberof Phaser.GameObjects
 * @since 3.50.0
 *
 * @param {Phaser.GameObjects.GameObject} src - The Game Object to calculate the transform matrix for.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera being used to render the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} [parentMatrix] - The transform matrix of the parent container, if any.
 *
 * @return {Phaser.Types.GameObjects.GetCalcMatrixResults} The results object containing the updated transform matrices.
 */
var GetCalcMatrix = function (src, camera, parentMatrix)
{
    var camMatrix = tempMatrix1;
    var spriteMatrix = tempMatrix2;
    var calcMatrix = tempMatrix3;

    spriteMatrix.applyITRS(src.x, src.y, src.rotation, src.scaleX, src.scaleY);

    camMatrix.copyFrom(camera.matrix);

    if (parentMatrix)
    {
        //  Multiply the camera by the parent matrix
        camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY);

        //  Undo the camera scroll
        spriteMatrix.e = src.x;
        spriteMatrix.f = src.y;
    }
    else
    {
        spriteMatrix.e -= camera.scrollX * src.scrollFactorX;
        spriteMatrix.f -= camera.scrollY * src.scrollFactorY;
    }

    //  Multiply by the Sprite matrix, store result in calcMatrix
    camMatrix.multiply(spriteMatrix, calcMatrix);

    return result;
};

module.exports = GetCalcMatrix;


/***/ }),

/***/ 4344:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Clamp = __webpack_require__(2915);

//  bitmask flag for GameObject.renderMask
var _FLAG = 2; // 0010

/**
 * Provides methods used for setting the alpha properties of a Game Object.
 * Should be applied as a mixin and not used directly.
 *
 * @namespace Phaser.GameObjects.Components.Alpha
 * @since 3.0.0
 */

var Alpha = {

    /**
     * Private internal value. Holds the global alpha value.
     *
     * @name Phaser.GameObjects.Components.Alpha#_alpha
     * @type {number}
     * @private
     * @default 1
     * @since 3.0.0
     */
    _alpha: 1,

    /**
     * Private internal value. Holds the top-left alpha value.
     *
     * @name Phaser.GameObjects.Components.Alpha#_alphaTL
     * @type {number}
     * @private
     * @default 1
     * @since 3.0.0
     */
    _alphaTL: 1,

    /**
     * Private internal value. Holds the top-right alpha value.
     *
     * @name Phaser.GameObjects.Components.Alpha#_alphaTR
     * @type {number}
     * @private
     * @default 1
     * @since 3.0.0
     */
    _alphaTR: 1,

    /**
     * Private internal value. Holds the bottom-left alpha value.
     *
     * @name Phaser.GameObjects.Components.Alpha#_alphaBL
     * @type {number}
     * @private
     * @default 1
     * @since 3.0.0
     */
    _alphaBL: 1,

    /**
     * Private internal value. Holds the bottom-right alpha value.
     *
     * @name Phaser.GameObjects.Components.Alpha#_alphaBR
     * @type {number}
     * @private
     * @default 1
     * @since 3.0.0
     */
    _alphaBR: 1,

    /**
     * Clears all alpha values associated with this Game Object.
     *
     * Immediately sets the alpha levels back to 1 (fully opaque).
     *
     * @method Phaser.GameObjects.Components.Alpha#clearAlpha
     * @since 3.0.0
     *
     * @return {this} This Game Object instance.
     */
    clearAlpha: function ()
    {
        return this.setAlpha(1);
    },

    /**
     * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders.
     * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque.
     *
     * If your game is running under WebGL you can optionally specify four different alpha values, each of which
     * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used.
     *
     * @method Phaser.GameObjects.Components.Alpha#setAlpha
     * @since 3.0.0
     *
     * @param {number} [topLeft=1] - The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object.
     * @param {number} [topRight] - The alpha value used for the top-right of the Game Object. WebGL only.
     * @param {number} [bottomLeft] - The alpha value used for the bottom-left of the Game Object. WebGL only.
     * @param {number} [bottomRight] - The alpha value used for the bottom-right of the Game Object. WebGL only.
     *
     * @return {this} This Game Object instance.
     */
    setAlpha: function (topLeft, topRight, bottomLeft, bottomRight)
    {
        if (topLeft === undefined) { topLeft = 1; }

        //  Treat as if there is only one alpha value for the whole Game Object
        if (topRight === undefined)
        {
            this.alpha = topLeft;
        }
        else
        {
            this._alphaTL = Clamp(topLeft, 0, 1);
            this._alphaTR = Clamp(topRight, 0, 1);
            this._alphaBL = Clamp(bottomLeft, 0, 1);
            this._alphaBR = Clamp(bottomRight, 0, 1);
        }

        return this;
    },

    /**
     * The alpha value of the Game Object.
     *
     * This is a global value, impacting the entire Game Object, not just a region of it.
     *
     * @name Phaser.GameObjects.Components.Alpha#alpha
     * @type {number}
     * @since 3.0.0
     */
    alpha: {

        get: function ()
        {
            return this._alpha;
        },

        set: function (value)
        {
            var v = Clamp(value, 0, 1);

            this._alpha = v;
            this._alphaTL = v;
            this._alphaTR = v;
            this._alphaBL = v;
            this._alphaBR = v;

            if (v === 0)
            {
                this.renderFlags &= ~_FLAG;
            }
            else
            {
                this.renderFlags |= _FLAG;
            }
        }

    },

    /**
     * The alpha value starting from the top-left of the Game Object.
     * This value is interpolated from the corner to the center of the Game Object.
     *
     * @name Phaser.GameObjects.Components.Alpha#alphaTopLeft
     * @type {number}
     * @webglOnly
     * @since 3.0.0
     */
    alphaTopLeft: {

        get: function ()
        {
            return this._alphaTL;
        },

        set: function (value)
        {
            var v = Clamp(value, 0, 1);

            this._alphaTL = v;

            if (v !== 0)
            {
                this.renderFlags |= _FLAG;
            }
        }

    },

    /**
     * The alpha value starting from the top-right of the Game Object.
     * This value is interpolated from the corner to the center of the Game Object.
     *
     * @name Phaser.GameObjects.Components.Alpha#alphaTopRight
     * @type {number}
     * @webglOnly
     * @since 3.0.0
     */
    alphaTopRight: {

        get: function ()
        {
            return this._alphaTR;
        },

        set: function (value)
        {
            var v = Clamp(value, 0, 1);

            this._alphaTR = v;

            if (v !== 0)
            {
                this.renderFlags |= _FLAG;
            }
        }

    },

    /**
     * The alpha value starting from the bottom-left of the Game Object.
     * This value is interpolated from the corner to the center of the Game Object.
     *
     * @name Phaser.GameObjects.Components.Alpha#alphaBottomLeft
     * @type {number}
     * @webglOnly
     * @since 3.0.0
     */
    alphaBottomLeft: {

        get: function ()
        {
            return this._alphaBL;
        },

        set: function (value)
        {
            var v = Clamp(value, 0, 1);

            this._alphaBL = v;

            if (v !== 0)
            {
                this.renderFlags |= _FLAG;
            }
        }

    },

    /**
     * The alpha value starting from the bottom-right of the Game Object.
     * This value is interpolated from the corner to the center of the Game Object.
     *
     * @name Phaser.GameObjects.Components.Alpha#alphaBottomRight
     * @type {number}
     * @webglOnly
     * @since 3.0.0
     */
    alphaBottomRight: {

        get: function ()
        {
            return this._alphaBR;
        },

        set: function (value)
        {
            var v = Clamp(value, 0, 1);

            this._alphaBR = v;

            if (v !== 0)
            {
                this.renderFlags |= _FLAG;
            }
        }

    }

};

module.exports = Alpha;


/***/ }),

/***/ 4518:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Clamp = __webpack_require__(2915);

//  bitmask flag for GameObject.renderMask
var _FLAG = 2; // 0010

/**
 * Provides methods used for setting the alpha property of a Game Object.
 * Should be applied as a mixin and not used directly.
 *
 * @namespace Phaser.GameObjects.Components.AlphaSingle
 * @since 3.22.0
 */

var AlphaSingle = {

    /**
     * Private internal value. Holds the global alpha value.
     *
     * @name Phaser.GameObjects.Components.AlphaSingle#_alpha
     * @type {number}
     * @private
     * @default 1
     * @since 3.0.0
     */
    _alpha: 1,

    /**
     * Clears all alpha values associated with this Game Object.
     *
     * Immediately sets the alpha levels back to 1 (fully opaque).
     *
     * @method Phaser.GameObjects.Components.AlphaSingle#clearAlpha
     * @since 3.0.0
     *
     * @return {this} This Game Object instance.
     */
    clearAlpha: function ()
    {
        return this.setAlpha(1);
    },

    /**
     * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders.
     * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque.
     *
     * @method Phaser.GameObjects.Components.AlphaSingle#setAlpha
     * @since 3.0.0
     *
     * @param {number} [value=1] - The alpha value applied across the whole Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setAlpha: function (value)
    {
        if (value === undefined) { value = 1; }

        this.alpha = value;

        return this;
    },

    /**
     * The alpha value of the Game Object.
     *
     * This is a global value, impacting the entire Game Object, not just a region of it.
     *
     * @name Phaser.GameObjects.Components.AlphaSingle#alpha
     * @type {number}
     * @since 3.0.0
     */
    alpha: {

        get: function ()
        {
            return this._alpha;
        },

        set: function (value)
        {
            var v = Clamp(value, 0, 1);

            this._alpha = v;

            if (v === 0)
            {
                this.renderFlags &= ~_FLAG;
            }
            else
            {
                this.renderFlags |= _FLAG;
            }
        }

    }

};

module.exports = AlphaSingle;


/***/ }),

/***/ 5173:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var BlendModes = __webpack_require__(8351);

/**
 * Provides methods used for setting the blend mode of a Game Object.
 * Should be applied as a mixin and not used directly.
 *
 * @namespace Phaser.GameObjects.Components.BlendMode
 * @since 3.0.0
 */

var BlendMode = {

    /**
     * Private internal value. Holds the current blend mode.
     *
     * @name Phaser.GameObjects.Components.BlendMode#_blendMode
     * @type {number}
     * @private
     * @default 0
     * @since 3.0.0
     */
    _blendMode: BlendModes.NORMAL,

    /**
     * Sets the Blend Mode being used by this Game Object.
     *
     * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay)
     *
     * Under WebGL only the following Blend Modes are available:
     *
     * * NORMAL
     * * ADD
     * * MULTIPLY
     * * SCREEN
     * * ERASE
     *
     * Canvas has more available depending on browser support.
     *
     * You can also create your own custom Blend Modes in WebGL.
     *
     * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending
     * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these
     * reasons try to be careful about the construction of your Scene and the frequency of which blend modes
     * are used.
     *
     * @name Phaser.GameObjects.Components.BlendMode#blendMode
     * @type {(Phaser.BlendModes|string|number)}
     * @since 3.0.0
     */
    blendMode: {

        get: function ()
        {
            return this._blendMode;
        },

        set: function (value)
        {
            if (typeof value === 'string')
            {
                value = BlendModes[value];
            }

            value |= 0;

            if (value >= -1)
            {
                this._blendMode = value;
            }
        }

    },

    /**
     * Sets the Blend Mode being used by this Game Object.
     *
     * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay)
     *
     * Under WebGL only the following Blend Modes are available:
     *
     * * NORMAL
     * * ADD
     * * MULTIPLY
     * * SCREEN
     * * ERASE (only works when rendering to a framebuffer, like a Render Texture)
     *
     * Canvas has more available depending on browser support.
     *
     * You can also create your own custom Blend Modes in WebGL.
     *
     * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending
     * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these
     * reasons try to be careful about the construction of your Scene and the frequency in which blend modes
     * are used.
     *
     * @method Phaser.GameObjects.Components.BlendMode#setBlendMode
     * @since 3.0.0
     *
     * @param {(string|Phaser.BlendModes|number)} value - The BlendMode value. Either a string, a CONST or a number.
     *
     * @return {this} This Game Object instance.
     */
    setBlendMode: function (value)
    {
        this.blendMode = value;

        return this;
    }

};

module.exports = BlendMode;


/***/ }),

/***/ 1991:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Provides methods used for calculating and setting the size of a non-Frame based Game Object.
 * Should be applied as a mixin and not used directly.
 *
 * @namespace Phaser.GameObjects.Components.ComputedSize
 * @since 3.0.0
 */

var ComputedSize = {

    /**
     * The native (un-scaled) width of this Game Object.
     *
     * Changing this value will not change the size that the Game Object is rendered in-game.
     * For that you need to either set the scale of the Game Object (`setScale`) or use
     * the `displayWidth` property.
     *
     * @name Phaser.GameObjects.Components.ComputedSize#width
     * @type {number}
     * @since 3.0.0
     */
    width: 0,

    /**
     * The native (un-scaled) height of this Game Object.
     *
     * Changing this value will not change the size that the Game Object is rendered in-game.
     * For that you need to either set the scale of the Game Object (`setScale`) or use
     * the `displayHeight` property.
     *
     * @name Phaser.GameObjects.Components.ComputedSize#height
     * @type {number}
     * @since 3.0.0
     */
    height: 0,

    /**
     * The displayed width of this Game Object.
     *
     * This value takes into account the scale factor.
     *
     * Setting this value will adjust the Game Object's scale property.
     *
     * @name Phaser.GameObjects.Components.ComputedSize#displayWidth
     * @type {number}
     * @since 3.0.0
     */
    displayWidth: {

        get: function ()
        {
            return this.scaleX * this.width;
        },

        set: function (value)
        {
            this.scaleX = value / this.width;
        }

    },

    /**
     * The displayed height of this Game Object.
     *
     * This value takes into account the scale factor.
     *
     * Setting this value will adjust the Game Object's scale property.
     *
     * @name Phaser.GameObjects.Components.ComputedSize#displayHeight
     * @type {number}
     * @since 3.0.0
     */
    displayHeight: {

        get: function ()
        {
            return this.scaleY * this.height;
        },

        set: function (value)
        {
            this.scaleY = value / this.height;
        }

    },

    /**
     * Sets the internal size of this Game Object, as used for frame or physics body creation.
     *
     * This will not change the size that the Game Object is rendered in-game.
     * For that you need to either set the scale of the Game Object (`setScale`) or call the
     * `setDisplaySize` method, which is the same thing as changing the scale but allows you
     * to do so by giving pixel values.
     *
     * If you have enabled this Game Object for input, changing the size will _not_ change the
     * size of the hit area. To do this you should adjust the `input.hitArea` object directly.
     *
     * @method Phaser.GameObjects.Components.ComputedSize#setSize
     * @since 3.4.0
     *
     * @param {number} width - The width of this Game Object.
     * @param {number} height - The height of this Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setSize: function (width, height)
    {
        this.width = width;
        this.height = height;

        return this;
    },

    /**
     * Sets the display size of this Game Object.
     *
     * Calling this will adjust the scale.
     *
     * @method Phaser.GameObjects.Components.ComputedSize#setDisplaySize
     * @since 3.4.0
     *
     * @param {number} width - The width of this Game Object.
     * @param {number} height - The height of this Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setDisplaySize: function (width, height)
    {
        this.displayWidth = width;
        this.displayHeight = height;

        return this;
    }

};

module.exports = ComputedSize;


/***/ }),

/***/ 8305:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Provides methods used for getting and setting the texture of a Game Object.
 *
 * @namespace Phaser.GameObjects.Components.Crop
 * @since 3.12.0
 */

var Crop = {

    /**
     * The Texture this Game Object is using to render with.
     *
     * @name Phaser.GameObjects.Components.Crop#texture
     * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture}
     * @since 3.0.0
     */
    texture: null,

    /**
     * The Texture Frame this Game Object is using to render with.
     *
     * @name Phaser.GameObjects.Components.Crop#frame
     * @type {Phaser.Textures.Frame}
     * @since 3.0.0
     */
    frame: null,

    /**
     * A boolean flag indicating if this Game Object is being cropped or not.
     * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off.
     * Equally, calling `setCrop` with no arguments will reset the crop and disable it.
     *
     * @name Phaser.GameObjects.Components.Crop#isCropped
     * @type {boolean}
     * @since 3.11.0
     */
    isCropped: false,

    /**
     * Applies a crop to a texture based Game Object, such as a Sprite or Image.
     *
     * The crop is a rectangle that limits the area of the texture frame that is visible during rendering.
     *
     * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just
     * changes what is shown when rendered.
     *
     * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left.
     *
     * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left
     * half of it, you could call `setCrop(0, 0, 400, 600)`.
     *
     * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop
     * an area of 200x100 when applied to a Game Object that had a scale factor of 2.
     *
     * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument.
     *
     * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`.
     *
     * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow
     * the renderer to skip several internal calculations.
     *
     * @method Phaser.GameObjects.Components.Crop#setCrop
     * @since 3.11.0
     *
     * @param {(number|Phaser.Geom.Rectangle)} [x] - The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored.
     * @param {number} [y] - The y coordinate to start the crop from.
     * @param {number} [width] - The width of the crop rectangle in pixels.
     * @param {number} [height] - The height of the crop rectangle in pixels.
     *
     * @return {this} This Game Object instance.
     */
    setCrop: function (x, y, width, height)
    {
        if (x === undefined)
        {
            this.isCropped = false;
        }
        else if (this.frame)
        {
            if (typeof x === 'number')
            {
                this.frame.setCropUVs(this._crop, x, y, width, height, this.flipX, this.flipY);
            }
            else
            {
                var rect = x;

                this.frame.setCropUVs(this._crop, rect.x, rect.y, rect.width, rect.height, this.flipX, this.flipY);
            }

            this.isCropped = true;
        }

        return this;
    },

    /**
     * Internal method that returns a blank, well-formed crop object for use by a Game Object.
     *
     * @method Phaser.GameObjects.Components.Crop#resetCropObject
     * @private
     * @since 3.12.0
     *
     * @return {object} The crop object.
     */
    resetCropObject: function ()
    {
        return { u0: 0, v0: 0, u1: 0, v1: 0, width: 0, height: 0, x: 0, y: 0, flipX: false, flipY: false, cx: 0, cy: 0, cw: 0, ch: 0 };
    }

};

module.exports = Crop;


/***/ }),

/***/ 3131:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Provides methods used for setting the depth of a Game Object.
 * Should be applied as a mixin and not used directly.
 *
 * @namespace Phaser.GameObjects.Components.Depth
 * @since 3.0.0
 */

var Depth = {

    /**
     * Private internal value. Holds the depth of the Game Object.
     *
     * @name Phaser.GameObjects.Components.Depth#_depth
     * @type {number}
     * @private
     * @default 0
     * @since 3.0.0
     */
    _depth: 0,

    /**
     * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type.
     *
     * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order
     * of Game Objects, without actually moving their position in the display list.
     *
     * The default depth is zero. A Game Object with a higher depth
     * value will always render in front of one with a lower value.
     *
     * Setting the depth will queue a depth sort event within the Scene.
     *
     * @name Phaser.GameObjects.Components.Depth#depth
     * @type {number}
     * @since 3.0.0
     */
    depth: {

        get: function ()
        {
            return this._depth;
        },

        set: function (value)
        {
            if (this.displayList)
            {
                this.displayList.queueDepthSort();
            }

            this._depth = value;
        }

    },

    /**
     * The depth of this Game Object within the Scene.
     *
     * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order
     * of Game Objects, without actually moving their position in the display list.
     *
     * The default depth is zero. A Game Object with a higher depth
     * value will always render in front of one with a lower value.
     *
     * Setting the depth will queue a depth sort event within the Scene.
     *
     * @method Phaser.GameObjects.Components.Depth#setDepth
     * @since 3.0.0
     *
     * @param {number} value - The depth of this Game Object. Ensure this value is only ever a number data-type.
     *
     * @return {this} This Game Object instance.
     */
    setDepth: function (value)
    {
        if (value === undefined) { value = 0; }

        this.depth = value;

        return this;
    }

};

module.exports = Depth;


/***/ }),

/***/ 1626:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Effects = __webpack_require__(7347);
var SpliceOne = __webpack_require__(8935);

/**
 * @classdesc
 * The FX Component features a set of methods used for applying a range of special built-in effects to a Game Object.
 *
 * The effects include the following:
 *
 * * Barrel Distortion
 * * Bloom
 * * Blur
 * * Bokeh / Tilt Shift
 * * Circle Outline
 * * Color Matrix
 * * Glow
 * * Displacement
 * * Gradient
 * * Pixelate
 * * Shine
 * * Shadow
 * * Vignette
 * * Wipe / Reveal
 *
 * All Game Objects support Post FX. These are effects applied after the Game Object has been rendered.
 *
 * Texture-based Game Objects also support Pre FX, including:
 *
 * * Image
 * * Sprite
 * * TileSprite
 * * Text
 * * RenderTexture
 * * Video
 *
 * And any Game Object that extends the above.
 *
 * The difference between Pre FX and Post FX are that all Post FX take place in a canvas (renderer) sized frame buffer,
 * after the Game Object has been rendered. Pre FX, however, take place in a texture sized frame buffer, which is sized
 * based on the Game Object itself. The end result is then composited back to the main game canvas. For intensive effects,
 * such as blur, bloom or glow, which can require many iterations, this is a much more efficient way to apply the effect,
 * as only it only has to work on a Game Object sized texture and not all pixels in the canvas.
 *
 * In short, you should always try and use a Pre FX if you can.
 *
 * Due to the way that FX work they can be stacked-up. For example, you can apply a blur to a Game Object, then apply
 * a bloom effect to the same Game Object. The bloom effect will be applied to the blurred texture, not the original.
 * Keep the order in mind when stacking effects.
 *
 * All effects are WebGL only and do not have canvas counterparts.
 *
 * As you can appreciate, some effects are more expensive than others. For example, a bloom effect is going to be more
 * expensive than a simple color matrix effect, so please consider using them wisely and performance test your target
 * platforms early on in production.
 *
 * This component is created automatically by the `PostPipeline` class and does not need to be instantiated directly.
 *
 * @class FX
 * @memberof Phaser.GameObjects.Components
 * @constructor
 * @since 3.60.0
 * @webglOnly
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that owns this FX Component.
 * @param {boolean} isPost - Is this a Pre or Post FX Component?
 */
var FX = new Class({

    initialize:

    function FX (gameObject, isPost)
    {
        /**
         * A reference to the Game Object that owns this FX Component.
         *
         * @name Phaser.GameObjects.Components.FX#gameObject
         * @type {Phaser.GameObjects.GameObject}
         * @readonly
         * @since 3.60.0
         */
        this.gameObject = gameObject;

        /**
         * Is this a Post FX Controller? or a Pre FX Controller?
         *
         * @name Phaser.GameObjects.Components.FX#isPost
         * @type {boolean}
         * @readonly
         * @since 3.60.0
         */
        this.isPost = isPost;

        /**
         * Has this FX Component been enabled?
         *
         * You should treat this property as read-only, although it is toggled
         * automaticaly during internal use.
         *
         * @name Phaser.GameObjects.Components.FX#enabled
         * @type {boolean}
         * @since 3.60.0
         */
        this.enabled = false;

        /**
         * An array containing all of the Pre FX Controllers that
         * have been added to this FX Component. They are processed in
         * the order they are added.
         *
         * This array is empty if this is a Post FX Component.
         *
         * @name Phaser.GameObjects.Components.FX#list
         * @type {Phaser.FX.Controller[]}
         * @since 3.60.0
         */
        this.list = [];

        /**
         * The amount of extra padding to be applied to this Game Object
         * when it is being rendered by a PreFX Pipeline.
         *
         * Lots of FX require additional spacing added to the texture the
         * Game Object uses, for example a glow or shadow effect, and this
         * method allows you to control how much extra padding is included
         * in addition to the texture size.
         *
         * You do not need to set this if you're only using Post FX.
         *
         * @name Phaser.GameObjects.Components.FX#padding
         * @type {number}
         * @default 0
         * @since 3.60.0
         */
        this.padding = 0;
    },

    /**
     * Sets the amount of extra padding to be applied to this Game Object
     * when it is being rendered by a PreFX Pipeline.
     *
     * Lots of FX require additional spacing added to the texture the
     * Game Object uses, for example a glow or shadow effect, and this
     * method allows you to control how much extra padding is included
     * in addition to the texture size.
     *
     * You do not need to set this if you're only using Post FX.
     *
     * @method Phaser.GameObjects.Components.FX#setPadding
     * @webglOnly
     * @since 3.60.0
     *
     * @param {number} [padding=0] - The amount of padding to add to this Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setPadding: function (padding)
    {
        if (padding === undefined) { padding = 0; }

        this.padding = padding;

        return this.gameObject;
    },

    /**
     * This callback is invoked when this Game Object is copied by a PreFX Pipeline.
     *
     * This happens when the pipeline uses its `copySprite` method.
     *
     * It's invoked prior to the copy, allowing you to set shader uniforms, etc on the pipeline.
     *
     * @method Phaser.GameObjects.Components.FX#onFXCopy
     * @since 3.60.0
     *
     * @param {Phaser.Renderer.WebGL.Pipelines.PreFXPipeline} pipeline - The PreFX Pipeline that invoked this callback.
     */
    onFXCopy: function ()
    {
    },

    /**
     * This callback is invoked when this Game Object is rendered by a PreFX Pipeline.
     *
     * This happens when the pipeline uses its `drawSprite` method.
     *
     * It's invoked prior to the draw, allowing you to set shader uniforms, etc on the pipeline.
     *
     * @method Phaser.GameObjects.Components.FX#onFX
     * @since 3.60.0
     *
     * @param {Phaser.Renderer.WebGL.Pipelines.PreFXPipeline} pipeline - The PreFX Pipeline that invoked this callback.
     */
    onFX: function ()
    {
    },

    /**
     * Enables this FX Component and applies the FXPipeline to the parent Game Object.
     *
     * This is called automatically whenever you call a method such as `addBloom`, etc.
     *
     * You can check the `enabled` property to see if the Game Object is already enabled, or not.
     *
     * This only applies to Pre FX. Post FX are always enabled.
     *
     * @method Phaser.GameObjects.Components.FX#enable
     * @since 3.60.0
     *
     * @param {number} [padding=0] - The amount of padding to add to this Game Object.
     */
    enable: function (padding)
    {
        if (this.isPost)
        {
            return;
        }

        var renderer = this.gameObject.scene.sys.renderer;

        if (renderer && renderer.pipelines)
        {
            this.gameObject.pipeline = renderer.pipelines.FX_PIPELINE;

            if (padding !== undefined)
            {
                this.padding = padding;
            }

            this.enabled = true;
        }
        else
        {
            this.enabled = false;
        }
    },

    /**
     * Destroys and removes all FX Controllers that are part of this FX Component,
     * then disables it.
     *
     * If this is a Pre FX Component it will only remove Pre FX.
     * If this is a Post FX Component it will only remove Post FX.
     *
     * To remove both at once use the `GameObject.clearFX` method instead.
     *
     * @method Phaser.GameObjects.Components.FX#clear
     * @since 3.60.0
     *
     * @return {this} This Game Object instance.
     */
    clear: function ()
    {
        if (this.isPost)
        {
            this.gameObject.resetPostPipeline(true);
        }
        else
        {
            var list = this.list;

            for (var i = 0; i < list.length; i++)
            {
                list[i].destroy();
            }

            this.list = [];
        }

        this.enabled = false;

        return this.gameObject;
    },

    /**
     * Searches for the given FX Controller within this FX Component.
     *
     * If found, the controller is removed from this component and then destroyed.
     *
     * @method Phaser.GameObjects.Components.FX#remove
     * @since 3.60.0
     *
     * @generic {Phaser.FX.Controller} T
     * @genericUse {T} - [fx]
     *
     * @param {Phaser.FX.Controller} fx - The FX Controller to remove from this FX Component.
     *
     * @return {this} This Game Object instance.
     */
    remove: function (fx)
    {
        var i;

        if (this.isPost)
        {
            var pipelines = this.gameObject.getPostPipeline(String(fx.type));

            if (!Array.isArray(pipelines))
            {
                pipelines = [ pipelines ];
            }

            for (i = 0; i < pipelines.length; i++)
            {
                var pipeline = pipelines[i];

                if (pipeline.controller === fx)
                {
                    this.gameObject.removePostPipeline(pipeline);

                    fx.destroy();

                    break;
                }
            }
        }
        else
        {
            var list = this.list;

            for (i = 0; i < list.length; i++)
            {
                if (list[i] === fx)
                {
                    SpliceOne(list, i);

                    fx.destroy();
                }
            }
        }

        return this.gameObject;
    },

    /**
     * Disables this FX Component.
     *
     * This will reset the pipeline on the Game Object that owns this component back to its
     * default and flag this component as disabled.
     *
     * You can re-enable it again by calling `enable` for Pre FX or by adding an FX for Post FX.
     *
     * Optionally, set `clear` to destroy all current FX Controllers.
     *
     * @method Phaser.GameObjects.Components.FX#disable
     * @since 3.60.0
     *
     * @param {boolean} [clear=false] - Destroy and remove all FX Controllers that are part of this component.
     *
     * @return {this} This Game Object instance.
     */
    disable: function (clear)
    {
        if (clear === undefined) { clear = false; }

        if (!this.isPost)
        {
            this.gameObject.resetPipeline();
        }

        this.enabled = false;

        if (clear)
        {
            this.clear();
        }

        return this.gameObject;
    },

    /**
     * Adds the given FX Controler to this FX Component.
     *
     * Note that adding an FX Controller does not remove any existing FX. They all stack-up
     * on-top of each other. If you don't want this, make sure to call either `remove` or
     * `clear` first.
     *
     * @method Phaser.GameObjects.Components.FX#add
     * @since 3.60.0
     *
     * @generic {Phaser.FX.Controller} T
     * @genericUse {T} - [fx]
     *
     * @param {Phaser.FX.Controller} fx - The FX Controller to add to this FX Component.
     * @param {object} [config] - Optional configuration object that is passed to the pipeline during instantiation.
     *
     * @return {Phaser.FX.Controller} The FX Controller.
     */
    add: function (fx, config)
    {
        if (this.isPost)
        {
            var type = String(fx.type);

            this.gameObject.setPostPipeline(type, config);

            var pipeline = this.gameObject.getPostPipeline(type);

            if (pipeline)
            {
                if (Array.isArray(pipeline))
                {
                    pipeline = pipeline.pop();
                }

                pipeline.controller = fx;

                return fx;
            }
        }
        else
        {
            if (!this.enabled)
            {
                this.enable();
            }

            this.list.push(fx);

            return fx;
        }
    },

    /**
     * Adds a Glow effect.
     *
     * The glow effect is a visual technique that creates a soft, luminous halo around game objects,
     * characters, or UI elements. This effect is used to emphasize importance, enhance visual appeal,
     * or convey a sense of energy, magic, or otherworldly presence. The effect can also be set on
     * the inside of the Game Object. The color and strength of the glow can be modified.
     *
     * @method Phaser.GameObjects.Components.FX#addGlow
     * @since 3.60.0
     *
     * @param {number} [color=0xffffff] - The color of the glow effect as a number value.
     * @param {number} [outerStrength=4] - The strength of the glow outward from the edge of the Sprite.
     * @param {number} [innerStrength=0] - The strength of the glow inward from the edge of the Sprite.
     * @param {boolean} [knockout=false] - If `true` only the glow is drawn, not the texture itself.
     * @param {number} [quality=0.1] - Only available for PostFX. Sets the quality of this Glow effect. Default is 0.1. Cannot be changed post-creation.
     * @param {number} [distance=10] - Only available for PostFX. Sets the distance of this Glow effect. Default is 10. Cannot be changed post-creation.
     *
     * @return {Phaser.FX.Glow} The Glow FX Controller.
     */
    addGlow: function (color, outerStrength, innerStrength, knockout, quality, distance)
    {
        return this.add(new Effects.Glow(this.gameObject, color, outerStrength, innerStrength, knockout), { quality: quality, distance: distance });
    },

    /**
     * Adds a Shadow effect.
     *
     * The shadow effect is a visual technique used to create the illusion of depth and realism by adding darker,
     * offset silhouettes or shapes beneath game objects, characters, or environments. These simulated shadows
     * help to enhance the visual appeal and immersion, making the 2D game world appear more dynamic and three-dimensional.
     *
     * @method Phaser.GameObjects.Components.FX#addShadow
     * @since 3.60.0
     *
     * @param {number} [x=0] - The horizontal offset of the shadow effect.
     * @param {number} [y=0] - The vertical offset of the shadow effect.
     * @param {number} [decay=0.1] - The amount of decay for shadow effect.
     * @param {number} [power=1] - The power of the shadow effect.
     * @param {number} [color=0x000000] - The color of the shadow.
     * @param {number} [samples=6] - The number of samples that the shadow effect will run for. An integer between 1 and 12.
     * @param {number} [intensity=1] - The intensity of the shadow effect.
     *
     * @return {Phaser.FX.Shadow} The Shadow FX Controller.
     */
    addShadow: function (x, y, decay, power, color, samples, intensity)
    {
        return this.add(new Effects.Shadow(this.gameObject, x, y, decay, power, color, samples, intensity));
    },

    /**
     * Adds a Pixelate effect.
     *
     * The pixelate effect is a visual technique that deliberately reduces the resolution or detail of an image,
     * creating a blocky or mosaic appearance composed of large, visible pixels. This effect can be used for stylistic
     * purposes, as a homage to retro gaming, or as a means to obscure certain elements within the game, such as
     * during a transition or to censor specific content.
     *
     * @method Phaser.GameObjects.Components.FX#addPixelate
     * @since 3.60.0
     *
     * @param {number} [amount=1] - The amount of pixelation to apply.
     *
     * @return {Phaser.FX.Pixelate} The Pixelate FX Controller.
     */
    addPixelate: function (amount)
    {
        return this.add(new Effects.Pixelate(this.gameObject, amount));
    },

    /**
     * Adds a Vignette effect.
     *
     * The vignette effect is a visual technique where the edges of the screen, or a Game Object, gradually darken or blur,
     * creating a frame-like appearance. This effect is used to draw the player's focus towards the central action or subject,
     * enhance immersion, and provide a cinematic or artistic quality to the game's visuals.
     *
     * @method Phaser.GameObjects.Components.FX#addVignette
     * @since 3.60.0
     *
     * @param {number} [x=0.5] - The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1.
     * @param {number} [y=0.5] - The vertical offset of the vignette effect. This value is normalized to the range 0 to 1.
     * @param {number} [radius=0.5] - The radius of the vignette effect. This value is normalized to the range 0 to 1.
     * @param {number} [strength=0.5] - The strength of the vignette effect.
     *
     * @return {Phaser.FX.Vignette} The Vignette FX Controller.
     */
    addVignette: function (x, y, radius, strength)
    {
        return this.add(new Effects.Vignette(this.gameObject, x, y, radius, strength));
    },

    /**
     * Adds a Shine effect.
     *
     * The shine effect is a visual technique that simulates the appearance of reflective
     * or glossy surfaces by passing a light beam across a Game Object. This effect is used to
     * enhance visual appeal, emphasize certain features, and create a sense of depth or
     * material properties.
     *
     * @method Phaser.GameObjects.Components.FX#addShine
     * @since 3.60.0
     *
     * @param {number} [speed=0.5] - The speed of the Shine effect.
     * @param {number} [lineWidth=0.5] - The line width of the Shine effect.
     * @param {number} [gradient=3] - The gradient of the Shine effect.
     * @param {boolean} [reveal=false] - Does this Shine effect reveal or get added to its target?
     *
     * @return {Phaser.FX.Shine} The Shine FX Controller.
     */
    addShine: function (speed, lineWidth, gradient, reveal)
    {
        return this.add(new Effects.Shine(this.gameObject, speed, lineWidth, gradient, reveal));
    },

    /**
     * Adds a Blur effect.
     *
     * A Gaussian blur is the result of blurring an image by a Gaussian function. It is a widely used effect,
     * typically to reduce image noise and reduce detail. The visual effect of this blurring technique is a
     * smooth blur resembling that of viewing the image through a translucent screen, distinctly different
     * from the bokeh effect produced by an out-of-focus lens or the shadow of an object under usual illumination.
     *
     * @method Phaser.GameObjects.Components.FX#addBlur
     * @since 3.60.0
     *
     * @param {number} [quality=0] - The quality of the blur effect. Can be either 0 for Low Quality, 1 for Medium Quality or 2 for High Quality.
     * @param {number} [x=2] - The horizontal offset of the blur effect.
     * @param {number} [y=2] - The vertical offset of the blur effect.
     * @param {number} [strength=1] - The strength of the blur effect.
     * @param {number} [color=0xffffff] - The color of the blur, as a hex value.
     * @param {number} [steps=4] - The number of steps to run the blur effect for. This value should always be an integer.
     *
     * @return {Phaser.FX.Blur} The Blur FX Controller.
     */
    addBlur: function (quality, x, y, strength, color, steps)
    {
        return this.add(new Effects.Blur(this.gameObject, quality, x, y, strength, color, steps));
    },

    /**
     * Adds a Gradient effect.
     *
     * The gradient overlay effect is a visual technique where a smooth color transition is applied over Game Objects,
     * such as sprites or UI components. This effect is used to enhance visual appeal, emphasize depth, or create
     * stylistic and atmospheric variations. It can also be utilized to convey information, such as representing
     * progress or health status through color changes.
     *
     * @method Phaser.GameObjects.Components.FX#addGradient
     * @since 3.60.0
     *
     * @param {number} [color1=0xff0000] - The first gradient color, given as a number value.
     * @param {number} [color2=0x00ff00] - The second gradient color, given as a number value.
     * @param {number} [alpha=0.2] - The alpha value of the gradient effect.
     * @param {number} [fromX=0] - The horizontal position the gradient will start from. This value is normalized, between 0 and 1, and is not in pixels.
     * @param {number} [fromY=0] - The vertical position the gradient will start from. This value is normalized, between 0 and 1, and is not in pixels.
     * @param {number} [toX=0] - The horizontal position the gradient will end at. This value is normalized, between 0 and 1, and is not in pixels.
     * @param {number} [toY=1] - The vertical position the gradient will end at. This value is normalized, between 0 and 1, and is not in pixels.
     * @param {number} [size=0] - How many 'chunks' the gradient is divided in to, as spread over the entire height of the texture. Leave this at zero for a smooth gradient, or set higher for a more retro chunky effect.
     *
     * @return {Phaser.FX.Gradient} The Gradient FX Controller.
     */
    addGradient: function (color1, color2, alpha, fromX, fromY, toX, toY, size)
    {
        return this.add(new Effects.Gradient(this.gameObject, color1, color2, alpha, fromX, fromY, toX, toY, size));
    },

    /**
     * Adds a Bloom effect.
     *
     * Bloom is an effect used to reproduce an imaging artifact of real-world cameras.
     * The effect produces fringes of light extending from the borders of bright areas in an image,
     * contributing to the illusion of an extremely bright light overwhelming the
     * camera or eye capturing the scene.
     *
     * @method Phaser.GameObjects.Components.FX#addBloom
     * @since 3.60.0
     *
     * @param {number} [color] - The color of the Bloom, as a hex value.
     * @param {number} [offsetX=1] - The horizontal offset of the bloom effect.
     * @param {number} [offsetY=1] - The vertical offset of the bloom effect.
     * @param {number} [blurStrength=1] - The strength of the blur process of the bloom effect.
     * @param {number} [strength=1] - The strength of the blend process of the bloom effect.
     * @param {number} [steps=4] - The number of steps to run the Bloom effect for. This value should always be an integer.
     *
     * @return {Phaser.FX.Bloom} The Bloom FX Controller.
     */
    addBloom: function (color, offsetX, offsetY, blurStrength, strength, steps)
    {
        return this.add(new Effects.Bloom(this.gameObject, color, offsetX, offsetY, blurStrength, strength, steps));
    },

    /**
     * Adds a ColorMatrix effect.
     *
     * The color matrix effect is a visual technique that involves manipulating the colors of an image
     * or scene using a mathematical matrix. This process can adjust hue, saturation, brightness, and contrast,
     * allowing developers to create various stylistic appearances or mood settings within the game.
     * Common applications include simulating different lighting conditions, applying color filters,
     * or achieving a specific visual style.
     *
     * @method Phaser.GameObjects.Components.FX#addColorMatrix
     * @since 3.60.0
     *
     * @return {Phaser.FX.ColorMatrix} The ColorMatrix FX Controller.
     */
    addColorMatrix: function ()
    {
        return this.add(new Effects.ColorMatrix(this.gameObject));
    },

    /**
     * Adds a Circle effect.
     *
     * This effect will draw a circle around the texture of the Game Object, effectively masking off
     * any area outside of the circle without the need for an actual mask. You can control the thickness
     * of the circle, the color of the circle and the color of the background, should the texture be
     * transparent. You can also control the feathering applied to the circle, allowing for a harsh or soft edge.
     *
     * Please note that adding this effect to a Game Object will not change the input area or physics body of
     * the Game Object, should it have one.
     *
     * @method Phaser.GameObjects.Components.FX#addCircle
     * @since 3.60.0
     *
     * @param {number} [thickness=8] - The width of the circle around the texture, in pixels.
     * @param {number} [color=0xfeedb6] - The color of the circular ring, given as a number value.
     * @param {number} [backgroundColor=0xff0000] - The color of the background, behind the texture, given as a number value.
     * @param {number} [scale=1] - The scale of the circle. The default scale is 1, which is a circle the full size of the underlying texture.
     * @param {number} [feather=0.005] - The amount of feathering to apply to the circle from the ring.
     *
     * @return {Phaser.FX.Circle} The Circle FX Controller.
     */
    addCircle: function (thickness, color, backgroundColor, scale, feather)
    {
        return this.add(new Effects.Circle(this.gameObject, thickness, color, backgroundColor, scale, feather));
    },

    /**
     * Adds a Barrel effect.
     *
     * A barrel effect allows you to apply either a 'pinch' or 'expand' distortion to
     * a Game Object. The amount of the effect can be modified in real-time.
     *
     * @method Phaser.GameObjects.Components.FX#addBarrel
     * @since 3.60.0
     *
     * @param {number} [amount=1] - The amount of distortion applied to the barrel effect. A value of 1 is no distortion. Typically keep this within +- 1.
     *
     * @return {Phaser.FX.Barrel} The Barrel FX Controller.
     */
    addBarrel: function (amount)
    {
        return this.add(new Effects.Barrel(this.gameObject, amount));
    },

    /**
     * Adds a Displacement effect.
     *
     * The displacement effect is a visual technique that alters the position of pixels in an image
     * or texture based on the values of a displacement map. This effect is used to create the illusion
     * of depth, surface irregularities, or distortion in otherwise flat elements. It can be applied to
     * characters, objects, or backgrounds to enhance realism, convey movement, or achieve various
     * stylistic appearances.
     *
     * @method Phaser.GameObjects.Components.FX#addDisplacement
     * @since 3.60.0
     *
     * @param {string} [texture='__WHITE'] - The unique string-based key of the texture to use for displacement, which must exist in the Texture Manager.
     * @param {number} [x=0.005] - The amount of horizontal displacement to apply. A very small float number, such as 0.005.
     * @param {number} [y=0.005] - The amount of vertical displacement to apply. A very small float number, such as 0.005.
     *
     * @return {Phaser.FX.Displacement} The Displacement FX Controller.
     */
    addDisplacement: function (texture, x, y)
    {
        return this.add(new Effects.Displacement(this.gameObject, texture, x, y));
    },

    /**
     * Adds a Wipe effect.
     *
     * The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements
     * in the game, such as images, text, or scene transitions. This effect is often used to create
     * a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition
     * between game states.
     *
     * You can set both the direction and the axis of the wipe effect. The following combinations are possible:
     *
     * * left to right: direction 0, axis 0
     * * right to left: direction 1, axis 0
     * * top to bottom: direction 1, axis 1
     * * bottom to top: direction 1, axis 0
     *
     * It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect.
     *
     * @method Phaser.GameObjects.Components.FX#addWipe
     * @since 3.60.0
     *
     * @param {number} [wipeWidth=0.1] - The width of the wipe effect. This value is normalized in the range 0 to 1.
     * @param {number} [direction=0] - The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property.
     * @param {number} [axis=0] - The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property.
     *
     * @return {Phaser.FX.Wipe} The Wipe FX Controller.
     */
    addWipe: function (wipeWidth, direction, axis)
    {
        return this.add(new Effects.Wipe(this.gameObject, wipeWidth, direction, axis));
    },

    /**
     * Adds a Reveal Wipe effect.
     *
     * The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements
     * in the game, such as images, text, or scene transitions. This effect is often used to create
     * a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition
     * between game states.
     *
     * You can set both the direction and the axis of the wipe effect. The following combinations are possible:
     *
     * * left to right: direction 0, axis 0
     * * right to left: direction 1, axis 0
     * * top to bottom: direction 1, axis 1
     * * bottom to top: direction 1, axis 0
     *
     * It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect.
     *
     * @method Phaser.GameObjects.Components.FX#addReveal
     * @since 3.60.0
     *
     * @param {number} [wipeWidth=0.1] - The width of the wipe effect. This value is normalized in the range 0 to 1.
     * @param {number} [direction=0] - The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property.
     * @param {number} [axis=0] - The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property.
     *
     * @return {Phaser.FX.Wipe} The Wipe FX Controller.
     */
    addReveal: function (wipeWidth, direction, axis)
    {
        return this.add(new Effects.Wipe(this.gameObject, wipeWidth, direction, axis, true));
    },

    /**
     * Adds a Bokeh effect.
     *
     * Bokeh refers to a visual effect that mimics the photographic technique of creating a shallow depth of field.
     * This effect is used to emphasize the game's main subject or action, by blurring the background or foreground
     * elements, resulting in a more immersive and visually appealing experience. It is achieved through rendering
     * techniques that simulate the out-of-focus areas, giving a sense of depth and realism to the game's graphics.
     *
     * See also Tilt Shift.
     *
     * @method Phaser.GameObjects.Components.FX#addBokeh
     * @since 3.60.0
     *
     * @param {number} [radius=0.5] - The radius of the bokeh effect.
     * @param {number} [amount=1] - The amount of the bokeh effect.
     * @param {number} [contrast=0.2] - The color contrast of the bokeh effect.
     *
     * @return {Phaser.FX.Bokeh} The Bokeh FX Controller.
     */
    addBokeh: function (radius, amount, contrast)
    {
        return this.add(new Effects.Bokeh(this.gameObject, radius, amount, contrast));
    },

    /**
     * Adds a Tilt Shift effect.
     *
     * This Bokeh effect can also be used to generate a Tilt Shift effect, which is a technique used to create a miniature
     * effect by blurring everything except a small area of the image. This effect is achieved by blurring the
     * top and bottom elements, while keeping the center area in focus.
     *
     * See also Bokeh.
     *
     * @method Phaser.GameObjects.Components.FX#addTiltShift
     * @since 3.60.0
     *
     * @param {number} [radius=0.5] - The radius of the bokeh effect.
     * @param {number} [amount=1] - The amount of the bokeh effect.
     * @param {number} [contrast=0.2] - The color contrast of the bokeh effect.
     * @param {number} [blurX=1] - The amount of horizontal blur.
     * @param {number} [blurY=1] - The amount of vertical blur.
     * @param {number} [strength=1] - The strength of the blur.
     *
     * @return {Phaser.FX.Bokeh} The Bokeh TiltShift FX Controller.
     */
    addTiltShift: function (radius, amount, contrast, blurX, blurY, strength)
    {
        return this.add(new Effects.Bokeh(this.gameObject, radius, amount, contrast, true, blurX, blurY, strength));
    },

    /**
     * Destroys this FX Component.
     *
     * Called automatically when Game Objects are destroyed.
     *
     * @method Phaser.GameObjects.Components.FX#destroy
     * @since 3.60.0
     */
    destroy: function ()
    {
        this.clear();

        this.gameObject = null;
    }

});

module.exports = FX;


/***/ }),

/***/ 9660:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Provides methods used for visually flipping a Game Object.
 * Should be applied as a mixin and not used directly.
 *
 * @namespace Phaser.GameObjects.Components.Flip
 * @since 3.0.0
 */

var Flip = {

    /**
     * The horizontally flipped state of the Game Object.
     *
     * A Game Object that is flipped horizontally will render inversed on the horizontal axis.
     * Flipping always takes place from the middle of the texture and does not impact the scale value.
     * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
     *
     * @name Phaser.GameObjects.Components.Flip#flipX
     * @type {boolean}
     * @default false
     * @since 3.0.0
     */
    flipX: false,

    /**
     * The vertically flipped state of the Game Object.
     *
     * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down)
     * Flipping always takes place from the middle of the texture and does not impact the scale value.
     * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
     *
     * @name Phaser.GameObjects.Components.Flip#flipY
     * @type {boolean}
     * @default false
     * @since 3.0.0
     */
    flipY: false,

    /**
     * Toggles the horizontal flipped state of this Game Object.
     *
     * A Game Object that is flipped horizontally will render inversed on the horizontal axis.
     * Flipping always takes place from the middle of the texture and does not impact the scale value.
     * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
     *
     * @method Phaser.GameObjects.Components.Flip#toggleFlipX
     * @since 3.0.0
     *
     * @return {this} This Game Object instance.
     */
    toggleFlipX: function ()
    {
        this.flipX = !this.flipX;

        return this;
    },

    /**
     * Toggles the vertical flipped state of this Game Object.
     *
     * @method Phaser.GameObjects.Components.Flip#toggleFlipY
     * @since 3.0.0
     *
     * @return {this} This Game Object instance.
     */
    toggleFlipY: function ()
    {
        this.flipY = !this.flipY;

        return this;
    },

    /**
     * Sets the horizontal flipped state of this Game Object.
     *
     * A Game Object that is flipped horizontally will render inversed on the horizontal axis.
     * Flipping always takes place from the middle of the texture and does not impact the scale value.
     * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
     *
     * @method Phaser.GameObjects.Components.Flip#setFlipX
     * @since 3.0.0
     *
     * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped.
     *
     * @return {this} This Game Object instance.
     */
    setFlipX: function (value)
    {
        this.flipX = value;

        return this;
    },

    /**
     * Sets the vertical flipped state of this Game Object.
     *
     * @method Phaser.GameObjects.Components.Flip#setFlipY
     * @since 3.0.0
     *
     * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped.
     *
     * @return {this} This Game Object instance.
     */
    setFlipY: function (value)
    {
        this.flipY = value;

        return this;
    },

    /**
     * Sets the horizontal and vertical flipped state of this Game Object.
     *
     * A Game Object that is flipped will render inversed on the flipped axis.
     * Flipping always takes place from the middle of the texture and does not impact the scale value.
     * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
     *
     * @method Phaser.GameObjects.Components.Flip#setFlip
     * @since 3.0.0
     *
     * @param {boolean} x - The horizontal flipped state. `false` for no flip, or `true` to be flipped.
     * @param {boolean} y - The horizontal flipped state. `false` for no flip, or `true` to be flipped.
     *
     * @return {this} This Game Object instance.
     */
    setFlip: function (x, y)
    {
        this.flipX = x;
        this.flipY = y;

        return this;
    },

    /**
     * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state.
     *
     * @method Phaser.GameObjects.Components.Flip#resetFlip
     * @since 3.0.0
     *
     * @return {this} This Game Object instance.
     */
    resetFlip: function ()
    {
        this.flipX = false;
        this.flipY = false;

        return this;
    }

};

module.exports = Flip;


/***/ }),

/***/ 3671:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Rectangle = __webpack_require__(1392);
var RotateAround = __webpack_require__(9876);
var Vector2 = __webpack_require__(2529);

/**
 * Provides methods used for obtaining the bounds of a Game Object.
 * Should be applied as a mixin and not used directly.
 *
 * @namespace Phaser.GameObjects.Components.GetBounds
 * @since 3.0.0
 */

var GetBounds = {

    /**
     * Processes the bounds output vector before returning it.
     *
     * @method Phaser.GameObjects.Components.GetBounds#prepareBoundsOutput
     * @private
     * @since 3.18.0
     *
     * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
     *
     * @param {Phaser.Types.Math.Vector2Like} output - An object to store the values in. If not provided a new Vector2 will be created.
     * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
     *
     * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
     */
    prepareBoundsOutput: function (output, includeParent)
    {
        if (includeParent === undefined) { includeParent = false; }

        if (this.rotation !== 0)
        {
            RotateAround(output, this.x, this.y, this.rotation);
        }

        if (includeParent && this.parentContainer)
        {
            var parentMatrix = this.parentContainer.getBoundsTransformMatrix();

            parentMatrix.transformPoint(output.x, output.y, output);
        }

        return output;
    },

    /**
     * Gets the center coordinate of this Game Object, regardless of origin.
     *
     * The returned point is calculated in local space and does not factor in any parent Containers,
     * unless the `includeParent` argument is set to `true`.
     *
     * @method Phaser.GameObjects.Components.GetBounds#getCenter
     * @since 3.0.0
     *
     * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
     *
     * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
     * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
     *
     * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
     */
    getCenter: function (output, includeParent)
    {
        if (output === undefined) { output = new Vector2(); }

        output.x = this.x - (this.displayWidth * this.originX) + (this.displayWidth / 2);
        output.y = this.y - (this.displayHeight * this.originY) + (this.displayHeight / 2);

        return this.prepareBoundsOutput(output, includeParent);
    },

    /**
     * Gets the top-left corner coordinate of this Game Object, regardless of origin.
     *
     * The returned point is calculated in local space and does not factor in any parent Containers,
     * unless the `includeParent` argument is set to `true`.
     *
     * @method Phaser.GameObjects.Components.GetBounds#getTopLeft
     * @since 3.0.0
     *
     * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
     *
     * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
     * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
     *
     * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
     */
    getTopLeft: function (output, includeParent)
    {
        if (!output) { output = new Vector2(); }

        output.x = this.x - (this.displayWidth * this.originX);
        output.y = this.y - (this.displayHeight * this.originY);

        return this.prepareBoundsOutput(output, includeParent);
    },

    /**
     * Gets the top-center coordinate of this Game Object, regardless of origin.
     *
     * The returned point is calculated in local space and does not factor in any parent Containers,
     * unless the `includeParent` argument is set to `true`.
     *
     * @method Phaser.GameObjects.Components.GetBounds#getTopCenter
     * @since 3.18.0
     *
     * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
     *
     * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
     * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
     *
     * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
     */
    getTopCenter: function (output, includeParent)
    {
        if (!output) { output = new Vector2(); }

        output.x = (this.x - (this.displayWidth * this.originX)) + (this.displayWidth / 2);
        output.y = this.y - (this.displayHeight * this.originY);

        return this.prepareBoundsOutput(output, includeParent);
    },

    /**
     * Gets the top-right corner coordinate of this Game Object, regardless of origin.
     *
     * The returned point is calculated in local space and does not factor in any parent Containers,
     * unless the `includeParent` argument is set to `true`.
     *
     * @method Phaser.GameObjects.Components.GetBounds#getTopRight
     * @since 3.0.0
     *
     * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
     *
     * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
     * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
     *
     * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
     */
    getTopRight: function (output, includeParent)
    {
        if (!output) { output = new Vector2(); }

        output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth;
        output.y = this.y - (this.displayHeight * this.originY);

        return this.prepareBoundsOutput(output, includeParent);
    },

    /**
     * Gets the left-center coordinate of this Game Object, regardless of origin.
     *
     * The returned point is calculated in local space and does not factor in any parent Containers,
     * unless the `includeParent` argument is set to `true`.
     *
     * @method Phaser.GameObjects.Components.GetBounds#getLeftCenter
     * @since 3.18.0
     *
     * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
     *
     * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
     * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
     *
     * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
     */
    getLeftCenter: function (output, includeParent)
    {
        if (!output) { output = new Vector2(); }

        output.x = this.x - (this.displayWidth * this.originX);
        output.y = (this.y - (this.displayHeight * this.originY)) + (this.displayHeight / 2);

        return this.prepareBoundsOutput(output, includeParent);
    },

    /**
     * Gets the right-center coordinate of this Game Object, regardless of origin.
     *
     * The returned point is calculated in local space and does not factor in any parent Containers,
     * unless the `includeParent` argument is set to `true`.
     *
     * @method Phaser.GameObjects.Components.GetBounds#getRightCenter
     * @since 3.18.0
     *
     * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
     *
     * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
     * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
     *
     * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
     */
    getRightCenter: function (output, includeParent)
    {
        if (!output) { output = new Vector2(); }

        output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth;
        output.y = (this.y - (this.displayHeight * this.originY)) + (this.displayHeight / 2);

        return this.prepareBoundsOutput(output, includeParent);
    },

    /**
     * Gets the bottom-left corner coordinate of this Game Object, regardless of origin.
     *
     * The returned point is calculated in local space and does not factor in any parent Containers,
     * unless the `includeParent` argument is set to `true`.
     *
     * @method Phaser.GameObjects.Components.GetBounds#getBottomLeft
     * @since 3.0.0
     *
     * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
     *
     * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
     * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
     *
     * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
     */
    getBottomLeft: function (output, includeParent)
    {
        if (!output) { output = new Vector2(); }

        output.x = this.x - (this.displayWidth * this.originX);
        output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight;

        return this.prepareBoundsOutput(output, includeParent);
    },

    /**
     * Gets the bottom-center coordinate of this Game Object, regardless of origin.
     *
     * The returned point is calculated in local space and does not factor in any parent Containers,
     * unless the `includeParent` argument is set to `true`.
     *
     * @method Phaser.GameObjects.Components.GetBounds#getBottomCenter
     * @since 3.18.0
     *
     * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
     *
     * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
     * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
     *
     * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
     */
    getBottomCenter: function (output, includeParent)
    {
        if (!output) { output = new Vector2(); }

        output.x = (this.x - (this.displayWidth * this.originX)) + (this.displayWidth / 2);
        output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight;

        return this.prepareBoundsOutput(output, includeParent);
    },

    /**
     * Gets the bottom-right corner coordinate of this Game Object, regardless of origin.
     *
     * The returned point is calculated in local space and does not factor in any parent Containers,
     * unless the `includeParent` argument is set to `true`.
     *
     * @method Phaser.GameObjects.Components.GetBounds#getBottomRight
     * @since 3.0.0
     *
     * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
     *
     * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
     * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
     *
     * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
     */
    getBottomRight: function (output, includeParent)
    {
        if (!output) { output = new Vector2(); }

        output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth;
        output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight;

        return this.prepareBoundsOutput(output, includeParent);
    },

    /**
     * Gets the bounds of this Game Object, regardless of origin.
     *
     * The values are stored and returned in a Rectangle, or Rectangle-like, object.
     *
     * @method Phaser.GameObjects.Components.GetBounds#getBounds
     * @since 3.0.0
     *
     * @generic {Phaser.Geom.Rectangle} O - [output,$return]
     *
     * @param {(Phaser.Geom.Rectangle|object)} [output] - An object to store the values in. If not provided a new Rectangle will be created.
     *
     * @return {(Phaser.Geom.Rectangle|object)} The values stored in the output object.
     */
    getBounds: function (output)
    {
        if (output === undefined) { output = new Rectangle(); }

        //  We can use the output object to temporarily store the x/y coords in:

        var TLx, TLy, TRx, TRy, BLx, BLy, BRx, BRy;

        // Instead of doing a check if parent container is
        // defined per corner we only do it once.
        if (this.parentContainer)
        {
            var parentMatrix = this.parentContainer.getBoundsTransformMatrix();

            this.getTopLeft(output);
            parentMatrix.transformPoint(output.x, output.y, output);

            TLx = output.x;
            TLy = output.y;

            this.getTopRight(output);
            parentMatrix.transformPoint(output.x, output.y, output);

            TRx = output.x;
            TRy = output.y;

            this.getBottomLeft(output);
            parentMatrix.transformPoint(output.x, output.y, output);

            BLx = output.x;
            BLy = output.y;

            this.getBottomRight(output);
            parentMatrix.transformPoint(output.x, output.y, output);

            BRx = output.x;
            BRy = output.y;
        }
        else
        {
            this.getTopLeft(output);

            TLx = output.x;
            TLy = output.y;

            this.getTopRight(output);

            TRx = output.x;
            TRy = output.y;

            this.getBottomLeft(output);

            BLx = output.x;
            BLy = output.y;

            this.getBottomRight(output);

            BRx = output.x;
            BRy = output.y;
        }

        output.x = Math.min(TLx, TRx, BLx, BRx);
        output.y = Math.min(TLy, TRy, BLy, BRy);
        output.width = Math.max(TLx, TRx, BLx, BRx) - output.x;
        output.height = Math.max(TLy, TRy, BLy, BRy) - output.y;

        return output;
    }

};

module.exports = GetBounds;


/***/ }),

/***/ 2246:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var BitmapMask = __webpack_require__(7499);
var GeometryMask = __webpack_require__(6726);

/**
 * Provides methods used for getting and setting the mask of a Game Object.
 *
 * @namespace Phaser.GameObjects.Components.Mask
 * @since 3.0.0
 */

var Mask = {

    /**
     * The Mask this Game Object is using during render.
     *
     * @name Phaser.GameObjects.Components.Mask#mask
     * @type {Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask}
     * @since 3.0.0
     */
    mask: null,

    /**
     * Sets the mask that this Game Object will use to render with.
     *
     * The mask must have been previously created and can be either a GeometryMask or a BitmapMask.
     * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas.
     *
     * If a mask is already set on this Game Object it will be immediately replaced.
     *
     * Masks are positioned in global space and are not relative to the Game Object to which they
     * are applied. The reason for this is that multiple Game Objects can all share the same mask.
     *
     * Masks have no impact on physics or input detection. They are purely a rendering component
     * that allows you to limit what is visible during the render pass.
     *
     * @method Phaser.GameObjects.Components.Mask#setMask
     * @since 3.6.2
     *
     * @param {Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask} mask - The mask this Game Object will use when rendering.
     *
     * @return {this} This Game Object instance.
     */
    setMask: function (mask)
    {
        this.mask = mask;

        return this;
    },

    /**
     * Clears the mask that this Game Object was using.
     *
     * @method Phaser.GameObjects.Components.Mask#clearMask
     * @since 3.6.2
     *
     * @param {boolean} [destroyMask=false] - Destroy the mask before clearing it?
     *
     * @return {this} This Game Object instance.
     */
    clearMask: function (destroyMask)
    {
        if (destroyMask === undefined) { destroyMask = false; }

        if (destroyMask && this.mask)
        {
            this.mask.destroy();
        }

        this.mask = null;

        return this;
    },

    /**
     * Creates and returns a Bitmap Mask. This mask can be used by any Game Object,
     * including this one, or a Dynamic Texture.
     *
     * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas.
     *
     * To create the mask you need to pass in a reference to a renderable Game Object.
     * A renderable Game Object is one that uses a texture to render with, such as an
     * Image, Sprite, Render Texture or BitmapText.
     *
     * If you do not provide a renderable object, and this Game Object has a texture,
     * it will use itself as the object. This means you can call this method to create
     * a Bitmap Mask from any renderable texture-based Game Object.
     *
     * @method Phaser.GameObjects.Components.Mask#createBitmapMask
     * @since 3.6.2
     *
     * @generic {Phaser.GameObjects.GameObject} G
     * @generic {Phaser.Textures.DynamicTexture} T
     * @genericUse {(G|T|null)} [maskObject]
     *
     * @param {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)} [maskObject] - The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments.
     * @param {number} [x] - If creating a Game Object, the horizontal position in the world.
     * @param {number} [y] - If creating a Game Object, the vertical position in the world.
     * @param {(string|Phaser.Textures.Texture)} [texture] - If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager.
     * @param {(string|number|Phaser.Textures.Frame)} [frame] - If creating a Game Object, an optional frame from the Texture this Game Object is rendering with.
     *
     * @return {Phaser.Display.Masks.BitmapMask} This Bitmap Mask that was created.
     */
    createBitmapMask: function (maskObject, x, y, texture, frame)
    {
        if (maskObject === undefined && (this.texture || this.shader || this.geom))
        {
            // eslint-disable-next-line consistent-this
            maskObject = this;
        }

        return new BitmapMask(this.scene, maskObject, x, y, texture, frame);
    },

    /**
     * Creates and returns a Geometry Mask. This mask can be used by any Game Object,
     * including this one.
     *
     * To create the mask you need to pass in a reference to a Graphics Game Object.
     *
     * If you do not provide a graphics object, and this Game Object is an instance
     * of a Graphics object, then it will use itself to create the mask.
     *
     * This means you can call this method to create a Geometry Mask from any Graphics Game Object.
     *
     * @method Phaser.GameObjects.Components.Mask#createGeometryMask
     * @since 3.6.2
     *
     * @generic {Phaser.GameObjects.Graphics} G
     * @generic {Phaser.GameObjects.Shape} S
     * @genericUse {(G|S)} [graphics]
     *
     * @param {Phaser.GameObjects.Graphics|Phaser.GameObjects.Shape} [graphics] - A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask.
     *
     * @return {Phaser.Display.Masks.GeometryMask} This Geometry Mask that was created.
     */
    createGeometryMask: function (graphics)
    {
        if (graphics === undefined && (this.type === 'Graphics' || this.geom))
        {
            // eslint-disable-next-line consistent-this
            graphics = this;
        }

        return new GeometryMask(this.scene, graphics);
    }

};

module.exports = Mask;


/***/ }),

/***/ 5085:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Provides methods used for getting and setting the origin of a Game Object.
 * Values are normalized, given in the range 0 to 1.
 * Display values contain the calculated pixel values.
 * Should be applied as a mixin and not used directly.
 *
 * @namespace Phaser.GameObjects.Components.Origin
 * @since 3.0.0
 */

var Origin = {

    /**
     * A property indicating that a Game Object has this component.
     *
     * @name Phaser.GameObjects.Components.Origin#_originComponent
     * @type {boolean}
     * @private
     * @default true
     * @since 3.2.0
     */
    _originComponent: true,

    /**
     * The horizontal origin of this Game Object.
     * The origin maps the relationship between the size and position of the Game Object.
     * The default value is 0.5, meaning all Game Objects are positioned based on their center.
     * Setting the value to 0 means the position now relates to the left of the Game Object.
     * Set this value with `setOrigin()`.
     *
     * @name Phaser.GameObjects.Components.Origin#originX
     * @type {number}
     * @readonly
     * @default 0.5
     * @since 3.0.0
     */
    originX: 0.5,

    /**
     * The vertical origin of this Game Object.
     * The origin maps the relationship between the size and position of the Game Object.
     * The default value is 0.5, meaning all Game Objects are positioned based on their center.
     * Setting the value to 0 means the position now relates to the top of the Game Object.
     * Set this value with `setOrigin()`.
     *
     * @name Phaser.GameObjects.Components.Origin#originY
     * @type {number}
     * @readonly
     * @default 0.5
     * @since 3.0.0
     */
    originY: 0.5,

    //  private + read only
    _displayOriginX: 0,
    _displayOriginY: 0,

    /**
     * The horizontal display origin of this Game Object.
     * The origin is a normalized value between 0 and 1.
     * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin.
     *
     * @name Phaser.GameObjects.Components.Origin#displayOriginX
     * @type {number}
     * @since 3.0.0
     */
    displayOriginX: {

        get: function ()
        {
            return this._displayOriginX;
        },

        set: function (value)
        {
            this._displayOriginX = value;
            this.originX = value / this.width;
        }

    },

    /**
     * The vertical display origin of this Game Object.
     * The origin is a normalized value between 0 and 1.
     * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin.
     *
     * @name Phaser.GameObjects.Components.Origin#displayOriginY
     * @type {number}
     * @since 3.0.0
     */
    displayOriginY: {

        get: function ()
        {
            return this._displayOriginY;
        },

        set: function (value)
        {
            this._displayOriginY = value;
            this.originY = value / this.height;
        }

    },

    /**
     * Sets the origin of this Game Object.
     *
     * The values are given in the range 0 to 1.
     *
     * @method Phaser.GameObjects.Components.Origin#setOrigin
     * @since 3.0.0
     *
     * @param {number} [x=0.5] - The horizontal origin value.
     * @param {number} [y=x] - The vertical origin value. If not defined it will be set to the value of `x`.
     *
     * @return {this} This Game Object instance.
     */
    setOrigin: function (x, y)
    {
        if (x === undefined) { x = 0.5; }
        if (y === undefined) { y = x; }

        this.originX = x;
        this.originY = y;

        return this.updateDisplayOrigin();
    },

    /**
     * Sets the origin of this Game Object based on the Pivot values in its Frame.
     *
     * @method Phaser.GameObjects.Components.Origin#setOriginFromFrame
     * @since 3.0.0
     *
     * @return {this} This Game Object instance.
     */
    setOriginFromFrame: function ()
    {
        if (!this.frame || !this.frame.customPivot)
        {
            return this.setOrigin();
        }
        else
        {
            this.originX = this.frame.pivotX;
            this.originY = this.frame.pivotY;
        }

        return this.updateDisplayOrigin();
    },

    /**
     * Sets the display origin of this Game Object.
     * The difference between this and setting the origin is that you can use pixel values for setting the display origin.
     *
     * @method Phaser.GameObjects.Components.Origin#setDisplayOrigin
     * @since 3.0.0
     *
     * @param {number} [x=0] - The horizontal display origin value.
     * @param {number} [y=x] - The vertical display origin value. If not defined it will be set to the value of `x`.
     *
     * @return {this} This Game Object instance.
     */
    setDisplayOrigin: function (x, y)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = x; }

        this.displayOriginX = x;
        this.displayOriginY = y;

        return this;
    },

    /**
     * Updates the Display Origin cached values internally stored on this Game Object.
     * You don't usually call this directly, but it is exposed for edge-cases where you may.
     *
     * @method Phaser.GameObjects.Components.Origin#updateDisplayOrigin
     * @since 3.0.0
     *
     * @return {this} This Game Object instance.
     */
    updateDisplayOrigin: function ()
    {
        this._displayOriginX = this.originX * this.width;
        this._displayOriginY = this.originY * this.height;

        return this;
    }

};

module.exports = Origin;


/***/ }),

/***/ 77:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var DegToRad = __webpack_require__(7149);
var GetBoolean = __webpack_require__(1864);
var GetValue = __webpack_require__(5851);
var TWEEN_CONST = __webpack_require__(3747);
var Vector2 = __webpack_require__(2529);

/**
 * Provides methods used for managing a Game Object following a Path.
 * Should be applied as a mixin and not used directly.
 *
 * @namespace Phaser.GameObjects.Components.PathFollower
 * @since 3.17.0
 */

var PathFollower = {

    /**
     * The Path this PathFollower is following. It can only follow one Path at a time.
     *
     * @name Phaser.GameObjects.Components.PathFollower#path
     * @type {Phaser.Curves.Path}
     * @since 3.0.0
     */
    path: null,

    /**
     * Should the PathFollower automatically rotate to point in the direction of the Path?
     *
     * @name Phaser.GameObjects.Components.PathFollower#rotateToPath
     * @type {boolean}
     * @default false
     * @since 3.0.0
     */
    rotateToPath: false,

    /**
     * If the PathFollower is rotating to match the Path (@see Phaser.GameObjects.PathFollower#rotateToPath)
     * this value is added to the rotation value. This allows you to rotate objects to a path but control
     * the angle of the rotation as well.
     *
     * @name Phaser.GameObjects.PathFollower#pathRotationOffset
     * @type {number}
     * @default 0
     * @since 3.0.0
     */
    pathRotationOffset: 0,

    /**
     * An additional vector to add to the PathFollowers position, allowing you to offset it from the
     * Path coordinates.
     *
     * @name Phaser.GameObjects.PathFollower#pathOffset
     * @type {Phaser.Math.Vector2}
     * @since 3.0.0
     */
    pathOffset: null,

    /**
     * A Vector2 that stores the current point of the path the follower is on.
     *
     * @name Phaser.GameObjects.PathFollower#pathVector
     * @type {Phaser.Math.Vector2}
     * @since 3.0.0
     */
    pathVector: null,

    /**
     * The distance the follower has traveled from the previous point to the current one, at the last update.
     *
     * @name Phaser.GameObjects.PathFollower#pathDelta
     * @type {Phaser.Math.Vector2}
     * @since 3.23.0
     */
    pathDelta: null,

    /**
     * The Tween used for following the Path.
     *
     * @name Phaser.GameObjects.PathFollower#pathTween
     * @type {Phaser.Tweens.Tween}
     * @since 3.0.0
     */
    pathTween: null,

    /**
     * Settings for the PathFollower.
     *
     * @name Phaser.GameObjects.PathFollower#pathConfig
     * @type {?Phaser.Types.GameObjects.PathFollower.PathConfig}
     * @default null
     * @since 3.0.0
     */
    pathConfig: null,

    /**
     * Records the direction of the follower so it can change direction.
     *
     * @name Phaser.GameObjects.PathFollower#_prevDirection
     * @type {number}
     * @private
     * @since 3.0.0
     */
    _prevDirection: TWEEN_CONST.PLAYING_FORWARD,

    /**
     * Set the Path that this PathFollower should follow.
     *
     * Optionally accepts {@link Phaser.Types.GameObjects.PathFollower.PathConfig} settings.
     *
     * @method Phaser.GameObjects.Components.PathFollower#setPath
     * @since 3.0.0
     *
     * @param {Phaser.Curves.Path} path - The Path this PathFollower is following. It can only follow one Path at a time.
     * @param {(number|Phaser.Types.GameObjects.PathFollower.PathConfig|Phaser.Types.Tweens.NumberTweenBuilderConfig)} [config] - Settings for the PathFollower.
     *
     * @return {this} This Game Object.
     */
    setPath: function (path, config)
    {
        if (config === undefined) { config = this.pathConfig; }

        var tween = this.pathTween;

        if (tween && tween.isPlaying())
        {
            tween.stop();
        }

        this.path = path;

        if (config)
        {
            this.startFollow(config);
        }

        return this;
    },

    /**
     * Set whether the PathFollower should automatically rotate to point in the direction of the Path.
     *
     * @method Phaser.GameObjects.Components.PathFollower#setRotateToPath
     * @since 3.0.0
     *
     * @param {boolean} value - Whether the PathFollower should automatically rotate to point in the direction of the Path.
     * @param {number} [offset=0] - Rotation offset in degrees.
     *
     * @return {this} This Game Object.
     */
    setRotateToPath: function (value, offset)
    {
        if (offset === undefined) { offset = 0; }

        this.rotateToPath = value;

        this.pathRotationOffset = offset;

        return this;
    },

    /**
     * Is this PathFollower actively following a Path or not?
     *
     * To be considered as `isFollowing` it must be currently moving on a Path, and not paused.
     *
     * @method Phaser.GameObjects.Components.PathFollower#isFollowing
     * @since 3.0.0
     *
     * @return {boolean} `true` is this PathFollower is actively following a Path, otherwise `false`.
     */
    isFollowing: function ()
    {
        var tween = this.pathTween;

        return (tween && tween.isPlaying());
    },

    /**
     * Starts this PathFollower following its given Path.
     *
     * @method Phaser.GameObjects.Components.PathFollower#startFollow
     * @since 3.3.0
     *
     * @param {(number|Phaser.Types.GameObjects.PathFollower.PathConfig|Phaser.Types.Tweens.NumberTweenBuilderConfig)} [config={}] - The duration of the follow, or a PathFollower config object.
     * @param {number} [startAt=0] - Optional start position of the follow, between 0 and 1.
     *
     * @return {this} This Game Object.
     */
    startFollow: function (config, startAt)
    {
        if (config === undefined) { config = {}; }
        if (startAt === undefined) { startAt = 0; }

        var tween = this.pathTween;

        if (tween && tween.isPlaying())
        {
            tween.stop();
        }

        if (typeof config === 'number')
        {
            config = { duration: config };
        }

        //  Override in case they've been specified in the config
        config.from = GetValue(config, 'from', 0);
        config.to = GetValue(config, 'to', 1);

        var positionOnPath = GetBoolean(config, 'positionOnPath', false);

        this.rotateToPath = GetBoolean(config, 'rotateToPath', false);
        this.pathRotationOffset = GetValue(config, 'rotationOffset', 0);

        //  This works, but it's not an ideal way of doing it as the follower jumps position
        var seek = GetValue(config, 'startAt', startAt);

        if (seek)
        {
            config.onStart = function (tween)
            {
                var tweenData = tween.data[0];
                tweenData.progress = seek;
                tweenData.elapsed = tweenData.duration * seek;
                var v = tweenData.ease(tweenData.progress);
                tweenData.current = tweenData.start + ((tweenData.end - tweenData.start) * v);
                tweenData.setTargetValue();
            };
        }

        if (!this.pathOffset)
        {
            this.pathOffset = new Vector2(this.x, this.y);
        }

        if (!this.pathVector)
        {
            this.pathVector = new Vector2();
        }

        if (!this.pathDelta)
        {
            this.pathDelta = new Vector2();
        }

        this.pathDelta.reset();

        config.persist = true;

        this.pathTween = this.scene.sys.tweens.addCounter(config);

        //  The starting point of the path, relative to this follower
        this.path.getStartPoint(this.pathOffset);

        if (positionOnPath)
        {
            this.x = this.pathOffset.x;
            this.y = this.pathOffset.y;
        }

        this.pathOffset.x = this.x - this.pathOffset.x;
        this.pathOffset.y = this.y - this.pathOffset.y;

        this._prevDirection = TWEEN_CONST.PLAYING_FORWARD;

        if (this.rotateToPath)
        {
            //  Set the rotation now (in case the tween has a delay on it, etc)
            var nextPoint = this.path.getPoint(0.1);

            this.rotation = Math.atan2(nextPoint.y - this.y, nextPoint.x - this.x) + DegToRad(this.pathRotationOffset);
        }

        this.pathConfig = config;

        return this;
    },

    /**
     * Pauses this PathFollower. It will still continue to render, but it will remain motionless at the
     * point on the Path at which you paused it.
     *
     * @method Phaser.GameObjects.Components.PathFollower#pauseFollow
     * @since 3.3.0
     *
     * @return {this} This Game Object.
     */
    pauseFollow: function ()
    {
        var tween = this.pathTween;

        if (tween && tween.isPlaying())
        {
            tween.pause();
        }

        return this;
    },

    /**
     * Resumes a previously paused PathFollower.
     *
     * If the PathFollower was not paused this has no effect.
     *
     * @method Phaser.GameObjects.Components.PathFollower#resumeFollow
     * @since 3.3.0
     *
     * @return {this} This Game Object.
     */
    resumeFollow: function ()
    {
        var tween = this.pathTween;

        if (tween && tween.isPaused())
        {
            tween.resume();
        }

        return this;
    },

    /**
     * Stops this PathFollower from following the path any longer.
     *
     * This will invoke any 'stop' conditions that may exist on the Path, or for the follower.
     *
     * @method Phaser.GameObjects.Components.PathFollower#stopFollow
     * @since 3.3.0
     *
     * @return {this} This Game Object.
     */
    stopFollow: function ()
    {
        var tween = this.pathTween;

        if (tween && tween.isPlaying())
        {
            tween.stop();
        }

        return this;
    },

    /**
     * Internal update handler that advances this PathFollower along the path.
     *
     * Called automatically by the Scene step, should not typically be called directly.
     *
     * @method Phaser.GameObjects.Components.PathFollower#pathUpdate
     * @since 3.17.0
     */
    pathUpdate: function ()
    {
        var tween = this.pathTween;

        if (tween && tween.data)
        {
            var tweenData = tween.data[0];
            var pathDelta = this.pathDelta;
            var pathVector = this.pathVector;

            pathDelta.copy(pathVector).negate();

            if (tweenData.state === TWEEN_CONST.COMPLETE)
            {
                this.path.getPoint(tweenData.end, pathVector);

                pathDelta.add(pathVector);
                pathVector.add(this.pathOffset);

                this.setPosition(pathVector.x, pathVector.y);

                return;
            }
            else if (tweenData.state !== TWEEN_CONST.PLAYING_FORWARD && tweenData.state !== TWEEN_CONST.PLAYING_BACKWARD)
            {
                //  If delayed, etc then bail out
                return;
            }

            this.path.getPoint(tween.getValue(), pathVector);

            pathDelta.add(pathVector);
            pathVector.add(this.pathOffset);

            var oldX = this.x;
            var oldY = this.y;

            this.setPosition(pathVector.x, pathVector.y);

            var speedX = this.x - oldX;
            var speedY = this.y - oldY;

            if (speedX === 0 && speedY === 0)
            {
                //  Bail out early
                return;
            }

            if (tweenData.state !== this._prevDirection)
            {
                //  We've changed direction, so don't do a rotate this frame
                this._prevDirection = tweenData.state;

                return;
            }

            if (this.rotateToPath)
            {
                this.rotation = Math.atan2(speedY, speedX) + DegToRad(this.pathRotationOffset);
            }
        }
    }

};

module.exports = PathFollower;


/***/ }),

/***/ 986:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var DeepCopy = __webpack_require__(3911);

/**
 * Provides methods used for setting the WebGL rendering pipeline of a Game Object.
 *
 * @namespace Phaser.GameObjects.Components.Pipeline
 * @webglOnly
 * @since 3.0.0
 */

var Pipeline = {

    /**
     * The initial WebGL pipeline of this Game Object.
     *
     * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default.
     *
     * @name Phaser.GameObjects.Components.Pipeline#defaultPipeline
     * @type {Phaser.Renderer.WebGL.WebGLPipeline}
     * @default null
     * @webglOnly
     * @since 3.0.0
     */
    defaultPipeline: null,

    /**
     * The current WebGL pipeline of this Game Object.
     *
     * @name Phaser.GameObjects.Components.Pipeline#pipeline
     * @type {Phaser.Renderer.WebGL.WebGLPipeline}
     * @default null
     * @webglOnly
     * @since 3.0.0
     */
    pipeline: null,

    /**
     * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses.
     *
     * @name Phaser.GameObjects.Components.Pipeline#pipelineData
     * @type {object}
     * @webglOnly
     * @since 3.50.0
     */
    pipelineData: null,

    /**
     * Sets the initial WebGL Pipeline of this Game Object.
     *
     * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`.
     *
     * @method Phaser.GameObjects.Components.Pipeline#initPipeline
     * @webglOnly
     * @since 3.0.0
     *
     * @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} [pipeline] - Either the string-based name of the pipeline, or a pipeline instance to set.
     *
     * @return {boolean} `true` if the pipeline was set successfully, otherwise `false`.
     */
    initPipeline: function (pipeline)
    {
        this.pipelineData = {};

        var renderer = this.scene.sys.renderer;

        if (!renderer)
        {
            return false;
        }

        var pipelines = renderer.pipelines;

        if (pipelines)
        {
            if (pipeline === undefined)
            {
                pipeline = pipelines.default;
            }

            var instance = pipelines.get(pipeline);

            if (instance)
            {
                this.defaultPipeline = instance;
                this.pipeline = instance;

                return true;
            }
        }

        return false;
    },

    /**
     * Sets the main WebGL Pipeline of this Game Object.
     *
     * Also sets the `pipelineData` property, if the parameter is given.
     *
     * @method Phaser.GameObjects.Components.Pipeline#setPipeline
     * @webglOnly
     * @since 3.0.0
     *
     * @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline, or a pipeline instance to set.
     * @param {object} [pipelineData] - Optional pipeline data object that is set in to the `pipelineData` property of this Game Object.
     * @param {boolean} [copyData=true] - Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead.
     *
     * @return {this} This Game Object instance.
     */
    setPipeline: function (pipeline, pipelineData, copyData)
    {
        var renderer = this.scene.sys.renderer;

        if (!renderer)
        {
            return this;
        }

        var pipelines = renderer.pipelines;

        if (pipelines)
        {
            var instance = pipelines.get(pipeline);

            if (instance)
            {
                this.pipeline = instance;
            }

            if (pipelineData)
            {
                this.pipelineData = (copyData) ? DeepCopy(pipelineData) : pipelineData;
            }
        }

        return this;
    },

    /**
     * Adds an entry to the `pipelineData` object belonging to this Game Object.
     *
     * If the 'key' already exists, its value is updated. If it doesn't exist, it is created.
     *
     * If `value` is undefined, and `key` exists, `key` is removed from the data object.
     *
     * @method Phaser.GameObjects.Components.Pipeline#setPipelineData
     * @webglOnly
     * @since 3.50.0
     *
     * @param {string} key - The key of the pipeline data to set, update, or delete.
     * @param {any} [value] - The value to be set with the key. If `undefined` then `key` will be deleted from the object.
     *
     * @return {this} This Game Object instance.
     */
    setPipelineData: function (key, value)
    {
        var data = this.pipelineData;

        if (value === undefined)
        {
            delete data[key];
        }
        else
        {
            data[key] = value;
        }

        return this;
    },

    /**
     * Resets the WebGL Pipeline of this Game Object back to the default it was created with.
     *
     * @method Phaser.GameObjects.Components.Pipeline#resetPipeline
     * @webglOnly
     * @since 3.0.0
     *
     * @param {boolean} [resetData=false] - Reset the `pipelineData` object to being an empty object?
     *
     * @return {boolean} `true` if the pipeline was reset successfully, otherwise `false`.
     */
    resetPipeline: function (resetData)
    {
        if (resetData === undefined) { resetData = false; }

        this.pipeline = this.defaultPipeline;

        if (resetData)
        {
            this.pipelineData = {};
        }

        return (this.pipeline !== null);
    },

    /**
     * Gets the name of the WebGL Pipeline this Game Object is currently using.
     *
     * @method Phaser.GameObjects.Components.Pipeline#getPipelineName
     * @webglOnly
     * @since 3.0.0
     *
     * @return {string} The string-based name of the pipeline being used by this Game Object.
     */
    getPipelineName: function ()
    {
        return this.pipeline.name;
    }

};

module.exports = Pipeline;


/***/ }),

/***/ 4461:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var DeepCopy = __webpack_require__(3911);
var FX = __webpack_require__(1626);
var SpliceOne = __webpack_require__(8935);

/**
 * Provides methods used for setting the WebGL rendering post pipeline of a Game Object.
 *
 * @namespace Phaser.GameObjects.Components.PostPipeline
 * @webglOnly
 * @since 3.60.0
 */

var PostPipeline = {

    /**
     * Does this Game Object have any Post Pipelines set?
     *
     * @name Phaser.GameObjects.Components.PostPipeline#hasPostPipeline
     * @type {boolean}
     * @webglOnly
     * @since 3.60.0
     */
    hasPostPipeline: false,

    /**
     * The WebGL Post FX Pipelines this Game Object uses for post-render effects.
     *
     * The pipelines are processed in the order in which they appear in this array.
     *
     * If you modify this array directly, be sure to set the
     * `hasPostPipeline` property accordingly.
     *
     * @name Phaser.GameObjects.Components.PostPipeline#postPipelines
     * @type {Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]}
     * @webglOnly
     * @since 3.60.0
     */
    postPipelines: null,

    /**
     * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses.
     *
     * @name Phaser.GameObjects.Components.PostPipeline#postPipelineData
     * @type {object}
     * @webglOnly
     * @since 3.60.0
     */
    postPipelineData: null,

    /**
     * The Pre FX component of this Game Object.
     *
     * This component allows you to apply a variety of built-in effects to this Game Object, such
     * as glow, blur, bloom, displacements, vignettes and more. You access them via this property,
     * for example:
     *
     * ```js
     * const player = this.add.sprite();
     * player.preFX.addBloom();
     * ```
     *
     * Only the following Game Objects support Pre FX:
     *
     * * Image
     * * Sprite
     * * TileSprite
     * * Text
     * * RenderTexture
     * * Video
     *
     * All FX are WebGL only and do not have Canvas counterparts.
     *
     * Please see the FX Class for more details and available methods.
     *
     * @name Phaser.GameObjects.Components.PostPipeline#preFX
     * @type {?Phaser.GameObjects.Components.FX}
     * @webglOnly
     * @since 3.60.0
     */
    preFX: null,

    /**
     * The Post FX component of this Game Object.
     *
     * This component allows you to apply a variety of built-in effects to this Game Object, such
     * as glow, blur, bloom, displacements, vignettes and more. You access them via this property,
     * for example:
     *
     * ```js
     * const player = this.add.sprite();
     * player.postFX.addBloom();
     * ```
     *
     * All FX are WebGL only and do not have Canvas counterparts.
     *
     * Please see the FX Class for more details and available methods.
     *
     * This property is always `null` until the `initPostPipeline` method is called.
     *
     * @name Phaser.GameObjects.Components.PostPipeline#postFX
     * @type {Phaser.GameObjects.Components.FX}
     * @webglOnly
     * @since 3.60.0
     */
    postFX: null,

    /**
     * This should only be called during the instantiation of the Game Object.
     *
     * It is called by default by all core Game Objects and doesn't need
     * calling again.
     *
     * After that, use `setPostPipeline`.
     *
     * @method Phaser.GameObjects.Components.PostPipeline#initPostPipeline
     * @webglOnly
     * @since 3.60.0
     *
     * @param {boolean} [preFX=false] - Does this Game Object support Pre FX?
     */
    initPostPipeline: function (preFX)
    {
        this.postPipelines = [];
        this.postPipelineData = {};

        this.postFX = new FX(this, true);

        if (preFX)
        {
            this.preFX = new FX(this, false);
        }
    },

    /**
     * Sets one, or more, Post Pipelines on this Game Object.
     *
     * Post Pipelines are invoked after this Game Object has rendered to its target and
     * are commonly used for post-fx.
     *
     * The post pipelines are appended to the `postPipelines` array belonging to this
     * Game Object. When the renderer processes this Game Object, it iterates through the post
     * pipelines in the order in which they appear in the array. If you are stacking together
     * multiple effects, be aware that the order is important.
     *
     * If you call this method multiple times, the new pipelines will be appended to any existing
     * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required.
     *
     * You can optionally also set the `postPipelineData` property, if the parameter is given.
     *
     * @method Phaser.GameObjects.Components.PostPipeline#setPostPipeline
     * @webglOnly
     * @since 3.60.0
     *
     * @param {(string|string[]|function|function[]|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[])} pipelines - Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them.
     * @param {object} [pipelineData] - Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object.
     * @param {boolean} [copyData=true] - Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead.
     *
     * @return {this} This Game Object instance.
     */
    setPostPipeline: function (pipelines, pipelineData, copyData)
    {
        var renderer = this.scene.sys.renderer;

        if (!renderer)
        {
            return this;
        }

        var pipelineManager = renderer.pipelines;

        if (pipelineManager)
        {
            if (!Array.isArray(pipelines))
            {
                pipelines = [ pipelines ];
            }

            for (var i = 0; i < pipelines.length; i++)
            {
                var instance = pipelineManager.getPostPipeline(pipelines[i], this, pipelineData);

                if (instance)
                {
                    this.postPipelines.push(instance);
                }
            }

            if (pipelineData)
            {
                this.postPipelineData = (copyData) ? DeepCopy(pipelineData) : pipelineData;
            }
        }

        this.hasPostPipeline = (this.postPipelines.length > 0);

        return this;
    },

    /**
     * Adds an entry to the `postPipelineData` object belonging to this Game Object.
     *
     * If the 'key' already exists, its value is updated. If it doesn't exist, it is created.
     *
     * If `value` is undefined, and `key` exists, `key` is removed from the data object.
     *
     * @method Phaser.GameObjects.Components.PostPipeline#setPostPipelineData
     * @webglOnly
     * @since 3.60.0
     *
     * @param {string} key - The key of the pipeline data to set, update, or delete.
     * @param {any} [value] - The value to be set with the key. If `undefined` then `key` will be deleted from the object.
     *
     * @return {this} This Game Object instance.
     */
    setPostPipelineData: function (key, value)
    {
        var data = this.postPipelineData;

        if (value === undefined)
        {
            delete data[key];
        }
        else
        {
            data[key] = value;
        }

        return this;
    },

    /**
     * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it.
     *
     * @method Phaser.GameObjects.Components.PostPipeline#getPostPipeline
     * @webglOnly
     * @since 3.60.0
     *
     * @param {(string|function|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline)} pipeline - The string-based name of the pipeline, or a pipeline class.
     *
     * @return {(Phaser.Renderer.WebGL.Pipelines.PostFXPipeline|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[])} An array of all the Post Pipelines matching the name. This array will be empty if there was no match. If there was only one single match, that pipeline is returned directly, not in an array.
     */
    getPostPipeline: function (pipeline)
    {
        var isString = (typeof pipeline === 'string');

        var pipelines = this.postPipelines;

        var results = [];

        for (var i = 0; i < pipelines.length; i++)
        {
            var instance = pipelines[i];

            if ((isString && instance.name === pipeline) || (!isString && instance instanceof pipeline))
            {
                results.push(instance);
            }
        }

        return (results.length === 1) ? results[0] : results;
    },

    /**
     * Resets the WebGL Post Pipelines of this Game Object. It does this by calling
     * the `destroy` method on each post pipeline and then clearing the local array.
     *
     * @method Phaser.GameObjects.Components.PostPipeline#resetPostPipeline
     * @webglOnly
     * @since 3.60.0
     *
     * @param {boolean} [resetData=false] - Reset the `postPipelineData` object to being an empty object?
     */
    resetPostPipeline: function (resetData)
    {
        if (resetData === undefined) { resetData = false; }

        var pipelines = this.postPipelines;

        for (var i = 0; i < pipelines.length; i++)
        {
            pipelines[i].destroy();
        }

        this.postPipelines = [];
        this.hasPostPipeline = false;

        if (resetData)
        {
            this.postPipelineData = {};
        }
    },

    /**
     * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them.
     *
     * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead.
     *
     * @method Phaser.GameObjects.Components.PostPipeline#removePostPipeline
     * @webglOnly
     * @since 3.60.0
     *
     * @param {string|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline} pipeline - The string-based name of the pipeline, or a pipeline class.
     *
     * @return {this} This Game Object.
     */
    removePostPipeline: function (pipeline)
    {
        var isString = (typeof pipeline === 'string');

        var pipelines = this.postPipelines;

        for (var i = pipelines.length - 1; i >= 0; i--)
        {
            var instance = pipelines[i];

            if (
                (isString && instance.name === pipeline) ||
                (!isString && instance === pipeline))
            {
                instance.destroy();

                SpliceOne(pipelines, i);
            }
        }

        this.hasPostPipeline = (this.postPipelines.length > 0);

        return this;
    },

    /**
     * Removes all Pre and Post FX Controllers from this Game Object.
     *
     * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead.
     *
     * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead.
     *
     * @method Phaser.GameObjects.Components.PostPipeline#clearFX
     * @webglOnly
     * @since 3.60.0
     *
     * @return {this} This Game Object.
     */
    clearFX: function ()
    {
        if (this.preFX)
        {
            this.preFX.clear();
        }

        if (this.postFX)
        {
            this.postFX.clear();
        }

        return this;
    }

};

module.exports = PostPipeline;


/***/ }),

/***/ 4627:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Provides methods used for getting and setting the Scroll Factor of a Game Object.
 *
 * @namespace Phaser.GameObjects.Components.ScrollFactor
 * @since 3.0.0
 */

var ScrollFactor = {

    /**
     * The horizontal scroll factor of this Game Object.
     *
     * The scroll factor controls the influence of the movement of a Camera upon this Game Object.
     *
     * When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
     * It does not change the Game Objects actual position values.
     *
     * A value of 1 means it will move exactly in sync with a camera.
     * A value of 0 means it will not move at all, even if the camera moves.
     * Other values control the degree to which the camera movement is mapped to this Game Object.
     *
     * Please be aware that scroll factor values other than 1 are not taken in to consideration when
     * calculating physics collisions. Bodies always collide based on their world position, but changing
     * the scroll factor is a visual adjustment to where the textures are rendered, which can offset
     * them from physics bodies if not accounted for in your code.
     *
     * @name Phaser.GameObjects.Components.ScrollFactor#scrollFactorX
     * @type {number}
     * @default 1
     * @since 3.0.0
     */
    scrollFactorX: 1,

    /**
     * The vertical scroll factor of this Game Object.
     *
     * The scroll factor controls the influence of the movement of a Camera upon this Game Object.
     *
     * When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
     * It does not change the Game Objects actual position values.
     *
     * A value of 1 means it will move exactly in sync with a camera.
     * A value of 0 means it will not move at all, even if the camera moves.
     * Other values control the degree to which the camera movement is mapped to this Game Object.
     *
     * Please be aware that scroll factor values other than 1 are not taken in to consideration when
     * calculating physics collisions. Bodies always collide based on their world position, but changing
     * the scroll factor is a visual adjustment to where the textures are rendered, which can offset
     * them from physics bodies if not accounted for in your code.
     *
     * @name Phaser.GameObjects.Components.ScrollFactor#scrollFactorY
     * @type {number}
     * @default 1
     * @since 3.0.0
     */
    scrollFactorY: 1,

    /**
     * Sets the scroll factor of this Game Object.
     *
     * The scroll factor controls the influence of the movement of a Camera upon this Game Object.
     *
     * When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
     * It does not change the Game Objects actual position values.
     *
     * A value of 1 means it will move exactly in sync with a camera.
     * A value of 0 means it will not move at all, even if the camera moves.
     * Other values control the degree to which the camera movement is mapped to this Game Object.
     *
     * Please be aware that scroll factor values other than 1 are not taken in to consideration when
     * calculating physics collisions. Bodies always collide based on their world position, but changing
     * the scroll factor is a visual adjustment to where the textures are rendered, which can offset
     * them from physics bodies if not accounted for in your code.
     *
     * @method Phaser.GameObjects.Components.ScrollFactor#setScrollFactor
     * @since 3.0.0
     *
     * @param {number} x - The horizontal scroll factor of this Game Object.
     * @param {number} [y=x] - The vertical scroll factor of this Game Object. If not set it will use the `x` value.
     *
     * @return {this} This Game Object instance.
     */
    setScrollFactor: function (x, y)
    {
        if (y === undefined) { y = x; }

        this.scrollFactorX = x;
        this.scrollFactorY = y;

        return this;
    }

};

module.exports = ScrollFactor;


/***/ }),

/***/ 1868:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Provides methods used for getting and setting the size of a Game Object.
 *
 * @namespace Phaser.GameObjects.Components.Size
 * @since 3.0.0
 */

var Size = {

    /**
     * A property indicating that a Game Object has this component.
     *
     * @name Phaser.GameObjects.Components.Size#_sizeComponent
     * @type {boolean}
     * @private
     * @default true
     * @since 3.2.0
     */
    _sizeComponent: true,

    /**
     * The native (un-scaled) width of this Game Object.
     *
     * Changing this value will not change the size that the Game Object is rendered in-game.
     * For that you need to either set the scale of the Game Object (`setScale`) or use
     * the `displayWidth` property.
     *
     * @name Phaser.GameObjects.Components.Size#width
     * @type {number}
     * @since 3.0.0
     */
    width: 0,

    /**
     * The native (un-scaled) height of this Game Object.
     *
     * Changing this value will not change the size that the Game Object is rendered in-game.
     * For that you need to either set the scale of the Game Object (`setScale`) or use
     * the `displayHeight` property.
     *
     * @name Phaser.GameObjects.Components.Size#height
     * @type {number}
     * @since 3.0.0
     */
    height: 0,

    /**
     * The displayed width of this Game Object.
     *
     * This value takes into account the scale factor.
     *
     * Setting this value will adjust the Game Object's scale property.
     *
     * @name Phaser.GameObjects.Components.Size#displayWidth
     * @type {number}
     * @since 3.0.0
     */
    displayWidth: {

        get: function ()
        {
            return Math.abs(this.scaleX * this.frame.realWidth);
        },

        set: function (value)
        {
            this.scaleX = value / this.frame.realWidth;
        }

    },

    /**
     * The displayed height of this Game Object.
     *
     * This value takes into account the scale factor.
     *
     * Setting this value will adjust the Game Object's scale property.
     *
     * @name Phaser.GameObjects.Components.Size#displayHeight
     * @type {number}
     * @since 3.0.0
     */
    displayHeight: {

        get: function ()
        {
            return Math.abs(this.scaleY * this.frame.realHeight);
        },

        set: function (value)
        {
            this.scaleY = value / this.frame.realHeight;
        }

    },

    /**
     * Sets the size of this Game Object to be that of the given Frame.
     *
     * This will not change the size that the Game Object is rendered in-game.
     * For that you need to either set the scale of the Game Object (`setScale`) or call the
     * `setDisplaySize` method, which is the same thing as changing the scale but allows you
     * to do so by giving pixel values.
     *
     * If you have enabled this Game Object for input, changing the size will _not_ change the
     * size of the hit area. To do this you should adjust the `input.hitArea` object directly.
     *
     * @method Phaser.GameObjects.Components.Size#setSizeToFrame
     * @since 3.0.0
     *
     * @param {Phaser.Textures.Frame|boolean} [frame] - The frame to base the size of this Game Object on.
     *
     * @return {this} This Game Object instance.
     */
    setSizeToFrame: function (frame)
    {
        if (!frame) { frame = this.frame; }

        this.width = frame.realWidth;
        this.height = frame.realHeight;

        var input = this.input;

        if (input && !input.customHitArea)
        {
            input.hitArea.width = this.width;
            input.hitArea.height = this.height;
        }

        return this;
    },

    /**
     * Sets the internal size of this Game Object, as used for frame or physics body creation.
     *
     * This will not change the size that the Game Object is rendered in-game.
     * For that you need to either set the scale of the Game Object (`setScale`) or call the
     * `setDisplaySize` method, which is the same thing as changing the scale but allows you
     * to do so by giving pixel values.
     *
     * If you have enabled this Game Object for input, changing the size will _not_ change the
     * size of the hit area. To do this you should adjust the `input.hitArea` object directly.
     *
     * @method Phaser.GameObjects.Components.Size#setSize
     * @since 3.0.0
     *
     * @param {number} width - The width of this Game Object.
     * @param {number} height - The height of this Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setSize: function (width, height)
    {
        this.width = width;
        this.height = height;

        return this;
    },

    /**
     * Sets the display size of this Game Object.
     *
     * Calling this will adjust the scale.
     *
     * @method Phaser.GameObjects.Components.Size#setDisplaySize
     * @since 3.0.0
     *
     * @param {number} width - The width of this Game Object.
     * @param {number} height - The height of this Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setDisplaySize: function (width, height)
    {
        this.displayWidth = width;
        this.displayHeight = height;

        return this;
    }

};

module.exports = Size;


/***/ }),

/***/ 4976:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Frame = __webpack_require__(2362);

//  bitmask flag for GameObject.renderMask
var _FLAG = 8; // 1000

/**
 * Provides methods used for getting and setting the texture of a Game Object.
 *
 * @namespace Phaser.GameObjects.Components.Texture
 * @since 3.0.0
 */

var Texture = {

    /**
     * The Texture this Game Object is using to render with.
     *
     * @name Phaser.GameObjects.Components.Texture#texture
     * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture}
     * @since 3.0.0
     */
    texture: null,

    /**
     * The Texture Frame this Game Object is using to render with.
     *
     * @name Phaser.GameObjects.Components.Texture#frame
     * @type {Phaser.Textures.Frame}
     * @since 3.0.0
     */
    frame: null,

    /**
     * Internal flag. Not to be set by this Game Object.
     *
     * @name Phaser.GameObjects.Components.Texture#isCropped
     * @type {boolean}
     * @private
     * @since 3.11.0
     */
    isCropped: false,

    /**
     * Sets the texture and frame this Game Object will use to render with.
     *
     * Textures are referenced by their string-based keys, as stored in the Texture Manager.
     *
     * Calling this method will modify the `width` and `height` properties of your Game Object.
     *
     * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer.
     *
     * @method Phaser.GameObjects.Components.Texture#setTexture
     * @since 3.0.0
     *
     * @param {(string|Phaser.Textures.Texture)} key - The key of the texture to be used, as stored in the Texture Manager, or a Texture instance.
     * @param {(string|number)} [frame] - The name or index of the frame within the Texture.
     * @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object?
     * @param {boolean} [updateOrigin=true] - Should this call change the origin of the Game Object?
     *
     * @return {this} This Game Object instance.
     */
    setTexture: function (key, frame, updateSize, updateOrigin)
    {
        this.texture = this.scene.sys.textures.get(key);

        return this.setFrame(frame, updateSize, updateOrigin);
    },

    /**
     * Sets the frame this Game Object will use to render with.
     *
     * If you pass a string or index then the Frame has to belong to the current Texture being used
     * by this Game Object.
     *
     * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated.
     *
     * Calling `setFrame` will modify the `width` and `height` properties of your Game Object.
     *
     * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer.
     *
     * @method Phaser.GameObjects.Components.Texture#setFrame
     * @since 3.0.0
     *
     * @param {(string|number|Phaser.Textures.Frame)} frame - The name or index of the frame within the Texture, or a Frame instance.
     * @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object?
     * @param {boolean} [updateOrigin=true] - Should this call adjust the origin of the Game Object?
     *
     * @return {this} This Game Object instance.
     */
    setFrame: function (frame, updateSize, updateOrigin)
    {
        if (updateSize === undefined) { updateSize = true; }
        if (updateOrigin === undefined) { updateOrigin = true; }

        if (frame instanceof Frame)
        {
            this.texture = this.scene.sys.textures.get(frame.texture.key);

            this.frame = frame;
        }
        else
        {
            this.frame = this.texture.get(frame);
        }

        if (!this.frame.cutWidth || !this.frame.cutHeight)
        {
            this.renderFlags &= ~_FLAG;
        }
        else
        {
            this.renderFlags |= _FLAG;
        }

        if (this._sizeComponent && updateSize)
        {
            this.setSizeToFrame();
        }

        if (this._originComponent && updateOrigin)
        {
            if (this.frame.customPivot)
            {
                this.setOrigin(this.frame.pivotX, this.frame.pivotY);
            }
            else
            {
                this.updateDisplayOrigin();
            }
        }

        return this;
    }

};

module.exports = Texture;


/***/ }),

/***/ 9243:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Frame = __webpack_require__(2362);

//  bitmask flag for GameObject.renderMask
var _FLAG = 8; // 1000

/**
 * Provides methods used for getting and setting the texture of a Game Object.
 *
 * @namespace Phaser.GameObjects.Components.TextureCrop
 * @since 3.0.0
 */

var TextureCrop = {

    /**
     * The Texture this Game Object is using to render with.
     *
     * @name Phaser.GameObjects.Components.TextureCrop#texture
     * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture}
     * @since 3.0.0
     */
    texture: null,

    /**
     * The Texture Frame this Game Object is using to render with.
     *
     * @name Phaser.GameObjects.Components.TextureCrop#frame
     * @type {Phaser.Textures.Frame}
     * @since 3.0.0
     */
    frame: null,

    /**
     * A boolean flag indicating if this Game Object is being cropped or not.
     * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off.
     * Equally, calling `setCrop` with no arguments will reset the crop and disable it.
     *
     * @name Phaser.GameObjects.Components.TextureCrop#isCropped
     * @type {boolean}
     * @since 3.11.0
     */
    isCropped: false,

    /**
     * Applies a crop to a texture based Game Object, such as a Sprite or Image.
     *
     * The crop is a rectangle that limits the area of the texture frame that is visible during rendering.
     *
     * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just
     * changes what is shown when rendered.
     *
     * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left.
     *
     * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left
     * half of it, you could call `setCrop(0, 0, 400, 600)`.
     *
     * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop
     * an area of 200x100 when applied to a Game Object that had a scale factor of 2.
     *
     * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument.
     *
     * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`.
     *
     * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow
     * the renderer to skip several internal calculations.
     *
     * @method Phaser.GameObjects.Components.TextureCrop#setCrop
     * @since 3.11.0
     *
     * @param {(number|Phaser.Geom.Rectangle)} [x] - The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored.
     * @param {number} [y] - The y coordinate to start the crop from.
     * @param {number} [width] - The width of the crop rectangle in pixels.
     * @param {number} [height] - The height of the crop rectangle in pixels.
     *
     * @return {this} This Game Object instance.
     */
    setCrop: function (x, y, width, height)
    {
        if (x === undefined)
        {
            this.isCropped = false;
        }
        else if (this.frame)
        {
            if (typeof x === 'number')
            {
                this.frame.setCropUVs(this._crop, x, y, width, height, this.flipX, this.flipY);
            }
            else
            {
                var rect = x;

                this.frame.setCropUVs(this._crop, rect.x, rect.y, rect.width, rect.height, this.flipX, this.flipY);
            }

            this.isCropped = true;
        }

        return this;
    },

    /**
     * Sets the texture and frame this Game Object will use to render with.
     *
     * Textures are referenced by their string-based keys, as stored in the Texture Manager.
     *
     * @method Phaser.GameObjects.Components.TextureCrop#setTexture
     * @since 3.0.0
     *
     * @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
     * @param {(string|number)} [frame] - The name or index of the frame within the Texture.
     *
     * @return {this} This Game Object instance.
     */
    setTexture: function (key, frame)
    {
        this.texture = this.scene.sys.textures.get(key);

        return this.setFrame(frame);
    },

    /**
     * Sets the frame this Game Object will use to render with.
     *
     * If you pass a string or index then the Frame has to belong to the current Texture being used
     * by this Game Object.
     *
     * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated.
     *
     * Calling `setFrame` will modify the `width` and `height` properties of your Game Object.
     *
     * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer.
     *
     * @method Phaser.GameObjects.Components.TextureCrop#setFrame
     * @since 3.0.0
     *
     * @param {(string|number|Phaser.Textures.Frame)} frame - The name or index of the frame within the Texture, or a Frame instance.
     * @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object?
     * @param {boolean} [updateOrigin=true] - Should this call adjust the origin of the Game Object?
     *
     * @return {this} This Game Object instance.
     */
    setFrame: function (frame, updateSize, updateOrigin)
    {
        if (updateSize === undefined) { updateSize = true; }
        if (updateOrigin === undefined) { updateOrigin = true; }

        if (frame instanceof Frame)
        {
            this.texture = this.scene.sys.textures.get(frame.texture.key);

            this.frame = frame;
        }
        else
        {
            this.frame = this.texture.get(frame);
        }

        if (!this.frame.cutWidth || !this.frame.cutHeight)
        {
            this.renderFlags &= ~_FLAG;
        }
        else
        {
            this.renderFlags |= _FLAG;
        }

        if (this._sizeComponent && updateSize)
        {
            this.setSizeToFrame();
        }

        if (this._originComponent && updateOrigin)
        {
            if (this.frame.customPivot)
            {
                this.setOrigin(this.frame.pivotX, this.frame.pivotY);
            }
            else
            {
                this.updateDisplayOrigin();
            }
        }

        if (this.isCropped)
        {
            this.frame.updateCropUVs(this._crop, this.flipX, this.flipY);
        }

        return this;
    },

    /**
     * Internal method that returns a blank, well-formed crop object for use by a Game Object.
     *
     * @method Phaser.GameObjects.Components.TextureCrop#resetCropObject
     * @private
     * @since 3.12.0
     *
     * @return {object} The crop object.
     */
    resetCropObject: function ()
    {
        return { u0: 0, v0: 0, u1: 0, v1: 0, width: 0, height: 0, x: 0, y: 0, flipX: false, flipY: false, cx: 0, cy: 0, cw: 0, ch: 0 };
    }

};

module.exports = TextureCrop;


/***/ }),

/***/ 5693:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Provides methods used for setting the tint of a Game Object.
 * Should be applied as a mixin and not used directly.
 *
 * @namespace Phaser.GameObjects.Components.Tint
 * @webglOnly
 * @since 3.0.0
 */

var Tint = {

    /**
     * The tint value being applied to the top-left vertice of the Game Object.
     * This value is interpolated from the corner to the center of the Game Object.
     * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
     *
     * @name Phaser.GameObjects.Components.Tint#tintTopLeft
     * @type {number}
     * @default 0xffffff
     * @since 3.0.0
     */
    tintTopLeft: 0xffffff,

    /**
     * The tint value being applied to the top-right vertice of the Game Object.
     * This value is interpolated from the corner to the center of the Game Object.
     * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
     *
     * @name Phaser.GameObjects.Components.Tint#tintTopRight
     * @type {number}
     * @default 0xffffff
     * @since 3.0.0
     */
    tintTopRight: 0xffffff,

    /**
     * The tint value being applied to the bottom-left vertice of the Game Object.
     * This value is interpolated from the corner to the center of the Game Object.
     * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
     *
     * @name Phaser.GameObjects.Components.Tint#tintBottomLeft
     * @type {number}
     * @default 0xffffff
     * @since 3.0.0
     */
    tintBottomLeft: 0xffffff,

    /**
     * The tint value being applied to the bottom-right vertice of the Game Object.
     * This value is interpolated from the corner to the center of the Game Object.
     * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
     *
     * @name Phaser.GameObjects.Components.Tint#tintBottomRight
     * @type {number}
     * @default 0xffffff
     * @since 3.0.0
     */
    tintBottomRight: 0xffffff,

    /**
     * The tint fill mode.
     *
     * `false` = An additive tint (the default), where vertices colors are blended with the texture.
     * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha.
     *
     * @name Phaser.GameObjects.Components.Tint#tintFill
     * @type {boolean}
     * @default false
     * @since 3.11.0
     */
    tintFill: false,

    /**
     * Clears all tint values associated with this Game Object.
     *
     * Immediately sets the color values back to 0xffffff and the tint type to 'additive',
     * which results in no visible change to the texture.
     *
     * @method Phaser.GameObjects.Components.Tint#clearTint
     * @webglOnly
     * @since 3.0.0
     *
     * @return {this} This Game Object instance.
     */
    clearTint: function ()
    {
        this.setTint(0xffffff);

        return this;
    },

    /**
     * Sets an additive tint on this Game Object.
     *
     * The tint works by taking the pixel color values from the Game Objects texture, and then
     * multiplying it by the color value of the tint. You can provide either one color value,
     * in which case the whole Game Object will be tinted in that color. Or you can provide a color
     * per corner. The colors are blended together across the extent of the Game Object.
     *
     * To modify the tint color once set, either call this method again with new values or use the
     * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight,
     * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently.
     *
     * To remove a tint call `clearTint`.
     *
     * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`.
     *
     * @method Phaser.GameObjects.Components.Tint#setTint
     * @webglOnly
     * @since 3.0.0
     *
     * @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object.
     * @param {number} [topRight] - The tint being applied to the top-right of the Game Object.
     * @param {number} [bottomLeft] - The tint being applied to the bottom-left of the Game Object.
     * @param {number} [bottomRight] - The tint being applied to the bottom-right of the Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setTint: function (topLeft, topRight, bottomLeft, bottomRight)
    {
        if (topLeft === undefined) { topLeft = 0xffffff; }

        if (topRight === undefined)
        {
            topRight = topLeft;
            bottomLeft = topLeft;
            bottomRight = topLeft;
        }

        this.tintTopLeft = topLeft;
        this.tintTopRight = topRight;
        this.tintBottomLeft = bottomLeft;
        this.tintBottomRight = bottomRight;

        this.tintFill = false;

        return this;
    },

    /**
     * Sets a fill-based tint on this Game Object.
     *
     * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture
     * with those in the tint. You can use this for effects such as making a player flash 'white'
     * if hit by something. You can provide either one color value, in which case the whole
     * Game Object will be rendered in that color. Or you can provide a color per corner. The colors
     * are blended together across the extent of the Game Object.
     *
     * To modify the tint color once set, either call this method again with new values or use the
     * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight,
     * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently.
     *
     * To remove a tint call `clearTint`.
     *
     * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`.
     *
     * @method Phaser.GameObjects.Components.Tint#setTintFill
     * @webglOnly
     * @since 3.11.0
     *
     * @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object.
     * @param {number} [topRight] - The tint being applied to the top-right of the Game Object.
     * @param {number} [bottomLeft] - The tint being applied to the bottom-left of the Game Object.
     * @param {number} [bottomRight] - The tint being applied to the bottom-right of the Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setTintFill: function (topLeft, topRight, bottomLeft, bottomRight)
    {
        this.setTint(topLeft, topRight, bottomLeft, bottomRight);

        this.tintFill = true;

        return this;
    },

    /**
     * The tint value being applied to the whole of the Game Object.
     * Return `tintTopLeft` when read this tint property.
     *
     * @name Phaser.GameObjects.Components.Tint#tint
     * @type {number}
     * @webglOnly
     * @since 3.0.0
     */
    tint: {

        get: function ()
        {
            return this.tintTopLeft;
        },

        set: function (value)
        {
            this.setTint(value, value, value, value);
        }
    },

    /**
     * Does this Game Object have a tint applied?
     *
     * It checks to see if the 4 tint properties are set to the value 0xffffff
     * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted.
     *
     * @name Phaser.GameObjects.Components.Tint#isTinted
     * @type {boolean}
     * @webglOnly
     * @readonly
     * @since 3.11.0
     */
    isTinted: {

        get: function ()
        {
            var white = 0xffffff;

            return (
                this.tintFill ||
                this.tintTopLeft !== white ||
                this.tintTopRight !== white ||
                this.tintBottomLeft !== white ||
                this.tintBottomRight !== white
            );
        }

    }

};

module.exports = Tint;


/***/ }),

/***/ 6125:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Build a JSON representation of the given Game Object.
 *
 * This is typically extended further by Game Object specific implementations.
 *
 * @method Phaser.GameObjects.Components.ToJSON
 * @since 3.0.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to export as JSON.
 *
 * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object.
 */
var ToJSON = function (gameObject)
{
    var out = {
        name: gameObject.name,
        type: gameObject.type,
        x: gameObject.x,
        y: gameObject.y,
        depth: gameObject.depth,
        scale: {
            x: gameObject.scaleX,
            y: gameObject.scaleY
        },
        origin: {
            x: gameObject.originX,
            y: gameObject.originY
        },
        flipX: gameObject.flipX,
        flipY: gameObject.flipY,
        rotation: gameObject.rotation,
        alpha: gameObject.alpha,
        visible: gameObject.visible,
        blendMode: gameObject.blendMode,
        textureKey: '',
        frameKey: '',
        data: {}
    };

    if (gameObject.texture)
    {
        out.textureKey = gameObject.texture.key;
        out.frameKey = gameObject.frame.name;
    }

    return out;
};

module.exports = ToJSON;


/***/ }),

/***/ 3212:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var MATH_CONST = __webpack_require__(7425);
var TransformMatrix = __webpack_require__(4227);
var TransformXY = __webpack_require__(7556);
var WrapAngle = __webpack_require__(3692);
var WrapAngleDegrees = __webpack_require__(2820);
var Vector2 = __webpack_require__(2529);

//  global bitmask flag for GameObject.renderMask (used by Scale)
var _FLAG = 4; // 0100

/**
 * Provides methods used for getting and setting the position, scale and rotation of a Game Object.
 *
 * @namespace Phaser.GameObjects.Components.Transform
 * @since 3.0.0
 */

var Transform = {

    /**
     * A property indicating that a Game Object has this component.
     *
     * @name Phaser.GameObjects.Components.Transform#hasTransformComponent
     * @type {boolean}
     * @readonly
     * @default true
     * @since 3.60.0
     */
    hasTransformComponent: true,

    /**
     * Private internal value. Holds the horizontal scale value.
     *
     * @name Phaser.GameObjects.Components.Transform#_scaleX
     * @type {number}
     * @private
     * @default 1
     * @since 3.0.0
     */
    _scaleX: 1,

    /**
     * Private internal value. Holds the vertical scale value.
     *
     * @name Phaser.GameObjects.Components.Transform#_scaleY
     * @type {number}
     * @private
     * @default 1
     * @since 3.0.0
     */
    _scaleY: 1,

    /**
     * Private internal value. Holds the rotation value in radians.
     *
     * @name Phaser.GameObjects.Components.Transform#_rotation
     * @type {number}
     * @private
     * @default 0
     * @since 3.0.0
     */
    _rotation: 0,

    /**
     * The x position of this Game Object.
     *
     * @name Phaser.GameObjects.Components.Transform#x
     * @type {number}
     * @default 0
     * @since 3.0.0
     */
    x: 0,

    /**
     * The y position of this Game Object.
     *
     * @name Phaser.GameObjects.Components.Transform#y
     * @type {number}
     * @default 0
     * @since 3.0.0
     */
    y: 0,

    /**
     * The z position of this Game Object.
     *
     * Note: The z position does not control the rendering order of 2D Game Objects. Use
     * {@link Phaser.GameObjects.Components.Depth#depth} instead.
     *
     * @name Phaser.GameObjects.Components.Transform#z
     * @type {number}
     * @default 0
     * @since 3.0.0
     */
    z: 0,

    /**
     * The w position of this Game Object.
     *
     * @name Phaser.GameObjects.Components.Transform#w
     * @type {number}
     * @default 0
     * @since 3.0.0
     */
    w: 0,

    /**
     * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object
     * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`.
     *
     * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this
     * isn't the case, use the `scaleX` or `scaleY` properties instead.
     *
     * @name Phaser.GameObjects.Components.Transform#scale
     * @type {number}
     * @default 1
     * @since 3.18.0
     */
    scale: {

        get: function ()
        {
            return (this._scaleX + this._scaleY) / 2;
        },

        set: function (value)
        {
            this._scaleX = value;
            this._scaleY = value;

            if (value === 0)
            {
                this.renderFlags &= ~_FLAG;
            }
            else
            {
                this.renderFlags |= _FLAG;
            }
        }

    },

    /**
     * The horizontal scale of this Game Object.
     *
     * @name Phaser.GameObjects.Components.Transform#scaleX
     * @type {number}
     * @default 1
     * @since 3.0.0
     */
    scaleX: {

        get: function ()
        {
            return this._scaleX;
        },

        set: function (value)
        {
            this._scaleX = value;

            if (value === 0)
            {
                this.renderFlags &= ~_FLAG;
            }
            else if (this._scaleY !== 0)
            {
                this.renderFlags |= _FLAG;
            }
        }

    },

    /**
     * The vertical scale of this Game Object.
     *
     * @name Phaser.GameObjects.Components.Transform#scaleY
     * @type {number}
     * @default 1
     * @since 3.0.0
     */
    scaleY: {

        get: function ()
        {
            return this._scaleY;
        },

        set: function (value)
        {
            this._scaleY = value;

            if (value === 0)
            {
                this.renderFlags &= ~_FLAG;
            }
            else if (this._scaleX !== 0)
            {
                this.renderFlags |= _FLAG;
            }
        }

    },

    /**
     * The angle of this Game Object as expressed in degrees.
     *
     * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left
     * and -90 is up.
     *
     * If you prefer to work in radians, see the `rotation` property instead.
     *
     * @name Phaser.GameObjects.Components.Transform#angle
     * @type {number}
     * @default 0
     * @since 3.0.0
     */
    angle: {

        get: function ()
        {
            return WrapAngleDegrees(this._rotation * MATH_CONST.RAD_TO_DEG);
        },

        set: function (value)
        {
            //  value is in degrees
            this.rotation = WrapAngleDegrees(value) * MATH_CONST.DEG_TO_RAD;
        }
    },

    /**
     * The angle of this Game Object in radians.
     *
     * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left
     * and -PI/2 is up.
     *
     * If you prefer to work in degrees, see the `angle` property instead.
     *
     * @name Phaser.GameObjects.Components.Transform#rotation
     * @type {number}
     * @default 1
     * @since 3.0.0
     */
    rotation: {

        get: function ()
        {
            return this._rotation;
        },

        set: function (value)
        {
            //  value is in radians
            this._rotation = WrapAngle(value);
        }
    },

    /**
     * Sets the position of this Game Object.
     *
     * @method Phaser.GameObjects.Components.Transform#setPosition
     * @since 3.0.0
     *
     * @param {number} [x=0] - The x position of this Game Object.
     * @param {number} [y=x] - The y position of this Game Object. If not set it will use the `x` value.
     * @param {number} [z=0] - The z position of this Game Object.
     * @param {number} [w=0] - The w position of this Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setPosition: function (x, y, z, w)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = x; }
        if (z === undefined) { z = 0; }
        if (w === undefined) { w = 0; }

        this.x = x;
        this.y = y;
        this.z = z;
        this.w = w;

        return this;
    },

    /**
     * Copies an object's coordinates to this Game Object's position.
     *
     * @method Phaser.GameObjects.Components.Transform#copyPosition
     * @since 3.50.0
     *
     * @param {(Phaser.Types.Math.Vector2Like|Phaser.Types.Math.Vector3Like|Phaser.Types.Math.Vector4Like)} source - An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied.
     *
     * @return {this} This Game Object instance.
     */
    copyPosition: function (source)
    {
        if (source.x !== undefined) { this.x = source.x; }
        if (source.y !== undefined) { this.y = source.y; }
        if (source.z !== undefined) { this.z = source.z; }
        if (source.w !== undefined) { this.w = source.w; }

        return this;
    },

    /**
     * Sets the position of this Game Object to be a random position within the confines of
     * the given area.
     *
     * If no area is specified a random position between 0 x 0 and the game width x height is used instead.
     *
     * The position does not factor in the size of this Game Object, meaning that only the origin is
     * guaranteed to be within the area.
     *
     * @method Phaser.GameObjects.Components.Transform#setRandomPosition
     * @since 3.8.0
     *
     * @param {number} [x=0] - The x position of the top-left of the random area.
     * @param {number} [y=0] - The y position of the top-left of the random area.
     * @param {number} [width] - The width of the random area.
     * @param {number} [height] - The height of the random area.
     *
     * @return {this} This Game Object instance.
     */
    setRandomPosition: function (x, y, width, height)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = 0; }
        if (width === undefined) { width = this.scene.sys.scale.width; }
        if (height === undefined) { height = this.scene.sys.scale.height; }

        this.x = x + (Math.random() * width);
        this.y = y + (Math.random() * height);

        return this;
    },

    /**
     * Sets the rotation of this Game Object.
     *
     * @method Phaser.GameObjects.Components.Transform#setRotation
     * @since 3.0.0
     *
     * @param {number} [radians=0] - The rotation of this Game Object, in radians.
     *
     * @return {this} This Game Object instance.
     */
    setRotation: function (radians)
    {
        if (radians === undefined) { radians = 0; }

        this.rotation = radians;

        return this;
    },

    /**
     * Sets the angle of this Game Object.
     *
     * @method Phaser.GameObjects.Components.Transform#setAngle
     * @since 3.0.0
     *
     * @param {number} [degrees=0] - The rotation of this Game Object, in degrees.
     *
     * @return {this} This Game Object instance.
     */
    setAngle: function (degrees)
    {
        if (degrees === undefined) { degrees = 0; }

        this.angle = degrees;

        return this;
    },

    /**
     * Sets the scale of this Game Object.
     *
     * @method Phaser.GameObjects.Components.Transform#setScale
     * @since 3.0.0
     *
     * @param {number} [x=1] - The horizontal scale of this Game Object.
     * @param {number} [y=x] - The vertical scale of this Game Object. If not set it will use the `x` value.
     *
     * @return {this} This Game Object instance.
     */
    setScale: function (x, y)
    {
        if (x === undefined) { x = 1; }
        if (y === undefined) { y = x; }

        this.scaleX = x;
        this.scaleY = y;

        return this;
    },

    /**
     * Sets the x position of this Game Object.
     *
     * @method Phaser.GameObjects.Components.Transform#setX
     * @since 3.0.0
     *
     * @param {number} [value=0] - The x position of this Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setX: function (value)
    {
        if (value === undefined) { value = 0; }

        this.x = value;

        return this;
    },

    /**
     * Sets the y position of this Game Object.
     *
     * @method Phaser.GameObjects.Components.Transform#setY
     * @since 3.0.0
     *
     * @param {number} [value=0] - The y position of this Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setY: function (value)
    {
        if (value === undefined) { value = 0; }

        this.y = value;

        return this;
    },

    /**
     * Sets the z position of this Game Object.
     *
     * Note: The z position does not control the rendering order of 2D Game Objects. Use
     * {@link Phaser.GameObjects.Components.Depth#setDepth} instead.
     *
     * @method Phaser.GameObjects.Components.Transform#setZ
     * @since 3.0.0
     *
     * @param {number} [value=0] - The z position of this Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setZ: function (value)
    {
        if (value === undefined) { value = 0; }

        this.z = value;

        return this;
    },

    /**
     * Sets the w position of this Game Object.
     *
     * @method Phaser.GameObjects.Components.Transform#setW
     * @since 3.0.0
     *
     * @param {number} [value=0] - The w position of this Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setW: function (value)
    {
        if (value === undefined) { value = 0; }

        this.w = value;

        return this;
    },

    /**
     * Gets the local transform matrix for this Game Object.
     *
     * @method Phaser.GameObjects.Components.Transform#getLocalTransformMatrix
     * @since 3.4.0
     *
     * @param {Phaser.GameObjects.Components.TransformMatrix} [tempMatrix] - The matrix to populate with the values from this Game Object.
     *
     * @return {Phaser.GameObjects.Components.TransformMatrix} The populated Transform Matrix.
     */
    getLocalTransformMatrix: function (tempMatrix)
    {
        if (tempMatrix === undefined) { tempMatrix = new TransformMatrix(); }

        return tempMatrix.applyITRS(this.x, this.y, this._rotation, this._scaleX, this._scaleY);
    },

    /**
     * Gets the world transform matrix for this Game Object, factoring in any parent Containers.
     *
     * @method Phaser.GameObjects.Components.Transform#getWorldTransformMatrix
     * @since 3.4.0
     *
     * @param {Phaser.GameObjects.Components.TransformMatrix} [tempMatrix] - The matrix to populate with the values from this Game Object.
     * @param {Phaser.GameObjects.Components.TransformMatrix} [parentMatrix] - A temporary matrix to hold parent values during the calculations.
     *
     * @return {Phaser.GameObjects.Components.TransformMatrix} The populated Transform Matrix.
     */
    getWorldTransformMatrix: function (tempMatrix, parentMatrix)
    {
        if (tempMatrix === undefined) { tempMatrix = new TransformMatrix(); }

        var parent = this.parentContainer;

        if (!parent)
        {
            return this.getLocalTransformMatrix(tempMatrix);
        }

        if (!parentMatrix)
        {
            parentMatrix = new TransformMatrix();
        }

        tempMatrix.applyITRS(this.x, this.y, this._rotation, this._scaleX, this._scaleY);

        while (parent)
        {
            parentMatrix.applyITRS(parent.x, parent.y, parent._rotation, parent._scaleX, parent._scaleY);

            parentMatrix.multiply(tempMatrix, tempMatrix);

            parent = parent.parentContainer;
        }

        return tempMatrix;
    },

    /**
     * Takes the given `x` and `y` coordinates and converts them into local space for this
     * Game Object, taking into account parent and local transforms, and the Display Origin.
     *
     * The returned Vector2 contains the translated point in its properties.
     *
     * A Camera needs to be provided in order to handle modified scroll factors. If no
     * camera is specified, it will use the `main` camera from the Scene to which this
     * Game Object belongs.
     *
     * @method Phaser.GameObjects.Components.Transform#getLocalPoint
     * @since 3.50.0
     *
     * @param {number} x - The x position to translate.
     * @param {number} y - The y position to translate.
     * @param {Phaser.Math.Vector2} [point] - A Vector2, or point-like object, to store the results in.
     * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera which is being tested against. If not given will use the Scene default camera.
     *
     * @return {Phaser.Math.Vector2} The translated point.
     */
    getLocalPoint: function (x, y, point, camera)
    {
        if (!point) { point = new Vector2(); }
        if (!camera) { camera = this.scene.sys.cameras.main; }

        var csx = camera.scrollX;
        var csy = camera.scrollY;

        var px = x + (csx * this.scrollFactorX) - csx;
        var py = y + (csy * this.scrollFactorY) - csy;

        if (this.parentContainer)
        {
            this.getWorldTransformMatrix().applyInverse(px, py, point);
        }
        else
        {
            TransformXY(px, py, this.x, this.y, this.rotation, this.scaleX, this.scaleY, point);
        }

        //  Normalize origin
        if (this._originComponent)
        {
            point.x += this._displayOriginX;
            point.y += this._displayOriginY;
        }

        return point;
    },

    /**
     * Gets the sum total rotation of all of this Game Objects parent Containers.
     *
     * The returned value is in radians and will be zero if this Game Object has no parent container.
     *
     * @method Phaser.GameObjects.Components.Transform#getParentRotation
     * @since 3.18.0
     *
     * @return {number} The sum total rotation, in radians, of all parent containers of this Game Object.
     */
    getParentRotation: function ()
    {
        var rotation = 0;

        var parent = this.parentContainer;

        while (parent)
        {
            rotation += parent.rotation;

            parent = parent.parentContainer;
        }

        return rotation;
    }

};

module.exports = Transform;


/***/ }),

/***/ 4227:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var MATH_CONST = __webpack_require__(7425);
var Vector2 = __webpack_require__(2529);

/**
 * @classdesc
 * A Matrix used for display transformations for rendering.
 *
 * It is represented like so:
 *
 * ```
 * | a | c | tx |
 * | b | d | ty |
 * | 0 | 0 | 1  |
 * ```
 *
 * @class TransformMatrix
 * @memberof Phaser.GameObjects.Components
 * @constructor
 * @since 3.0.0
 *
 * @param {number} [a=1] - The Scale X value.
 * @param {number} [b=0] - The Skew Y value.
 * @param {number} [c=0] - The Skew X value.
 * @param {number} [d=1] - The Scale Y value.
 * @param {number} [tx=0] - The Translate X value.
 * @param {number} [ty=0] - The Translate Y value.
 */
var TransformMatrix = new Class({

    initialize:

    function TransformMatrix (a, b, c, d, tx, ty)
    {
        if (a === undefined) { a = 1; }
        if (b === undefined) { b = 0; }
        if (c === undefined) { c = 0; }
        if (d === undefined) { d = 1; }
        if (tx === undefined) { tx = 0; }
        if (ty === undefined) { ty = 0; }

        /**
         * The matrix values.
         *
         * @name Phaser.GameObjects.Components.TransformMatrix#matrix
         * @type {Float32Array}
         * @since 3.0.0
         */
        this.matrix = new Float32Array([ a, b, c, d, tx, ty, 0, 0, 1 ]);

        /**
         * The decomposed matrix.
         *
         * @name Phaser.GameObjects.Components.TransformMatrix#decomposedMatrix
         * @type {object}
         * @since 3.0.0
         */
        this.decomposedMatrix = {
            translateX: 0,
            translateY: 0,
            scaleX: 1,
            scaleY: 1,
            rotation: 0
        };

        /**
         * The temporary quad value cache.
         *
         * @name Phaser.GameObjects.Components.TransformMatrix#quad
         * @type {Float32Array}
         * @since 3.60.0
         */
        this.quad = new Float32Array(8);
    },

    /**
     * The Scale X value.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#a
     * @type {number}
     * @since 3.4.0
     */
    a: {

        get: function ()
        {
            return this.matrix[0];
        },

        set: function (value)
        {
            this.matrix[0] = value;
        }

    },

    /**
     * The Skew Y value.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#b
     * @type {number}
     * @since 3.4.0
     */
    b: {

        get: function ()
        {
            return this.matrix[1];
        },

        set: function (value)
        {
            this.matrix[1] = value;
        }

    },

    /**
     * The Skew X value.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#c
     * @type {number}
     * @since 3.4.0
     */
    c: {

        get: function ()
        {
            return this.matrix[2];
        },

        set: function (value)
        {
            this.matrix[2] = value;
        }

    },

    /**
     * The Scale Y value.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#d
     * @type {number}
     * @since 3.4.0
     */
    d: {

        get: function ()
        {
            return this.matrix[3];
        },

        set: function (value)
        {
            this.matrix[3] = value;
        }

    },

    /**
     * The Translate X value.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#e
     * @type {number}
     * @since 3.11.0
     */
    e: {

        get: function ()
        {
            return this.matrix[4];
        },

        set: function (value)
        {
            this.matrix[4] = value;
        }

    },

    /**
     * The Translate Y value.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#f
     * @type {number}
     * @since 3.11.0
     */
    f: {

        get: function ()
        {
            return this.matrix[5];
        },

        set: function (value)
        {
            this.matrix[5] = value;
        }

    },

    /**
     * The Translate X value.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#tx
     * @type {number}
     * @since 3.4.0
     */
    tx: {

        get: function ()
        {
            return this.matrix[4];
        },

        set: function (value)
        {
            this.matrix[4] = value;
        }

    },

    /**
     * The Translate Y value.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#ty
     * @type {number}
     * @since 3.4.0
     */
    ty: {

        get: function ()
        {
            return this.matrix[5];
        },

        set: function (value)
        {
            this.matrix[5] = value;
        }

    },

    /**
     * The rotation of the Matrix. Value is in radians.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#rotation
     * @type {number}
     * @readonly
     * @since 3.4.0
     */
    rotation: {

        get: function ()
        {
            return Math.acos(this.a / this.scaleX) * ((Math.atan(-this.c / this.a) < 0) ? -1 : 1);
        }

    },

    /**
     * The rotation of the Matrix, normalized to be within the Phaser right-handed
     * clockwise rotation space. Value is in radians.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#rotationNormalized
     * @type {number}
     * @readonly
     * @since 3.19.0
     */
    rotationNormalized: {

        get: function ()
        {
            var matrix = this.matrix;

            var a = matrix[0];
            var b = matrix[1];
            var c = matrix[2];
            var d = matrix[3];

            if (a || b)
            {
                // var r = Math.sqrt(a * a + b * b);

                return (b > 0) ? Math.acos(a / this.scaleX) : -Math.acos(a / this.scaleX);
            }
            else if (c || d)
            {
                // var s = Math.sqrt(c * c + d * d);

                return MATH_CONST.TAU - ((d > 0) ? Math.acos(-c / this.scaleY) : -Math.acos(c / this.scaleY));
            }
            else
            {
                return 0;
            }
        }

    },

    /**
     * The decomposed horizontal scale of the Matrix. This value is always positive.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#scaleX
     * @type {number}
     * @readonly
     * @since 3.4.0
     */
    scaleX: {

        get: function ()
        {
            return Math.sqrt((this.a * this.a) + (this.b * this.b));
        }

    },

    /**
     * The decomposed vertical scale of the Matrix. This value is always positive.
     *
     * @name Phaser.GameObjects.Components.TransformMatrix#scaleY
     * @type {number}
     * @readonly
     * @since 3.4.0
     */
    scaleY: {

        get: function ()
        {
            return Math.sqrt((this.c * this.c) + (this.d * this.d));
        }

    },

    /**
     * Reset the Matrix to an identity matrix.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#loadIdentity
     * @since 3.0.0
     *
     * @return {this} This TransformMatrix.
     */
    loadIdentity: function ()
    {
        var matrix = this.matrix;

        matrix[0] = 1;
        matrix[1] = 0;
        matrix[2] = 0;
        matrix[3] = 1;
        matrix[4] = 0;
        matrix[5] = 0;

        return this;
    },

    /**
     * Translate the Matrix.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#translate
     * @since 3.0.0
     *
     * @param {number} x - The horizontal translation value.
     * @param {number} y - The vertical translation value.
     *
     * @return {this} This TransformMatrix.
     */
    translate: function (x, y)
    {
        var matrix = this.matrix;

        matrix[4] = matrix[0] * x + matrix[2] * y + matrix[4];
        matrix[5] = matrix[1] * x + matrix[3] * y + matrix[5];

        return this;
    },

    /**
     * Scale the Matrix.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#scale
     * @since 3.0.0
     *
     * @param {number} x - The horizontal scale value.
     * @param {number} y - The vertical scale value.
     *
     * @return {this} This TransformMatrix.
     */
    scale: function (x, y)
    {
        var matrix = this.matrix;

        matrix[0] *= x;
        matrix[1] *= x;
        matrix[2] *= y;
        matrix[3] *= y;

        return this;
    },

    /**
     * Rotate the Matrix.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#rotate
     * @since 3.0.0
     *
     * @param {number} angle - The angle of rotation in radians.
     *
     * @return {this} This TransformMatrix.
     */
    rotate: function (angle)
    {
        var sin = Math.sin(angle);
        var cos = Math.cos(angle);

        var matrix = this.matrix;

        var a = matrix[0];
        var b = matrix[1];
        var c = matrix[2];
        var d = matrix[3];

        matrix[0] = a * cos + c * sin;
        matrix[1] = b * cos + d * sin;
        matrix[2] = a * -sin + c * cos;
        matrix[3] = b * -sin + d * cos;

        return this;
    },

    /**
     * Multiply this Matrix by the given Matrix.
     *
     * If an `out` Matrix is given then the results will be stored in it.
     * If it is not given, this matrix will be updated in place instead.
     * Use an `out` Matrix if you do not wish to mutate this matrix.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#multiply
     * @since 3.0.0
     *
     * @param {Phaser.GameObjects.Components.TransformMatrix} rhs - The Matrix to multiply by.
     * @param {Phaser.GameObjects.Components.TransformMatrix} [out] - An optional Matrix to store the results in.
     *
     * @return {(this|Phaser.GameObjects.Components.TransformMatrix)} Either this TransformMatrix, or the `out` Matrix, if given in the arguments.
     */
    multiply: function (rhs, out)
    {
        var matrix = this.matrix;
        var source = rhs.matrix;

        var localA = matrix[0];
        var localB = matrix[1];
        var localC = matrix[2];
        var localD = matrix[3];
        var localE = matrix[4];
        var localF = matrix[5];

        var sourceA = source[0];
        var sourceB = source[1];
        var sourceC = source[2];
        var sourceD = source[3];
        var sourceE = source[4];
        var sourceF = source[5];

        var destinationMatrix = (out === undefined) ? matrix : out.matrix;

        destinationMatrix[0] = (sourceA * localA) + (sourceB * localC);
        destinationMatrix[1] = (sourceA * localB) + (sourceB * localD);
        destinationMatrix[2] = (sourceC * localA) + (sourceD * localC);
        destinationMatrix[3] = (sourceC * localB) + (sourceD * localD);
        destinationMatrix[4] = (sourceE * localA) + (sourceF * localC) + localE;
        destinationMatrix[5] = (sourceE * localB) + (sourceF * localD) + localF;

        return destinationMatrix;
    },

    /**
     * Multiply this Matrix by the matrix given, including the offset.
     *
     * The offsetX is added to the tx value: `offsetX * a + offsetY * c + tx`.
     * The offsetY is added to the ty value: `offsetY * b + offsetY * d + ty`.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#multiplyWithOffset
     * @since 3.11.0
     *
     * @param {Phaser.GameObjects.Components.TransformMatrix} src - The source Matrix to copy from.
     * @param {number} offsetX - Horizontal offset to factor in to the multiplication.
     * @param {number} offsetY - Vertical offset to factor in to the multiplication.
     *
     * @return {this} This TransformMatrix.
     */
    multiplyWithOffset: function (src, offsetX, offsetY)
    {
        var matrix = this.matrix;
        var otherMatrix = src.matrix;

        var a0 = matrix[0];
        var b0 = matrix[1];
        var c0 = matrix[2];
        var d0 = matrix[3];
        var tx0 = matrix[4];
        var ty0 = matrix[5];

        var pse = offsetX * a0 + offsetY * c0 + tx0;
        var psf = offsetX * b0 + offsetY * d0 + ty0;

        var a1 = otherMatrix[0];
        var b1 = otherMatrix[1];
        var c1 = otherMatrix[2];
        var d1 = otherMatrix[3];
        var tx1 = otherMatrix[4];
        var ty1 = otherMatrix[5];

        matrix[0] = a1 * a0 + b1 * c0;
        matrix[1] = a1 * b0 + b1 * d0;
        matrix[2] = c1 * a0 + d1 * c0;
        matrix[3] = c1 * b0 + d1 * d0;
        matrix[4] = tx1 * a0 + ty1 * c0 + pse;
        matrix[5] = tx1 * b0 + ty1 * d0 + psf;

        return this;
    },

    /**
     * Transform the Matrix.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#transform
     * @since 3.0.0
     *
     * @param {number} a - The Scale X value.
     * @param {number} b - The Shear Y value.
     * @param {number} c - The Shear X value.
     * @param {number} d - The Scale Y value.
     * @param {number} tx - The Translate X value.
     * @param {number} ty - The Translate Y value.
     *
     * @return {this} This TransformMatrix.
     */
    transform: function (a, b, c, d, tx, ty)
    {
        var matrix = this.matrix;

        var a0 = matrix[0];
        var b0 = matrix[1];
        var c0 = matrix[2];
        var d0 = matrix[3];
        var tx0 = matrix[4];
        var ty0 = matrix[5];

        matrix[0] = a * a0 + b * c0;
        matrix[1] = a * b0 + b * d0;
        matrix[2] = c * a0 + d * c0;
        matrix[3] = c * b0 + d * d0;
        matrix[4] = tx * a0 + ty * c0 + tx0;
        matrix[5] = tx * b0 + ty * d0 + ty0;

        return this;
    },

    /**
     * Transform a point in to the local space of this Matrix.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#transformPoint
     * @since 3.0.0
     *
     * @param {number} x - The x coordinate of the point to transform.
     * @param {number} y - The y coordinate of the point to transform.
     * @param {Phaser.Types.Math.Vector2Like} [point] - Optional Point object to store the transformed coordinates in.
     *
     * @return {Phaser.Types.Math.Vector2Like} The Point containing the transformed coordinates.
     */
    transformPoint: function (x, y, point)
    {
        if (point === undefined) { point = { x: 0, y: 0 }; }

        var matrix = this.matrix;

        var a = matrix[0];
        var b = matrix[1];
        var c = matrix[2];
        var d = matrix[3];
        var tx = matrix[4];
        var ty = matrix[5];

        point.x = x * a + y * c + tx;
        point.y = x * b + y * d + ty;

        return point;
    },

    /**
     * Invert the Matrix.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#invert
     * @since 3.0.0
     *
     * @return {this} This TransformMatrix.
     */
    invert: function ()
    {
        var matrix = this.matrix;

        var a = matrix[0];
        var b = matrix[1];
        var c = matrix[2];
        var d = matrix[3];
        var tx = matrix[4];
        var ty = matrix[5];

        var n = a * d - b * c;

        matrix[0] = d / n;
        matrix[1] = -b / n;
        matrix[2] = -c / n;
        matrix[3] = a / n;
        matrix[4] = (c * ty - d * tx) / n;
        matrix[5] = -(a * ty - b * tx) / n;

        return this;
    },

    /**
     * Set the values of this Matrix to copy those of the matrix given.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#copyFrom
     * @since 3.11.0
     *
     * @param {Phaser.GameObjects.Components.TransformMatrix} src - The source Matrix to copy from.
     *
     * @return {this} This TransformMatrix.
     */
    copyFrom: function (src)
    {
        var matrix = this.matrix;

        matrix[0] = src.a;
        matrix[1] = src.b;
        matrix[2] = src.c;
        matrix[3] = src.d;
        matrix[4] = src.e;
        matrix[5] = src.f;

        return this;
    },

    /**
     * Set the values of this Matrix to copy those of the array given.
     * Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#copyFromArray
     * @since 3.11.0
     *
     * @param {array} src - The array of values to set into this matrix.
     *
     * @return {this} This TransformMatrix.
     */
    copyFromArray: function (src)
    {
        var matrix = this.matrix;

        matrix[0] = src[0];
        matrix[1] = src[1];
        matrix[2] = src[2];
        matrix[3] = src[3];
        matrix[4] = src[4];
        matrix[5] = src[5];

        return this;
    },

    /**
     * Copy the values from this Matrix to the given Canvas Rendering Context.
     * This will use the Context.transform method.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#copyToContext
     * @since 3.12.0
     *
     * @param {CanvasRenderingContext2D} ctx - The Canvas Rendering Context to copy the matrix values to.
     *
     * @return {CanvasRenderingContext2D} The Canvas Rendering Context.
     */
    copyToContext: function (ctx)
    {
        var matrix = this.matrix;

        ctx.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);

        return ctx;
    },

    /**
     * Copy the values from this Matrix to the given Canvas Rendering Context.
     * This will use the Context.setTransform method.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#setToContext
     * @since 3.12.0
     *
     * @param {CanvasRenderingContext2D} ctx - The Canvas Rendering Context to copy the matrix values to.
     *
     * @return {CanvasRenderingContext2D} The Canvas Rendering Context.
     */
    setToContext: function (ctx)
    {
        ctx.setTransform(this);

        return ctx;
    },

    /**
     * Copy the values in this Matrix to the array given.
     *
     * Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#copyToArray
     * @since 3.12.0
     *
     * @param {array} [out] - The array to copy the matrix values in to.
     *
     * @return {array} An array where elements 0 to 5 contain the values from this matrix.
     */
    copyToArray: function (out)
    {
        var matrix = this.matrix;

        if (out === undefined)
        {
            out = [ matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5] ];
        }
        else
        {
            out[0] = matrix[0];
            out[1] = matrix[1];
            out[2] = matrix[2];
            out[3] = matrix[3];
            out[4] = matrix[4];
            out[5] = matrix[5];
        }

        return out;
    },

    /**
     * Set the values of this Matrix.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#setTransform
     * @since 3.0.0
     *
     * @param {number} a - The Scale X value.
     * @param {number} b - The Shear Y value.
     * @param {number} c - The Shear X value.
     * @param {number} d - The Scale Y value.
     * @param {number} tx - The Translate X value.
     * @param {number} ty - The Translate Y value.
     *
     * @return {this} This TransformMatrix.
     */
    setTransform: function (a, b, c, d, tx, ty)
    {
        var matrix = this.matrix;

        matrix[0] = a;
        matrix[1] = b;
        matrix[2] = c;
        matrix[3] = d;
        matrix[4] = tx;
        matrix[5] = ty;

        return this;
    },

    /**
     * Decompose this Matrix into its translation, scale and rotation values using QR decomposition.
     *
     * The result must be applied in the following order to reproduce the current matrix:
     *
     * translate -> rotate -> scale
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#decomposeMatrix
     * @since 3.0.0
     *
     * @return {Phaser.Types.GameObjects.DecomposeMatrixResults} The decomposed Matrix.
     */
    decomposeMatrix: function ()
    {
        var decomposedMatrix = this.decomposedMatrix;

        var matrix = this.matrix;

        //  a = scale X (1)
        //  b = shear Y (0)
        //  c = shear X (0)
        //  d = scale Y (1)

        var a = matrix[0];
        var b = matrix[1];
        var c = matrix[2];
        var d = matrix[3];

        var determ = a * d - b * c;

        decomposedMatrix.translateX = matrix[4];
        decomposedMatrix.translateY = matrix[5];

        if (a || b)
        {
            var r = Math.sqrt(a * a + b * b);

            decomposedMatrix.rotation = (b > 0) ? Math.acos(a / r) : -Math.acos(a / r);
            decomposedMatrix.scaleX = r;
            decomposedMatrix.scaleY = determ / r;
        }
        else if (c || d)
        {
            var s = Math.sqrt(c * c + d * d);

            decomposedMatrix.rotation = Math.PI * 0.5 - (d > 0 ? Math.acos(-c / s) : -Math.acos(c / s));
            decomposedMatrix.scaleX = determ / s;
            decomposedMatrix.scaleY = s;
        }
        else
        {
            decomposedMatrix.rotation = 0;
            decomposedMatrix.scaleX = 0;
            decomposedMatrix.scaleY = 0;
        }

        return decomposedMatrix;
    },

    /**
     * Apply the identity, translate, rotate and scale operations on the Matrix.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#applyITRS
     * @since 3.0.0
     *
     * @param {number} x - The horizontal translation.
     * @param {number} y - The vertical translation.
     * @param {number} rotation - The angle of rotation in radians.
     * @param {number} scaleX - The horizontal scale.
     * @param {number} scaleY - The vertical scale.
     *
     * @return {this} This TransformMatrix.
     */
    applyITRS: function (x, y, rotation, scaleX, scaleY)
    {
        var matrix = this.matrix;

        var radianSin = Math.sin(rotation);
        var radianCos = Math.cos(rotation);

        // Translate
        matrix[4] = x;
        matrix[5] = y;

        // Rotate and Scale
        matrix[0] = radianCos * scaleX;
        matrix[1] = radianSin * scaleX;
        matrix[2] = -radianSin * scaleY;
        matrix[3] = radianCos * scaleY;

        return this;
    },

    /**
     * Takes the `x` and `y` values and returns a new position in the `output` vector that is the inverse of
     * the current matrix with its transformation applied.
     *
     * Can be used to translate points from world to local space.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#applyInverse
     * @since 3.12.0
     *
     * @param {number} x - The x position to translate.
     * @param {number} y - The y position to translate.
     * @param {Phaser.Math.Vector2} [output] - A Vector2, or point-like object, to store the results in.
     *
     * @return {Phaser.Math.Vector2} The coordinates, inverse-transformed through this matrix.
     */
    applyInverse: function (x, y, output)
    {
        if (output === undefined) { output = new Vector2(); }

        var matrix = this.matrix;

        var a = matrix[0];
        var b = matrix[1];
        var c = matrix[2];
        var d = matrix[3];
        var tx = matrix[4];
        var ty = matrix[5];

        var id = 1 / ((a * d) + (c * -b));

        output.x = (d * id * x) + (-c * id * y) + (((ty * c) - (tx * d)) * id);
        output.y = (a * id * y) + (-b * id * x) + (((-ty * a) + (tx * b)) * id);

        return output;
    },

    /**
     * Performs the 8 calculations required to create the vertices of
     * a quad based on this matrix and the given x/y/xw/yh values.
     *
     * The result is stored in `TransformMatrix.quad`, which is returned
     * from this method.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#setQuad
     * @since 3.60.0
     *
     * @param {number} x - The x value.
     * @param {number} y - The y value.
     * @param {number} xw - The xw value.
     * @param {number} yh - The yh value.
     * @param {boolean} [roundPixels=false] - Pass the results via Math.round?
     * @param {Float32Array} [quad] - Optional Float32Array to store the results in. Otherwises uses the local quad array.
     *
     * @return {Float32Array} The quad Float32Array.
     */
    setQuad: function (x, y, xw, yh, roundPixels, quad)
    {
        if (roundPixels === undefined) { roundPixels = false; }
        if (quad === undefined) { quad = this.quad; }

        var matrix = this.matrix;

        var a = matrix[0];
        var b = matrix[1];
        var c = matrix[2];
        var d = matrix[3];
        var e = matrix[4];
        var f = matrix[5];

        if (roundPixels)
        {
            quad[0] = Math.round(x * a + y * c + e);
            quad[1] = Math.round(x * b + y * d + f);

            quad[2] = Math.round(x * a + yh * c + e);
            quad[3] = Math.round(x * b + yh * d + f);

            quad[4] = Math.round(xw * a + yh * c + e);
            quad[5] = Math.round(xw * b + yh * d + f);

            quad[6] = Math.round(xw * a + y * c + e);
            quad[7] = Math.round(xw * b + y * d + f);
        }
        else
        {
            quad[0] = x * a + y * c + e;
            quad[1] = x * b + y * d + f;

            quad[2] = x * a + yh * c + e;
            quad[3] = x * b + yh * d + f;

            quad[4] = xw * a + yh * c + e;
            quad[5] = xw * b + yh * d + f;

            quad[6] = xw * a + y * c + e;
            quad[7] = xw * b + y * d + f;
        }

        return quad;
    },

    /**
     * Returns the X component of this matrix multiplied by the given values.
     * This is the same as `x * a + y * c + e`.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#getX
     * @since 3.12.0
     *
     * @param {number} x - The x value.
     * @param {number} y - The y value.
     *
     * @return {number} The calculated x value.
     */
    getX: function (x, y)
    {
        return x * this.a + y * this.c + this.e;
    },

    /**
     * Returns the Y component of this matrix multiplied by the given values.
     * This is the same as `x * b + y * d + f`.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#getY
     * @since 3.12.0
     *
     * @param {number} x - The x value.
     * @param {number} y - The y value.
     *
     * @return {number} The calculated y value.
     */
    getY: function (x, y)
    {
        return x * this.b + y * this.d + this.f;
    },

    /**
     * Returns the X component of this matrix multiplied by the given values.
     *
     * This is the same as `x * a + y * c + e`, optionally passing via `Math.round`.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#getXRound
     * @since 3.50.0
     *
     * @param {number} x - The x value.
     * @param {number} y - The y value.
     * @param {boolean} [round=false] - Math.round the resulting value?
     *
     * @return {number} The calculated x value.
     */
    getXRound: function (x, y, round)
    {
        var v = this.getX(x, y);

        if (round)
        {
            v = Math.round(v);
        }

        return v;
    },

    /**
     * Returns the Y component of this matrix multiplied by the given values.
     *
     * This is the same as `x * b + y * d + f`, optionally passing via `Math.round`.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#getYRound
     * @since 3.50.0
     *
     * @param {number} x - The x value.
     * @param {number} y - The y value.
     * @param {boolean} [round=false] - Math.round the resulting value?
     *
     * @return {number} The calculated y value.
     */
    getYRound: function (x, y, round)
    {
        var v = this.getY(x, y);

        if (round)
        {
            v = Math.round(v);
        }

        return v;
    },

    /**
     * Returns a string that can be used in a CSS Transform call as a `matrix` property.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#getCSSMatrix
     * @since 3.12.0
     *
     * @return {string} A string containing the CSS Transform matrix values.
     */
    getCSSMatrix: function ()
    {
        var m = this.matrix;

        return 'matrix(' + m[0] + ',' + m[1] + ',' + m[2] + ',' + m[3] + ',' + m[4] + ',' + m[5] + ')';
    },

    /**
     * Destroys this Transform Matrix.
     *
     * @method Phaser.GameObjects.Components.TransformMatrix#destroy
     * @since 3.4.0
     */
    destroy: function ()
    {
        this.matrix = null;
        this.quad = null;
        this.decomposedMatrix = null;
    }

});

module.exports = TransformMatrix;


/***/ }),

/***/ 8414:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

//  bitmask flag for GameObject.renderMask
var _FLAG = 1; // 0001

/**
 * Provides methods used for setting the visibility of a Game Object.
 * Should be applied as a mixin and not used directly.
 *
 * @namespace Phaser.GameObjects.Components.Visible
 * @since 3.0.0
 */

var Visible = {

    /**
     * Private internal value. Holds the visible value.
     *
     * @name Phaser.GameObjects.Components.Visible#_visible
     * @type {boolean}
     * @private
     * @default true
     * @since 3.0.0
     */
    _visible: true,

    /**
     * The visible state of the Game Object.
     *
     * An invisible Game Object will skip rendering, but will still process update logic.
     *
     * @name Phaser.GameObjects.Components.Visible#visible
     * @type {boolean}
     * @since 3.0.0
     */
    visible: {

        get: function ()
        {
            return this._visible;
        },

        set: function (value)
        {
            if (value)
            {
                this._visible = true;
                this.renderFlags |= _FLAG;
            }
            else
            {
                this._visible = false;
                this.renderFlags &= ~_FLAG;
            }
        }

    },

    /**
     * Sets the visibility of this Game Object.
     *
     * An invisible Game Object will skip rendering, but will still process update logic.
     *
     * @method Phaser.GameObjects.Components.Visible#setVisible
     * @since 3.0.0
     *
     * @param {boolean} value - The visible state of the Game Object.
     *
     * @return {this} This Game Object instance.
     */
    setVisible: function (value)
    {
        this.visible = value;

        return this;
    }
};

module.exports = Visible;


/***/ }),

/***/ 4286:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.GameObjects.Components
 */

module.exports = {

    Alpha: __webpack_require__(4344),
    AlphaSingle: __webpack_require__(4518),
    BlendMode: __webpack_require__(5173),
    ComputedSize: __webpack_require__(1991),
    Crop: __webpack_require__(8305),
    Depth: __webpack_require__(3131),
    Flip: __webpack_require__(9660),
    FX: __webpack_require__(1626),
    GetBounds: __webpack_require__(3671),
    Mask: __webpack_require__(2246),
    Origin: __webpack_require__(5085),
    PathFollower: __webpack_require__(77),
    Pipeline: __webpack_require__(986),
    PostPipeline: __webpack_require__(4461),
    ScrollFactor: __webpack_require__(4627),
    Size: __webpack_require__(1868),
    Texture: __webpack_require__(4976),
    TextureCrop: __webpack_require__(9243),
    Tint: __webpack_require__(5693),
    ToJSON: __webpack_require__(6125),
    Transform: __webpack_require__(3212),
    TransformMatrix: __webpack_require__(4227),
    Visible: __webpack_require__(8414)

};


/***/ }),

/***/ 7361:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       Felipe Alfonso <@bitnenfer>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var ArrayUtils = __webpack_require__(1953);
var BlendModes = __webpack_require__(8351);
var Class = __webpack_require__(7473);
var Components = __webpack_require__(4286);
var Events = __webpack_require__(3389);
var GameObject = __webpack_require__(2273);
var Rectangle = __webpack_require__(1392);
var Render = __webpack_require__(3232);
var Union = __webpack_require__(9422);
var Vector2 = __webpack_require__(2529);

/**
 * @classdesc
 * A Container Game Object.
 *
 * A Container, as the name implies, can 'contain' other types of Game Object.
 * When a Game Object is added to a Container, the Container becomes responsible for the rendering of it.
 * By default it will be removed from the Display List and instead added to the Containers own internal list.
 *
 * The position of the Game Object automatically becomes relative to the position of the Container.
 *
 * The transform point of a Container is 0x0 (in local space) and that cannot be changed. The children you add to the
 * Container should be positioned with this value in mind. I.e. you should treat 0x0 as being the center of
 * the Container, and position children positively and negative around it as required.
 *
 * When the Container is rendered, all of its children are rendered as well, in the order in which they exist
 * within the Container. Container children can be repositioned using methods such as `MoveUp`, `MoveDown` and `SendToBack`.
 *
 * If you modify a transform property of the Container, such as `Container.x` or `Container.rotation` then it will
 * automatically influence all children as well.
 *
 * Containers can include other Containers for deeply nested transforms.
 *
 * Containers can have masks set on them and can be used as a mask too. However, Container children cannot be masked.
 * The masks do not 'stack up'. Only a Container on the root of the display list will use its mask.
 *
 * Containers can be enabled for input. Because they do not have a texture you need to provide a shape for them
 * to use as their hit area. Container children can also be enabled for input, independent of the Container.
 *
 * If input enabling a _child_ you should not set both the `origin` and a **negative** scale factor on the child,
 * or the input area will become misaligned.
 *
 * Containers can be given a physics body for either Arcade Physics, Impact Physics or Matter Physics. However,
 * if Container _children_ are enabled for physics you may get unexpected results, such as offset bodies,
 * if the Container itself, or any of its ancestors, is positioned anywhere other than at 0 x 0. Container children
 * with physics do not factor in the Container due to the excessive extra calculations needed. Please structure
 * your game to work around this.
 *
 * It's important to understand the impact of using Containers. They add additional processing overhead into
 * every one of their children. The deeper you nest them, the more the cost escalates. This is especially true
 * for input events. You also loose the ability to set the display depth of Container children in the same
 * flexible manner as those not within them. In short, don't use them for the sake of it. You pay a small cost
 * every time you create one, try to structure your game around avoiding that where possible.
 *
 * @class Container
 * @extends Phaser.GameObjects.GameObject
 * @memberof Phaser.GameObjects
 * @constructor
 * @since 3.4.0
 *
 * @extends Phaser.GameObjects.Components.AlphaSingle
 * @extends Phaser.GameObjects.Components.BlendMode
 * @extends Phaser.GameObjects.Components.ComputedSize
 * @extends Phaser.GameObjects.Components.Depth
 * @extends Phaser.GameObjects.Components.Mask
 * @extends Phaser.GameObjects.Components.PostPipeline
 * @extends Phaser.GameObjects.Components.Transform
 * @extends Phaser.GameObjects.Components.Visible
 *
 * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time.
 * @param {number} [x=0] - The horizontal position of this Game Object in the world.
 * @param {number} [y=0] - The vertical position of this Game Object in the world.
 * @param {Phaser.GameObjects.GameObject[]} [children] - An optional array of Game Objects to add to this Container.
 */
var Container = new Class({

    Extends: GameObject,

    Mixins: [
        Components.AlphaSingle,
        Components.BlendMode,
        Components.ComputedSize,
        Components.Depth,
        Components.Mask,
        Components.PostPipeline,
        Components.Transform,
        Components.Visible,
        Render
    ],

    initialize:

    function Container (scene, x, y, children)
    {
        GameObject.call(this, scene, 'Container');

        /**
         * An array holding the children of this Container.
         *
         * @name Phaser.GameObjects.Container#list
         * @type {Phaser.GameObjects.GameObject[]}
         * @since 3.4.0
         */
        this.list = [];

        /**
         * Does this Container exclusively manage its children?
         *
         * The default is `true` which means a child added to this Container cannot
         * belong in another Container, which includes the Scene display list.
         *
         * If you disable this then this Container will no longer exclusively manage its children.
         * This allows you to create all kinds of interesting graphical effects, such as replicating
         * Game Objects without reparenting them all over the Scene.
         * However, doing so will prevent children from receiving any kind of input event or have
         * their physics bodies work by default, as they're no longer a single entity on the
         * display list, but are being replicated where-ever this Container is.
         *
         * @name Phaser.GameObjects.Container#exclusive
         * @type {boolean}
         * @default true
         * @since 3.4.0
         */
        this.exclusive = true;

        /**
         * Containers can have an optional maximum size. If set to anything above 0 it
         * will constrict the addition of new Game Objects into the Container, capping off
         * the maximum limit the Container can grow in size to.
         *
         * @name Phaser.GameObjects.Container#maxSize
         * @type {number}
         * @default -1
         * @since 3.4.0
         */
        this.maxSize = -1;

        /**
         * The cursor position.
         *
         * @name Phaser.GameObjects.Container#position
         * @type {number}
         * @since 3.4.0
         */
        this.position = 0;

        /**
         * Internal Transform Matrix used for local space conversion.
         *
         * @name Phaser.GameObjects.Container#localTransform
         * @type {Phaser.GameObjects.Components.TransformMatrix}
         * @since 3.4.0
         */
        this.localTransform = new Components.TransformMatrix();

        /**
         * Internal temporary Transform Matrix used to avoid object creation.
         *
         * @name Phaser.GameObjects.Container#tempTransformMatrix
         * @type {Phaser.GameObjects.Components.TransformMatrix}
         * @private
         * @since 3.4.0
         */
        this.tempTransformMatrix = new Components.TransformMatrix();

        /**
         * The property key to sort by.
         *
         * @name Phaser.GameObjects.Container#_sortKey
         * @type {string}
         * @private
         * @since 3.4.0
         */
        this._sortKey = '';

        /**
         * A reference to the Scene Systems Event Emitter.
         *
         * @name Phaser.GameObjects.Container#_sysEvents
         * @type {Phaser.Events.EventEmitter}
         * @private
         * @since 3.9.0
         */
        this._sysEvents = scene.sys.events;

        /**
         * The horizontal scroll factor of this Container.
         *
         * The scroll factor controls the influence of the movement of a Camera upon this Container.
         *
         * When a camera scrolls it will change the location at which this Container is rendered on-screen.
         * It does not change the Containers actual position values.
         *
         * For a Container, setting this value will only update the Container itself, not its children.
         * If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method.
         *
         * A value of 1 means it will move exactly in sync with a camera.
         * A value of 0 means it will not move at all, even if the camera moves.
         * Other values control the degree to which the camera movement is mapped to this Container.
         *
         * Please be aware that scroll factor values other than 1 are not taken in to consideration when
         * calculating physics collisions. Bodies always collide based on their world position, but changing
         * the scroll factor is a visual adjustment to where the textures are rendered, which can offset
         * them from physics bodies if not accounted for in your code.
         *
         * @name Phaser.GameObjects.Container#scrollFactorX
         * @type {number}
         * @default 1
         * @since 3.4.0
         */
        this.scrollFactorX = 1;

        /**
         * The vertical scroll factor of this Container.
         *
         * The scroll factor controls the influence of the movement of a Camera upon this Container.
         *
         * When a camera scrolls it will change the location at which this Container is rendered on-screen.
         * It does not change the Containers actual position values.
         *
         * For a Container, setting this value will only update the Container itself, not its children.
         * If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method.
         *
         * A value of 1 means it will move exactly in sync with a camera.
         * A value of 0 means it will not move at all, even if the camera moves.
         * Other values control the degree to which the camera movement is mapped to this Container.
         *
         * Please be aware that scroll factor values other than 1 are not taken in to consideration when
         * calculating physics collisions. Bodies always collide based on their world position, but changing
         * the scroll factor is a visual adjustment to where the textures are rendered, which can offset
         * them from physics bodies if not accounted for in your code.
         *
         * @name Phaser.GameObjects.Container#scrollFactorY
         * @type {number}
         * @default 1
         * @since 3.4.0
         */
        this.scrollFactorY = 1;

        this.initPostPipeline();

        this.setPosition(x, y);

        this.setBlendMode(BlendModes.SKIP_CHECK);

        if (children)
        {
            this.add(children);
        }
    },

    /**
     * Internal value to allow Containers to be used for input and physics.
     * Do not change this value. It has no effect other than to break things.
     *
     * @name Phaser.GameObjects.Container#originX
     * @type {number}
     * @readonly
     * @override
     * @since 3.4.0
     */
    originX: {

        get: function ()
        {
            return 0.5;
        }

    },

    /**
     * Internal value to allow Containers to be used for input and physics.
     * Do not change this value. It has no effect other than to break things.
     *
     * @name Phaser.GameObjects.Container#originY
     * @type {number}
     * @readonly
     * @override
     * @since 3.4.0
     */
    originY: {

        get: function ()
        {
            return 0.5;
        }

    },

    /**
     * Internal value to allow Containers to be used for input and physics.
     * Do not change this value. It has no effect other than to break things.
     *
     * @name Phaser.GameObjects.Container#displayOriginX
     * @type {number}
     * @readonly
     * @override
     * @since 3.4.0
     */
    displayOriginX: {

        get: function ()
        {
            return this.width * 0.5;
        }

    },

    /**
     * Internal value to allow Containers to be used for input and physics.
     * Do not change this value. It has no effect other than to break things.
     *
     * @name Phaser.GameObjects.Container#displayOriginY
     * @type {number}
     * @readonly
     * @override
     * @since 3.4.0
     */
    displayOriginY: {

        get: function ()
        {
            return this.height * 0.5;
        }

    },

    /**
     * Does this Container exclusively manage its children?
     *
     * The default is `true` which means a child added to this Container cannot
     * belong in another Container, which includes the Scene display list.
     *
     * If you disable this then this Container will no longer exclusively manage its children.
     * This allows you to create all kinds of interesting graphical effects, such as replicating
     * Game Objects without reparenting them all over the Scene.
     * However, doing so will prevent children from receiving any kind of input event or have
     * their physics bodies work by default, as they're no longer a single entity on the
     * display list, but are being replicated where-ever this Container is.
     *
     * @method Phaser.GameObjects.Container#setExclusive
     * @since 3.4.0
     *
     * @param {boolean} [value=true] - The exclusive state of this Container.
     *
     * @return {this} This Container.
     */
    setExclusive: function (value)
    {
        if (value === undefined) { value = true; }

        this.exclusive = value;

        return this;
    },

    /**
     * Gets the bounds of this Container. It works by iterating all children of the Container,
     * getting their respective bounds, and then working out a min-max rectangle from that.
     * It does not factor in if the children render or not, all are included.
     *
     * Some children are unable to return their bounds, such as Graphics objects, in which case
     * they are skipped.
     *
     * Depending on the quantity of children in this Container it could be a really expensive call,
     * so cache it and only poll it as needed.
     *
     * The values are stored and returned in a Rectangle object.
     *
     * @method Phaser.GameObjects.Container#getBounds
     * @since 3.4.0
     *
     * @param {Phaser.Geom.Rectangle} [output] - A Geom.Rectangle object to store the values in. If not provided a new Rectangle will be created.
     *
     * @return {Phaser.Geom.Rectangle} The values stored in the output object.
     */
    getBounds: function (output)
    {
        if (output === undefined) { output = new Rectangle(); }

        output.setTo(this.x, this.y, 0, 0);

        if (this.parentContainer)
        {
            var parentMatrix = this.parentContainer.getBoundsTransformMatrix();
            var transformedPosition = parentMatrix.transformPoint(this.x, this.y);

            output.setTo(transformedPosition.x, transformedPosition.y, 0, 0);
        }

        if (this.list.length > 0)
        {
            var children = this.list;
            var tempRect = new Rectangle();
            var hasSetFirst = false;

            output.setEmpty();

            for (var i = 0; i < children.length; i++)
            {
                var entry = children[i];

                if (entry.getBounds)
                {
                    entry.getBounds(tempRect);

                    if (!hasSetFirst)
                    {
                        output.setTo(tempRect.x, tempRect.y, tempRect.width, tempRect.height);
                        hasSetFirst = true;
                    }
                    else
                    {
                        Union(tempRect, output, output);
                    }
                }
            }
        }

        return output;
    },

    /**
     * Internal add handler.
     *
     * @method Phaser.GameObjects.Container#addHandler
     * @private
     * @since 3.4.0
     *
     * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just added to this Container.
     */
    addHandler: function (gameObject)
    {
        gameObject.once(Events.DESTROY, this.remove, this);

        if (this.exclusive)
        {
            if (gameObject.parentContainer)
            {
                gameObject.parentContainer.remove(gameObject);
            }

            gameObject.parentContainer = this;

            gameObject.removeFromDisplayList();

            gameObject.addedToScene();
        }
    },

    /**
     * Internal remove handler.
     *
     * @method Phaser.GameObjects.Container#removeHandler
     * @private
     * @since 3.4.0
     *
     * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just removed from this Container.
     */
    removeHandler: function (gameObject)
    {
        gameObject.off(Events.DESTROY, this.remove, this);

        if (this.exclusive)
        {
            gameObject.parentContainer = null;

            gameObject.removedFromScene();

            gameObject.addToDisplayList();
        }
    },

    /**
     * Takes a Point-like object, such as a Vector2, Geom.Point or object with public x and y properties,
     * and transforms it into the space of this Container, then returns it in the output object.
     *
     * @method Phaser.GameObjects.Container#pointToContainer
     * @since 3.4.0
     *
     * @param {Phaser.Types.Math.Vector2Like} source - The Source Point to be transformed.
     * @param {Phaser.Types.Math.Vector2Like} [output] - A destination object to store the transformed point in. If none given a Vector2 will be created and returned.
     *
     * @return {Phaser.Types.Math.Vector2Like} The transformed point.
     */
    pointToContainer: function (source, output)
    {
        if (output === undefined) { output = new Vector2(); }

        if (this.parentContainer)
        {
            this.parentContainer.pointToContainer(source, output);
        }
        else
        {
            output.x = source.x;
            output.y = source.y;
        }

        var tempMatrix = this.tempTransformMatrix;

        //  No need to loadIdentity because applyITRS overwrites every value anyway
        tempMatrix.applyITRS(this.x, this.y, this.rotation, this.scaleX, this.scaleY);

        tempMatrix.invert();

        tempMatrix.transformPoint(source.x, source.y, output);

        return output;
    },

    /**
     * Returns the world transform matrix as used for Bounds checks.
     *
     * The returned matrix is temporal and shouldn't be stored.
     *
     * @method Phaser.GameObjects.Container#getBoundsTransformMatrix
     * @since 3.4.0
     *
     * @return {Phaser.GameObjects.Components.TransformMatrix} The world transform matrix.
     */
    getBoundsTransformMatrix: function ()
    {
        return this.getWorldTransformMatrix(this.tempTransformMatrix, this.localTransform);
    },

    /**
     * Adds the given Game Object, or array of Game Objects, to this Container.
     *
     * Each Game Object must be unique within the Container.
     *
     * @method Phaser.GameObjects.Container#add
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {(T|T[])} - [child]
     *
     * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to add to the Container.
     *
     * @return {this} This Container instance.
     */
    add: function (child)
    {
        ArrayUtils.Add(this.list, child, this.maxSize, this.addHandler, this);

        return this;
    },

    /**
     * Adds the given Game Object, or array of Game Objects, to this Container at the specified position.
     *
     * Existing Game Objects in the Container are shifted up.
     *
     * Each Game Object must be unique within the Container.
     *
     * @method Phaser.GameObjects.Container#addAt
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {(T|T[])} - [child]
     *
     * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to add to the Container.
     * @param {number} [index=0] - The position to insert the Game Object/s at.
     *
     * @return {this} This Container instance.
     */
    addAt: function (child, index)
    {
        ArrayUtils.AddAt(this.list, child, index, this.maxSize, this.addHandler, this);

        return this;
    },

    /**
     * Returns the Game Object at the given position in this Container.
     *
     * @method Phaser.GameObjects.Container#getAt
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [$return]
     *
     * @param {number} index - The position to get the Game Object from.
     *
     * @return {?Phaser.GameObjects.GameObject} The Game Object at the specified index, or `null` if none found.
     */
    getAt: function (index)
    {
        return this.list[index];
    },

    /**
     * Returns the index of the given Game Object in this Container.
     *
     * @method Phaser.GameObjects.Container#getIndex
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [child]
     *
     * @param {Phaser.GameObjects.GameObject} child - The Game Object to search for in this Container.
     *
     * @return {number} The index of the Game Object in this Container, or -1 if not found.
     */
    getIndex: function (child)
    {
        return this.list.indexOf(child);
    },

    /**
     * Sort the contents of this Container so the items are in order based on the given property.
     * For example: `sort('alpha')` would sort the elements based on the value of their `alpha` property.
     *
     * @method Phaser.GameObjects.Container#sort
     * @since 3.4.0
     *
     * @param {string} property - The property to lexically sort by.
     * @param {function} [handler] - Provide your own custom handler function. Will receive 2 children which it should compare and return a boolean.
     *
     * @return {this} This Container instance.
     */
    sort: function (property, handler)
    {
        if (!property)
        {
            return this;
        }

        if (handler === undefined)
        {
            handler = function (childA, childB)
            {
                return childA[property] - childB[property];
            };
        }

        ArrayUtils.StableSort(this.list, handler);

        return this;
    },

    /**
     * Searches for the first instance of a child with its `name` property matching the given argument.
     * Should more than one child have the same name only the first is returned.
     *
     * @method Phaser.GameObjects.Container#getByName
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [$return]
     *
     * @param {string} name - The name to search for.
     *
     * @return {?Phaser.GameObjects.GameObject} The first child with a matching name, or `null` if none were found.
     */
    getByName: function (name)
    {
        return ArrayUtils.GetFirst(this.list, 'name', name);
    },

    /**
     * Returns a random Game Object from this Container.
     *
     * @method Phaser.GameObjects.Container#getRandom
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [$return]
     *
     * @param {number} [startIndex=0] - An optional start index.
     * @param {number} [length] - An optional length, the total number of elements (from the startIndex) to choose from.
     *
     * @return {?Phaser.GameObjects.GameObject} A random child from the Container, or `null` if the Container is empty.
     */
    getRandom: function (startIndex, length)
    {
        return ArrayUtils.GetRandom(this.list, startIndex, length);
    },

    /**
     * Gets the first Game Object in this Container.
     *
     * You can also specify a property and value to search for, in which case it will return the first
     * Game Object in this Container with a matching property and / or value.
     *
     * For example: `getFirst('visible', true)` would return the first Game Object that had its `visible` property set.
     *
     * You can limit the search to the `startIndex` - `endIndex` range.
     *
     * @method Phaser.GameObjects.Container#getFirst
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [$return]
     *
     * @param {string} property - The property to test on each Game Object in the Container.
     * @param {*} value - The value to test the property against. Must pass a strict (`===`) comparison check.
     * @param {number} [startIndex=0] - An optional start index to search from.
     * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included)
     *
     * @return {?Phaser.GameObjects.GameObject} The first matching Game Object, or `null` if none was found.
     */
    getFirst: function (property, value, startIndex, endIndex)
    {
        return ArrayUtils.GetFirst(this.list, property, value, startIndex, endIndex);
    },

    /**
     * Returns all Game Objects in this Container.
     *
     * You can optionally specify a matching criteria using the `property` and `value` arguments.
     *
     * For example: `getAll('body')` would return only Game Objects that have a body property.
     *
     * You can also specify a value to compare the property to:
     *
     * `getAll('visible', true)` would return only Game Objects that have their visible property set to `true`.
     *
     * Optionally you can specify a start and end index. For example if this Container had 100 Game Objects,
     * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only
     * the first 50 Game Objects.
     *
     * @method Phaser.GameObjects.Container#getAll
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T[]} - [$return]
     *
     * @param {string} [property] - The property to test on each Game Object in the Container.
     * @param {any} [value] - If property is set then the `property` must strictly equal this value to be included in the results.
     * @param {number} [startIndex=0] - An optional start index to search from.
     * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included)
     *
     * @return {Phaser.GameObjects.GameObject[]} An array of matching Game Objects from this Container.
     */
    getAll: function (property, value, startIndex, endIndex)
    {
        return ArrayUtils.GetAll(this.list, property, value, startIndex, endIndex);
    },

    /**
     * Returns the total number of Game Objects in this Container that have a property
     * matching the given value.
     *
     * For example: `count('visible', true)` would count all the elements that have their visible property set.
     *
     * You can optionally limit the operation to the `startIndex` - `endIndex` range.
     *
     * @method Phaser.GameObjects.Container#count
     * @since 3.4.0
     *
     * @param {string} property - The property to check.
     * @param {any} value - The value to check.
     * @param {number} [startIndex=0] - An optional start index to search from.
     * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included)
     *
     * @return {number} The total number of Game Objects in this Container with a property matching the given value.
     */
    count: function (property, value, startIndex, endIndex)
    {
        return ArrayUtils.CountAllMatching(this.list, property, value, startIndex, endIndex);
    },

    /**
     * Swaps the position of two Game Objects in this Container.
     * Both Game Objects must belong to this Container.
     *
     * @method Phaser.GameObjects.Container#swap
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [child1,child2]
     *
     * @param {Phaser.GameObjects.GameObject} child1 - The first Game Object to swap.
     * @param {Phaser.GameObjects.GameObject} child2 - The second Game Object to swap.
     *
     * @return {this} This Container instance.
     */
    swap: function (child1, child2)
    {
        ArrayUtils.Swap(this.list, child1, child2);

        return this;
    },

    /**
     * Moves a Game Object to a new position within this Container.
     *
     * The Game Object must already be a child of this Container.
     *
     * The Game Object is removed from its old position and inserted into the new one.
     * Therefore the Container size does not change. Other children will change position accordingly.
     *
     * @method Phaser.GameObjects.Container#moveTo
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [child]
     *
     * @param {Phaser.GameObjects.GameObject} child - The Game Object to move.
     * @param {number} index - The new position of the Game Object in this Container.
     *
     * @return {this} This Container instance.
     */
    moveTo: function (child, index)
    {
        ArrayUtils.MoveTo(this.list, child, index);

        return this;
    },

    /**
     * Moves a Game Object above another one within this Container.
     *
     * These 2 Game Objects must already be children of this Container.
     *
     * @method Phaser.GameObjects.Container#moveAbove
     * @since 3.55.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [child1,child2]
     *
     * @param {Phaser.GameObjects.GameObject} child1 - The Game Object to move above base Game Object.
     * @param {Phaser.GameObjects.GameObject} child2 - The base Game Object.
     *
     * @return {this} This Container instance.
     */
    moveAbove: function (child1, child2)
    {
        ArrayUtils.MoveAbove(this.list, child1, child2);

        return this;
    },

    /**
     * Moves a Game Object below another one within this Container.
     *
     * These 2 Game Objects must already be children of this Container.
     *
     * @method Phaser.GameObjects.Container#moveBelow
     * @since 3.55.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [child1,child2]
     *
     * @param {Phaser.GameObjects.GameObject} child1 - The Game Object to move below base Game Object.
     * @param {Phaser.GameObjects.GameObject} child2 - The base Game Object.
     *
     * @return {this} This Container instance.
     */
    moveBelow: function (child1, child2)
    {
        ArrayUtils.MoveBelow(this.list, child1, child2);

        return this;
    },

    /**
     * Removes the given Game Object, or array of Game Objects, from this Container.
     *
     * The Game Objects must already be children of this Container.
     *
     * You can also optionally call `destroy` on each Game Object that is removed from the Container.
     *
     * @method Phaser.GameObjects.Container#remove
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {(T|T[])} - [child]
     *
     * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to be removed from the Container.
     * @param {boolean} [destroyChild=false] - Optionally call `destroy` on each child successfully removed from this Container.
     *
     * @return {this} This Container instance.
     */
    remove: function (child, destroyChild)
    {
        var removed = ArrayUtils.Remove(this.list, child, this.removeHandler, this);

        if (destroyChild && removed)
        {
            if (!Array.isArray(removed))
            {
                removed = [ removed ];
            }

            for (var i = 0; i < removed.length; i++)
            {
                removed[i].destroy();
            }
        }

        return this;
    },

    /**
     * Removes the Game Object at the given position in this Container.
     *
     * You can also optionally call `destroy` on the Game Object, if one is found.
     *
     * @method Phaser.GameObjects.Container#removeAt
     * @since 3.4.0
     *
     * @param {number} index - The index of the Game Object to be removed.
     * @param {boolean} [destroyChild=false] - Optionally call `destroy` on the Game Object if successfully removed from this Container.
     *
     * @return {this} This Container instance.
     */
    removeAt: function (index, destroyChild)
    {
        var removed = ArrayUtils.RemoveAt(this.list, index, this.removeHandler, this);

        if (destroyChild && removed)
        {
            removed.destroy();
        }

        return this;
    },

    /**
     * Removes the Game Objects between the given positions in this Container.
     *
     * You can also optionally call `destroy` on each Game Object that is removed from the Container.
     *
     * @method Phaser.GameObjects.Container#removeBetween
     * @since 3.4.0
     *
     * @param {number} [startIndex=0] - An optional start index to search from.
     * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included)
     * @param {boolean} [destroyChild=false] - Optionally call `destroy` on each Game Object successfully removed from this Container.
     *
     * @return {this} This Container instance.
     */
    removeBetween: function (startIndex, endIndex, destroyChild)
    {
        var removed = ArrayUtils.RemoveBetween(this.list, startIndex, endIndex, this.removeHandler, this);

        if (destroyChild)
        {
            for (var i = 0; i < removed.length; i++)
            {
                removed[i].destroy();
            }
        }

        return this;
    },

    /**
     * Removes all Game Objects from this Container.
     *
     * You can also optionally call `destroy` on each Game Object that is removed from the Container.
     *
     * @method Phaser.GameObjects.Container#removeAll
     * @since 3.4.0
     *
     * @param {boolean} [destroyChild=false] - Optionally call `destroy` on each Game Object successfully removed from this Container.
     *
     * @return {this} This Container instance.
     */
    removeAll: function (destroyChild)
    {
        var list = this.list;

        if (destroyChild)
        {
            for (var i = 0; i < list.length; i++)
            {
                if (list[i] && list[i].scene)
                {
                    list[i].off(Events.DESTROY, this.remove, this);

                    list[i].destroy();
                }
            }

            this.list = [];
        }
        else
        {
            ArrayUtils.RemoveBetween(list, 0, list.length, this.removeHandler, this);
        }

        return this;
    },

    /**
     * Brings the given Game Object to the top of this Container.
     * This will cause it to render on-top of any other objects in the Container.
     *
     * @method Phaser.GameObjects.Container#bringToTop
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [child]
     *
     * @param {Phaser.GameObjects.GameObject} child - The Game Object to bring to the top of the Container.
     *
     * @return {this} This Container instance.
     */
    bringToTop: function (child)
    {
        ArrayUtils.BringToTop(this.list, child);

        return this;
    },

    /**
     * Sends the given Game Object to the bottom of this Container.
     * This will cause it to render below any other objects in the Container.
     *
     * @method Phaser.GameObjects.Container#sendToBack
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [child]
     *
     * @param {Phaser.GameObjects.GameObject} child - The Game Object to send to the bottom of the Container.
     *
     * @return {this} This Container instance.
     */
    sendToBack: function (child)
    {
        ArrayUtils.SendToBack(this.list, child);

        return this;
    },

    /**
     * Moves the given Game Object up one place in this Container, unless it's already at the top.
     *
     * @method Phaser.GameObjects.Container#moveUp
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [child]
     *
     * @param {Phaser.GameObjects.GameObject} child - The Game Object to be moved in the Container.
     *
     * @return {this} This Container instance.
     */
    moveUp: function (child)
    {
        ArrayUtils.MoveUp(this.list, child);

        return this;
    },

    /**
     * Moves the given Game Object down one place in this Container, unless it's already at the bottom.
     *
     * @method Phaser.GameObjects.Container#moveDown
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [child]
     *
     * @param {Phaser.GameObjects.GameObject} child - The Game Object to be moved in the Container.
     *
     * @return {this} This Container instance.
     */
    moveDown: function (child)
    {
        ArrayUtils.MoveDown(this.list, child);

        return this;
    },

    /**
     * Reverses the order of all Game Objects in this Container.
     *
     * @method Phaser.GameObjects.Container#reverse
     * @since 3.4.0
     *
     * @return {this} This Container instance.
     */
    reverse: function ()
    {
        this.list.reverse();

        return this;
    },

    /**
     * Shuffles the all Game Objects in this Container using the Fisher-Yates implementation.
     *
     * @method Phaser.GameObjects.Container#shuffle
     * @since 3.4.0
     *
     * @return {this} This Container instance.
     */
    shuffle: function ()
    {
        ArrayUtils.Shuffle(this.list);

        return this;
    },

    /**
     * Replaces a Game Object in this Container with the new Game Object.
     * The new Game Object cannot already be a child of this Container.
     *
     * @method Phaser.GameObjects.Container#replace
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [oldChild,newChild]
     *
     * @param {Phaser.GameObjects.GameObject} oldChild - The Game Object in this Container that will be replaced.
     * @param {Phaser.GameObjects.GameObject} newChild - The Game Object to be added to this Container.
     * @param {boolean} [destroyChild=false] - Optionally call `destroy` on the Game Object if successfully removed from this Container.
     *
     * @return {this} This Container instance.
     */
    replace: function (oldChild, newChild, destroyChild)
    {
        var moved = ArrayUtils.Replace(this.list, oldChild, newChild);

        if (moved)
        {
            this.addHandler(newChild);
            this.removeHandler(oldChild);

            if (destroyChild)
            {
                oldChild.destroy();
            }
        }

        return this;
    },

    /**
     * Returns `true` if the given Game Object is a direct child of this Container.
     *
     * This check does not scan nested Containers.
     *
     * @method Phaser.GameObjects.Container#exists
     * @since 3.4.0
     *
     * @generic {Phaser.GameObjects.GameObject} T
     * @genericUse {T} - [child]
     *
     * @param {Phaser.GameObjects.GameObject} child - The Game Object to check for within this Container.
     *
     * @return {boolean} True if the Game Object is an immediate child of this Container, otherwise false.
     */
    exists: function (child)
    {
        return (this.list.indexOf(child) > -1);
    },

    /**
     * Sets the property to the given value on all Game Objects in this Container.
     *
     * Optionally you can specify a start and end index. For example if this Container had 100 Game Objects,
     * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only
     * the first 50 Game Objects.
     *
     * @method Phaser.GameObjects.Container#setAll
     * @since 3.4.0
     *
     * @param {string} property - The property that must exist on the Game Object.
     * @param {any} value - The value to get the property to.
     * @param {number} [startIndex=0] - An optional start index to search from.
     * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included)
     *
     * @return {this} This Container instance.
     */
    setAll: function (property, value, startIndex, endIndex)
    {
        ArrayUtils.SetAll(this.list, property, value, startIndex, endIndex);

        return this;
    },

    /**
     * @callback EachContainerCallback
     * @generic I - [item]
     *
     * @param {*} item - The child Game Object of the Container.
     * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
     */

    /**
     * Passes all Game Objects in this Container to the given callback.
     *
     * A copy of the Container is made before passing each entry to your callback.
     * This protects against the callback itself modifying the Container.
     *
     * If you know for sure that the callback will not change the size of this Container
     * then you can use the more performant `Container.iterate` method instead.
     *
     * @method Phaser.GameObjects.Container#each
     * @since 3.4.0
     *
     * @param {function} callback - The function to call.
     * @param {object} [context] - Value to use as `this` when executing callback.
     * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
     *
     * @return {this} This Container instance.
     */
    each: function (callback, context)
    {
        var args = [ null ];
        var i;
        var temp = this.list.slice();
        var len = temp.length;

        for (i = 2; i < arguments.length; i++)
        {
            args.push(arguments[i]);
        }

        for (i = 0; i < len; i++)
        {
            args[0] = temp[i];

            callback.apply(context, args);
        }

        return this;
    },

    /**
     * Passes all Game Objects in this Container to the given callback.
     *
     * Only use this method when you absolutely know that the Container will not be modified during
     * the iteration, i.e. by removing or adding to its contents.
     *
     * @method Phaser.GameObjects.Container#iterate
     * @since 3.4.0
     *
     * @param {function} callback - The function to call.
     * @param {object} [context] - Value to use as `this` when executing callback.
     * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
     *
     * @return {this} This Container instance.
     */
    iterate: function (callback, context)
    {
        var args = [ null ];
        var i;

        for (i = 2; i < arguments.length; i++)
        {
            args.push(arguments[i]);
        }

        for (i = 0; i < this.list.length; i++)
        {
            args[0] = this.list[i];

            callback.apply(context, args);
        }

        return this;
    },

    /**
     * Sets the scroll factor of this Container and optionally all of its children.
     *
     * The scroll factor controls the influence of the movement of a Camera upon this Game Object.
     *
     * When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
     * It does not change the Game Objects actual position values.
     *
     * A value of 1 means it will move exactly in sync with a camera.
     * A value of 0 means it will not move at all, even if the camera moves.
     * Other values control the degree to which the camera movement is mapped to this Game Object.
     *
     * Please be aware that scroll factor values other than 1 are not taken in to consideration when
     * calculating physics collisions. Bodies always collide based on their world position, but changing
     * the scroll factor is a visual adjustment to where the textures are rendered, which can offset
     * them from physics bodies if not accounted for in your code.
     *
     * @method Phaser.GameObjects.Container#setScrollFactor
     * @since 3.4.0
     *
     * @param {number} x - The horizontal scroll factor of this Game Object.
     * @param {number} [y=x] - The vertical scroll factor of this Game Object. If not set it will use the `x` value.
     * @param {boolean} [updateChildren=false] - Apply this scrollFactor to all Container children as well?
     *
     * @return {this} This Game Object instance.
     */
    setScrollFactor: function (x, y, updateChildren)
    {
        if (y === undefined) { y = x; }
        if (updateChildren === undefined) { updateChildren = false; }

        this.scrollFactorX = x;
        this.scrollFactorY = y;

        if (updateChildren)
        {
            ArrayUtils.SetAll(this.list, 'scrollFactorX', x);
            ArrayUtils.SetAll(this.list, 'scrollFactorY', y);
        }

        return this;
    },

    /**
     * The number of Game Objects inside this Container.
     *
     * @name Phaser.GameObjects.Container#length
     * @type {number}
     * @readonly
     * @since 3.4.0
     */
    length: {

        get: function ()
        {
            return this.list.length;
        }

    },

    /**
     * Returns the first Game Object within the Container, or `null` if it is empty.
     *
     * You can move the cursor by calling `Container.next` and `Container.previous`.
     *
     * @name Phaser.GameObjects.Container#first
     * @type {?Phaser.GameObjects.GameObject}
     * @readonly
     * @since 3.4.0
     */
    first: {

        get: function ()
        {
            this.position = 0;

            if (this.list.length > 0)
            {
                return this.list[0];
            }
            else
            {
                return null;
            }
        }

    },

    /**
     * Returns the last Game Object within the Container, or `null` if it is empty.
     *
     * You can move the cursor by calling `Container.next` and `Container.previous`.
     *
     * @name Phaser.GameObjects.Container#last
     * @type {?Phaser.GameObjects.GameObject}
     * @readonly
     * @since 3.4.0
     */
    last: {

        get: function ()
        {
            if (this.list.length > 0)
            {
                this.position = this.list.length - 1;

                return this.list[this.position];
            }
            else
            {
                return null;
            }
        }

    },

    /**
     * Returns the next Game Object within the Container, or `null` if it is empty.
     *
     * You can move the cursor by calling `Container.next` and `Container.previous`.
     *
     * @name Phaser.GameObjects.Container#next
     * @type {?Phaser.GameObjects.GameObject}
     * @readonly
     * @since 3.4.0
     */
    next: {

        get: function ()
        {
            if (this.position < this.list.length)
            {
                this.position++;

                return this.list[this.position];
            }
            else
            {
                return null;
            }
        }

    },

    /**
     * Returns the previous Game Object within the Container, or `null` if it is empty.
     *
     * You can move the cursor by calling `Container.next` and `Container.previous`.
     *
     * @name Phaser.GameObjects.Container#previous
     * @type {?Phaser.GameObjects.GameObject}
     * @readonly
     * @since 3.4.0
     */
    previous: {

        get: function ()
        {
            if (this.position > 0)
            {
                this.position--;

                return this.list[this.position];
            }
            else
            {
                return null;
            }
        }

    },

    /**
     * Internal destroy handler, called as part of the destroy process.
     *
     * @method Phaser.GameObjects.Container#preDestroy
     * @protected
     * @since 3.9.0
     */
    preDestroy: function ()
    {
        this.removeAll(!!this.exclusive);

        this.localTransform.destroy();
        this.tempTransformMatrix.destroy();

        this.list = [];
    }

});

module.exports = Container;


/***/ }),

/***/ 2840:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       Felipe Alfonso <@bitnenfer>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Renders this Game Object with the Canvas Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method Phaser.GameObjects.Container#renderCanvas
 * @since 3.4.0
 * @private
 *
 * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer.
 * @param {Phaser.GameObjects.Container} container - The Game Object being rendered in this call.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
 */
var ContainerCanvasRenderer = function (renderer, container, camera, parentMatrix)
{
    camera.addToRenderList(container);

    var children = container.list;

    if (children.length === 0)
    {
        return;
    }

    var transformMatrix = container.localTransform;

    if (parentMatrix)
    {
        transformMatrix.loadIdentity();
        transformMatrix.multiply(parentMatrix);
        transformMatrix.translate(container.x, container.y);
        transformMatrix.rotate(container.rotation);
        transformMatrix.scale(container.scaleX, container.scaleY);
    }
    else
    {
        transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY);
    }

    var containerHasBlendMode = (container.blendMode !== -1);

    if (!containerHasBlendMode)
    {
        //  If Container is SKIP_TEST then set blend mode to be Normal
        renderer.setBlendMode(0);
    }

    var alpha = container._alpha;
    var scrollFactorX = container.scrollFactorX;
    var scrollFactorY = container.scrollFactorY;

    if (container.mask)
    {
        container.mask.preRenderCanvas(renderer, null, camera);
    }

    for (var i = 0; i < children.length; i++)
    {
        var child = children[i];

        if (!child.willRender(camera))
        {
            continue;
        }

        var childAlpha = child.alpha;
        var childScrollFactorX = child.scrollFactorX;
        var childScrollFactorY = child.scrollFactorY;

        if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode)
        {
            //  If Container doesn't have its own blend mode, then a child can have one
            renderer.setBlendMode(child.blendMode);
        }

        //  Set parent values
        child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY);
        child.setAlpha(childAlpha * alpha);

        //  Render
        child.renderCanvas(renderer, child, camera, transformMatrix);

        //  Restore original values
        child.setAlpha(childAlpha);
        child.setScrollFactor(childScrollFactorX, childScrollFactorY);
    }

    if (container.mask)
    {
        container.mask.postRenderCanvas(renderer);
    }
};

module.exports = ContainerCanvasRenderer;


/***/ }),

/***/ 3232:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       Felipe Alfonso <@bitnenfer>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var NOOP = __webpack_require__(1984);
var renderWebGL = NOOP;
var renderCanvas = NOOP;

if (true)
{
    renderWebGL = __webpack_require__(4343);
}

if (true)
{
    renderCanvas = __webpack_require__(2840);
}

module.exports = {

    renderWebGL: renderWebGL,
    renderCanvas: renderCanvas

};


/***/ }),

/***/ 4343:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       Felipe Alfonso <@bitnenfer>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Renders this Game Object with the WebGL Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method Phaser.GameObjects.Container#renderWebGL
 * @since 3.4.0
 * @private
 *
 * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
 * @param {Phaser.GameObjects.Container} container - The Game Object being rendered in this call.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
 */
var ContainerWebGLRenderer = function (renderer, container, camera, parentMatrix)
{
    camera.addToRenderList(container);

    var children = container.list;
    var childCount = children.length;

    if (childCount === 0)
    {
        return;
    }

    var transformMatrix = container.localTransform;

    if (parentMatrix)
    {
        transformMatrix.loadIdentity();
        transformMatrix.multiply(parentMatrix);
        transformMatrix.translate(container.x, container.y);
        transformMatrix.rotate(container.rotation);
        transformMatrix.scale(container.scaleX, container.scaleY);
    }
    else
    {
        transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY);
    }

    renderer.pipelines.preBatch(container);

    var containerHasBlendMode = (container.blendMode !== -1);

    if (!containerHasBlendMode)
    {
        //  If Container is SKIP_TEST then set blend mode to be Normal
        renderer.setBlendMode(0);
    }

    var alpha = container.alpha;

    var scrollFactorX = container.scrollFactorX;
    var scrollFactorY = container.scrollFactorY;

    for (var i = 0; i < childCount; i++)
    {
        var child = children[i];

        if (!child.willRender(camera))
        {
            continue;
        }

        var childAlphaTopLeft;
        var childAlphaTopRight;
        var childAlphaBottomLeft;
        var childAlphaBottomRight;

        if (child.alphaTopLeft !== undefined)
        {
            childAlphaTopLeft = child.alphaTopLeft;
            childAlphaTopRight = child.alphaTopRight;
            childAlphaBottomLeft = child.alphaBottomLeft;
            childAlphaBottomRight = child.alphaBottomRight;
        }
        else
        {
            var childAlpha = child.alpha;

            childAlphaTopLeft = childAlpha;
            childAlphaTopRight = childAlpha;
            childAlphaBottomLeft = childAlpha;
            childAlphaBottomRight = childAlpha;
        }

        var childScrollFactorX = child.scrollFactorX;
        var childScrollFactorY = child.scrollFactorY;

        if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode)
        {
            //  If Container doesn't have its own blend mode, then a child can have one
            renderer.setBlendMode(child.blendMode);
        }

        var mask = child.mask;

        if (mask)
        {
            mask.preRenderWebGL(renderer, child, camera);
        }

        var type = child.type;

        if (type !== renderer.currentType)
        {
            renderer.newType = true;
            renderer.currentType = type;
        }

        renderer.nextTypeMatch = (i < childCount - 1) ? (children[i + 1].type === renderer.currentType) : false;

        //  Set parent values
        child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY);

        child.setAlpha(childAlphaTopLeft * alpha, childAlphaTopRight * alpha, childAlphaBottomLeft * alpha, childAlphaBottomRight * alpha);

        //  Render
        child.renderWebGL(renderer, child, camera, transformMatrix, container);

        //  Restore original values

        child.setAlpha(childAlphaTopLeft, childAlphaTopRight, childAlphaBottomLeft, childAlphaBottomRight);

        child.setScrollFactor(childScrollFactorX, childScrollFactorY);

        if (mask)
        {
            mask.postRenderWebGL(renderer, camera);
        }

        renderer.newType = false;
    }

    renderer.pipelines.postBatch(container);
};

module.exports = ContainerWebGLRenderer;


/***/ }),

/***/ 6608:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Game Object Added to Scene Event.
 *
 * This event is dispatched when a Game Object is added to a Scene.
 *
 * Listen for it on a Game Object instance using `GameObject.on('addedtoscene', listener)`.
 *
 * @event Phaser.GameObjects.Events#ADDED_TO_SCENE
 * @type {string}
 * @since 3.50.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the Scene.
 * @param {Phaser.Scene} scene - The Scene to which the Game Object was added.
 */
module.exports = 'addedtoscene';


/***/ }),

/***/ 4265:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Game Object Destroy Event.
 *
 * This event is dispatched when a Game Object instance is being destroyed.
 *
 * Listen for it on a Game Object instance using `GameObject.on('destroy', listener)`.
 *
 * @event Phaser.GameObjects.Events#DESTROY
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object which is being destroyed.
 * @param {boolean} fromScene - `True` if this Game Object is being destroyed by the Scene, `false` if not.
 */
module.exports = 'destroy';


/***/ }),

/***/ 8671:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Game Object Removed from Scene Event.
 *
 * This event is dispatched when a Game Object is removed from a Scene.
 *
 * Listen for it on a Game Object instance using `GameObject.on('removedfromscene', listener)`.
 *
 * @event Phaser.GameObjects.Events#REMOVED_FROM_SCENE
 * @type {string}
 * @since 3.50.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the Scene.
 * @param {Phaser.Scene} scene - The Scene from which the Game Object was removed.
 */
module.exports = 'removedfromscene';


/***/ }),

/***/ 3420:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Complete Event.
 *
 * This event is dispatched when a Video finishes playback by reaching the end of its duration. It
 * is also dispatched if a video marker sequence is being played and reaches the end.
 *
 * Note that not all videos can fire this event. Live streams, for example, have no fixed duration,
 * so never technically 'complete'.
 *
 * If a video is stopped from playback, via the `Video.stop` method, it will emit the
 * `VIDEO_STOP` event instead of this one.
 *
 * Listen for it from a Video Game Object instance using `Video.on('complete', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_COMPLETE
 * @type {string}
 * @since 3.20.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which completed playback.
 */
module.exports = 'complete';


/***/ }),

/***/ 601:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Created Event.
 *
 * This event is dispatched when the texture for a Video has been created. This happens
 * when enough of the video source has been loaded that the browser is able to render a
 * frame from it.
 *
 * Listen for it from a Video Game Object instance using `Video.on('created', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_CREATED
 * @type {string}
 * @since 3.20.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which raised the event.
 * @param {number} width - The width of the video.
 * @param {number} height - The height of the video.
 */
module.exports = 'created';


/***/ }),

/***/ 7919:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Error Event.
 *
 * This event is dispatched when a Video tries to play a source that does not exist, or is the wrong file type.
 *
 * Listen for it from a Video Game Object instance using `Video.on('error', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_ERROR
 * @type {string}
 * @since 3.20.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which threw the error.
 * @param {DOMException|string} event - The native DOM event the browser raised during playback.
 */
module.exports = 'error';


/***/ }),

/***/ 6231:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Locked Event.
 *
 * This event is dispatched when a Video was attempted to be played, but the browser prevented it
 * from doing so due to the Media Engagement Interaction policy.
 *
 * If you get this event you will need to wait for the user to interact with the browser before
 * the video will play. This is a browser security measure to prevent autoplaying videos with
 * audio. An interaction includes a mouse click, a touch, or a key press.
 *
 * Listen for it from a Video Game Object instance using `Video.on('locked', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_LOCKED
 * @type {string}
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which raised the event.
 */
module.exports = 'locked';


/***/ }),

/***/ 5241:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Loop Event.
 *
 * This event is dispatched when a Video that is currently playing has looped. This only
 * happens if the `loop` parameter was specified, or the `setLoop` method was called,
 * and if the video has a fixed duration. Video streams, for example, cannot loop, as
 * they have no duration.
 *
 * Looping is based on the result of the Video `timeupdate` event. This event is not
 * frame-accurate, due to the way browsers work, so please do not rely on this loop
 * event to be time or frame precise.
 *
 * Listen for it from a Video Game Object instance using `Video.on('loop', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_LOOP
 * @type {string}
 * @since 3.20.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which has looped.
 */
module.exports = 'loop';


/***/ }),

/***/ 8325:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Playing Event.
 *
 * The playing event is fired after playback is first started,
 * and whenever it is restarted. For example it is fired when playback
 * resumes after having been paused or delayed due to lack of data.
 *
 * Listen for it from a Video Game Object instance using `Video.on('playing', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_PLAYING
 * @type {string}
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which started playback.
 */
module.exports = 'playing';


/***/ }),

/***/ 3356:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Play Event.
 *
 * This event is dispatched when a Video begins playback. For videos that do not require
 * interaction unlocking, this is usually as soon as the `Video.play` method is called.
 * However, for videos that require unlocking, it is fired once playback begins after
 * they've been unlocked.
 *
 * Listen for it from a Video Game Object instance using `Video.on('play', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_PLAY
 * @type {string}
 * @since 3.20.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which started playback.
 */
module.exports = 'play';


/***/ }),

/***/ 7513:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Seeked Event.
 *
 * This event is dispatched when a Video completes seeking to a new point in its timeline.
 *
 * Listen for it from a Video Game Object instance using `Video.on('seeked', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_SEEKED
 * @type {string}
 * @since 3.20.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which completed seeking.
 */
module.exports = 'seeked';


/***/ }),

/***/ 5788:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Seeking Event.
 *
 * This event is dispatched when a Video _begins_ seeking to a new point in its timeline.
 * When the seek is complete, it will dispatch the `VIDEO_SEEKED` event to conclude.
 *
 * Listen for it from a Video Game Object instance using `Video.on('seeking', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_SEEKING
 * @type {string}
 * @since 3.20.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which started seeking.
 */
module.exports = 'seeking';


/***/ }),

/***/ 7111:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Stalled Event.
 *
 * This event is dispatched by a Video Game Object when the video playback stalls.
 *
 * This can happen if the video is buffering.
 *
 * If will fire for any of the following native DOM events:
 *
 * `stalled`
 * `suspend`
 * `waiting`
 *
 * Listen for it from a Video Game Object instance using `Video.on('stalled', listener)`.
 *
 * Note that being stalled isn't always a negative thing. A video can be stalled if it
 * has downloaded enough data in to its buffer to not need to download any more until
 * the current batch of frames have rendered.
 *
 * @event Phaser.GameObjects.Events#VIDEO_STALLED
 * @type {string}
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which threw the error.
 * @param {Event} event - The native DOM event the browser raised during playback.
 */
module.exports = 'stalled';


/***/ }),

/***/ 8118:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Stopped Event.
 *
 * This event is dispatched when a Video is stopped from playback via a call to the `Video.stop` method,
 * either directly via game code, or indirectly as the result of changing a video source or destroying it.
 *
 * Listen for it from a Video Game Object instance using `Video.on('stop', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_STOP
 * @type {string}
 * @since 3.20.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which stopped playback.
 */
module.exports = 'stop';


/***/ }),

/***/ 9184:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Texture Ready Event.
 *
 * This event is dispatched by a Video Game Object when it has finished creating its texture.
 *
 * This happens when the video has finished loading enough data for its first frame.
 *
 * If you wish to use the Video texture elsewhere in your game, such as as a Sprite texture,
 * then you should listen for this event first, before creating the Sprites that use it.
 *
 * Listen for it from a Video Game Object instance using `Video.on('textureready', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_TEXTURE
 * @type {string}
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object that emitted the event.
 * @param {Phaser.Textures.Texture} texture - The Texture that was created.
 */
module.exports = 'textureready';


/***/ }),

/***/ 4287:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Unlocked Event.
 *
 * This event is dispatched when a Video that was prevented from playback due to the browsers
 * Media Engagement Interaction policy, is unlocked by a user gesture.
 *
 * Listen for it from a Video Game Object instance using `Video.on('unlocked', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_UNLOCKED
 * @type {string}
 * @since 3.20.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which raised the event.
 */
module.exports = 'unlocked';


/***/ }),

/***/ 857:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Video Game Object Unsupported Event.
 *
 * This event is dispatched by a Video Game Object if the media source
 * (which may be specified as a MediaStream, MediaSource, Blob, or File,
 * for example) doesn't represent a supported media format.
 *
 * Listen for it from a Video Game Object instance using `Video.on('unsupported', listener)`.
 *
 * @event Phaser.GameObjects.Events#VIDEO_UNSUPPORTED
 * @type {string}
 * @since 3.60.0
 *
 * @param {Phaser.GameObjects.Video} video - The Video Game Object which started playback.
 * @param {DOMException|string} event - The native DOM event the browser raised during playback.
 */
module.exports = 'unsupported';


/***/ }),

/***/ 3389:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.GameObjects.Events
 */

module.exports = {

    ADDED_TO_SCENE: __webpack_require__(6608),
    DESTROY: __webpack_require__(4265),
    REMOVED_FROM_SCENE: __webpack_require__(8671),
    VIDEO_COMPLETE: __webpack_require__(3420),
    VIDEO_CREATED: __webpack_require__(601),
    VIDEO_ERROR: __webpack_require__(7919),
    VIDEO_LOCKED: __webpack_require__(6231),
    VIDEO_LOOP: __webpack_require__(5241),
    VIDEO_PLAY: __webpack_require__(3356),
    VIDEO_PLAYING: __webpack_require__(8325),
    VIDEO_SEEKED: __webpack_require__(7513),
    VIDEO_SEEKING: __webpack_require__(5788),
    VIDEO_STALLED: __webpack_require__(7111),
    VIDEO_STOP: __webpack_require__(8118),
    VIDEO_TEXTURE: __webpack_require__(9184),
    VIDEO_UNLOCKED: __webpack_require__(4287),
    VIDEO_UNSUPPORTED: __webpack_require__(857)

};


/***/ }),

/***/ 1643:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var GEOM_CONST = {

    /**
     * A Circle Geometry object type.
     *
     * @name Phaser.Geom.CIRCLE
     * @type {number}
     * @since 3.19.0
     */
    CIRCLE: 0,

    /**
     * An Ellipse Geometry object type.
     *
     * @name Phaser.Geom.ELLIPSE
     * @type {number}
     * @since 3.19.0
     */
    ELLIPSE: 1,

    /**
     * A Line Geometry object type.
     *
     * @name Phaser.Geom.LINE
     * @type {number}
     * @since 3.19.0
     */
    LINE: 2,

    /**
     * A Point Geometry object type.
     *
     * @name Phaser.Geom.POINT
     * @type {number}
     * @since 3.19.0
     */
    POINT: 3,

    /**
     * A Polygon Geometry object type.
     *
     * @name Phaser.Geom.POLYGON
     * @type {number}
     * @since 3.19.0
     */
    POLYGON: 4,

    /**
     * A Rectangle Geometry object type.
     *
     * @name Phaser.Geom.RECTANGLE
     * @type {number}
     * @since 3.19.0
     */
    RECTANGLE: 5,

    /**
     * A Triangle Geometry object type.
     *
     * @name Phaser.Geom.TRIANGLE
     * @type {number}
     * @since 3.19.0
     */
    TRIANGLE: 6

};

module.exports = GEOM_CONST;


/***/ }),

/***/ 8881:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Point = __webpack_require__(7655);

/**
 * Get a point on a line that's a given percentage along its length.
 *
 * @function Phaser.Geom.Line.GetPoint
 * @since 3.0.0
 *
 * @generic {Phaser.Geom.Point} O - [out,$return]
 *
 * @param {Phaser.Geom.Line} line - The line.
 * @param {number} position - A value between 0 and 1, where 0 is the start, 0.5 is the middle and 1 is the end of the line.
 * @param {(Phaser.Geom.Point|object)} [out] - An optional point, or point-like object, to store the coordinates of the point on the line.
 *
 * @return {(Phaser.Geom.Point|object)} The point on the line.
 */
var GetPoint = function (line, position, out)
{
    if (out === undefined) { out = new Point(); }

    out.x = line.x1 + (line.x2 - line.x1) * position;
    out.y = line.y1 + (line.y2 - line.y1) * position;

    return out;
};

module.exports = GetPoint;


/***/ }),

/***/ 4479:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Length = __webpack_require__(4771);
var Point = __webpack_require__(7655);

/**
 * Get a number of points along a line's length.
 *
 * Provide a `quantity` to get an exact number of points along the line.
 *
 * Provide a `stepRate` to ensure a specific distance between each point on the line. Set `quantity` to `0` when
 * providing a `stepRate`.
 *
 * @function Phaser.Geom.Line.GetPoints
 * @since 3.0.0
 *
 * @generic {Phaser.Geom.Point[]} O - [out,$return]
 *
 * @param {Phaser.Geom.Line} line - The line.
 * @param {number} quantity - The number of points to place on the line. Set to `0` to use `stepRate` instead.
 * @param {number} [stepRate] - The distance between each point on the line. When set, `quantity` is implied and should be set to `0`.
 * @param {(array|Phaser.Geom.Point[])} [out] - An optional array of Points, or point-like objects, to store the coordinates of the points on the line.
 *
 * @return {(array|Phaser.Geom.Point[])} An array of Points, or point-like objects, containing the coordinates of the points on the line.
 */
var GetPoints = function (line, quantity, stepRate, out)
{
    if (out === undefined) { out = []; }

    //  If quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead.
    if (!quantity && stepRate > 0)
    {
        quantity = Length(line) / stepRate;
    }

    var x1 = line.x1;
    var y1 = line.y1;

    var x2 = line.x2;
    var y2 = line.y2;

    for (var i = 0; i < quantity; i++)
    {
        var position = i / quantity;

        var x = x1 + (x2 - x1) * position;
        var y = y1 + (y2 - y1) * position;

        out.push(new Point(x, y));
    }

    return out;
};

module.exports = GetPoints;


/***/ }),

/***/ 4771:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the length of the given line.
 *
 * @function Phaser.Geom.Line.Length
 * @since 3.0.0
 *
 * @param {Phaser.Geom.Line} line - The line to calculate the length of.
 *
 * @return {number} The length of the line.
 */
var Length = function (line)
{
    return Math.sqrt((line.x2 - line.x1) * (line.x2 - line.x1) + (line.y2 - line.y1) * (line.y2 - line.y1));
};

module.exports = Length;


/***/ }),

/***/ 284:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var GetPoint = __webpack_require__(8881);
var GetPoints = __webpack_require__(4479);
var GEOM_CONST = __webpack_require__(1643);
var Random = __webpack_require__(3915);
var Vector2 = __webpack_require__(2529);

/**
 * @classdesc
 * Defines a Line segment, a part of a line between two endpoints.
 *
 * @class Line
 * @memberof Phaser.Geom
 * @constructor
 * @since 3.0.0
 *
 * @param {number} [x1=0] - The x coordinate of the lines starting point.
 * @param {number} [y1=0] - The y coordinate of the lines starting point.
 * @param {number} [x2=0] - The x coordinate of the lines ending point.
 * @param {number} [y2=0] - The y coordinate of the lines ending point.
 */
var Line = new Class({

    initialize:

    function Line (x1, y1, x2, y2)
    {
        if (x1 === undefined) { x1 = 0; }
        if (y1 === undefined) { y1 = 0; }
        if (x2 === undefined) { x2 = 0; }
        if (y2 === undefined) { y2 = 0; }

        /**
         * The geometry constant type of this object: `GEOM_CONST.LINE`.
         * Used for fast type comparisons.
         *
         * @name Phaser.Geom.Line#type
         * @type {number}
         * @readonly
         * @since 3.19.0
         */
        this.type = GEOM_CONST.LINE;

        /**
         * The x coordinate of the lines starting point.
         *
         * @name Phaser.Geom.Line#x1
         * @type {number}
         * @since 3.0.0
         */
        this.x1 = x1;

        /**
         * The y coordinate of the lines starting point.
         *
         * @name Phaser.Geom.Line#y1
         * @type {number}
         * @since 3.0.0
         */
        this.y1 = y1;

        /**
         * The x coordinate of the lines ending point.
         *
         * @name Phaser.Geom.Line#x2
         * @type {number}
         * @since 3.0.0
         */
        this.x2 = x2;

        /**
         * The y coordinate of the lines ending point.
         *
         * @name Phaser.Geom.Line#y2
         * @type {number}
         * @since 3.0.0
         */
        this.y2 = y2;
    },

    /**
     * Get a point on a line that's a given percentage along its length.
     *
     * @method Phaser.Geom.Line#getPoint
     * @since 3.0.0
     *
     * @generic {Phaser.Geom.Point} O - [output,$return]
     *
     * @param {number} position - A value between 0 and 1, where 0 is the start, 0.5 is the middle and 1 is the end of the line.
     * @param {(Phaser.Geom.Point|object)} [output] - An optional point, or point-like object, to store the coordinates of the point on the line.
     *
     * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point on the line.
     */
    getPoint: function (position, output)
    {
        return GetPoint(this, position, output);
    },

    /**
     * Get a number of points along a line's length.
     *
     * Provide a `quantity` to get an exact number of points along the line.
     *
     * Provide a `stepRate` to ensure a specific distance between each point on the line. Set `quantity` to `0` when
     * providing a `stepRate`.
     *
     * @method Phaser.Geom.Line#getPoints
     * @since 3.0.0
     *
     * @generic {Phaser.Geom.Point[]} O - [output,$return]
     *
     * @param {number} quantity - The number of points to place on the line. Set to `0` to use `stepRate` instead.
     * @param {number} [stepRate] - The distance between each point on the line. When set, `quantity` is implied and should be set to `0`.
     * @param {(array|Phaser.Geom.Point[])} [output] - An optional array of Points, or point-like objects, to store the coordinates of the points on the line.
     *
     * @return {(array|Phaser.Geom.Point[])} An array of Points, or point-like objects, containing the coordinates of the points on the line.
     */
    getPoints: function (quantity, stepRate, output)
    {
        return GetPoints(this, quantity, stepRate, output);
    },

    /**
     * Get a random Point on the Line.
     *
     * @method Phaser.Geom.Line#getRandomPoint
     * @since 3.0.0
     *
     * @generic {Phaser.Geom.Point} O - [point,$return]
     *
     * @param {(Phaser.Geom.Point|object)} [point] - An instance of a Point to be modified.
     *
     * @return {Phaser.Geom.Point} A random Point on the Line.
     */
    getRandomPoint: function (point)
    {
        return Random(this, point);
    },

    /**
     * Set new coordinates for the line endpoints.
     *
     * @method Phaser.Geom.Line#setTo
     * @since 3.0.0
     *
     * @param {number} [x1=0] - The x coordinate of the lines starting point.
     * @param {number} [y1=0] - The y coordinate of the lines starting point.
     * @param {number} [x2=0] - The x coordinate of the lines ending point.
     * @param {number} [y2=0] - The y coordinate of the lines ending point.
     *
     * @return {this} This Line object.
     */
    setTo: function (x1, y1, x2, y2)
    {
        if (x1 === undefined) { x1 = 0; }
        if (y1 === undefined) { y1 = 0; }
        if (x2 === undefined) { x2 = 0; }
        if (y2 === undefined) { y2 = 0; }

        this.x1 = x1;
        this.y1 = y1;

        this.x2 = x2;
        this.y2 = y2;

        return this;
    },

    /**
     * Sets this Line to match the x/y coordinates of the two given Vector2Like objects.
     *
     * @method Phaser.Geom.Line#setFromObjects
     * @since 3.70.0
     *
     * @param {Phaser.Types.Math.Vector2Like} start - Any object with public `x` and `y` properties, whose values will be assigned to the x1/y1 components of this Line.
     * @param {Phaser.Types.Math.Vector2Like} end - Any object with public `x` and `y` properties, whose values will be assigned to the x2/y2 components of this Line.
     *
     * @return {this} This Line object.
     */
    setFromObjects: function (start, end)
    {
        this.x1 = start.x;
        this.y1 = start.y;

        this.x2 = end.x;
        this.y2 = end.y;

        return this;
    },

    /**
     * Returns a Vector2 object that corresponds to the start of this Line.
     *
     * @method Phaser.Geom.Line#getPointA
     * @since 3.0.0
     *
     * @generic {Phaser.Math.Vector2} O - [vec2,$return]
     *
     * @param {Phaser.Math.Vector2} [vec2] - A Vector2 object to set the results in. If `undefined` a new Vector2 will be created.
     *
     * @return {Phaser.Math.Vector2} A Vector2 object that corresponds to the start of this Line.
     */
    getPointA: function (vec2)
    {
        if (vec2 === undefined) { vec2 = new Vector2(); }

        vec2.set(this.x1, this.y1);

        return vec2;
    },

    /**
     * Returns a Vector2 object that corresponds to the end of this Line.
     *
     * @method Phaser.Geom.Line#getPointB
     * @since 3.0.0
     *
     * @generic {Phaser.Math.Vector2} O - [vec2,$return]
     *
     * @param {Phaser.Math.Vector2} [vec2] - A Vector2 object to set the results in. If `undefined` a new Vector2 will be created.
     *
     * @return {Phaser.Math.Vector2} A Vector2 object that corresponds to the end of this Line.
     */
    getPointB: function (vec2)
    {
        if (vec2 === undefined) { vec2 = new Vector2(); }

        vec2.set(this.x2, this.y2);

        return vec2;
    },

    /**
     * The left position of the Line.
     *
     * @name Phaser.Geom.Line#left
     * @type {number}
     * @since 3.0.0
     */
    left: {

        get: function ()
        {
            return Math.min(this.x1, this.x2);
        },

        set: function (value)
        {
            if (this.x1 <= this.x2)
            {
                this.x1 = value;
            }
            else
            {
                this.x2 = value;
            }
        }

    },

    /**
     * The right position of the Line.
     *
     * @name Phaser.Geom.Line#right
     * @type {number}
     * @since 3.0.0
     */
    right: {

        get: function ()
        {
            return Math.max(this.x1, this.x2);
        },

        set: function (value)
        {
            if (this.x1 > this.x2)
            {
                this.x1 = value;
            }
            else
            {
                this.x2 = value;
            }
        }

    },

    /**
     * The top position of the Line.
     *
     * @name Phaser.Geom.Line#top
     * @type {number}
     * @since 3.0.0
     */
    top: {

        get: function ()
        {
            return Math.min(this.y1, this.y2);
        },

        set: function (value)
        {
            if (this.y1 <= this.y2)
            {
                this.y1 = value;
            }
            else
            {
                this.y2 = value;
            }
        }

    },

    /**
     * The bottom position of the Line.
     *
     * @name Phaser.Geom.Line#bottom
     * @type {number}
     * @since 3.0.0
     */
    bottom: {

        get: function ()
        {
            return Math.max(this.y1, this.y2);
        },

        set: function (value)
        {
            if (this.y1 > this.y2)
            {
                this.y1 = value;
            }
            else
            {
                this.y2 = value;
            }
        }

    }

});

module.exports = Line;


/***/ }),

/***/ 3915:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Point = __webpack_require__(7655);

/**
 * Returns a random point on a given Line.
 *
 * @function Phaser.Geom.Line.Random
 * @since 3.0.0
 *
 * @generic {Phaser.Geom.Point} O - [out,$return]
 *
 * @param {Phaser.Geom.Line} line - The Line to calculate the random Point on.
 * @param {(Phaser.Geom.Point|object)} [out] - An instance of a Point to be modified.
 *
 * @return {(Phaser.Geom.Point|object)} A random Point on the Line.
 */
var Random = function (line, out)
{
    if (out === undefined) { out = new Point(); }

    var t = Math.random();

    out.x = line.x1 + t * (line.x2 - line.x1);
    out.y = line.y1 + t * (line.y2 - line.y1);

    return out;
};

module.exports = Random;


/***/ }),

/***/ 7655:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var GEOM_CONST = __webpack_require__(1643);

/**
 * @classdesc
 * Defines a Point in 2D space, with an x and y component.
 *
 * @class Point
 * @memberof Phaser.Geom
 * @constructor
 * @since 3.0.0
 *
 * @param {number} [x=0] - The x coordinate of this Point.
 * @param {number} [y=x] - The y coordinate of this Point.
 */
var Point = new Class({

    initialize:

    function Point (x, y)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = x; }

        /**
         * The geometry constant type of this object: `GEOM_CONST.POINT`.
         * Used for fast type comparisons.
         *
         * @name Phaser.Geom.Point#type
         * @type {number}
         * @readonly
         * @since 3.19.0
         */
        this.type = GEOM_CONST.POINT;

        /**
         * The x coordinate of this Point.
         *
         * @name Phaser.Geom.Point#x
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.x = x;

        /**
         * The y coordinate of this Point.
         *
         * @name Phaser.Geom.Point#y
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.y = y;
    },

    /**
     * Set the x and y coordinates of the point to the given values.
     *
     * @method Phaser.Geom.Point#setTo
     * @since 3.0.0
     *
     * @param {number} [x=0] - The x coordinate of this Point.
     * @param {number} [y=x] - The y coordinate of this Point.
     *
     * @return {this} This Point object.
     */
    setTo: function (x, y)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = x; }

        this.x = x;
        this.y = y;

        return this;
    }

});

module.exports = Point;


/***/ }),

/***/ 5956:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Checks if a given point is inside a Rectangle's bounds.
 *
 * @function Phaser.Geom.Rectangle.Contains
 * @since 3.0.0
 *
 * @param {Phaser.Geom.Rectangle} rect - The Rectangle to check.
 * @param {number} x - The X coordinate of the point to check.
 * @param {number} y - The Y coordinate of the point to check.
 *
 * @return {boolean} `true` if the point is within the Rectangle's bounds, otherwise `false`.
 */
var Contains = function (rect, x, y)
{
    if (rect.width <= 0 || rect.height <= 0)
    {
        return false;
    }

    return (rect.x <= x && rect.x + rect.width >= x && rect.y <= y && rect.y + rect.height >= y);
};

module.exports = Contains;


/***/ }),

/***/ 716:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Perimeter = __webpack_require__(7120);
var Point = __webpack_require__(7655);

/**
 * Calculates the coordinates of a point at a certain `position` on the Rectangle's perimeter.
 *
 * The `position` is a fraction between 0 and 1 which defines how far into the perimeter the point is.
 *
 * A value of 0 or 1 returns the point at the top left corner of the rectangle, while a value of 0.5 returns the point at the bottom right corner of the rectangle. Values between 0 and 0.5 are on the top or the right side and values between 0.5 and 1 are on the bottom or the left side.
 *
 * @function Phaser.Geom.Rectangle.GetPoint
 * @since 3.0.0
 *
 * @generic {Phaser.Geom.Point} O - [out,$return]
 *
 * @param {Phaser.Geom.Rectangle} rectangle - The Rectangle to get the perimeter point from.
 * @param {number} position - The normalized distance into the Rectangle's perimeter to return.
 * @param {(Phaser.Geom.Point|object)} [out] - An object to update with the `x` and `y` coordinates of the point.
 *
 * @return {Phaser.Geom.Point} The updated `output` object, or a new Point if no `output` object was given.
 */
var GetPoint = function (rectangle, position, out)
{
    if (out === undefined) { out = new Point(); }

    if (position <= 0 || position >= 1)
    {
        out.x = rectangle.x;
        out.y = rectangle.y;

        return out;
    }

    var p = Perimeter(rectangle) * position;

    if (position > 0.5)
    {
        p -= (rectangle.width + rectangle.height);

        if (p <= rectangle.width)
        {
            //  Face 3
            out.x = rectangle.right - p;
            out.y = rectangle.bottom;
        }
        else
        {
            //  Face 4
            out.x = rectangle.x;
            out.y = rectangle.bottom - (p - rectangle.width);
        }
    }
    else if (p <= rectangle.width)
    {
        //  Face 1
        out.x = rectangle.x + p;
        out.y = rectangle.y;
    }
    else
    {
        //  Face 2
        out.x = rectangle.right;
        out.y = rectangle.y + (p - rectangle.width);
    }

    return out;
};

module.exports = GetPoint;


/***/ }),

/***/ 8151:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var GetPoint = __webpack_require__(716);
var Perimeter = __webpack_require__(7120);

/**
 * Return an array of points from the perimeter of the rectangle, each spaced out based on the quantity or step required.
 *
 * @function Phaser.Geom.Rectangle.GetPoints
 * @since 3.0.0
 *
 * @generic {Phaser.Geom.Point[]} O - [out,$return]
 *
 * @param {Phaser.Geom.Rectangle} rectangle - The Rectangle object to get the points from.
 * @param {number} step - Step between points. Used to calculate the number of points to return when quantity is falsey. Ignored if quantity is positive.
 * @param {number} quantity - The number of evenly spaced points from the rectangles perimeter to return. If falsey, step param will be used to calculate the number of points.
 * @param {(array|Phaser.Geom.Point[])} [out] - An optional array to store the points in.
 *
 * @return {(array|Phaser.Geom.Point[])} An array of Points from the perimeter of the rectangle.
 */
var GetPoints = function (rectangle, quantity, stepRate, out)
{
    if (out === undefined) { out = []; }

    //  If quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead.
    if (!quantity && stepRate > 0)
    {
        quantity = Perimeter(rectangle) / stepRate;
    }

    for (var i = 0; i < quantity; i++)
    {
        var position = i / quantity;

        out.push(GetPoint(rectangle, position));
    }

    return out;
};

module.exports = GetPoints;


/***/ }),

/***/ 7120:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculates the perimeter of a Rectangle.
 *
 * @function Phaser.Geom.Rectangle.Perimeter
 * @since 3.0.0
 *
 * @param {Phaser.Geom.Rectangle} rect - The Rectangle to use.
 *
 * @return {number} The perimeter of the Rectangle, equal to `(width * 2) + (height * 2)`.
 */
var Perimeter = function (rect)
{
    return 2 * (rect.width + rect.height);
};

module.exports = Perimeter;


/***/ }),

/***/ 2161:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Point = __webpack_require__(7655);

/**
 * Returns a random point within a Rectangle.
 *
 * @function Phaser.Geom.Rectangle.Random
 * @since 3.0.0
 *
 * @generic {Phaser.Geom.Point} O - [out,$return]
 *
 * @param {Phaser.Geom.Rectangle} rect - The Rectangle to return a point from.
 * @param {Phaser.Geom.Point} out - The object to update with the point's coordinates.
 *
 * @return {Phaser.Geom.Point} The modified `out` object, or a new Point if none was provided.
 */
var Random = function (rect, out)
{
    if (out === undefined) { out = new Point(); }

    out.x = rect.x + (Math.random() * rect.width);
    out.y = rect.y + (Math.random() * rect.height);

    return out;
};

module.exports = Random;


/***/ }),

/***/ 1392:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Contains = __webpack_require__(5956);
var GetPoint = __webpack_require__(716);
var GetPoints = __webpack_require__(8151);
var GEOM_CONST = __webpack_require__(1643);
var Line = __webpack_require__(284);
var Random = __webpack_require__(2161);

/**
 * @classdesc
 * Encapsulates a 2D rectangle defined by its corner point in the top-left and its extends in x (width) and y (height)
 *
 * @class Rectangle
 * @memberof Phaser.Geom
 * @constructor
 * @since 3.0.0
 *
 * @param {number} [x=0] - The X coordinate of the top left corner of the Rectangle.
 * @param {number} [y=0] - The Y coordinate of the top left corner of the Rectangle.
 * @param {number} [width=0] - The width of the Rectangle.
 * @param {number} [height=0] - The height of the Rectangle.
 */
var Rectangle = new Class({

    initialize:

    function Rectangle (x, y, width, height)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = 0; }
        if (width === undefined) { width = 0; }
        if (height === undefined) { height = 0; }

        /**
         * The geometry constant type of this object: `GEOM_CONST.RECTANGLE`.
         * Used for fast type comparisons.
         *
         * @name Phaser.Geom.Rectangle#type
         * @type {number}
         * @readonly
         * @since 3.19.0
         */
        this.type = GEOM_CONST.RECTANGLE;

        /**
         * The X coordinate of the top left corner of the Rectangle.
         *
         * @name Phaser.Geom.Rectangle#x
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.x = x;

        /**
         * The Y coordinate of the top left corner of the Rectangle.
         *
         * @name Phaser.Geom.Rectangle#y
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.y = y;

        /**
         * The width of the Rectangle, i.e. the distance between its left side (defined by `x`) and its right side.
         *
         * @name Phaser.Geom.Rectangle#width
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.width = width;

        /**
         * The height of the Rectangle, i.e. the distance between its top side (defined by `y`) and its bottom side.
         *
         * @name Phaser.Geom.Rectangle#height
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.height = height;
    },

    /**
     * Checks if the given point is inside the Rectangle's bounds.
     *
     * @method Phaser.Geom.Rectangle#contains
     * @since 3.0.0
     *
     * @param {number} x - The X coordinate of the point to check.
     * @param {number} y - The Y coordinate of the point to check.
     *
     * @return {boolean} `true` if the point is within the Rectangle's bounds, otherwise `false`.
     */
    contains: function (x, y)
    {
        return Contains(this, x, y);
    },

    /**
     * Calculates the coordinates of a point at a certain `position` on the Rectangle's perimeter.
     *
     * The `position` is a fraction between 0 and 1 which defines how far into the perimeter the point is.
     *
     * A value of 0 or 1 returns the point at the top left corner of the rectangle, while a value of 0.5 returns the point at the bottom right corner of the rectangle. Values between 0 and 0.5 are on the top or the right side and values between 0.5 and 1 are on the bottom or the left side.
     *
     * @method Phaser.Geom.Rectangle#getPoint
     * @since 3.0.0
     *
     * @generic {Phaser.Geom.Point} O - [output,$return]
     *
     * @param {number} position - The normalized distance into the Rectangle's perimeter to return.
     * @param {(Phaser.Geom.Point|object)} [output] - An object to update with the `x` and `y` coordinates of the point.
     *
     * @return {(Phaser.Geom.Point|object)} The updated `output` object, or a new Point if no `output` object was given.
     */
    getPoint: function (position, output)
    {
        return GetPoint(this, position, output);
    },

    /**
     * Returns an array of points from the perimeter of the Rectangle, each spaced out based on the quantity or step required.
     *
     * @method Phaser.Geom.Rectangle#getPoints
     * @since 3.0.0
     *
     * @generic {Phaser.Geom.Point[]} O - [output,$return]
     *
     * @param {number} quantity - The number of points to return. Set to `false` or 0 to return an arbitrary number of points (`perimeter / stepRate`) evenly spaced around the Rectangle based on the `stepRate`.
     * @param {number} [stepRate] - If `quantity` is 0, determines the normalized distance between each returned point.
     * @param {(array|Phaser.Geom.Point[])} [output] - An array to which to append the points.
     *
     * @return {(array|Phaser.Geom.Point[])} The modified `output` array, or a new array if none was provided.
     */
    getPoints: function (quantity, stepRate, output)
    {
        return GetPoints(this, quantity, stepRate, output);
    },

    /**
     * Returns a random point within the Rectangle's bounds.
     *
     * @method Phaser.Geom.Rectangle#getRandomPoint
     * @since 3.0.0
     *
     * @generic {Phaser.Geom.Point} O - [point,$return]
     *
     * @param {Phaser.Geom.Point} [point] - The object in which to store the `x` and `y` coordinates of the point.
     *
     * @return {Phaser.Geom.Point} The updated `point`, or a new Point if none was provided.
     */
    getRandomPoint: function (point)
    {
        return Random(this, point);
    },

    /**
     * Sets the position, width, and height of the Rectangle.
     *
     * @method Phaser.Geom.Rectangle#setTo
     * @since 3.0.0
     *
     * @param {number} x - The X coordinate of the top left corner of the Rectangle.
     * @param {number} y - The Y coordinate of the top left corner of the Rectangle.
     * @param {number} width - The width of the Rectangle.
     * @param {number} height - The height of the Rectangle.
     *
     * @return {this} This Rectangle object.
     */
    setTo: function (x, y, width, height)
    {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;

        return this;
    },

    /**
     * Resets the position, width, and height of the Rectangle to 0.
     *
     * @method Phaser.Geom.Rectangle#setEmpty
     * @since 3.0.0
     *
     * @return {this} This Rectangle object.
     */
    setEmpty: function ()
    {
        return this.setTo(0, 0, 0, 0);
    },

    /**
     * Sets the position of the Rectangle.
     *
     * @method Phaser.Geom.Rectangle#setPosition
     * @since 3.0.0
     *
     * @param {number} x - The X coordinate of the top left corner of the Rectangle.
     * @param {number} [y=x] - The Y coordinate of the top left corner of the Rectangle.
     *
     * @return {this} This Rectangle object.
     */
    setPosition: function (x, y)
    {
        if (y === undefined) { y = x; }

        this.x = x;
        this.y = y;

        return this;
    },

    /**
     * Sets the width and height of the Rectangle.
     *
     * @method Phaser.Geom.Rectangle#setSize
     * @since 3.0.0
     *
     * @param {number} width - The width to set the Rectangle to.
     * @param {number} [height=width] - The height to set the Rectangle to.
     *
     * @return {this} This Rectangle object.
     */
    setSize: function (width, height)
    {
        if (height === undefined) { height = width; }

        this.width = width;
        this.height = height;

        return this;
    },

    /**
     * Determines if the Rectangle is empty. A Rectangle is empty if its width or height is less than or equal to 0.
     *
     * @method Phaser.Geom.Rectangle#isEmpty
     * @since 3.0.0
     *
     * @return {boolean} `true` if the Rectangle is empty. A Rectangle object is empty if its width or height is less than or equal to 0.
     */
    isEmpty: function ()
    {
        return (this.width <= 0 || this.height <= 0);
    },

    /**
     * Returns a Line object that corresponds to the top of this Rectangle.
     *
     * @method Phaser.Geom.Rectangle#getLineA
     * @since 3.0.0
     *
     * @generic {Phaser.Geom.Line} O - [line,$return]
     *
     * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
     *
     * @return {Phaser.Geom.Line} A Line object that corresponds to the top of this Rectangle.
     */
    getLineA: function (line)
    {
        if (line === undefined) { line = new Line(); }

        line.setTo(this.x, this.y, this.right, this.y);

        return line;
    },

    /**
     * Returns a Line object that corresponds to the right of this Rectangle.
     *
     * @method Phaser.Geom.Rectangle#getLineB
     * @since 3.0.0
     *
     * @generic {Phaser.Geom.Line} O - [line,$return]
     *
     * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
     *
     * @return {Phaser.Geom.Line} A Line object that corresponds to the right of this Rectangle.
     */
    getLineB: function (line)
    {
        if (line === undefined) { line = new Line(); }

        line.setTo(this.right, this.y, this.right, this.bottom);

        return line;
    },

    /**
     * Returns a Line object that corresponds to the bottom of this Rectangle.
     *
     * @method Phaser.Geom.Rectangle#getLineC
     * @since 3.0.0
     *
     * @generic {Phaser.Geom.Line} O - [line,$return]
     *
     * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
     *
     * @return {Phaser.Geom.Line} A Line object that corresponds to the bottom of this Rectangle.
     */
    getLineC: function (line)
    {
        if (line === undefined) { line = new Line(); }

        line.setTo(this.right, this.bottom, this.x, this.bottom);

        return line;
    },

    /**
     * Returns a Line object that corresponds to the left of this Rectangle.
     *
     * @method Phaser.Geom.Rectangle#getLineD
     * @since 3.0.0
     *
     * @generic {Phaser.Geom.Line} O - [line,$return]
     *
     * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
     *
     * @return {Phaser.Geom.Line} A Line object that corresponds to the left of this Rectangle.
     */
    getLineD: function (line)
    {
        if (line === undefined) { line = new Line(); }

        line.setTo(this.x, this.bottom, this.x, this.y);

        return line;
    },

    /**
     * The x coordinate of the left of the Rectangle.
     * Changing the left property of a Rectangle object has no effect on the y and height properties. However it does affect the width property, whereas changing the x value does not affect the width property.
     *
     * @name Phaser.Geom.Rectangle#left
     * @type {number}
     * @since 3.0.0
     */
    left: {

        get: function ()
        {
            return this.x;
        },

        set: function (value)
        {
            if (value >= this.right)
            {
                this.width = 0;
            }
            else
            {
                this.width = this.right - value;
            }

            this.x = value;
        }

    },

    /**
     * The sum of the x and width properties.
     * Changing the right property of a Rectangle object has no effect on the x, y and height properties, however it does affect the width property.
     *
     * @name Phaser.Geom.Rectangle#right
     * @type {number}
     * @since 3.0.0
     */
    right: {

        get: function ()
        {
            return this.x + this.width;
        },

        set: function (value)
        {
            if (value <= this.x)
            {
                this.width = 0;
            }
            else
            {
                this.width = value - this.x;
            }
        }

    },

    /**
     * The y coordinate of the top of the Rectangle. Changing the top property of a Rectangle object has no effect on the x and width properties.
     * However it does affect the height property, whereas changing the y value does not affect the height property.
     *
     * @name Phaser.Geom.Rectangle#top
     * @type {number}
     * @since 3.0.0
     */
    top: {

        get: function ()
        {
            return this.y;
        },

        set: function (value)
        {
            if (value >= this.bottom)
            {
                this.height = 0;
            }
            else
            {
                this.height = (this.bottom - value);
            }

            this.y = value;
        }

    },

    /**
     * The sum of the y and height properties.
     * Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
     *
     * @name Phaser.Geom.Rectangle#bottom
     * @type {number}
     * @since 3.0.0
     */
    bottom: {

        get: function ()
        {
            return this.y + this.height;
        },

        set: function (value)
        {
            if (value <= this.y)
            {
                this.height = 0;
            }
            else
            {
                this.height = value - this.y;
            }
        }

    },

    /**
     * The x coordinate of the center of the Rectangle.
     *
     * @name Phaser.Geom.Rectangle#centerX
     * @type {number}
     * @since 3.0.0
     */
    centerX: {

        get: function ()
        {
            return this.x + (this.width / 2);
        },

        set: function (value)
        {
            this.x = value - (this.width / 2);
        }

    },

    /**
     * The y coordinate of the center of the Rectangle.
     *
     * @name Phaser.Geom.Rectangle#centerY
     * @type {number}
     * @since 3.0.0
     */
    centerY: {

        get: function ()
        {
            return this.y + (this.height / 2);
        },

        set: function (value)
        {
            this.y = value - (this.height / 2);
        }

    }

});

module.exports = Rectangle;


/***/ }),

/***/ 9422:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Rectangle = __webpack_require__(1392);

/**
 * Creates a new Rectangle or repositions and/or resizes an existing Rectangle so that it encompasses the two given Rectangles, i.e. calculates their union.
 *
 * @function Phaser.Geom.Rectangle.Union
 * @since 3.0.0
 *
 * @generic {Phaser.Geom.Rectangle} O - [out,$return]
 *
 * @param {Phaser.Geom.Rectangle} rectA - The first Rectangle to use.
 * @param {Phaser.Geom.Rectangle} rectB - The second Rectangle to use.
 * @param {Phaser.Geom.Rectangle} [out] - The Rectangle to store the union in.
 *
 * @return {Phaser.Geom.Rectangle} The modified `out` Rectangle, or a new Rectangle if none was provided.
 */
var Union = function (rectA, rectB, out)
{
    if (out === undefined) { out = new Rectangle(); }

    //  Cache vars so we can use one of the input rects as the output rect
    var x = Math.min(rectA.x, rectB.x);
    var y = Math.min(rectA.y, rectB.y);
    var w = Math.max(rectA.right, rectB.right) - x;
    var h = Math.max(rectA.bottom, rectB.bottom) - y;

    return out.setTo(x, y, w, h);
};

module.exports = Union;


/***/ }),

/***/ 1593:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var CONST = __webpack_require__(4359);
var Events = __webpack_require__(1179);
var GetFastValue = __webpack_require__(4597);
var GetURL = __webpack_require__(5593);
var MergeXHRSettings = __webpack_require__(7410);
var XHRLoader = __webpack_require__(5874);
var XHRSettings = __webpack_require__(707);

/**
 * @classdesc
 * The base File class used by all File Types that the Loader can support.
 * You shouldn't create an instance of a File directly, but should extend it with your own class, setting a custom type and processing methods.
 *
 * @class File
 * @memberof Phaser.Loader
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Loader.LoaderPlugin} loader - The Loader that is going to load this File.
 * @param {Phaser.Types.Loader.FileConfig} fileConfig - The file configuration object, as created by the file type.
 */
var File = new Class({

    initialize:

    function File (loader, fileConfig)
    {
        /**
         * A reference to the Loader that is going to load this file.
         *
         * @name Phaser.Loader.File#loader
         * @type {Phaser.Loader.LoaderPlugin}
         * @since 3.0.0
         */
        this.loader = loader;

        /**
         * A reference to the Cache, or Texture Manager, that is going to store this file if it loads.
         *
         * @name Phaser.Loader.File#cache
         * @type {(Phaser.Cache.BaseCache|Phaser.Textures.TextureManager)}
         * @since 3.7.0
         */
        this.cache = GetFastValue(fileConfig, 'cache', false);

        /**
         * The file type string (image, json, etc) for sorting within the Loader.
         *
         * @name Phaser.Loader.File#type
         * @type {string}
         * @since 3.0.0
         */
        this.type = GetFastValue(fileConfig, 'type', false);

        if (!this.type)
        {
            throw new Error('Invalid File type: ' + this.type);
        }

        /**
         * Unique cache key (unique within its file type)
         *
         * @name Phaser.Loader.File#key
         * @type {string}
         * @since 3.0.0
         */
        this.key = GetFastValue(fileConfig, 'key', false);

        var loadKey = this.key;

        if (loader.prefix && loader.prefix !== '')
        {
            this.key = loader.prefix + loadKey;
        }

        if (!this.key)
        {
            throw new Error('Invalid File key: ' + this.key);
        }

        var url = GetFastValue(fileConfig, 'url');

        if (url === undefined)
        {
            url = loader.path + loadKey + '.' + GetFastValue(fileConfig, 'extension', '');
        }
        else if (typeof url === 'string' && !url.match(/^(?:blob:|data:|capacitor:\/\/|http:\/\/|https:\/\/|\/\/)/))
        {
            url = loader.path + url;
        }

        /**
         * The URL of the file, not including baseURL.
         *
         * Automatically has Loader.path prepended to it if a string.
         *
         * Can also be a JavaScript Object, such as the results of parsing JSON data.
         *
         * @name Phaser.Loader.File#url
         * @type {object|string}
         * @since 3.0.0
         */
        this.url = url;

        /**
         * The final URL this file will load from, including baseURL and path.
         * Set automatically when the Loader calls 'load' on this file.
         *
         * @name Phaser.Loader.File#src
         * @type {string}
         * @since 3.0.0
         */
        this.src = '';

        /**
         * The merged XHRSettings for this file.
         *
         * @name Phaser.Loader.File#xhrSettings
         * @type {Phaser.Types.Loader.XHRSettingsObject}
         * @since 3.0.0
         */
        this.xhrSettings = XHRSettings(GetFastValue(fileConfig, 'responseType', undefined));

        if (GetFastValue(fileConfig, 'xhrSettings', false))
        {
            this.xhrSettings = MergeXHRSettings(this.xhrSettings, GetFastValue(fileConfig, 'xhrSettings', {}));
        }

        /**
         * The XMLHttpRequest instance (as created by XHR Loader) that is loading this File.
         *
         * @name Phaser.Loader.File#xhrLoader
         * @type {?XMLHttpRequest}
         * @since 3.0.0
         */
        this.xhrLoader = null;

        /**
         * The current state of the file. One of the FILE_CONST values.
         *
         * @name Phaser.Loader.File#state
         * @type {number}
         * @since 3.0.0
         */
        this.state = (typeof(this.url) === 'function') ? CONST.FILE_POPULATED : CONST.FILE_PENDING;

        /**
         * The total size of this file.
         * Set by onProgress and only if loading via XHR.
         *
         * @name Phaser.Loader.File#bytesTotal
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.bytesTotal = 0;

        /**
         * Updated as the file loads.
         * Only set if loading via XHR.
         *
         * @name Phaser.Loader.File#bytesLoaded
         * @type {number}
         * @default -1
         * @since 3.0.0
         */
        this.bytesLoaded = -1;

        /**
         * A percentage value between 0 and 1 indicating how much of this file has loaded.
         * Only set if loading via XHR.
         *
         * @name Phaser.Loader.File#percentComplete
         * @type {number}
         * @default -1
         * @since 3.0.0
         */
        this.percentComplete = -1;

        /**
         * For CORs based loading.
         * If this is undefined then the File will check BaseLoader.crossOrigin and use that (if set)
         *
         * @name Phaser.Loader.File#crossOrigin
         * @type {(string|undefined)}
         * @since 3.0.0
         */
        this.crossOrigin = undefined;

        /**
         * The processed file data, stored here after the file has loaded.
         *
         * @name Phaser.Loader.File#data
         * @type {*}
         * @since 3.0.0
         */
        this.data = undefined;

        /**
         * A config object that can be used by file types to store transitional data.
         *
         * @name Phaser.Loader.File#config
         * @type {*}
         * @since 3.0.0
         */
        this.config = GetFastValue(fileConfig, 'config', {});

        /**
         * If this is a multipart file, i.e. an atlas and its json together, then this is a reference
         * to the parent MultiFile. Set and used internally by the Loader or specific file types.
         *
         * @name Phaser.Loader.File#multiFile
         * @type {?Phaser.Loader.MultiFile}
         * @since 3.7.0
         */
        this.multiFile;

        /**
         * Does this file have an associated linked file? Such as an image and a normal map.
         * Atlases and Bitmap Fonts use the multiFile, because those files need loading together but aren't
         * actually bound by data, where-as a linkFile is.
         *
         * @name Phaser.Loader.File#linkFile
         * @type {?Phaser.Loader.File}
         * @since 3.7.0
         */
        this.linkFile;
    },

    /**
     * Links this File with another, so they depend upon each other for loading and processing.
     *
     * @method Phaser.Loader.File#setLink
     * @since 3.7.0
     *
     * @param {Phaser.Loader.File} fileB - The file to link to this one.
     */
    setLink: function (fileB)
    {
        this.linkFile = fileB;

        fileB.linkFile = this;
    },

    /**
     * Resets the XHRLoader instance this file is using.
     *
     * @method Phaser.Loader.File#resetXHR
     * @since 3.0.0
     */
    resetXHR: function ()
    {
        if (this.xhrLoader)
        {
            this.xhrLoader.onload = undefined;
            this.xhrLoader.onerror = undefined;
            this.xhrLoader.onprogress = undefined;
        }
    },

    /**
     * Called by the Loader, starts the actual file downloading.
     * During the load the methods onLoad, onError and onProgress are called, based on the XHR events.
     * You shouldn't normally call this method directly, it's meant to be invoked by the Loader.
     *
     * @method Phaser.Loader.File#load
     * @since 3.0.0
     */
    load: function ()
    {
        if (this.state === CONST.FILE_POPULATED)
        {
            //  Can happen for example in a JSONFile if they've provided a JSON object instead of a URL
            this.loader.nextFile(this, true);
        }
        else
        {
            this.state = CONST.FILE_LOADING;

            this.src = GetURL(this, this.loader.baseURL);

            if (this.src.indexOf('data:') === 0)
            {
                console.warn('Local data URIs are not supported: ' + this.key);
            }
            else
            {
                //  The creation of this XHRLoader starts the load process going.
                //  It will automatically call the following, based on the load outcome:
                //
                // xhr.onload = this.onLoad
                // xhr.onerror = this.onError
                // xhr.onprogress = this.onProgress

                this.xhrLoader = XHRLoader(this, this.loader.xhr);
            }
        }
    },

    /**
     * Called when the file finishes loading, is sent a DOM ProgressEvent.
     *
     * @method Phaser.Loader.File#onLoad
     * @since 3.0.0
     *
     * @param {XMLHttpRequest} xhr - The XMLHttpRequest that caused this onload event.
     * @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this load.
     */
    onLoad: function (xhr, event)
    {
        var isLocalFile = xhr.responseURL && this.loader.localSchemes.some(function (scheme)
        {
            return xhr.responseURL.indexOf(scheme) === 0;
        });

        var localFileOk = (isLocalFile && event.target.status === 0);

        var success = !(event.target && event.target.status !== 200) || localFileOk;

        //  Handle HTTP status codes of 4xx and 5xx as errors, even if xhr.onerror was not called.
        if (xhr.readyState === 4 && xhr.status >= 400 && xhr.status <= 599)
        {
            success = false;
        }

        this.state = CONST.FILE_LOADED;

        this.resetXHR();

        this.loader.nextFile(this, success);
    },

    /**
     * Called if the file errors while loading, is sent a DOM ProgressEvent.
     *
     * @method Phaser.Loader.File#onError
     * @since 3.0.0
     *
     * @param {XMLHttpRequest} xhr - The XMLHttpRequest that caused this onload event.
     * @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this error.
     */
    onError: function ()
    {
        this.resetXHR();

        this.loader.nextFile(this, false);
    },

    /**
     * Called during the file load progress. Is sent a DOM ProgressEvent.
     *
     * @method Phaser.Loader.File#onProgress
     * @fires Phaser.Loader.Events#FILE_PROGRESS
     * @since 3.0.0
     *
     * @param {ProgressEvent} event - The DOM ProgressEvent.
     */
    onProgress: function (event)
    {
        if (event.lengthComputable)
        {
            this.bytesLoaded = event.loaded;
            this.bytesTotal = event.total;

            this.percentComplete = Math.min((this.bytesLoaded / this.bytesTotal), 1);

            this.loader.emit(Events.FILE_PROGRESS, this, this.percentComplete);
        }
    },

    /**
     * Usually overridden by the FileTypes and is called by Loader.nextFile.
     * This method controls what extra work this File does with its loaded data, for example a JSON file will parse itself during this stage.
     *
     * @method Phaser.Loader.File#onProcess
     * @since 3.0.0
     */
    onProcess: function ()
    {
        this.state = CONST.FILE_PROCESSING;

        this.onProcessComplete();
    },

    /**
     * Called when the File has completed processing.
     * Checks on the state of its multifile, if set.
     *
     * @method Phaser.Loader.File#onProcessComplete
     * @since 3.7.0
     */
    onProcessComplete: function ()
    {
        this.state = CONST.FILE_COMPLETE;

        if (this.multiFile)
        {
            this.multiFile.onFileComplete(this);
        }

        this.loader.fileProcessComplete(this);
    },

    /**
     * Called when the File has completed processing but it generated an error.
     * Checks on the state of its multifile, if set.
     *
     * @method Phaser.Loader.File#onProcessError
     * @since 3.7.0
     */
    onProcessError: function ()
    {
        // eslint-disable-next-line no-console
        console.error('Failed to process file: %s "%s"', this.type, this.key);

        this.state = CONST.FILE_ERRORED;

        if (this.multiFile)
        {
            this.multiFile.onFileFailed(this);
        }

        this.loader.fileProcessComplete(this);
    },

    /**
     * Checks if a key matching the one used by this file exists in the target Cache or not.
     * This is called automatically by the LoaderPlugin to decide if the file can be safely
     * loaded or will conflict.
     *
     * @method Phaser.Loader.File#hasCacheConflict
     * @since 3.7.0
     *
     * @return {boolean} `true` if adding this file will cause a conflict, otherwise `false`.
     */
    hasCacheConflict: function ()
    {
        return (this.cache && this.cache.exists(this.key));
    },

    /**
     * Adds this file to its target cache upon successful loading and processing.
     * This method is often overridden by specific file types.
     *
     * @method Phaser.Loader.File#addToCache
     * @since 3.7.0
     */
    addToCache: function ()
    {
        if (this.cache && this.data)
        {
            this.cache.add(this.key, this.data);
        }
    },

    /**
     * Called once the file has been added to its cache and is now ready for deletion from the Loader.
     * It will emit a `filecomplete` event from the LoaderPlugin.
     *
     * @method Phaser.Loader.File#pendingDestroy
     * @fires Phaser.Loader.Events#FILE_COMPLETE
     * @fires Phaser.Loader.Events#FILE_KEY_COMPLETE
     * @since 3.7.0
     */
    pendingDestroy: function (data)
    {
        if (this.state === CONST.FILE_PENDING_DESTROY)
        {
            return;
        }

        if (data === undefined) { data = this.data; }

        var key = this.key;
        var type = this.type;

        this.loader.emit(Events.FILE_COMPLETE, key, type, data);
        this.loader.emit(Events.FILE_KEY_COMPLETE + type + '-' + key, key, type, data);

        this.loader.flagForRemoval(this);

        this.state = CONST.FILE_PENDING_DESTROY;
    },

    /**
     * Destroy this File and any references it holds.
     *
     * @method Phaser.Loader.File#destroy
     * @since 3.7.0
     */
    destroy: function ()
    {
        this.loader = null;
        this.cache = null;
        this.xhrSettings = null;
        this.multiFile = null;
        this.linkFile = null;
        this.data = null;
    }

});

/**
 * Static method for creating object URL using URL API and setting it as image 'src' attribute.
 * If URL API is not supported (usually on old browsers) it falls back to creating Base64 encoded url using FileReader.
 *
 * @method Phaser.Loader.File.createObjectURL
 * @static
 * @since 3.7.0
 *
 * @param {HTMLImageElement} image - Image object which 'src' attribute should be set to object URL.
 * @param {Blob} blob - A Blob object to create an object URL for.
 * @param {string} defaultType - Default mime type used if blob type is not available.
 */
File.createObjectURL = function (image, blob, defaultType)
{
    if (typeof URL === 'function')
    {
        image.src = URL.createObjectURL(blob);
    }
    else
    {
        var reader = new FileReader();

        reader.onload = function ()
        {
            image.removeAttribute('crossOrigin');
            image.src = 'data:' + (blob.type || defaultType) + ';base64,' + reader.result.split(',')[1];
        };

        reader.onerror = image.onerror;

        reader.readAsDataURL(blob);
    }
};

/**
 * Static method for releasing an existing object URL which was previously created
 * by calling {@link File#createObjectURL} method.
 *
 * @method Phaser.Loader.File.revokeObjectURL
 * @static
 * @since 3.7.0
 *
 * @param {HTMLImageElement} image - Image object which 'src' attribute should be revoked.
 */
File.revokeObjectURL = function (image)
{
    if (typeof URL === 'function')
    {
        URL.revokeObjectURL(image.src);
    }
};

module.exports = File;


/***/ }),

/***/ 9845:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var types = {};

/**
 * @namespace Phaser.Loader.FileTypesManager
 */

var FileTypesManager = {

    /**
     * Static method called when a LoaderPlugin is created.
     *
     * Loops through the local types object and injects all of them as
     * properties into the LoaderPlugin instance.
     *
     * @method Phaser.Loader.FileTypesManager.install
     * @since 3.0.0
     *
     * @param {Phaser.Loader.LoaderPlugin} loader - The LoaderPlugin to install the types into.
     */
    install: function (loader)
    {
        for (var key in types)
        {
            loader[key] = types[key];
        }
    },

    /**
     * Static method called directly by the File Types.
     *
     * The key is a reference to the function used to load the files via the Loader, i.e. `image`.
     *
     * @method Phaser.Loader.FileTypesManager.register
     * @since 3.0.0
     *
     * @param {string} key - The key that will be used as the method name in the LoaderPlugin.
     * @param {function} factoryFunction - The function that will be called when LoaderPlugin.key is invoked.
     */
    register: function (key, factoryFunction)
    {
        types[key] = factoryFunction;
    },

    /**
     * Removed all associated file types.
     *
     * @method Phaser.Loader.FileTypesManager.destroy
     * @since 3.0.0
     */
    destroy: function ()
    {
        types = {};
    }

};

module.exports = FileTypesManager;


/***/ }),

/***/ 5593:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Given a File and a baseURL value this returns the URL the File will use to download from.
 *
 * @function Phaser.Loader.GetURL
 * @since 3.0.0
 *
 * @param {Phaser.Loader.File} file - The File object.
 * @param {string} baseURL - A default base URL.
 *
 * @return {string} The URL the File will use.
 */
var GetURL = function (file, baseURL)
{
    if (!file.url)
    {
        return false;
    }

    if (file.url.match(/^(?:blob:|data:|capacitor:\/\/|http:\/\/|https:\/\/|\/\/)/))
    {
        return file.url;
    }
    else
    {
        return baseURL + file.url;
    }
};

module.exports = GetURL;


/***/ }),

/***/ 7410:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Extend = __webpack_require__(1030);
var XHRSettings = __webpack_require__(707);

/**
 * Takes two XHRSettings Objects and creates a new XHRSettings object from them.
 *
 * The new object is seeded by the values given in the global settings, but any setting in
 * the local object overrides the global ones.
 *
 * @function Phaser.Loader.MergeXHRSettings
 * @since 3.0.0
 *
 * @param {Phaser.Types.Loader.XHRSettingsObject} global - The global XHRSettings object.
 * @param {Phaser.Types.Loader.XHRSettingsObject} local - The local XHRSettings object.
 *
 * @return {Phaser.Types.Loader.XHRSettingsObject} A newly formed XHRSettings object.
 */
var MergeXHRSettings = function (global, local)
{
    var output = (global === undefined) ? XHRSettings() : Extend({}, global);

    if (local)
    {
        for (var setting in local)
        {
            if (local[setting] !== undefined)
            {
                output[setting] = local[setting];
            }
        }
    }

    return output;
};

module.exports = MergeXHRSettings;


/***/ }),

/***/ 3137:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var CONST = __webpack_require__(4359);
var Events = __webpack_require__(1179);

/**
 * @classdesc
 * A MultiFile is a special kind of parent that contains two, or more, Files as children and looks after
 * the loading and processing of them all. It is commonly extended and used as a base class for file types such as AtlasJSON or BitmapFont.
 *
 * You shouldn't create an instance of a MultiFile directly, but should extend it with your own class, setting a custom type and processing methods.
 *
 * @class MultiFile
 * @memberof Phaser.Loader
 * @constructor
 * @since 3.7.0
 *
 * @param {Phaser.Loader.LoaderPlugin} loader - The Loader that is going to load this File.
 * @param {string} type - The file type string for sorting within the Loader.
 * @param {string} key - The key of the file within the loader.
 * @param {Phaser.Loader.File[]} files - An array of Files that make-up this MultiFile.
 */
var MultiFile = new Class({

    initialize:

    function MultiFile (loader, type, key, files)
    {
        var finalFiles = [];

        //  Clean out any potential 'null' or 'undefined' file entries
        files.forEach(function (file)
        {
            if (file)
            {
                finalFiles.push(file);
            }
        });

        /**
         * A reference to the Loader that is going to load this file.
         *
         * @name Phaser.Loader.MultiFile#loader
         * @type {Phaser.Loader.LoaderPlugin}
         * @since 3.7.0
         */
        this.loader = loader;

        /**
         * The file type string for sorting within the Loader.
         *
         * @name Phaser.Loader.MultiFile#type
         * @type {string}
         * @since 3.7.0
         */
        this.type = type;

        /**
         * Unique cache key (unique within its file type)
         *
         * @name Phaser.Loader.MultiFile#key
         * @type {string}
         * @since 3.7.0
         */
        this.key = key;

        var loadKey = this.key;

        if (loader.prefix && loader.prefix !== '')
        {
            this.key = loader.prefix + loadKey;
        }

        /**
         * The current index being used by multi-file loaders to avoid key clashes.
         *
         * @name Phaser.Loader.MultiFile#multiKeyIndex
         * @type {number}
         * @private
         * @since 3.20.0
         */
        this.multiKeyIndex = loader.multiKeyIndex++;

        /**
         * Array of files that make up this MultiFile.
         *
         * @name Phaser.Loader.MultiFile#files
         * @type {Phaser.Loader.File[]}
         * @since 3.7.0
         */
        this.files = finalFiles;

        /**
         * The current state of the file. One of the FILE_CONST values.
         *
         * @name Phaser.Loader.MultiFile#state
         * @type {number}
         * @since 3.60.0
         */
        this.state = CONST.FILE_PENDING;

        /**
         * The completion status of this MultiFile.
         *
         * @name Phaser.Loader.MultiFile#complete
         * @type {boolean}
         * @default false
         * @since 3.7.0
         */
        this.complete = false;

        /**
         * The number of files to load.
         *
         * @name Phaser.Loader.MultiFile#pending
         * @type {number}
         * @since 3.7.0
         */

        this.pending = finalFiles.length;

        /**
         * The number of files that failed to load.
         *
         * @name Phaser.Loader.MultiFile#failed
         * @type {number}
         * @default 0
         * @since 3.7.0
         */
        this.failed = 0;

        /**
         * A storage container for transient data that the loading files need.
         *
         * @name Phaser.Loader.MultiFile#config
         * @type {any}
         * @since 3.7.0
         */
        this.config = {};

        /**
         * A reference to the Loaders baseURL at the time this MultiFile was created.
         * Used to populate child-files.
         *
         * @name Phaser.Loader.MultiFile#baseURL
         * @type {string}
         * @since 3.20.0
         */
        this.baseURL = loader.baseURL;

        /**
         * A reference to the Loaders path at the time this MultiFile was created.
         * Used to populate child-files.
         *
         * @name Phaser.Loader.MultiFile#path
         * @type {string}
         * @since 3.20.0
         */
        this.path = loader.path;

        /**
         * A reference to the Loaders prefix at the time this MultiFile was created.
         * Used to populate child-files.
         *
         * @name Phaser.Loader.MultiFile#prefix
         * @type {string}
         * @since 3.20.0
         */
        this.prefix = loader.prefix;

        //  Link the files
        for (var i = 0; i < finalFiles.length; i++)
        {
            finalFiles[i].multiFile = this;
        }
    },

    /**
     * Checks if this MultiFile is ready to process its children or not.
     *
     * @method Phaser.Loader.MultiFile#isReadyToProcess
     * @since 3.7.0
     *
     * @return {boolean} `true` if all children of this MultiFile have loaded, otherwise `false`.
     */
    isReadyToProcess: function ()
    {
        return (this.pending === 0 && this.failed === 0 && !this.complete);
    },

    /**
     * Adds another child to this MultiFile, increases the pending count and resets the completion status.
     *
     * @method Phaser.Loader.MultiFile#addToMultiFile
     * @since 3.7.0
     *
     * @param {Phaser.Loader.File} files - The File to add to this MultiFile.
     *
     * @return {Phaser.Loader.MultiFile} This MultiFile instance.
     */
    addToMultiFile: function (file)
    {
        this.files.push(file);

        file.multiFile = this;

        this.pending++;

        this.complete = false;

        return this;
    },

    /**
     * Called by each File when it finishes loading.
     *
     * @method Phaser.Loader.MultiFile#onFileComplete
     * @since 3.7.0
     *
     * @param {Phaser.Loader.File} file - The File that has completed processing.
     */
    onFileComplete: function (file)
    {
        var index = this.files.indexOf(file);

        if (index !== -1)
        {
            this.pending--;
        }
    },

    /**
     * Called by each File that fails to load.
     *
     * @method Phaser.Loader.MultiFile#onFileFailed
     * @since 3.7.0
     *
     * @param {Phaser.Loader.File} file - The File that has failed to load.
     */
    onFileFailed: function (file)
    {
        var index = this.files.indexOf(file);

        if (index !== -1)
        {
            this.failed++;

            // eslint-disable-next-line no-console
            console.error('File failed: %s "%s" (via %s "%s")', this.type, this.key, file.type, file.key);
        }
    },

    /**
     * Called once all children of this multi file have been added to their caches and is now
     * ready for deletion from the Loader.
     *
     * It will emit a `filecomplete` event from the LoaderPlugin.
     *
     * @method Phaser.Loader.MultiFile#pendingDestroy
     * @fires Phaser.Loader.Events#FILE_COMPLETE
     * @fires Phaser.Loader.Events#FILE_KEY_COMPLETE
     * @since 3.60.0
     */
    pendingDestroy: function ()
    {
        if (this.state === CONST.FILE_PENDING_DESTROY)
        {
            return;
        }

        var key = this.key;
        var type = this.type;

        this.loader.emit(Events.FILE_COMPLETE, key, type);
        this.loader.emit(Events.FILE_KEY_COMPLETE + type + '-' + key, key, type);

        this.loader.flagForRemoval(this);

        for (var i = 0; i < this.files.length; i++)
        {
            this.files[i].pendingDestroy();
        }

        this.state = CONST.FILE_PENDING_DESTROY;
    },

    /**
     * Destroy this Multi File and any references it holds.
     *
     * @method Phaser.Loader.MultiFile#destroy
     * @since 3.60.0
     */
    destroy: function ()
    {
        this.loader = null;
        this.files = null;
        this.config = null;
    }

});

module.exports = MultiFile;


/***/ }),

/***/ 5874:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var MergeXHRSettings = __webpack_require__(7410);

/**
 * Creates a new XMLHttpRequest (xhr) object based on the given File and XHRSettings
 * and starts the download of it. It uses the Files own XHRSettings and merges them
 * with the global XHRSettings object to set the xhr values before download.
 *
 * @function Phaser.Loader.XHRLoader
 * @since 3.0.0
 *
 * @param {Phaser.Loader.File} file - The File to download.
 * @param {Phaser.Types.Loader.XHRSettingsObject} globalXHRSettings - The global XHRSettings object.
 *
 * @return {XMLHttpRequest} The XHR object.
 */
var XHRLoader = function (file, globalXHRSettings)
{
    var config = MergeXHRSettings(globalXHRSettings, file.xhrSettings);

    var xhr = new XMLHttpRequest();

    xhr.open('GET', file.src, config.async, config.user, config.password);

    xhr.responseType = file.xhrSettings.responseType;
    xhr.timeout = config.timeout;

    if (config.headers)
    {
        for (var key in config.headers)
        {
            xhr.setRequestHeader(key, config.headers[key]);
        }
    }

    if (config.header && config.headerValue)
    {
        xhr.setRequestHeader(config.header, config.headerValue);
    }

    if (config.requestedWith)
    {
        xhr.setRequestHeader('X-Requested-With', config.requestedWith);
    }

    if (config.overrideMimeType)
    {
        xhr.overrideMimeType(config.overrideMimeType);
    }

    if (config.withCredentials)
    {
        xhr.withCredentials = true;
    }

    // After a successful request, the xhr.response property will contain the requested data as a DOMString, ArrayBuffer, Blob, or Document (depending on what was set for responseType.)

    xhr.onload = file.onLoad.bind(file, xhr);
    xhr.onerror = file.onError.bind(file, xhr);
    xhr.onprogress = file.onProgress.bind(file);

    //  This is the only standard method, the ones above are browser additions (maybe not universal?)
    // xhr.onreadystatechange

    xhr.send();

    return xhr;
};

module.exports = XHRLoader;


/***/ }),

/***/ 707:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Creates an XHRSettings Object with default values.
 *
 * @function Phaser.Loader.XHRSettings
 * @since 3.0.0
 *
 * @param {XMLHttpRequestResponseType} [responseType=''] - The responseType, such as 'text'.
 * @param {boolean} [async=true] - Should the XHR request use async or not?
 * @param {string} [user=''] - Optional username for the XHR request.
 * @param {string} [password=''] - Optional password for the XHR request.
 * @param {number} [timeout=0] - Optional XHR timeout value.
 * @param {boolean} [withCredentials=false] - Optional XHR withCredentials value.
 *
 * @return {Phaser.Types.Loader.XHRSettingsObject} The XHRSettings object as used by the Loader.
 */
var XHRSettings = function (responseType, async, user, password, timeout, withCredentials)
{
    if (responseType === undefined) { responseType = ''; }
    if (async === undefined) { async = true; }
    if (user === undefined) { user = ''; }
    if (password === undefined) { password = ''; }
    if (timeout === undefined) { timeout = 0; }
    if (withCredentials === undefined) { withCredentials = false; }

    // Before sending a request, set the xhr.responseType to "text",
    // "arraybuffer", "blob", or "document", depending on your data needs.
    // Note, setting xhr.responseType = '' (or omitting) will default the response to "text".

    return {

        //  Ignored by the Loader, only used by File.
        responseType: responseType,

        async: async,

        //  credentials
        user: user,
        password: password,

        //  timeout in ms (0 = no timeout)
        timeout: timeout,

        //  setRequestHeader
        headers: undefined,
        header: undefined,
        headerValue: undefined,
        requestedWith: false,

        //  overrideMimeType
        overrideMimeType: undefined,

        //  withCredentials
        withCredentials: withCredentials

    };
};

module.exports = XHRSettings;


/***/ }),

/***/ 4359:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var FILE_CONST = {

    /**
     * The Loader is idle.
     *
     * @name Phaser.Loader.LOADER_IDLE
     * @type {number}
     * @since 3.0.0
     */
    LOADER_IDLE: 0,

    /**
     * The Loader is actively loading.
     *
     * @name Phaser.Loader.LOADER_LOADING
     * @type {number}
     * @since 3.0.0
     */
    LOADER_LOADING: 1,

    /**
     * The Loader is processing files is has loaded.
     *
     * @name Phaser.Loader.LOADER_PROCESSING
     * @type {number}
     * @since 3.0.0
     */
    LOADER_PROCESSING: 2,

    /**
     * The Loader has completed loading and processing.
     *
     * @name Phaser.Loader.LOADER_COMPLETE
     * @type {number}
     * @since 3.0.0
     */
    LOADER_COMPLETE: 3,

    /**
     * The Loader is shutting down.
     *
     * @name Phaser.Loader.LOADER_SHUTDOWN
     * @type {number}
     * @since 3.0.0
     */
    LOADER_SHUTDOWN: 4,

    /**
     * The Loader has been destroyed.
     *
     * @name Phaser.Loader.LOADER_DESTROYED
     * @type {number}
     * @since 3.0.0
     */
    LOADER_DESTROYED: 5,

    /**
     * File is in the load queue but not yet started.
     *
     * @name Phaser.Loader.FILE_PENDING
     * @type {number}
     * @since 3.0.0
     */
    FILE_PENDING: 10,

    /**
     * File has been started to load by the loader (onLoad called)
     *
     * @name Phaser.Loader.FILE_LOADING
     * @type {number}
     * @since 3.0.0
     */
    FILE_LOADING: 11,

    /**
     * File has loaded successfully, awaiting processing.
     *
     * @name Phaser.Loader.FILE_LOADED
     * @type {number}
     * @since 3.0.0
     */
    FILE_LOADED: 12,

    /**
     * File failed to load.
     *
     * @name Phaser.Loader.FILE_FAILED
     * @type {number}
     * @since 3.0.0
     */
    FILE_FAILED: 13,

    /**
     * File is being processed (onProcess callback)
     *
     * @name Phaser.Loader.FILE_PROCESSING
     * @type {number}
     * @since 3.0.0
     */
    FILE_PROCESSING: 14,

    /**
     * The File has errored somehow during processing.
     *
     * @name Phaser.Loader.FILE_ERRORED
     * @type {number}
     * @since 3.0.0
     */
    FILE_ERRORED: 16,

    /**
     * File has finished processing.
     *
     * @name Phaser.Loader.FILE_COMPLETE
     * @type {number}
     * @since 3.0.0
     */
    FILE_COMPLETE: 17,

    /**
     * File has been destroyed.
     *
     * @name Phaser.Loader.FILE_DESTROYED
     * @type {number}
     * @since 3.0.0
     */
    FILE_DESTROYED: 18,

    /**
     * File was populated from local data and doesn't need an HTTP request.
     *
     * @name Phaser.Loader.FILE_POPULATED
     * @type {number}
     * @since 3.0.0
     */
    FILE_POPULATED: 19,

    /**
     * File is pending being destroyed.
     *
     * @name Phaser.Loader.FILE_PENDING_DESTROY
     * @type {number}
     * @since 3.60.0
     */
    FILE_PENDING_DESTROY: 20

};

module.exports = FILE_CONST;


/***/ }),

/***/ 462:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Loader Plugin Add File Event.
 *
 * This event is dispatched when a new file is successfully added to the Loader and placed into the load queue.
 *
 * Listen to it from a Scene using: `this.load.on('addfile', listener)`.
 *
 * If you add lots of files to a Loader from a `preload` method, it will dispatch this event for each one of them.
 *
 * @event Phaser.Loader.Events#ADD
 * @type {string}
 * @since 3.0.0
 *
 * @param {string} key - The unique key of the file that was added to the Loader.
 * @param {string} type - The [file type]{@link Phaser.Loader.File#type} string of the file that was added to the Loader, i.e. `image`.
 * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event.
 * @param {Phaser.Loader.File} file - A reference to the File which was added to the Loader.
 */
module.exports = 'addfile';


/***/ }),

/***/ 7297:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Loader Plugin Complete Event.
 *
 * This event is dispatched when the Loader has fully processed everything in the load queue.
 * By this point every loaded file will now be in its associated cache and ready for use.
 *
 * Listen to it from a Scene using: `this.load.on('complete', listener)`.
 *
 * @event Phaser.Loader.Events#COMPLETE
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event.
 * @param {number} totalComplete - The total number of files that successfully loaded.
 * @param {number} totalFailed - The total number of files that failed to load.
 */
module.exports = 'complete';


/***/ }),

/***/ 8660:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The File Load Complete Event.
 *
 * This event is dispatched by the Loader Plugin when _any_ file in the queue finishes loading.
 *
 * Listen to it from a Scene using: `this.load.on('filecomplete', listener)`.
 *
 * Make sure you remove this listener when you have finished, or it will continue to fire if the Scene reloads.
 *
 * You can also listen for the completion of a specific file. See the [FILE_KEY_COMPLETE]{@linkcode Phaser.Loader.Events#event:FILE_KEY_COMPLETE} event.
 *
 * @event Phaser.Loader.Events#FILE_COMPLETE
 * @type {string}
 * @since 3.0.0
 *
 * @param {string} key - The key of the file that just loaded and finished processing.
 * @param {string} type - The [file type]{@link Phaser.Loader.File#type} of the file that just loaded, i.e. `image`.
 * @param {any} [data] - The raw data the file contained. If the file was a multi-file, like an atlas or bitmap font, this parameter will be undefined.
 */
module.exports = 'filecomplete';


/***/ }),

/***/ 6484:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The File Load Complete Event.
 *
 * This event is dispatched by the Loader Plugin when any file in the queue finishes loading.
 *
 * It uses a special dynamic event name constructed from the key and type of the file.
 *
 * For example, if you have loaded an `image` with a key of `monster`, you can listen for it
 * using the following:
 *
 * ```javascript
 * this.load.on('filecomplete-image-monster', function (key, type, data) {
 *     // Your handler code
 * });
 * ```
 *
 * Or, if you have loaded a texture `atlas` with a key of `Level1`:
 *
 * ```javascript
 * this.load.on('filecomplete-atlasjson-Level1', function (key, type, data) {
 *     // Your handler code
 * });
 * ```
 *
 * Or, if you have loaded a sprite sheet with a key of `Explosion` and a prefix of `GAMEOVER`:
 *
 * ```javascript
 * this.load.on('filecomplete-spritesheet-GAMEOVERExplosion', function (key, type, data) {
 *     // Your handler code
 * });
 * ```
 *
 * Make sure you remove your listeners when you have finished, or they will continue to fire if the Scene reloads.
 *
 * You can also listen for the generic completion of files. See the [FILE_COMPLETE]{@linkcode Phaser.Loader.Events#event:FILE_COMPLETE} event.
 *
 * @event Phaser.Loader.Events#FILE_KEY_COMPLETE
 * @type {string}
 * @since 3.0.0
 *
 * @param {string} key - The key of the file that just loaded and finished processing.
 * @param {string} type - The [file type]{@link Phaser.Loader.File#type} of the file that just loaded, i.e. `image`.
 * @param {any} [data] - The raw data the file contained. If the file was a multi-file, like an atlas or bitmap font, this parameter will be undefined.
 */
module.exports = 'filecomplete-';


/***/ }),

/***/ 7972:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The File Load Error Event.
 *
 * This event is dispatched by the Loader Plugin when a file fails to load.
 *
 * Listen to it from a Scene using: `this.load.on('loaderror', listener)`.
 *
 * @event Phaser.Loader.Events#FILE_LOAD_ERROR
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Loader.File} file - A reference to the File which errored during load.
 */
module.exports = 'loaderror';


/***/ }),

/***/ 1906:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The File Load Event.
 *
 * This event is dispatched by the Loader Plugin when a file finishes loading,
 * but _before_ it is processed and added to the internal Phaser caches.
 *
 * Listen to it from a Scene using: `this.load.on('load', listener)`.
 *
 * @event Phaser.Loader.Events#FILE_LOAD
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Loader.File} file - A reference to the File which just finished loading.
 */
module.exports = 'load';


/***/ }),

/***/ 1441:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The File Load Progress Event.
 *
 * This event is dispatched by the Loader Plugin during the load of a file, if the browser receives a DOM ProgressEvent and
 * the `lengthComputable` event property is true. Depending on the size of the file and browser in use, this may, or may not happen.
 *
 * Listen to it from a Scene using: `this.load.on('fileprogress', listener)`.
 *
 * @event Phaser.Loader.Events#FILE_PROGRESS
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Loader.File} file - A reference to the File which errored during load.
 * @param {number} percentComplete - A value between 0 and 1 indicating how 'complete' this file is.
 */
module.exports = 'fileprogress';


/***/ }),

/***/ 1072:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Loader Plugin Post Process Event.
 *
 * This event is dispatched by the Loader Plugin when the Loader has finished loading everything in the load queue.
 * It is dispatched before the internal lists are cleared and each File is destroyed.
 *
 * Use this hook to perform any last minute processing of files that can only happen once the
 * Loader has completed, but prior to it emitting the `complete` event.
 *
 * Listen to it from a Scene using: `this.load.on('postprocess', listener)`.
 *
 * @event Phaser.Loader.Events#POST_PROCESS
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event.
 */
module.exports = 'postprocess';


/***/ }),

/***/ 1927:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Loader Plugin Progress Event.
 *
 * This event is dispatched when the Loader updates its load progress, typically as a result of a file having completed loading.
 *
 * Listen to it from a Scene using: `this.load.on('progress', listener)`.
 *
 * @event Phaser.Loader.Events#PROGRESS
 * @type {string}
 * @since 3.0.0
 *
 * @param {number} progress - The current progress of the load. A value between 0 and 1.
 */
module.exports = 'progress';


/***/ }),

/***/ 6597:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Loader Plugin Start Event.
 *
 * This event is dispatched when the Loader starts running. At this point load progress is zero.
 *
 * This event is dispatched even if there aren't any files in the load queue.
 *
 * Listen to it from a Scene using: `this.load.on('start', listener)`.
 *
 * @event Phaser.Loader.Events#START
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event.
 */
module.exports = 'start';


/***/ }),

/***/ 1179:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Loader.Events
 */

module.exports = {

    ADD: __webpack_require__(462),
    COMPLETE: __webpack_require__(7297),
    FILE_COMPLETE: __webpack_require__(8660),
    FILE_KEY_COMPLETE: __webpack_require__(6484),
    FILE_LOAD_ERROR: __webpack_require__(7972),
    FILE_LOAD: __webpack_require__(1906),
    FILE_PROGRESS: __webpack_require__(1441),
    POST_PROCESS: __webpack_require__(1072),
    PROGRESS: __webpack_require__(1927),
    START: __webpack_require__(6597)

};


/***/ }),

/***/ 6732:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var CONST = __webpack_require__(4359);
var File = __webpack_require__(1593);
var FileTypesManager = __webpack_require__(9845);
var GetFastValue = __webpack_require__(4597);
var IsPlainObject = __webpack_require__(2482);
var GetURL = __webpack_require__(5593);

/**
 * @classdesc
 * A single Image File suitable for loading by the Loader.
 *
 * These are created when you use the Phaser.Loader.LoaderPlugin#image method and are not typically created directly.
 *
 * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#image.
 *
 * @class ImageFile
 * @extends Phaser.Loader.File
 * @memberof Phaser.Loader.FileTypes
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
 * @param {(string|Phaser.Types.Loader.FileTypes.ImageFileConfig)} key - The key to use for this file, or a file configuration object.
 * @param {string|string[]} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.png`, i.e. if `key` was "alien" then the URL will be "alien.png".
 * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file.
 * @param {Phaser.Types.Loader.FileTypes.ImageFrameConfig} [frameConfig] - The frame configuration object. Only provided for, and used by, Sprite Sheets.
 */
var ImageFile = new Class({

    Extends: File,

    initialize:

    function ImageFile (loader, key, url, xhrSettings, frameConfig)
    {
        var extension = 'png';
        var normalMapURL;

        if (IsPlainObject(key))
        {
            var config = key;

            key = GetFastValue(config, 'key');
            url = GetFastValue(config, 'url');
            normalMapURL = GetFastValue(config, 'normalMap');
            xhrSettings = GetFastValue(config, 'xhrSettings');
            extension = GetFastValue(config, 'extension', extension);
            frameConfig = GetFastValue(config, 'frameConfig');
        }

        if (Array.isArray(url))
        {
            normalMapURL = url[1];
            url = url[0];
        }

        var fileConfig = {
            type: 'image',
            cache: loader.textureManager,
            extension: extension,
            responseType: 'blob',
            key: key,
            url: url,
            xhrSettings: xhrSettings,
            config: frameConfig
        };

        File.call(this, loader, fileConfig);

        //  Do we have a normal map to load as well?
        if (normalMapURL)
        {
            var normalMap = new ImageFile(loader, this.key, normalMapURL, xhrSettings, frameConfig);

            normalMap.type = 'normalMap';

            this.setLink(normalMap);

            loader.addFile(normalMap);
        }

        this.useImageElementLoad = loader.imageLoadType === 'HTMLImageElement';

        if (this.useImageElementLoad)
        {
            this.load = this.loadImage;
            this.onProcess = this.onProcessImage;
        }
    },

    /**
     * Called automatically by Loader.nextFile.
     * This method controls what extra work this File does with its loaded data.
     *
     * @method Phaser.Loader.FileTypes.ImageFile#onProcess
     * @since 3.7.0
     */
    onProcess: function ()
    {
        this.state = CONST.FILE_PROCESSING;

        this.data = new Image();

        this.data.crossOrigin = this.crossOrigin;

        var _this = this;

        this.data.onload = function ()
        {
            File.revokeObjectURL(_this.data);

            _this.onProcessComplete();
        };

        this.data.onerror = function ()
        {
            File.revokeObjectURL(_this.data);

            _this.onProcessError();
        };

        File.createObjectURL(this.data, this.xhrLoader.response, 'image/png');
    },

    /**
     * Handles image load processing.
     *
     * @method Phaser.Loader.FileTypes.ImageFile#onProcessImage
     * @private
     * @since 3.60.0
     */
    onProcessImage: function ()
    {
        var result = this.state;

        this.state = CONST.FILE_PROCESSING;

        if (result === CONST.FILE_LOADED)
        {
            this.onProcessComplete();
        }
        else
        {
            this.onProcessError();
        }
    },

    /**
     * Loads the image using either XHR or an Image tag.
     *
     * @method Phaser.Loader.FileTypes.ImageFile#loadImage
     * @private
     * @since 3.60.0
     */
    loadImage: function ()
    {
        this.state = CONST.FILE_LOADING;

        this.src = GetURL(this, this.loader.baseURL);

        if (this.src.indexOf('data:') === 0)
        {
            console.warn('Local data URIs are not supported: ' + this.key);
        }
        else
        {
            this.data = new Image();

            this.data.crossOrigin = this.crossOrigin;

            var _this = this;

            this.data.onload = function ()
            {
                _this.state = CONST.FILE_LOADED;

                _this.loader.nextFile(_this, true);
            };

            this.data.onerror = function ()
            {
                _this.loader.nextFile(_this, false);
            };

            this.data.src = this.src;
        }
    },

    /**
     * Adds this file to its target cache upon successful loading and processing.
     *
     * @method Phaser.Loader.FileTypes.ImageFile#addToCache
     * @since 3.7.0
     */
    addToCache: function ()
    {
        //  Check if we have a linked normal map
        var linkFile = this.linkFile;

        if (linkFile)
        {
            //  We do, but has it loaded?
            if (linkFile.state >= CONST.FILE_COMPLETE)
            {
                if (linkFile.type === 'spritesheet')
                {
                    linkFile.addToCache();
                }
                else if (this.type === 'normalMap')
                {
                    //  linkFile.data = Image
                    //  this.data = Normal Map
                    this.cache.addImage(this.key, linkFile.data, this.data);
                }
                else
                {
                    //  linkFile.data = Normal Map
                    //  this.data = Image
                    this.cache.addImage(this.key, this.data, linkFile.data);
                }
            }

            //  Nothing to do here, we'll use the linkFile `addToCache` call
            //  to process this pair
        }
        else
        {
            this.cache.addImage(this.key, this.data);
        }
    }

});

/**
 * Adds an Image, or array of Images, to the current load queue.
 *
 * You can call this method from within your Scene's `preload`, along with any other files you wish to load:
 *
 * ```javascript
 * function preload ()
 * {
 *     this.load.image('logo', 'images/phaserLogo.png');
 * }
 * ```
 *
 * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
 * or if it's already running, when the next free load slot becomes available. This happens automatically if you
 * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
 * it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
 * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
 * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
 * loaded.
 *
 * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle.
 * If you try to load an animated gif only the first frame will be rendered. Browsers do not natively support playback
 * of animated gifs to Canvas elements.
 *
 * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load.
 * The key should be unique both in terms of files being loaded and files already present in the Texture Manager.
 * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file
 * then remove it from the Texture Manager first, before loading a new one.
 *
 * Instead of passing arguments you can pass a configuration object, such as:
 *
 * ```javascript
 * this.load.image({
 *     key: 'logo',
 *     url: 'images/AtariLogo.png'
 * });
 * ```
 *
 * See the documentation for `Phaser.Types.Loader.FileTypes.ImageFileConfig` for more details.
 *
 * Once the file has finished loading you can use it as a texture for a Game Object by referencing its key:
 *
 * ```javascript
 * this.load.image('logo', 'images/AtariLogo.png');
 * // and later in your game ...
 * this.add.image(x, y, 'logo');
 * ```
 *
 * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files
 * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and
 * this is what you would use to retrieve the image from the Texture Manager.
 *
 * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
 *
 * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien"
 * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although
 * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
 *
 * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image,
 * then you can specify it by providing an array as the `url` where the second element is the normal map:
 *
 * ```javascript
 * this.load.image('logo', [ 'images/AtariLogo.png', 'images/AtariLogo-n.png' ]);
 * ```
 *
 * Or, if you are using a config object use the `normalMap` property:
 *
 * ```javascript
 * this.load.image({
 *     key: 'logo',
 *     url: 'images/AtariLogo.png',
 *     normalMap: 'images/AtariLogo-n.png'
 * });
 * ```
 *
 * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings.
 * Normal maps are a WebGL only feature.
 *
 * In Phaser 3.60 a new property was added that allows you to control how images are loaded. By default, images are loaded via XHR as Blobs.
 * However, you can set `loader.imageLoadType: "HTMLImageElement"` in the Game Configuration and instead, the Loader will load all images
 * via the Image tag instead.
 *
 * Note: The ability to load this type of file will only be available if the Image File type has been built into Phaser.
 * It is available in the default build but can be excluded from custom builds.
 *
 * @method Phaser.Loader.LoaderPlugin#image
 * @fires Phaser.Loader.Events#ADD
 * @since 3.0.0
 *
 * @param {(string|Phaser.Types.Loader.FileTypes.ImageFileConfig|Phaser.Types.Loader.FileTypes.ImageFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
 * @param {string|string[]} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.png`, i.e. if `key` was "alien" then the URL will be "alien.png".
 * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings.
 *
 * @return {this} The Loader instance.
 */
FileTypesManager.register('image', function (key, url, xhrSettings)
{
    if (Array.isArray(key))
    {
        for (var i = 0; i < key.length; i++)
        {
            //  If it's an array it has to be an array of Objects, so we get everything out of the 'key' object
            this.addFile(new ImageFile(this, key[i]));
        }
    }
    else
    {
        this.addFile(new ImageFile(this, key, url, xhrSettings));
    }

    return this;
});

module.exports = ImageFile;


/***/ }),

/***/ 704:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var CONST = __webpack_require__(4359);
var File = __webpack_require__(1593);
var FileTypesManager = __webpack_require__(9845);
var GetFastValue = __webpack_require__(4597);
var GetValue = __webpack_require__(5851);
var IsPlainObject = __webpack_require__(2482);

/**
 * @classdesc
 * A single JSON File suitable for loading by the Loader.
 *
 * These are created when you use the Phaser.Loader.LoaderPlugin#json method and are not typically created directly.
 *
 * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#json.
 *
 * @class JSONFile
 * @extends Phaser.Loader.File
 * @memberof Phaser.Loader.FileTypes
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
 * @param {(string|Phaser.Types.Loader.FileTypes.JSONFileConfig)} key - The key to use for this file, or a file configuration object.
 * @param {(object|string)} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json". Or, can be a fully formed JSON Object.
 * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file.
 * @param {string} [dataKey] - When the JSON file loads only this property will be stored in the Cache.
 */
var JSONFile = new Class({

    Extends: File,

    initialize:

    //  url can either be a string, in which case it is treated like a proper url, or an object, in which case it is treated as a ready-made JS Object
    //  dataKey allows you to pluck a specific object out of the JSON and put just that into the cache, rather than the whole thing

    function JSONFile (loader, key, url, xhrSettings, dataKey)
    {
        var extension = 'json';

        if (IsPlainObject(key))
        {
            var config = key;

            key = GetFastValue(config, 'key');
            url = GetFastValue(config, 'url');
            xhrSettings = GetFastValue(config, 'xhrSettings');
            extension = GetFastValue(config, 'extension', extension);
            dataKey = GetFastValue(config, 'dataKey', dataKey);
        }

        var fileConfig = {
            type: 'json',
            cache: loader.cacheManager.json,
            extension: extension,
            responseType: 'text',
            key: key,
            url: url,
            xhrSettings: xhrSettings,
            config: dataKey
        };

        File.call(this, loader, fileConfig);

        //  A JSON object has been provided (instead of a URL), so we'll use it directly as the File.data. No need to load it.
        if (IsPlainObject(url))
        {
            if (dataKey)
            {
                this.data = GetValue(url, dataKey);
            }
            else
            {
                this.data = url;
            }

            this.state = CONST.FILE_POPULATED;
        }
    },

    /**
     * Called automatically by Loader.nextFile.
     * This method controls what extra work this File does with its loaded data.
     *
     * @method Phaser.Loader.FileTypes.JSONFile#onProcess
     * @since 3.7.0
     */
    onProcess: function ()
    {
        if (this.state !== CONST.FILE_POPULATED)
        {
            this.state = CONST.FILE_PROCESSING;

            try
            {
                var json = JSON.parse(this.xhrLoader.responseText);
            }
            catch (e)
            {
                this.onProcessError();

                throw e;
            }

            var key = this.config;

            if (typeof key === 'string')
            {
                this.data = GetValue(json, key, json);
            }
            else
            {
                this.data = json;
            }
        }

        this.onProcessComplete();
    }

});

/**
 * Adds a JSON file, or array of JSON files, to the current load queue.
 *
 * You can call this method from within your Scene's `preload`, along with any other files you wish to load:
 *
 * ```javascript
 * function preload ()
 * {
 *     this.load.json('wavedata', 'files/AlienWaveData.json');
 * }
 * ```
 *
 * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
 * or if it's already running, when the next free load slot becomes available. This happens automatically if you
 * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
 * it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
 * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
 * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
 * loaded.
 *
 * The key must be a unique String. It is used to add the file to the global JSON Cache upon a successful load.
 * The key should be unique both in terms of files being loaded and files already present in the JSON Cache.
 * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file
 * then remove it from the JSON Cache first, before loading a new one.
 *
 * Instead of passing arguments you can pass a configuration object, such as:
 *
 * ```javascript
 * this.load.json({
 *     key: 'wavedata',
 *     url: 'files/AlienWaveData.json'
 * });
 * ```
 *
 * See the documentation for `Phaser.Types.Loader.FileTypes.JSONFileConfig` for more details.
 *
 * Once the file has finished loading you can access it from its Cache using its key:
 *
 * ```javascript
 * this.load.json('wavedata', 'files/AlienWaveData.json');
 * // and later in your game ...
 * var data = this.cache.json.get('wavedata');
 * ```
 *
 * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files
 * key. For example, if the prefix was `LEVEL1.` and the key was `Waves` the final key will be `LEVEL1.Waves` and
 * this is what you would use to retrieve the text from the JSON Cache.
 *
 * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
 *
 * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "data"
 * and no URL is given then the Loader will set the URL to be "data.json". It will always add `.json` as the extension, although
 * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
 *
 * You can also optionally provide a `dataKey` to use. This allows you to extract only a part of the JSON and store it in the Cache,
 * rather than the whole file. For example, if your JSON data had a structure like this:
 *
 * ```json
 * {
 *     "level1": {
 *         "baddies": {
 *             "aliens": {},
 *             "boss": {}
 *         }
 *     },
 *     "level2": {},
 *     "level3": {}
 * }
 * ```
 *
 * And you only wanted to store the `boss` data in the Cache, then you could pass `level1.baddies.boss`as the `dataKey`.
 *
 * Note: The ability to load this type of file will only be available if the JSON File type has been built into Phaser.
 * It is available in the default build but can be excluded from custom builds.
 *
 * @method Phaser.Loader.LoaderPlugin#json
 * @fires Phaser.Loader.Events#ADD
 * @since 3.0.0
 *
 * @param {(string|Phaser.Types.Loader.FileTypes.JSONFileConfig|Phaser.Types.Loader.FileTypes.JSONFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
 * @param {(object|string)} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json". Or, can be a fully formed JSON Object.
 * @param {string} [dataKey] - When the JSON file loads only this property will be stored in the Cache.
 * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings.
 *
 * @return {this} The Loader instance.
 */
FileTypesManager.register('json', function (key, url, dataKey, xhrSettings)
{
    if (Array.isArray(key))
    {
        for (var i = 0; i < key.length; i++)
        {
            //  If it's an array it has to be an array of Objects, so we get everything out of the 'key' object
            this.addFile(new JSONFile(this, key[i]));
        }
    }
    else
    {
        this.addFile(new JSONFile(this, key, url, xhrSettings, dataKey));
    }

    return this;
});

module.exports = JSONFile;


/***/ }),

/***/ 1192:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var CONST = __webpack_require__(4359);
var File = __webpack_require__(1593);
var FileTypesManager = __webpack_require__(9845);
var GetFastValue = __webpack_require__(4597);
var IsPlainObject = __webpack_require__(2482);

/**
 * @classdesc
 * A single Text File suitable for loading by the Loader.
 *
 * These are created when you use the Phaser.Loader.LoaderPlugin#text method and are not typically created directly.
 *
 * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#text.
 *
 * @class TextFile
 * @extends Phaser.Loader.File
 * @memberof Phaser.Loader.FileTypes
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
 * @param {(string|Phaser.Types.Loader.FileTypes.TextFileConfig)} key - The key to use for this file, or a file configuration object.
 * @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt".
 * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file.
 */
var TextFile = new Class({

    Extends: File,

    initialize:

    function TextFile (loader, key, url, xhrSettings)
    {
        var type = 'text';
        var extension = 'txt';
        var cache = loader.cacheManager.text;

        if (IsPlainObject(key))
        {
            var config = key;

            key = GetFastValue(config, 'key');
            url = GetFastValue(config, 'url');
            xhrSettings = GetFastValue(config, 'xhrSettings');
            extension = GetFastValue(config, 'extension', extension);
            type = GetFastValue(config, 'type', type);
            cache = GetFastValue(config, 'cache', cache);
        }

        var fileConfig = {
            type: type,
            cache: cache,
            extension: extension,
            responseType: 'text',
            key: key,
            url: url,
            xhrSettings: xhrSettings
        };

        File.call(this, loader, fileConfig);
    },

    /**
     * Called automatically by Loader.nextFile.
     * This method controls what extra work this File does with its loaded data.
     *
     * @method Phaser.Loader.FileTypes.TextFile#onProcess
     * @since 3.7.0
     */
    onProcess: function ()
    {
        this.state = CONST.FILE_PROCESSING;

        this.data = this.xhrLoader.responseText;

        this.onProcessComplete();
    }

});

/**
 * Adds a Text file, or array of Text files, to the current load queue.
 *
 * You can call this method from within your Scene's `preload`, along with any other files you wish to load:
 *
 * ```javascript
 * function preload ()
 * {
 *     this.load.text('story', 'files/IntroStory.txt');
 * }
 * ```
 *
 * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
 * or if it's already running, when the next free load slot becomes available. This happens automatically if you
 * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
 * it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
 * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
 * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
 * loaded.
 *
 * The key must be a unique String. It is used to add the file to the global Text Cache upon a successful load.
 * The key should be unique both in terms of files being loaded and files already present in the Text Cache.
 * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file
 * then remove it from the Text Cache first, before loading a new one.
 *
 * Instead of passing arguments you can pass a configuration object, such as:
 *
 * ```javascript
 * this.load.text({
 *     key: 'story',
 *     url: 'files/IntroStory.txt'
 * });
 * ```
 *
 * See the documentation for `Phaser.Types.Loader.FileTypes.TextFileConfig` for more details.
 *
 * Once the file has finished loading you can access it from its Cache using its key:
 *
 * ```javascript
 * this.load.text('story', 'files/IntroStory.txt');
 * // and later in your game ...
 * var data = this.cache.text.get('story');
 * ```
 *
 * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files
 * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and
 * this is what you would use to retrieve the text from the Text Cache.
 *
 * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
 *
 * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "story"
 * and no URL is given then the Loader will set the URL to be "story.txt". It will always add `.txt` as the extension, although
 * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
 *
 * Note: The ability to load this type of file will only be available if the Text File type has been built into Phaser.
 * It is available in the default build but can be excluded from custom builds.
 *
 * @method Phaser.Loader.LoaderPlugin#text
 * @fires Phaser.Loader.Events#ADD
 * @since 3.0.0
 *
 * @param {(string|Phaser.Types.Loader.FileTypes.TextFileConfig|Phaser.Types.Loader.FileTypes.TextFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
 * @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `<key>.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt".
 * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings.
 *
 * @return {this} The Loader instance.
 */
FileTypesManager.register('text', function (key, url, xhrSettings)
{
    if (Array.isArray(key))
    {
        for (var i = 0; i < key.length; i++)
        {
            //  If it's an array it has to be an array of Objects, so we get everything out of the 'key' object
            this.addFile(new TextFile(this, key[i]));
        }
    }
    else
    {
        this.addFile(new TextFile(this, key, url, xhrSettings));
    }

    return this;
});

module.exports = TextFile;


/***/ }),

/***/ 3136:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the mean average of the given values.
 *
 * @function Phaser.Math.Average
 * @since 3.0.0
 *
 * @param {number[]} values - The values to average.
 *
 * @return {number} The average value.
 */
var Average = function (values)
{
    var sum = 0;

    for (var i = 0; i < values.length; i++)
    {
        sum += (+values[i]);
    }

    return sum / values.length;
};

module.exports = Average;


/***/ }),

/***/ 785:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Factorial = __webpack_require__(3916);

/**
 * Calculates the Bernstein basis from the three factorial coefficients.
 *
 * @function Phaser.Math.Bernstein
 * @since 3.0.0
 *
 * @param {number} n - The first value.
 * @param {number} i - The second value.
 *
 * @return {number} The Bernstein basis of Factorial(n) / Factorial(i) / Factorial(n - i)
 */
var Bernstein = function (n, i)
{
    return Factorial(n) / Factorial(i) / Factorial(n - i);
};

module.exports = Bernstein;


/***/ }),

/***/ 7025:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Compute a random integer between the `min` and `max` values, inclusive.
 *
 * @function Phaser.Math.Between
 * @since 3.0.0
 *
 * @param {number} min - The minimum value.
 * @param {number} max - The maximum value.
 *
 * @return {number} The random integer.
 */
var Between = function (min, max)
{
    return Math.floor(Math.random() * (max - min + 1) + min);
};

module.exports = Between;


/***/ }),

/***/ 48:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculates a Catmull-Rom value from the given points, based on an alpha of 0.5.
 *
 * @function Phaser.Math.CatmullRom
 * @since 3.0.0
 *
 * @param {number} t - The amount to interpolate by.
 * @param {number} p0 - The first control point.
 * @param {number} p1 - The second control point.
 * @param {number} p2 - The third control point.
 * @param {number} p3 - The fourth control point.
 *
 * @return {number} The Catmull-Rom value.
 */
var CatmullRom = function (t, p0, p1, p2, p3)
{
    var v0 = (p2 - p0) * 0.5;
    var v1 = (p3 - p1) * 0.5;
    var t2 = t * t;
    var t3 = t * t2;

    return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
};

module.exports = CatmullRom;


/***/ }),

/***/ 5035:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Ceils to some place comparative to a `base`, default is 10 for decimal place.
 *
 * The `place` is represented by the power applied to `base` to get that place.
 *
 * @function Phaser.Math.CeilTo
 * @since 3.0.0
 *
 * @param {number} value - The value to round.
 * @param {number} [place=0] - The place to round to.
 * @param {number} [base=10] - The base to round in. Default is 10 for decimal.
 *
 * @return {number} The rounded value.
 */
var CeilTo = function (value, place, base)
{
    if (place === undefined) { place = 0; }
    if (base === undefined) { base = 10; }

    var p = Math.pow(base, -place);

    return Math.ceil(value * p) / p;
};

module.exports = CeilTo;


/***/ }),

/***/ 2915:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Force a value within the boundaries by clamping it to the range `min`, `max`.
 *
 * @function Phaser.Math.Clamp
 * @since 3.0.0
 *
 * @param {number} value - The value to be clamped.
 * @param {number} min - The minimum bounds.
 * @param {number} max - The maximum bounds.
 *
 * @return {number} The clamped value.
 */
var Clamp = function (value, min, max)
{
    return Math.max(min, Math.min(max, value));
};

module.exports = Clamp;


/***/ }),

/***/ 7149:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var CONST = __webpack_require__(7425);

/**
 * Convert the given angle from degrees, to the equivalent angle in radians.
 *
 * @function Phaser.Math.DegToRad
 * @since 3.0.0
 *
 * @param {number} degrees - The angle (in degrees) to convert to radians.
 *
 * @return {number} The given angle converted to radians.
 */
var DegToRad = function (degrees)
{
    return degrees * CONST.DEG_TO_RAD;
};

module.exports = DegToRad;


/***/ }),

/***/ 2975:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculates the positive difference of two given numbers.
 *
 * @function Phaser.Math.Difference
 * @since 3.0.0
 *
 * @param {number} a - The first number in the calculation.
 * @param {number} b - The second number in the calculation.
 *
 * @return {number} The positive difference of the two given numbers.
 */
var Difference = function (a, b)
{
    return Math.abs(a - b);
};

module.exports = Difference;


/***/ }),

/***/ 2107:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Clamp = __webpack_require__(2915);
var Class = __webpack_require__(7473);
var Matrix4 = __webpack_require__(9652);
var NOOP = __webpack_require__(1984);

var tempMatrix = new Matrix4();

/**
 * @classdesc
 *
 * @class Euler
 * @memberof Phaser.Math
 * @constructor
 * @since 3.50.0
 *
 * @param {number} [x] - The x component.
 * @param {number} [y] - The y component.
 * @param {number} [z] - The z component.
 */
var Euler = new Class({

    initialize:

    function Euler (x, y, z, order)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = 0; }
        if (z === undefined) { z = 0; }
        if (order === undefined) { order = Euler.DefaultOrder; }

        this._x = x;
        this._y = y;
        this._z = z;
        this._order = order;

        this.onChangeCallback = NOOP;
    },

    x: {
        get: function ()
        {
            return this._x;
        },

        set: function (value)
        {
            this._x = value;

            this.onChangeCallback(this);
        }
    },

    y: {
        get: function ()
        {
            return this._y;
        },

        set: function (value)
        {
            this._y = value;

            this.onChangeCallback(this);
        }
    },

    z: {
        get: function ()
        {
            return this._z;
        },

        set: function (value)
        {
            this._z = value;

            this.onChangeCallback(this);
        }
    },

    order: {
        get: function ()
        {
            return this._order;
        },

        set: function (value)
        {
            this._order = value;

            this.onChangeCallback(this);
        }
    },

    set: function (x, y, z, order)
    {
        if (order === undefined) { order = this._order; }

        this._x = x;
        this._y = y;
        this._z = z;
        this._order = order;

        this.onChangeCallback(this);

        return this;
    },

    copy: function (euler)
    {
        return this.set(euler.x, euler.y, euler.z, euler.order);
    },

    setFromQuaternion: function (quaternion, order, update)
    {
        if (order === undefined) { order = this._order; }
        if (update === undefined) { update = false; }

        tempMatrix.fromQuat(quaternion);

        return this.setFromRotationMatrix(tempMatrix, order, update);
    },

    setFromRotationMatrix: function (matrix, order, update)
    {
        if (order === undefined) { order = this._order; }
        if (update === undefined) { update = false; }

        var elements = matrix.val;

        //  Upper 3x3 of matrix is un-scaled rotation matrix
        var m11 = elements[0];
        var m12 = elements[4];
        var m13 = elements[8];
        var m21 = elements[1];
        var m22 = elements[5];
        var m23 = elements[9];
        var m31 = elements[2];
        var m32 = elements[6];
        var m33 = elements[10];

        var x = 0;
        var y = 0;
        var z = 0;
        var epsilon = 0.99999;

        switch (order)
        {
            case 'XYZ':
            {
                y = Math.asin(Clamp(m13, -1, 1));

                if (Math.abs(m13) < epsilon)
                {
                    x = Math.atan2(-m23, m33);
                    z = Math.atan2(-m12, m11);
                }
                else
                {
                    x = Math.atan2(m32, m22);
                }

                break;
            }

            case 'YXZ':
            {
                x = Math.asin(-Clamp(m23, -1, 1));

                if (Math.abs(m23) < epsilon)
                {
                    y = Math.atan2(m13, m33);
                    z = Math.atan2(m21, m22);
                }
                else
                {
                    y = Math.atan2(-m31, m11);
                }

                break;
            }

            case 'ZXY':
            {
                x = Math.asin(Clamp(m32, -1, 1));

                if (Math.abs(m32) < epsilon)
                {
                    y = Math.atan2(-m31, m33);
                    z = Math.atan2(-m12, m22);
                }
                else
                {
                    z = Math.atan2(m21, m11);
                }

                break;
            }

            case 'ZYX':
            {
                y = Math.asin(-Clamp(m31, -1, 1));

                if (Math.abs(m31) < epsilon)
                {
                    x = Math.atan2(m32, m33);
                    z = Math.atan2(m21, m11);
                }
                else
                {
                    z = Math.atan2(-m12, m22);
                }

                break;
            }

            case 'YZX':
            {
                z = Math.asin(Clamp(m21, -1, 1));

                if (Math.abs(m21) < epsilon)
                {
                    x = Math.atan2(-m23, m22);
                    y = Math.atan2(-m31, m11);
                }
                else
                {
                    y = Math.atan2(m13, m33);
                }

                break;
            }

            case 'XZY':
            {
                z = Math.asin(-Clamp(m12, -1, 1));

                if (Math.abs(m12) < epsilon)
                {
                    x = Math.atan2(m32, m22);
                    y = Math.atan2(m13, m11);
                }
                else
                {
                    x = Math.atan2(-m23, m33);
                }

                break;
            }
        }

        this._x = x;
        this._y = y;
        this._z = z;
        this._order = order;

        if (update)
        {
            this.onChangeCallback(this);
        }

        return this;
    }

});

Euler.RotationOrders = [ 'XYZ', 'YXZ', 'ZXY', 'ZYX', 'YZX', 'XZY' ];

Euler.DefaultOrder = 'XYZ';

module.exports = Euler;


/***/ }),

/***/ 3916:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculates the factorial of a given number for integer values greater than 0.
 *
 * @function Phaser.Math.Factorial
 * @since 3.0.0
 *
 * @param {number} value - A positive integer to calculate the factorial of.
 *
 * @return {number} The factorial of the given number.
 */
var Factorial = function (value)
{
    if (value === 0)
    {
        return 1;
    }

    var res = value;

    while (--value)
    {
        res *= value;
    }

    return res;
};

module.exports = Factorial;


/***/ }),

/***/ 104:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Generate a random floating point number between the two given bounds, minimum inclusive, maximum exclusive.
 *
 * @function Phaser.Math.FloatBetween
 * @since 3.0.0
 *
 * @param {number} min - The lower bound for the float, inclusive.
 * @param {number} max - The upper bound for the float exclusive.
 *
 * @return {number} A random float within the given range.
 */
var FloatBetween = function (min, max)
{
    return Math.random() * (max - min) + min;
};

module.exports = FloatBetween;


/***/ }),

/***/ 4941:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Floors to some place comparative to a `base`, default is 10 for decimal place.
 *
 * The `place` is represented by the power applied to `base` to get that place.
 *
 * @function Phaser.Math.FloorTo
 * @since 3.0.0
 *
 * @param {number} value - The value to round.
 * @param {number} [place=0] - The place to round to.
 * @param {number} [base=10] - The base to round in. Default is 10 for decimal.
 *
 * @return {number} The rounded value.
 */
var FloorTo = function (value, place, base)
{
    if (place === undefined) { place = 0; }
    if (base === undefined) { base = 10; }

    var p = Math.pow(base, -place);

    return Math.floor(value * p) / p;
};

module.exports = FloorTo;


/***/ }),

/***/ 1555:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Clamp = __webpack_require__(2915);

/**
 * Return a value based on the range between `min` and `max` and the percentage given.
 *
 * @function Phaser.Math.FromPercent
 * @since 3.0.0
 *
 * @param {number} percent - A value between 0 and 1 representing the percentage.
 * @param {number} min - The minimum value.
 * @param {number} [max] - The maximum value.
 *
 * @return {number} The value that is `percent` percent between `min` and `max`.
 */
var FromPercent = function (percent, min, max)
{
    percent = Clamp(percent, 0, 1);

    return (max - min) * percent + min;
};

module.exports = FromPercent;


/***/ }),

/***/ 5005:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate a per-ms speed from a distance and time (given in seconds).
 *
 * @function Phaser.Math.GetSpeed
 * @since 3.0.0
 *
 * @param {number} distance - The distance.
 * @param {number} time - The time, in seconds.
 *
 * @return {number} The speed, in distance per ms.
 *
 * @example
 * // 400px over 1 second is 0.4 px/ms
 * Phaser.Math.GetSpeed(400, 1) // -> 0.4
 */
var GetSpeed = function (distance, time)
{
    return (distance / time) / 1000;
};

module.exports = GetSpeed;


/***/ }),

/***/ 3702:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Check if a given value is an even number.
 *
 * @function Phaser.Math.IsEven
 * @since 3.0.0
 *
 * @param {number} value - The number to perform the check with.
 *
 * @return {boolean} Whether the number is even or not.
 */
var IsEven = function (value)
{
    // Use abstract equality == for "is number" test

    // eslint-disable-next-line eqeqeq
    return (value == parseFloat(value)) ? !(value % 2) : void 0;
};

module.exports = IsEven;


/***/ }),

/***/ 8820:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Check if a given value is an even number using a strict type check.
 *
 * @function Phaser.Math.IsEvenStrict
 * @since 3.0.0
 *
 * @param {number} value - The number to perform the check with.
 *
 * @return {boolean} Whether the number is even or not.
 */
var IsEvenStrict = function (value)
{
    // Use strict equality === for "is number" test
    return (value === parseFloat(value)) ? !(value % 2) : void 0;
};

module.exports = IsEvenStrict;


/***/ }),

/***/ 1743:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculates a linear (interpolation) value over t.
 *
 * @function Phaser.Math.Linear
 * @since 3.0.0
 *
 * @param {number} p0 - The first point.
 * @param {number} p1 - The second point.
 * @param {number} t - The percentage between p0 and p1 to return, represented as a number between 0 and 1.
 *
 * @return {number} The step t% of the way between p0 and p1.
 */
var Linear = function (p0, p1, t)
{
    return (p1 - p0) * t + p0;
};

module.exports = Linear;


/***/ }),

/***/ 3416:
/***/ ((module) => {

/**
 * @author       Greg McLean <GregDevProjects>
 * @copyright    2021 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Interpolates two given Vectors and returns a new Vector between them.
 *
 * Does not modify either of the passed Vectors.
 *
 * @function Phaser.Math.LinearXY
 * @since 3.60.0
 *
 * @param {Phaser.Math.Vector2} vector1 - Starting vector
 * @param {Phaser.Math.Vector2} vector2 - Ending vector
 * @param {number} [t=0] - The percentage between vector1 and vector2 to return, represented as a number between 0 and 1.
 *
 * @return {Phaser.Math.Vector2} The step t% of the way between vector1 and vector2.
 */
var LinearXY = function (vector1, vector2, t)
{
    if (t === undefined) { t = 0; }

    return vector1.clone().lerp(vector2, t);
};

module.exports = LinearXY;


/***/ }),

/***/ 2149:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

//  Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
//  and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl

var Class = __webpack_require__(7473);

/**
 * @classdesc
 * A three-dimensional matrix.
 *
 * Defaults to the identity matrix when instantiated.
 *
 * @class Matrix3
 * @memberof Phaser.Math
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Math.Matrix3} [m] - Optional Matrix3 to copy values from.
 */
var Matrix3 = new Class({

    initialize:

    function Matrix3 (m)
    {
        /**
         * The matrix values.
         *
         * @name Phaser.Math.Matrix3#val
         * @type {Float32Array}
         * @since 3.0.0
         */
        this.val = new Float32Array(9);

        if (m)
        {
            //  Assume Matrix3 with val:
            this.copy(m);
        }
        else
        {
            //  Default to identity
            this.identity();
        }
    },

    /**
     * Make a clone of this Matrix3.
     *
     * @method Phaser.Math.Matrix3#clone
     * @since 3.0.0
     *
     * @return {Phaser.Math.Matrix3} A clone of this Matrix3.
     */
    clone: function ()
    {
        return new Matrix3(this);
    },

    /**
     * This method is an alias for `Matrix3.copy`.
     *
     * @method Phaser.Math.Matrix3#set
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix3} src - The Matrix to set the values of this Matrix's from.
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    set: function (src)
    {
        return this.copy(src);
    },

    /**
     * Copy the values of a given Matrix into this Matrix.
     *
     * @method Phaser.Math.Matrix3#copy
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix3} src - The Matrix to copy the values from.
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    copy: function (src)
    {
        var out = this.val;
        var a = src.val;

        out[0] = a[0];
        out[1] = a[1];
        out[2] = a[2];
        out[3] = a[3];
        out[4] = a[4];
        out[5] = a[5];
        out[6] = a[6];
        out[7] = a[7];
        out[8] = a[8];

        return this;
    },

    /**
     * Copy the values of a given Matrix4 into this Matrix3.
     *
     * @method Phaser.Math.Matrix3#fromMat4
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} m - The Matrix4 to copy the values from.
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    fromMat4: function (m)
    {
        var a = m.val;
        var out = this.val;

        out[0] = a[0];
        out[1] = a[1];
        out[2] = a[2];
        out[3] = a[4];
        out[4] = a[5];
        out[5] = a[6];
        out[6] = a[8];
        out[7] = a[9];
        out[8] = a[10];

        return this;
    },

    /**
     * Set the values of this Matrix from the given array.
     *
     * @method Phaser.Math.Matrix3#fromArray
     * @since 3.0.0
     *
     * @param {array} a - The array to copy the values from.
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    fromArray: function (a)
    {
        var out = this.val;

        out[0] = a[0];
        out[1] = a[1];
        out[2] = a[2];
        out[3] = a[3];
        out[4] = a[4];
        out[5] = a[5];
        out[6] = a[6];
        out[7] = a[7];
        out[8] = a[8];

        return this;
    },

    /**
     * Reset this Matrix to an identity (default) matrix.
     *
     * @method Phaser.Math.Matrix3#identity
     * @since 3.0.0
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    identity: function ()
    {
        var out = this.val;

        out[0] = 1;
        out[1] = 0;
        out[2] = 0;
        out[3] = 0;
        out[4] = 1;
        out[5] = 0;
        out[6] = 0;
        out[7] = 0;
        out[8] = 1;

        return this;
    },

    /**
     * Transpose this Matrix.
     *
     * @method Phaser.Math.Matrix3#transpose
     * @since 3.0.0
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    transpose: function ()
    {
        var a = this.val;
        var a01 = a[1];
        var a02 = a[2];
        var a12 = a[5];

        a[1] = a[3];
        a[2] = a[6];
        a[3] = a01;
        a[5] = a[7];
        a[6] = a02;
        a[7] = a12;

        return this;
    },

    /**
     * Invert this Matrix.
     *
     * @method Phaser.Math.Matrix3#invert
     * @since 3.0.0
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    invert: function ()
    {
        var a = this.val;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a10 = a[3];
        var a11 = a[4];
        var a12 = a[5];
        var a20 = a[6];
        var a21 = a[7];
        var a22 = a[8];

        var b01 = a22 * a11 - a12 * a21;
        var b11 = -a22 * a10 + a12 * a20;
        var b21 = a21 * a10 - a11 * a20;

        // Calculate the determinant
        var det = a00 * b01 + a01 * b11 + a02 * b21;

        if (!det)
        {
            return null;
        }

        det = 1 / det;

        a[0] = b01 * det;
        a[1] = (-a22 * a01 + a02 * a21) * det;
        a[2] = (a12 * a01 - a02 * a11) * det;
        a[3] = b11 * det;
        a[4] = (a22 * a00 - a02 * a20) * det;
        a[5] = (-a12 * a00 + a02 * a10) * det;
        a[6] = b21 * det;
        a[7] = (-a21 * a00 + a01 * a20) * det;
        a[8] = (a11 * a00 - a01 * a10) * det;

        return this;
    },

    /**
     * Calculate the adjoint, or adjugate, of this Matrix.
     *
     * @method Phaser.Math.Matrix3#adjoint
     * @since 3.0.0
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    adjoint: function ()
    {
        var a = this.val;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a10 = a[3];
        var a11 = a[4];
        var a12 = a[5];
        var a20 = a[6];
        var a21 = a[7];
        var a22 = a[8];

        a[0] = (a11 * a22 - a12 * a21);
        a[1] = (a02 * a21 - a01 * a22);
        a[2] = (a01 * a12 - a02 * a11);
        a[3] = (a12 * a20 - a10 * a22);
        a[4] = (a00 * a22 - a02 * a20);
        a[5] = (a02 * a10 - a00 * a12);
        a[6] = (a10 * a21 - a11 * a20);
        a[7] = (a01 * a20 - a00 * a21);
        a[8] = (a00 * a11 - a01 * a10);

        return this;
    },

    /**
     * Calculate the determinant of this Matrix.
     *
     * @method Phaser.Math.Matrix3#determinant
     * @since 3.0.0
     *
     * @return {number} The determinant of this Matrix.
     */
    determinant: function ()
    {
        var a = this.val;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a10 = a[3];
        var a11 = a[4];
        var a12 = a[5];
        var a20 = a[6];
        var a21 = a[7];
        var a22 = a[8];

        return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
    },

    /**
     * Multiply this Matrix by the given Matrix.
     *
     * @method Phaser.Math.Matrix3#multiply
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix3} src - The Matrix to multiply this Matrix by.
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    multiply: function (src)
    {
        var a = this.val;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a10 = a[3];
        var a11 = a[4];
        var a12 = a[5];
        var a20 = a[6];
        var a21 = a[7];
        var a22 = a[8];

        var b = src.val;

        var b00 = b[0];
        var b01 = b[1];
        var b02 = b[2];
        var b10 = b[3];
        var b11 = b[4];
        var b12 = b[5];
        var b20 = b[6];
        var b21 = b[7];
        var b22 = b[8];

        a[0] = b00 * a00 + b01 * a10 + b02 * a20;
        a[1] = b00 * a01 + b01 * a11 + b02 * a21;
        a[2] = b00 * a02 + b01 * a12 + b02 * a22;

        a[3] = b10 * a00 + b11 * a10 + b12 * a20;
        a[4] = b10 * a01 + b11 * a11 + b12 * a21;
        a[5] = b10 * a02 + b11 * a12 + b12 * a22;

        a[6] = b20 * a00 + b21 * a10 + b22 * a20;
        a[7] = b20 * a01 + b21 * a11 + b22 * a21;
        a[8] = b20 * a02 + b21 * a12 + b22 * a22;

        return this;
    },

    /**
     * Translate this Matrix using the given Vector.
     *
     * @method Phaser.Math.Matrix3#translate
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to translate this Matrix with.
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    translate: function (v)
    {
        var a = this.val;
        var x = v.x;
        var y = v.y;

        a[6] = x * a[0] + y * a[3] + a[6];
        a[7] = x * a[1] + y * a[4] + a[7];
        a[8] = x * a[2] + y * a[5] + a[8];

        return this;
    },

    /**
     * Apply a rotation transformation to this Matrix.
     *
     * @method Phaser.Math.Matrix3#rotate
     * @since 3.0.0
     *
     * @param {number} rad - The angle in radians to rotate by.
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    rotate: function (rad)
    {
        var a = this.val;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a10 = a[3];
        var a11 = a[4];
        var a12 = a[5];

        var s = Math.sin(rad);
        var c = Math.cos(rad);

        a[0] = c * a00 + s * a10;
        a[1] = c * a01 + s * a11;
        a[2] = c * a02 + s * a12;

        a[3] = c * a10 - s * a00;
        a[4] = c * a11 - s * a01;
        a[5] = c * a12 - s * a02;

        return this;
    },

    /**
     * Apply a scale transformation to this Matrix.
     *
     * Uses the `x` and `y` components of the given Vector to scale the Matrix.
     *
     * @method Phaser.Math.Matrix3#scale
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to scale this Matrix with.
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    scale: function (v)
    {
        var a = this.val;
        var x = v.x;
        var y = v.y;

        a[0] = x * a[0];
        a[1] = x * a[1];
        a[2] = x * a[2];

        a[3] = y * a[3];
        a[4] = y * a[4];
        a[5] = y * a[5];

        return this;
    },

    /**
     * Set the values of this Matrix from the given Quaternion.
     *
     * @method Phaser.Math.Matrix3#fromQuat
     * @since 3.0.0
     *
     * @param {Phaser.Math.Quaternion} q - The Quaternion to set the values of this Matrix from.
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    fromQuat: function (q)
    {
        var x = q.x;
        var y = q.y;
        var z = q.z;
        var w = q.w;

        var x2 = x + x;
        var y2 = y + y;
        var z2 = z + z;

        var xx = x * x2;
        var xy = x * y2;
        var xz = x * z2;

        var yy = y * y2;
        var yz = y * z2;
        var zz = z * z2;

        var wx = w * x2;
        var wy = w * y2;
        var wz = w * z2;

        var out = this.val;

        out[0] = 1 - (yy + zz);
        out[3] = xy + wz;
        out[6] = xz - wy;

        out[1] = xy - wz;
        out[4] = 1 - (xx + zz);
        out[7] = yz + wx;

        out[2] = xz + wy;
        out[5] = yz - wx;
        out[8] = 1 - (xx + yy);

        return this;
    },

    /**
     * Set the values of this Matrix3 to be normalized from the given Matrix4.
     *
     * @method Phaser.Math.Matrix3#normalFromMat4
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} m - The Matrix4 to normalize the values from.
     *
     * @return {Phaser.Math.Matrix3} This Matrix3.
     */
    normalFromMat4: function (m)
    {
        var a = m.val;
        var out = this.val;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a03 = a[3];

        var a10 = a[4];
        var a11 = a[5];
        var a12 = a[6];
        var a13 = a[7];

        var a20 = a[8];
        var a21 = a[9];
        var a22 = a[10];
        var a23 = a[11];

        var a30 = a[12];
        var a31 = a[13];
        var a32 = a[14];
        var a33 = a[15];

        var b00 = a00 * a11 - a01 * a10;
        var b01 = a00 * a12 - a02 * a10;
        var b02 = a00 * a13 - a03 * a10;
        var b03 = a01 * a12 - a02 * a11;

        var b04 = a01 * a13 - a03 * a11;
        var b05 = a02 * a13 - a03 * a12;
        var b06 = a20 * a31 - a21 * a30;
        var b07 = a20 * a32 - a22 * a30;

        var b08 = a20 * a33 - a23 * a30;
        var b09 = a21 * a32 - a22 * a31;
        var b10 = a21 * a33 - a23 * a31;
        var b11 = a22 * a33 - a23 * a32;

        // Calculate the determinant
        var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

        if (!det)
        {
            return null;
        }

        det = 1 / det;

        out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
        out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
        out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;

        out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
        out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
        out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;

        out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
        out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
        out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;

        return this;
    }

});

module.exports = Matrix3;


/***/ }),

/***/ 9652:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Vector3 = __webpack_require__(5689);

/**
 * @ignore
 */
var EPSILON = 0.000001;

/**
 * @classdesc
 * A four-dimensional matrix.
 *
 * Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
 * and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl
 *
 * @class Matrix4
 * @memberof Phaser.Math
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Math.Matrix4} [m] - Optional Matrix4 to copy values from.
 */
var Matrix4 = new Class({

    initialize:

    function Matrix4 (m)
    {
        /**
         * The matrix values.
         *
         * @name Phaser.Math.Matrix4#val
         * @type {Float32Array}
         * @since 3.0.0
         */
        this.val = new Float32Array(16);

        if (m)
        {
            //  Assume Matrix4 with val:
            this.copy(m);
        }
        else
        {
            //  Default to identity
            this.identity();
        }
    },

    /**
     * Make a clone of this Matrix4.
     *
     * @method Phaser.Math.Matrix4#clone
     * @since 3.0.0
     *
     * @return {Phaser.Math.Matrix4} A clone of this Matrix4.
     */
    clone: function ()
    {
        return new Matrix4(this);
    },

    /**
     * This method is an alias for `Matrix4.copy`.
     *
     * @method Phaser.Math.Matrix4#set
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} src - The Matrix to set the values of this Matrix's from.
     *
     * @return {this} This Matrix4.
     */
    set: function (src)
    {
        return this.copy(src);
    },

    /**
     * Sets all values of this Matrix4.
     *
     * @method Phaser.Math.Matrix4#setValues
     * @since 3.50.0
     *
     * @param {number} m00 - The m00 value.
     * @param {number} m01 - The m01 value.
     * @param {number} m02 - The m02 value.
     * @param {number} m03 - The m03 value.
     * @param {number} m10 - The m10 value.
     * @param {number} m11 - The m11 value.
     * @param {number} m12 - The m12 value.
     * @param {number} m13 - The m13 value.
     * @param {number} m20 - The m20 value.
     * @param {number} m21 - The m21 value.
     * @param {number} m22 - The m22 value.
     * @param {number} m23 - The m23 value.
     * @param {number} m30 - The m30 value.
     * @param {number} m31 - The m31 value.
     * @param {number} m32 - The m32 value.
     * @param {number} m33 - The m33 value.
     *
     * @return {this} This Matrix4 instance.
     */
    setValues: function (m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33)
    {
        var out = this.val;

        out[0] = m00;
        out[1] = m01;
        out[2] = m02;
        out[3] = m03;
        out[4] = m10;
        out[5] = m11;
        out[6] = m12;
        out[7] = m13;
        out[8] = m20;
        out[9] = m21;
        out[10] = m22;
        out[11] = m23;
        out[12] = m30;
        out[13] = m31;
        out[14] = m32;
        out[15] = m33;

        return this;
    },

    /**
     * Copy the values of a given Matrix into this Matrix.
     *
     * @method Phaser.Math.Matrix4#copy
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} src - The Matrix to copy the values from.
     *
     * @return {this} This Matrix4.
     */
    copy: function (src)
    {
        var a = src.val;

        return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
    },

    /**
     * Set the values of this Matrix from the given array.
     *
     * @method Phaser.Math.Matrix4#fromArray
     * @since 3.0.0
     *
     * @param {number[]} a - The array to copy the values from. Must have at least 16 elements.
     *
     * @return {this} This Matrix4.
     */
    fromArray: function (a)
    {
        return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
    },

    /**
     * Reset this Matrix.
     *
     * Sets all values to `0`.
     *
     * @method Phaser.Math.Matrix4#zero
     * @since 3.0.0
     *
     * @return {Phaser.Math.Matrix4} This Matrix4.
     */
    zero: function ()
    {
        return this.setValues(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    },

    /**
     * Generates a transform matrix based on the given position, scale and rotation.
     *
     * @method Phaser.Math.Matrix4#transform
     * @since 3.50.0
     *
     * @param {Phaser.Math.Vector3} position - The position vector.
     * @param {Phaser.Math.Vector3} scale - The scale vector.
     * @param {Phaser.Math.Quaternion} rotation - The rotation quaternion.
     *
     * @return {this} This Matrix4.
     */
    transform: function (position, scale, rotation)
    {
        var rotMatrix = _tempMat1.fromQuat(rotation);

        var rm = rotMatrix.val;

        var sx = scale.x;
        var sy = scale.y;
        var sz = scale.z;

        return this.setValues(
            rm[0] * sx,
            rm[1] * sx,
            rm[2] * sx,
            0,

            rm[4] * sy,
            rm[5] * sy,
            rm[6] * sy,
            0,

            rm[8] * sz,
            rm[9] * sz,
            rm[10] * sz,
            0,

            position.x,
            position.y,
            position.z,
            1
        );
    },

    /**
     * Set the `x`, `y` and `z` values of this Matrix.
     *
     * @method Phaser.Math.Matrix4#xyz
     * @since 3.0.0
     *
     * @param {number} x - The x value.
     * @param {number} y - The y value.
     * @param {number} z - The z value.
     *
     * @return {this} This Matrix4.
     */
    xyz: function (x, y, z)
    {
        this.identity();

        var out = this.val;

        out[12] = x;
        out[13] = y;
        out[14] = z;

        return this;
    },

    /**
     * Set the scaling values of this Matrix.
     *
     * @method Phaser.Math.Matrix4#scaling
     * @since 3.0.0
     *
     * @param {number} x - The x scaling value.
     * @param {number} y - The y scaling value.
     * @param {number} z - The z scaling value.
     *
     * @return {this} This Matrix4.
     */
    scaling: function (x, y, z)
    {
        this.zero();

        var out = this.val;

        out[0] = x;
        out[5] = y;
        out[10] = z;
        out[15] = 1;

        return this;
    },

    /**
     * Reset this Matrix to an identity (default) matrix.
     *
     * @method Phaser.Math.Matrix4#identity
     * @since 3.0.0
     *
     * @return {this} This Matrix4.
     */
    identity: function ()
    {
        return this.setValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
    },

    /**
     * Transpose this Matrix.
     *
     * @method Phaser.Math.Matrix4#transpose
     * @since 3.0.0
     *
     * @return {this} This Matrix4.
     */
    transpose: function ()
    {
        var a = this.val;

        var a01 = a[1];
        var a02 = a[2];
        var a03 = a[3];
        var a12 = a[6];
        var a13 = a[7];
        var a23 = a[11];

        a[1] = a[4];
        a[2] = a[8];
        a[3] = a[12];
        a[4] = a01;
        a[6] = a[9];
        a[7] = a[13];
        a[8] = a02;
        a[9] = a12;
        a[11] = a[14];
        a[12] = a03;
        a[13] = a13;
        a[14] = a23;

        return this;
    },

    /**
     * Copies the given Matrix4 into this Matrix and then inverses it.
     *
     * @method Phaser.Math.Matrix4#getInverse
     * @since 3.50.0
     *
     * @param {Phaser.Math.Matrix4} m - The Matrix4 to invert into this Matrix4.
     *
     * @return {this} This Matrix4.
     */
    getInverse: function (m)
    {
        this.copy(m);

        return this.invert();
    },

    /**
     * Invert this Matrix.
     *
     * @method Phaser.Math.Matrix4#invert
     * @since 3.0.0
     *
     * @return {this} This Matrix4.
     */
    invert: function ()
    {
        var a = this.val;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a03 = a[3];

        var a10 = a[4];
        var a11 = a[5];
        var a12 = a[6];
        var a13 = a[7];

        var a20 = a[8];
        var a21 = a[9];
        var a22 = a[10];
        var a23 = a[11];

        var a30 = a[12];
        var a31 = a[13];
        var a32 = a[14];
        var a33 = a[15];

        var b00 = a00 * a11 - a01 * a10;
        var b01 = a00 * a12 - a02 * a10;
        var b02 = a00 * a13 - a03 * a10;
        var b03 = a01 * a12 - a02 * a11;

        var b04 = a01 * a13 - a03 * a11;
        var b05 = a02 * a13 - a03 * a12;
        var b06 = a20 * a31 - a21 * a30;
        var b07 = a20 * a32 - a22 * a30;

        var b08 = a20 * a33 - a23 * a30;
        var b09 = a21 * a32 - a22 * a31;
        var b10 = a21 * a33 - a23 * a31;
        var b11 = a22 * a33 - a23 * a32;

        //  Calculate the determinant
        var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

        if (!det)
        {
            return this;
        }

        det = 1 / det;

        return this.setValues(
            (a11 * b11 - a12 * b10 + a13 * b09) * det,
            (a02 * b10 - a01 * b11 - a03 * b09) * det,
            (a31 * b05 - a32 * b04 + a33 * b03) * det,
            (a22 * b04 - a21 * b05 - a23 * b03) * det,
            (a12 * b08 - a10 * b11 - a13 * b07) * det,
            (a00 * b11 - a02 * b08 + a03 * b07) * det,
            (a32 * b02 - a30 * b05 - a33 * b01) * det,
            (a20 * b05 - a22 * b02 + a23 * b01) * det,
            (a10 * b10 - a11 * b08 + a13 * b06) * det,
            (a01 * b08 - a00 * b10 - a03 * b06) * det,
            (a30 * b04 - a31 * b02 + a33 * b00) * det,
            (a21 * b02 - a20 * b04 - a23 * b00) * det,
            (a11 * b07 - a10 * b09 - a12 * b06) * det,
            (a00 * b09 - a01 * b07 + a02 * b06) * det,
            (a31 * b01 - a30 * b03 - a32 * b00) * det,
            (a20 * b03 - a21 * b01 + a22 * b00) * det
        );
    },

    /**
     * Calculate the adjoint, or adjugate, of this Matrix.
     *
     * @method Phaser.Math.Matrix4#adjoint
     * @since 3.0.0
     *
     * @return {this} This Matrix4.
     */
    adjoint: function ()
    {
        var a = this.val;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a03 = a[3];

        var a10 = a[4];
        var a11 = a[5];
        var a12 = a[6];
        var a13 = a[7];

        var a20 = a[8];
        var a21 = a[9];
        var a22 = a[10];
        var a23 = a[11];

        var a30 = a[12];
        var a31 = a[13];
        var a32 = a[14];
        var a33 = a[15];

        return this.setValues(
            (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22)),
            -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)),
            (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12)),
            -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)),
            -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)),
            (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22)),
            -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)),
            (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12)),
            (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21)),
            -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)),
            (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11)),
            -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)),
            -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)),
            (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21)),
            -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)),
            (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11))
        );
    },

    /**
     * Calculate the determinant of this Matrix.
     *
     * @method Phaser.Math.Matrix4#determinant
     * @since 3.0.0
     *
     * @return {number} The determinant of this Matrix.
     */
    determinant: function ()
    {
        var a = this.val;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a03 = a[3];

        var a10 = a[4];
        var a11 = a[5];
        var a12 = a[6];
        var a13 = a[7];

        var a20 = a[8];
        var a21 = a[9];
        var a22 = a[10];
        var a23 = a[11];

        var a30 = a[12];
        var a31 = a[13];
        var a32 = a[14];
        var a33 = a[15];

        var b00 = a00 * a11 - a01 * a10;
        var b01 = a00 * a12 - a02 * a10;
        var b02 = a00 * a13 - a03 * a10;
        var b03 = a01 * a12 - a02 * a11;
        var b04 = a01 * a13 - a03 * a11;
        var b05 = a02 * a13 - a03 * a12;
        var b06 = a20 * a31 - a21 * a30;
        var b07 = a20 * a32 - a22 * a30;
        var b08 = a20 * a33 - a23 * a30;
        var b09 = a21 * a32 - a22 * a31;
        var b10 = a21 * a33 - a23 * a31;
        var b11 = a22 * a33 - a23 * a32;

        // Calculate the determinant
        return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
    },

    /**
     * Multiply this Matrix by the given Matrix.
     *
     * @method Phaser.Math.Matrix4#multiply
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} src - The Matrix to multiply this Matrix by.
     *
     * @return {this} This Matrix4.
     */
    multiply: function (src)
    {
        var a = this.val;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a03 = a[3];

        var a10 = a[4];
        var a11 = a[5];
        var a12 = a[6];
        var a13 = a[7];

        var a20 = a[8];
        var a21 = a[9];
        var a22 = a[10];
        var a23 = a[11];

        var a30 = a[12];
        var a31 = a[13];
        var a32 = a[14];
        var a33 = a[15];

        var b = src.val;

        // Cache only the current line of the second matrix
        var b0 = b[0];
        var b1 = b[1];
        var b2 = b[2];
        var b3 = b[3];

        a[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
        a[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
        a[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
        a[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;

        b0 = b[4];
        b1 = b[5];
        b2 = b[6];
        b3 = b[7];

        a[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
        a[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
        a[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
        a[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;

        b0 = b[8];
        b1 = b[9];
        b2 = b[10];
        b3 = b[11];

        a[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
        a[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
        a[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
        a[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;

        b0 = b[12];
        b1 = b[13];
        b2 = b[14];
        b3 = b[15];

        a[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
        a[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
        a[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
        a[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;

        return this;
    },

    /**
     * Multiply the values of this Matrix4 by those given in the `src` argument.
     *
     * @method Phaser.Math.Matrix4#multiplyLocal
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} src - The source Matrix4 that this Matrix4 is multiplied by.
     *
     * @return {this} This Matrix4.
     */
    multiplyLocal: function (src)
    {
        var a = this.val;
        var b = src.val;

        return this.setValues(
            a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12],
            a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13],
            a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14],
            a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15],

            a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12],
            a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13],
            a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14],
            a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15],

            a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12],
            a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13],
            a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14],
            a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15],

            a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12],
            a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13],
            a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14],
            a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15]
        );
    },

    /**
     * Multiplies the given Matrix4 object with this Matrix.
     *
     * This is the same as calling `multiplyMatrices(m, this)`.
     *
     * @method Phaser.Math.Matrix4#premultiply
     * @since 3.50.0
     *
     * @param {Phaser.Math.Matrix4} m - The Matrix4 to multiply with this one.
     *
     * @return {this} This Matrix4.
     */
    premultiply: function (m)
    {
        return this.multiplyMatrices(m, this);
    },

    /**
     * Multiplies the two given Matrix4 objects and stores the results in this Matrix.
     *
     * @method Phaser.Math.Matrix4#multiplyMatrices
     * @since 3.50.0
     *
     * @param {Phaser.Math.Matrix4} a - The first Matrix4 to multiply.
     * @param {Phaser.Math.Matrix4} b - The second Matrix4 to multiply.
     *
     * @return {this} This Matrix4.
     */
    multiplyMatrices: function (a, b)
    {
        var am = a.val;
        var bm = b.val;

        var a11 = am[0];
        var a12 = am[4];
        var a13 = am[8];
        var a14 = am[12];
        var a21 = am[1];
        var a22 = am[5];
        var a23 = am[9];
        var a24 = am[13];
        var a31 = am[2];
        var a32 = am[6];
        var a33 = am[10];
        var a34 = am[14];
        var a41 = am[3];
        var a42 = am[7];
        var a43 = am[11];
        var a44 = am[15];

        var b11 = bm[0];
        var b12 = bm[4];
        var b13 = bm[8];
        var b14 = bm[12];
        var b21 = bm[1];
        var b22 = bm[5];
        var b23 = bm[9];
        var b24 = bm[13];
        var b31 = bm[2];
        var b32 = bm[6];
        var b33 = bm[10];
        var b34 = bm[14];
        var b41 = bm[3];
        var b42 = bm[7];
        var b43 = bm[11];
        var b44 = bm[15];

        return this.setValues(
            a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41,
            a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41,
            a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41,
            a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41,
            a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42,
            a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42,
            a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42,
            a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42,
            a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43,
            a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43,
            a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43,
            a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43,
            a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44,
            a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44,
            a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44,
            a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44
        );
    },

    /**
     * Translate this Matrix using the given Vector.
     *
     * @method Phaser.Math.Matrix4#translate
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to translate this Matrix with.
     *
     * @return {this} This Matrix4.
     */
    translate: function (v)
    {
        return this.translateXYZ(v.x, v.y, v.z);
    },

    /**
     * Translate this Matrix using the given values.
     *
     * @method Phaser.Math.Matrix4#translateXYZ
     * @since 3.16.0
     *
     * @param {number} x - The x component.
     * @param {number} y - The y component.
     * @param {number} z - The z component.
     *
     * @return {this} This Matrix4.
     */
    translateXYZ: function (x, y, z)
    {
        var a = this.val;

        a[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
        a[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
        a[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
        a[15] = a[3] * x + a[7] * y + a[11] * z + a[15];

        return this;
    },

    /**
     * Apply a scale transformation to this Matrix.
     *
     * Uses the `x`, `y` and `z` components of the given Vector to scale the Matrix.
     *
     * @method Phaser.Math.Matrix4#scale
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to scale this Matrix with.
     *
     * @return {this} This Matrix4.
     */
    scale: function (v)
    {
        return this.scaleXYZ(v.x, v.y, v.z);
    },

    /**
     * Apply a scale transformation to this Matrix.
     *
     * @method Phaser.Math.Matrix4#scaleXYZ
     * @since 3.16.0
     *
     * @param {number} x - The x component.
     * @param {number} y - The y component.
     * @param {number} z - The z component.
     *
     * @return {this} This Matrix4.
     */
    scaleXYZ: function (x, y, z)
    {
        var a = this.val;

        a[0] = a[0] * x;
        a[1] = a[1] * x;
        a[2] = a[2] * x;
        a[3] = a[3] * x;

        a[4] = a[4] * y;
        a[5] = a[5] * y;
        a[6] = a[6] * y;
        a[7] = a[7] * y;

        a[8] = a[8] * z;
        a[9] = a[9] * z;
        a[10] = a[10] * z;
        a[11] = a[11] * z;

        return this;
    },

    /**
     * Derive a rotation matrix around the given axis.
     *
     * @method Phaser.Math.Matrix4#makeRotationAxis
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector3|Phaser.Math.Vector4)} axis - The rotation axis.
     * @param {number} angle - The rotation angle in radians.
     *
     * @return {this} This Matrix4.
     */
    makeRotationAxis: function (axis, angle)
    {
        // Based on http://www.gamedev.net/reference/articles/article1199.asp

        var c = Math.cos(angle);
        var s = Math.sin(angle);
        var t = 1 - c;
        var x = axis.x;
        var y = axis.y;
        var z = axis.z;
        var tx = t * x;
        var ty = t * y;

        return this.setValues(
            tx * x + c, tx * y - s * z, tx * z + s * y, 0,
            tx * y + s * z, ty * y + c, ty * z - s * x, 0,
            tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
            0, 0, 0, 1
        );
    },

    /**
     * Apply a rotation transformation to this Matrix.
     *
     * @method Phaser.Math.Matrix4#rotate
     * @since 3.0.0
     *
     * @param {number} rad - The angle in radians to rotate by.
     * @param {Phaser.Math.Vector3} axis - The axis to rotate upon.
     *
     * @return {this} This Matrix4.
     */
    rotate: function (rad, axis)
    {
        var a = this.val;
        var x = axis.x;
        var y = axis.y;
        var z = axis.z;
        var len = Math.sqrt(x * x + y * y + z * z);

        if (Math.abs(len) < EPSILON)
        {
            return this;
        }

        len = 1 / len;
        x *= len;
        y *= len;
        z *= len;

        var s = Math.sin(rad);
        var c = Math.cos(rad);
        var t = 1 - c;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a03 = a[3];

        var a10 = a[4];
        var a11 = a[5];
        var a12 = a[6];
        var a13 = a[7];

        var a20 = a[8];
        var a21 = a[9];
        var a22 = a[10];
        var a23 = a[11];

        var a30 = a[12];
        var a31 = a[13];
        var a32 = a[14];
        var a33 = a[15];

        //  Construct the elements of the rotation matrix
        var b00 = x * x * t + c;
        var b01 = y * x * t + z * s;
        var b02 = z * x * t - y * s;

        var b10 = x * y * t - z * s;
        var b11 = y * y * t + c;
        var b12 = z * y * t + x * s;

        var b20 = x * z * t + y * s;
        var b21 = y * z * t - x * s;
        var b22 = z * z * t + c;

        //  Perform rotation-specific matrix multiplication
        return this.setValues(
            a00 * b00 + a10 * b01 + a20 * b02,
            a01 * b00 + a11 * b01 + a21 * b02,
            a02 * b00 + a12 * b01 + a22 * b02,
            a03 * b00 + a13 * b01 + a23 * b02,
            a00 * b10 + a10 * b11 + a20 * b12,
            a01 * b10 + a11 * b11 + a21 * b12,
            a02 * b10 + a12 * b11 + a22 * b12,
            a03 * b10 + a13 * b11 + a23 * b12,
            a00 * b20 + a10 * b21 + a20 * b22,
            a01 * b20 + a11 * b21 + a21 * b22,
            a02 * b20 + a12 * b21 + a22 * b22,
            a03 * b20 + a13 * b21 + a23 * b22,
            a30, a31, a32, a33
        );
    },

    /**
     * Rotate this matrix on its X axis.
     *
     * @method Phaser.Math.Matrix4#rotateX
     * @since 3.0.0
     *
     * @param {number} rad - The angle in radians to rotate by.
     *
     * @return {this} This Matrix4.
     */
    rotateX: function (rad)
    {
        var a = this.val;
        var s = Math.sin(rad);
        var c = Math.cos(rad);

        var a10 = a[4];
        var a11 = a[5];
        var a12 = a[6];
        var a13 = a[7];

        var a20 = a[8];
        var a21 = a[9];
        var a22 = a[10];
        var a23 = a[11];

        //  Perform axis-specific matrix multiplication
        a[4] = a10 * c + a20 * s;
        a[5] = a11 * c + a21 * s;
        a[6] = a12 * c + a22 * s;
        a[7] = a13 * c + a23 * s;
        a[8] = a20 * c - a10 * s;
        a[9] = a21 * c - a11 * s;
        a[10] = a22 * c - a12 * s;
        a[11] = a23 * c - a13 * s;

        return this;
    },

    /**
     * Rotate this matrix on its Y axis.
     *
     * @method Phaser.Math.Matrix4#rotateY
     * @since 3.0.0
     *
     * @param {number} rad - The angle to rotate by, in radians.
     *
     * @return {this} This Matrix4.
     */
    rotateY: function (rad)
    {
        var a = this.val;
        var s = Math.sin(rad);
        var c = Math.cos(rad);

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a03 = a[3];

        var a20 = a[8];
        var a21 = a[9];
        var a22 = a[10];
        var a23 = a[11];

        //  Perform axis-specific matrix multiplication
        a[0] = a00 * c - a20 * s;
        a[1] = a01 * c - a21 * s;
        a[2] = a02 * c - a22 * s;
        a[3] = a03 * c - a23 * s;
        a[8] = a00 * s + a20 * c;
        a[9] = a01 * s + a21 * c;
        a[10] = a02 * s + a22 * c;
        a[11] = a03 * s + a23 * c;

        return this;
    },

    /**
     * Rotate this matrix on its Z axis.
     *
     * @method Phaser.Math.Matrix4#rotateZ
     * @since 3.0.0
     *
     * @param {number} rad - The angle to rotate by, in radians.
     *
     * @return {this} This Matrix4.
     */
    rotateZ: function (rad)
    {
        var a = this.val;
        var s = Math.sin(rad);
        var c = Math.cos(rad);

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a03 = a[3];

        var a10 = a[4];
        var a11 = a[5];
        var a12 = a[6];
        var a13 = a[7];

        //  Perform axis-specific matrix multiplication
        a[0] = a00 * c + a10 * s;
        a[1] = a01 * c + a11 * s;
        a[2] = a02 * c + a12 * s;
        a[3] = a03 * c + a13 * s;
        a[4] = a10 * c - a00 * s;
        a[5] = a11 * c - a01 * s;
        a[6] = a12 * c - a02 * s;
        a[7] = a13 * c - a03 * s;

        return this;
    },

    /**
     * Set the values of this Matrix from the given rotation Quaternion and translation Vector.
     *
     * @method Phaser.Math.Matrix4#fromRotationTranslation
     * @since 3.0.0
     *
     * @param {Phaser.Math.Quaternion} q - The Quaternion to set rotation from.
     * @param {Phaser.Math.Vector3} v - The Vector to set translation from.
     *
     * @return {this} This Matrix4.
     */
    fromRotationTranslation: function (q, v)
    {
        //  Quaternion math
        var x = q.x;
        var y = q.y;
        var z = q.z;
        var w = q.w;

        var x2 = x + x;
        var y2 = y + y;
        var z2 = z + z;

        var xx = x * x2;
        var xy = x * y2;
        var xz = x * z2;

        var yy = y * y2;
        var yz = y * z2;
        var zz = z * z2;

        var wx = w * x2;
        var wy = w * y2;
        var wz = w * z2;

        return this.setValues(
            1 - (yy + zz),
            xy + wz,
            xz - wy,
            0,

            xy - wz,
            1 - (xx + zz),
            yz + wx,
            0,

            xz + wy,
            yz - wx,
            1 - (xx + yy),
            0,

            v.x,
            v.y,
            v.z,
            1
        );
    },

    /**
     * Set the values of this Matrix from the given Quaternion.
     *
     * @method Phaser.Math.Matrix4#fromQuat
     * @since 3.0.0
     *
     * @param {Phaser.Math.Quaternion} q - The Quaternion to set the values of this Matrix from.
     *
     * @return {this} This Matrix4.
     */
    fromQuat: function (q)
    {
        var x = q.x;
        var y = q.y;
        var z = q.z;
        var w = q.w;

        var x2 = x + x;
        var y2 = y + y;
        var z2 = z + z;

        var xx = x * x2;
        var xy = x * y2;
        var xz = x * z2;

        var yy = y * y2;
        var yz = y * z2;
        var zz = z * z2;

        var wx = w * x2;
        var wy = w * y2;
        var wz = w * z2;

        return this.setValues(
            1 - (yy + zz),
            xy + wz,
            xz - wy,
            0,

            xy - wz,
            1 - (xx + zz),
            yz + wx,
            0,

            xz + wy,
            yz - wx,
            1 - (xx + yy),
            0,

            0,
            0,
            0,
            1
        );
    },

    /**
     * Generate a frustum matrix with the given bounds.
     *
     * @method Phaser.Math.Matrix4#frustum
     * @since 3.0.0
     *
     * @param {number} left - The left bound of the frustum.
     * @param {number} right - The right bound of the frustum.
     * @param {number} bottom - The bottom bound of the frustum.
     * @param {number} top - The top bound of the frustum.
     * @param {number} near - The near bound of the frustum.
     * @param {number} far - The far bound of the frustum.
     *
     * @return {this} This Matrix4.
     */
    frustum: function (left, right, bottom, top, near, far)
    {
        var rl = 1 / (right - left);
        var tb = 1 / (top - bottom);
        var nf = 1 / (near - far);

        return this.setValues(
            (near * 2) * rl,
            0,
            0,
            0,

            0,
            (near * 2) * tb,
            0,
            0,

            (right + left) * rl,
            (top + bottom) * tb,
            (far + near) * nf,
            -1,

            0,
            0,
            (far * near * 2) * nf,
            0
        );
    },

    /**
     * Generate a perspective projection matrix with the given bounds.
     *
     * @method Phaser.Math.Matrix4#perspective
     * @since 3.0.0
     *
     * @param {number} fovy - Vertical field of view in radians
     * @param {number} aspect - Aspect ratio. Typically viewport width  /height.
     * @param {number} near - Near bound of the frustum.
     * @param {number} far - Far bound of the frustum.
     *
     * @return {this} This Matrix4.
     */
    perspective: function (fovy, aspect, near, far)
    {
        var f = 1.0 / Math.tan(fovy / 2);
        var nf = 1 / (near - far);

        return this.setValues(
            f / aspect,
            0,
            0,
            0,

            0,
            f,
            0,
            0,

            0,
            0,
            (far + near) * nf,
            -1,

            0,
            0,
            (2 * far * near) * nf,
            0
        );
    },

    /**
     * Generate a perspective projection matrix with the given bounds.
     *
     * @method Phaser.Math.Matrix4#perspectiveLH
     * @since 3.0.0
     *
     * @param {number} width - The width of the frustum.
     * @param {number} height - The height of the frustum.
     * @param {number} near - Near bound of the frustum.
     * @param {number} far - Far bound of the frustum.
     *
     * @return {this} This Matrix4.
     */
    perspectiveLH: function (width, height, near, far)
    {
        return this.setValues(
            (2 * near) / width,
            0,
            0,
            0,

            0,
            (2 * near) / height,
            0,
            0,

            0,
            0,
            -far / (near - far),
            1,

            0,
            0,
            (near * far) / (near - far),
            0
        );
    },

    /**
     * Generate an orthogonal projection matrix with the given bounds.
     *
     * @method Phaser.Math.Matrix4#ortho
     * @since 3.0.0
     *
     * @param {number} left - The left bound of the frustum.
     * @param {number} right - The right bound of the frustum.
     * @param {number} bottom - The bottom bound of the frustum.
     * @param {number} top - The top bound of the frustum.
     * @param {number} near - The near bound of the frustum.
     * @param {number} far - The far bound of the frustum.
     *
     * @return {this} This Matrix4.
     */
    ortho: function (left, right, bottom, top, near, far)
    {
        var lr = left - right;
        var bt = bottom - top;
        var nf = near - far;

        //  Avoid division by zero
        lr = (lr === 0) ? lr : 1 / lr;
        bt = (bt === 0) ? bt : 1 / bt;
        nf = (nf === 0) ? nf : 1 / nf;

        return this.setValues(
            -2 * lr,
            0,
            0,
            0,

            0,
            -2 * bt,
            0,
            0,

            0,
            0,
            2 * nf,
            0,

            (left + right) * lr,
            (top + bottom) * bt,
            (far + near) * nf,
            1
        );
    },

    /**
     * Generate a right-handed look-at matrix with the given eye position, target and up axis.
     *
     * @method Phaser.Math.Matrix4#lookAtRH
     * @since 3.50.0
     *
     * @param {Phaser.Math.Vector3} eye - Position of the viewer.
     * @param {Phaser.Math.Vector3} target - Point the viewer is looking at.
     * @param {Phaser.Math.Vector3} up - vec3 pointing up.
     *
     * @return {this} This Matrix4.
     */
    lookAtRH: function (eye, target, up)
    {
        var m = this.val;

        _z.subVectors(eye, target);

        if (_z.getLengthSquared() === 0)
        {
            // eye and target are in the same position
            _z.z = 1;
        }

        _z.normalize();
        _x.crossVectors(up, _z);

        if (_x.getLengthSquared() === 0)
        {
            // up and z are parallel

            if (Math.abs(up.z) === 1)
            {
                _z.x += 0.0001;
            }
            else
            {
                _z.z += 0.0001;
            }

            _z.normalize();
            _x.crossVectors(up, _z);
        }

        _x.normalize();
        _y.crossVectors(_z, _x);

        m[0] = _x.x;
        m[1] = _x.y;
        m[2] = _x.z;
        m[4] = _y.x;
        m[5] = _y.y;
        m[6] = _y.z;
        m[8] = _z.x;
        m[9] = _z.y;
        m[10] = _z.z;

        return this;
    },

    /**
     * Generate a look-at matrix with the given eye position, focal point, and up axis.
     *
     * @method Phaser.Math.Matrix4#lookAt
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector3} eye - Position of the viewer
     * @param {Phaser.Math.Vector3} center - Point the viewer is looking at
     * @param {Phaser.Math.Vector3} up - vec3 pointing up.
     *
     * @return {this} This Matrix4.
     */
    lookAt: function (eye, center, up)
    {
        var eyex = eye.x;
        var eyey = eye.y;
        var eyez = eye.z;

        var upx = up.x;
        var upy = up.y;
        var upz = up.z;

        var centerx = center.x;
        var centery = center.y;
        var centerz = center.z;

        if (Math.abs(eyex - centerx) < EPSILON &&
            Math.abs(eyey - centery) < EPSILON &&
            Math.abs(eyez - centerz) < EPSILON)
        {
            return this.identity();
        }

        var z0 = eyex - centerx;
        var z1 = eyey - centery;
        var z2 = eyez - centerz;

        var len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);

        z0 *= len;
        z1 *= len;
        z2 *= len;

        var x0 = upy * z2 - upz * z1;
        var x1 = upz * z0 - upx * z2;
        var x2 = upx * z1 - upy * z0;

        len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);

        if (!len)
        {
            x0 = 0;
            x1 = 0;
            x2 = 0;
        }
        else
        {
            len = 1 / len;
            x0 *= len;
            x1 *= len;
            x2 *= len;
        }

        var y0 = z1 * x2 - z2 * x1;
        var y1 = z2 * x0 - z0 * x2;
        var y2 = z0 * x1 - z1 * x0;

        len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);

        if (!len)
        {
            y0 = 0;
            y1 = 0;
            y2 = 0;
        }
        else
        {
            len = 1 / len;
            y0 *= len;
            y1 *= len;
            y2 *= len;
        }

        return this.setValues(
            x0,
            y0,
            z0,
            0,

            x1,
            y1,
            z1,
            0,

            x2,
            y2,
            z2,
            0,

            -(x0 * eyex + x1 * eyey + x2 * eyez),
            -(y0 * eyex + y1 * eyey + y2 * eyez),
            -(z0 * eyex + z1 * eyey + z2 * eyez),
            1
        );
    },

    /**
     * Set the values of this matrix from the given `yaw`, `pitch` and `roll` values.
     *
     * @method Phaser.Math.Matrix4#yawPitchRoll
     * @since 3.0.0
     *
     * @param {number} yaw - The yaw value.
     * @param {number} pitch - The pitch value.
     * @param {number} roll - The roll value.
     *
     * @return {this} This Matrix4.
     */
    yawPitchRoll: function (yaw, pitch, roll)
    {
        this.zero();
        _tempMat1.zero();
        _tempMat2.zero();

        var m0 = this.val;
        var m1 = _tempMat1.val;
        var m2 = _tempMat2.val;

        //  Rotate Z
        var s = Math.sin(roll);
        var c = Math.cos(roll);

        m0[10] = 1;
        m0[15] = 1;
        m0[0] = c;
        m0[1] = s;
        m0[4] = -s;
        m0[5] = c;

        //  Rotate X
        s = Math.sin(pitch);
        c = Math.cos(pitch);

        m1[0] = 1;
        m1[15] = 1;
        m1[5] = c;
        m1[10] = c;
        m1[9] = -s;
        m1[6] = s;

        //  Rotate Y
        s = Math.sin(yaw);
        c = Math.cos(yaw);

        m2[5] = 1;
        m2[15] = 1;
        m2[0] = c;
        m2[2] = -s;
        m2[8] = s;
        m2[10] = c;

        this.multiplyLocal(_tempMat1);
        this.multiplyLocal(_tempMat2);

        return this;
    },

    /**
     * Generate a world matrix from the given rotation, position, scale, view matrix and projection matrix.
     *
     * @method Phaser.Math.Matrix4#setWorldMatrix
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector3} rotation - The rotation of the world matrix.
     * @param {Phaser.Math.Vector3} position - The position of the world matrix.
     * @param {Phaser.Math.Vector3} scale - The scale of the world matrix.
     * @param {Phaser.Math.Matrix4} [viewMatrix] - The view matrix.
     * @param {Phaser.Math.Matrix4} [projectionMatrix] - The projection matrix.
     *
     * @return {this} This Matrix4.
     */
    setWorldMatrix: function (rotation, position, scale, viewMatrix, projectionMatrix)
    {
        this.yawPitchRoll(rotation.y, rotation.x, rotation.z);

        _tempMat1.scaling(scale.x, scale.y, scale.z);
        _tempMat2.xyz(position.x, position.y, position.z);

        this.multiplyLocal(_tempMat1);
        this.multiplyLocal(_tempMat2);

        if (viewMatrix)
        {
            this.multiplyLocal(viewMatrix);
        }

        if (projectionMatrix)
        {
            this.multiplyLocal(projectionMatrix);
        }

        return this;
    },

    /**
     * Multiplies this Matrix4 by the given `src` Matrix4 and stores the results in the `out` Matrix4.
     *
     * @method Phaser.Math.Matrix4#multiplyToMat4
     * @since 3.50.0
     *
     * @param {Phaser.Math.Matrix4} src - The Matrix4 to multiply with this one.
     * @param {Phaser.Math.Matrix4} out - The receiving Matrix.
     *
     * @return {Phaser.Math.Matrix4} This `out` Matrix4.
     */
    multiplyToMat4: function (src, out)
    {
        var a = this.val;
        var b = src.val;

        var a00 = a[0];
        var a01 = a[1];
        var a02 = a[2];
        var a03 = a[3];
        var a10 = a[4];
        var a11 = a[5];
        var a12 = a[6];
        var a13 = a[7];
        var a20 = a[8];
        var a21 = a[9];
        var a22 = a[10];
        var a23 = a[11];
        var a30 = a[12];
        var a31 = a[13];
        var a32 = a[14];
        var a33 = a[15];

        var b00 = b[0];
        var b01 = b[1];
        var b02 = b[2];
        var b03 = b[3];
        var b10 = b[4];
        var b11 = b[5];
        var b12 = b[6];
        var b13 = b[7];
        var b20 = b[8];
        var b21 = b[9];
        var b22 = b[10];
        var b23 = b[11];
        var b30 = b[12];
        var b31 = b[13];
        var b32 = b[14];
        var b33 = b[15];

        return out.setValues(
            b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30,
            b01 * a01 + b01 * a11 + b02 * a21 + b03 * a31,
            b02 * a02 + b01 * a12 + b02 * a22 + b03 * a32,
            b03 * a03 + b01 * a13 + b02 * a23 + b03 * a33,

            b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30,
            b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31,
            b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32,
            b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33,

            b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30,
            b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31,
            b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32,
            b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33,

            b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30,
            b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31,
            b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32,
            b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33
        );
    },

    /**
     * Takes the rotation and position vectors and builds this Matrix4 from them.
     *
     * @method Phaser.Math.Matrix4#fromRotationXYTranslation
     * @since 3.50.0
     *
     * @param {Phaser.Math.Vector3} rotation - The rotation vector.
     * @param {Phaser.Math.Vector3} position - The position vector.
     * @param {boolean} translateFirst - Should the operation translate then rotate (`true`), or rotate then translate? (`false`)
     *
     * @return {this} This Matrix4.
     */
    fromRotationXYTranslation: function (rotation, position, translateFirst)
    {
        var x = position.x;
        var y = position.y;
        var z = position.z;

        var sx = Math.sin(rotation.x);
        var cx = Math.cos(rotation.x);

        var sy = Math.sin(rotation.y);
        var cy = Math.cos(rotation.y);

        var a30 = x;
        var a31 = y;
        var a32 = z;

        //  Rotate X

        var b21 = -sx;

        //  Rotate Y

        var c01 = 0 - b21 * sy;

        var c02 = 0 - cx * sy;

        var c21 = b21 * cy;

        var c22 = cx * cy;

        //  Translate
        if (!translateFirst)
        {
            // a30 = cy * x + 0 * y + sy * z;
            a30 = cy * x + sy * z;
            a31 = c01 * x + cx * y + c21 * z;
            a32 = c02 * x + sx * y + c22 * z;
        }

        return this.setValues(
            cy,
            c01,
            c02,
            0,
            0,
            cx,
            sx,
            0,
            sy,
            c21,
            c22,
            0,
            a30,
            a31,
            a32,
            1
        );
    },

    /**
     * Returns the maximum axis scale from this Matrix4.
     *
     * @method Phaser.Math.Matrix4#getMaxScaleOnAxis
     * @since 3.50.0
     *
     * @return {number} The maximum axis scale.
     */
    getMaxScaleOnAxis: function ()
    {
        var m = this.val;

        var scaleXSq = m[0] * m[0] + m[1] * m[1] + m[2] * m[2];
        var scaleYSq = m[4] * m[4] + m[5] * m[5] + m[6] * m[6];
        var scaleZSq = m[8] * m[8] + m[9] * m[9] + m[10] * m[10];

        return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq));
    }

});

/**
 * @ignore
 */
var _tempMat1 = new Matrix4();

/**
 * @ignore
 */
var _tempMat2 = new Matrix4();

/**
 * @ignore
 */
var _x = new Vector3();

/**
 * @ignore
 */
var _y = new Vector3();

/**
 * @ignore
 */
var _z = new Vector3();

module.exports = Matrix4;


/***/ }),

/***/ 3733:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Add an `amount` to a `value`, limiting the maximum result to `max`.
 *
 * @function Phaser.Math.MaxAdd
 * @since 3.0.0
 *
 * @param {number} value - The value to add to.
 * @param {number} amount - The amount to add.
 * @param {number} max - The maximum value to return.
 *
 * @return {number} The resulting value.
 */
var MaxAdd = function (value, amount, max)
{
    return Math.min(value + amount, max);
};

module.exports = MaxAdd;


/***/ }),

/***/ 44:
/***/ ((module) => {

/**
 * @author       Vladislav Forsh <vlad@robowhale.com>
 * @copyright    2021 RoboWhale
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the median of the given values. The values are sorted and the middle value is returned.
 * In case of an even number of values, the average of the two middle values is returned.
 *
 * @function Phaser.Math.Median
 * @since 3.54.0
 *
 * @param {number[]} values - The values to average.
 *
 * @return {number} The median value.
 */
var Median = function (values)
{
    var valuesNum = values.length;
    if (valuesNum === 0)
    {
        return 0;
    }

    values.sort(function (a, b) { return a - b; });

    var halfIndex = Math.floor(valuesNum / 2);

    return valuesNum % 2 === 0
        ? (values[halfIndex] + values[halfIndex - 1]) / 2
        : values[halfIndex];
};

module.exports = Median;


/***/ }),

/***/ 5385:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Subtract an `amount` from `value`, limiting the minimum result to `min`.
 *
 * @function Phaser.Math.MinSub
 * @since 3.0.0
 *
 * @param {number} value - The value to subtract from.
 * @param {number} amount - The amount to subtract.
 * @param {number} min - The minimum value to return.
 *
 * @return {number} The resulting value.
 */
var MinSub = function (value, amount, min)
{
    return Math.max(value - amount, min);
};

module.exports = MinSub;


/***/ }),

/***/ 8585:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Work out what percentage `value` is of the range between `min` and `max`.
 * If `max` isn't given then it will return the percentage of `value` to `min`.
 *
 * You can optionally specify an `upperMax` value, which is a mid-way point in the range that represents 100%, after which the % starts to go down to zero again.
 *
 * @function Phaser.Math.Percent
 * @since 3.0.0
 *
 * @param {number} value - The value to determine the percentage of.
 * @param {number} min - The minimum value.
 * @param {number} [max] - The maximum value.
 * @param {number} [upperMax] - The mid-way point in the range that represents 100%.
 *
 * @return {number} A value between 0 and 1 representing the percentage.
 */
var Percent = function (value, min, max, upperMax)
{
    if (max === undefined) { max = min + 1; }

    var percentage = (value - min) / (max - min);

    if (percentage > 1)
    {
        if (upperMax !== undefined)
        {
            percentage = ((upperMax - value)) / (upperMax - max);

            if (percentage < 0)
            {
                percentage = 0;
            }
        }
        else
        {
            percentage = 1;
        }
    }
    else if (percentage < 0)
    {
        percentage = 0;
    }

    return percentage;
};

module.exports = Percent;


/***/ }),

/***/ 372:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

//  Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
//  and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl

var Class = __webpack_require__(7473);
var Matrix3 = __webpack_require__(2149);
var NOOP = __webpack_require__(1984);
var Vector3 = __webpack_require__(5689);

var EPSILON = 0.000001;

//  Some shared 'private' arrays
var siNext = new Int8Array([ 1, 2, 0 ]);
var tmp = new Float32Array([ 0, 0, 0 ]);

var xUnitVec3 = new Vector3(1, 0, 0);
var yUnitVec3 = new Vector3(0, 1, 0);

var tmpvec = new Vector3();
var tmpMat3 = new Matrix3();

/**
 * @classdesc
 * A quaternion.
 *
 * @class Quaternion
 * @memberof Phaser.Math
 * @constructor
 * @since 3.0.0
 *
 * @param {number} [x=0] - The x component.
 * @param {number} [y=0] - The y component.
 * @param {number} [z=0] - The z component.
 * @param {number} [w=1] - The w component.
 */
var Quaternion = new Class({

    initialize:

    function Quaternion (x, y, z, w)
    {
        /**
         * The x component of this Quaternion.
         *
         * @name Phaser.Math.Quaternion#_x
         * @type {number}
         * @default 0
         * @private
         * @since 3.50.0
         */

        /**
         * The y component of this Quaternion.
         *
         * @name Phaser.Math.Quaternion#_y
         * @type {number}
         * @default 0
         * @private
         * @since 3.50.0
         */

        /**
         * The z component of this Quaternion.
         *
         * @name Phaser.Math.Quaternion#_z
         * @type {number}
         * @default 0
         * @private
         * @since 3.50.0
         */

        /**
         * The w component of this Quaternion.
         *
         * @name Phaser.Math.Quaternion#_w
         * @type {number}
         * @default 0
         * @private
         * @since 3.50.0
         */

        /**
         * This callback is invoked, if set, each time a value in this quaternion is changed.
         * The callback is passed one argument, a reference to this quaternion.
         *
         * @name Phaser.Math.Quaternion#onChangeCallback
         * @type {function}
         * @since 3.50.0
         */
        this.onChangeCallback = NOOP;

        this.set(x, y, z, w);
    },

    /**
     * The x component of this Quaternion.
     *
     * @name Phaser.Math.Quaternion#x
     * @type {number}
     * @default 0
     * @since 3.0.0
     */
    x: {
        get: function ()
        {
            return this._x;
        },

        set: function (value)
        {
            this._x = value;

            this.onChangeCallback(this);
        }
    },

    /**
     * The y component of this Quaternion.
     *
     * @name Phaser.Math.Quaternion#y
     * @type {number}
     * @default 0
     * @since 3.0.0
     */
    y: {
        get: function ()
        {
            return this._y;
        },

        set: function (value)
        {
            this._y = value;

            this.onChangeCallback(this);
        }
    },

    /**
     * The z component of this Quaternion.
     *
     * @name Phaser.Math.Quaternion#z
     * @type {number}
     * @default 0
     * @since 3.0.0
     */
    z: {
        get: function ()
        {
            return this._z;
        },

        set: function (value)
        {
            this._z = value;

            this.onChangeCallback(this);
        }
    },

    /**
     * The w component of this Quaternion.
     *
     * @name Phaser.Math.Quaternion#w
     * @type {number}
     * @default 0
     * @since 3.0.0
     */
    w: {
        get: function ()
        {
            return this._w;
        },

        set: function (value)
        {
            this._w = value;

            this.onChangeCallback(this);
        }
    },

    /**
     * Copy the components of a given Quaternion or Vector into this Quaternion.
     *
     * @method Phaser.Math.Quaternion#copy
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} src - The Quaternion or Vector to copy the components from.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    copy: function (src)
    {
        return this.set(src);
    },

    /**
     * Set the components of this Quaternion and optionally call the `onChangeCallback`.
     *
     * @method Phaser.Math.Quaternion#set
     * @since 3.0.0
     *
     * @param {(number|object)} [x=0] - The x component, or an object containing x, y, z, and w components.
     * @param {number} [y=0] - The y component.
     * @param {number} [z=0] - The z component.
     * @param {number} [w=0] - The w component.
     * @param {boolean} [update=true] - Call the `onChangeCallback`?
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    set: function (x, y, z, w, update)
    {
        if (update === undefined) { update = true; }

        if (typeof x === 'object')
        {
            this._x = x.x || 0;
            this._y = x.y || 0;
            this._z = x.z || 0;
            this._w = x.w || 0;
        }
        else
        {
            this._x = x || 0;
            this._y = y || 0;
            this._z = z || 0;
            this._w = w || 0;
        }

        if (update)
        {
            this.onChangeCallback(this);
        }

        return this;
    },

    /**
     * Add a given Quaternion or Vector to this Quaternion. Addition is component-wise.
     *
     * @method Phaser.Math.Quaternion#add
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to add to this Quaternion.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    add: function (v)
    {
        this._x += v.x;
        this._y += v.y;
        this._z += v.z;
        this._w += v.w;

        this.onChangeCallback(this);

        return this;
    },

    /**
     * Subtract a given Quaternion or Vector from this Quaternion. Subtraction is component-wise.
     *
     * @method Phaser.Math.Quaternion#subtract
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to subtract from this Quaternion.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    subtract: function (v)
    {
        this._x -= v.x;
        this._y -= v.y;
        this._z -= v.z;
        this._w -= v.w;

        this.onChangeCallback(this);

        return this;
    },

    /**
     * Scale this Quaternion by the given value.
     *
     * @method Phaser.Math.Quaternion#scale
     * @since 3.0.0
     *
     * @param {number} scale - The value to scale this Quaternion by.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    scale: function (scale)
    {
        this._x *= scale;
        this._y *= scale;
        this._z *= scale;
        this._w *= scale;

        this.onChangeCallback(this);

        return this;
    },

    /**
     * Calculate the length of this Quaternion.
     *
     * @method Phaser.Math.Quaternion#length
     * @since 3.0.0
     *
     * @return {number} The length of this Quaternion.
     */
    length: function ()
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var w = this.w;

        return Math.sqrt(x * x + y * y + z * z + w * w);
    },

    /**
     * Calculate the length of this Quaternion squared.
     *
     * @method Phaser.Math.Quaternion#lengthSq
     * @since 3.0.0
     *
     * @return {number} The length of this Quaternion, squared.
     */
    lengthSq: function ()
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var w = this.w;

        return x * x + y * y + z * z + w * w;
    },

    /**
     * Normalize this Quaternion.
     *
     * @method Phaser.Math.Quaternion#normalize
     * @since 3.0.0
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    normalize: function ()
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var w = this.w;
        var len = x * x + y * y + z * z + w * w;

        if (len > 0)
        {
            len = 1 / Math.sqrt(len);

            this._x = x * len;
            this._y = y * len;
            this._z = z * len;
            this._w = w * len;
        }

        this.onChangeCallback(this);

        return this;
    },

    /**
     * Calculate the dot product of this Quaternion and the given Quaternion or Vector.
     *
     * @method Phaser.Math.Quaternion#dot
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to dot product with this Quaternion.
     *
     * @return {number} The dot product of this Quaternion and the given Quaternion or Vector.
     */
    dot: function (v)
    {
        return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
    },

    /**
     * Linearly interpolate this Quaternion towards the given Quaternion or Vector.
     *
     * @method Phaser.Math.Quaternion#lerp
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to interpolate towards.
     * @param {number} [t=0] - The percentage of interpolation.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    lerp: function (v, t)
    {
        if (t === undefined) { t = 0; }

        var ax = this.x;
        var ay = this.y;
        var az = this.z;
        var aw = this.w;

        return this.set(
            ax + t * (v.x - ax),
            ay + t * (v.y - ay),
            az + t * (v.z - az),
            aw + t * (v.w - aw)
        );
    },

    /**
     * Rotates this Quaternion based on the two given vectors.
     *
     * @method Phaser.Math.Quaternion#rotationTo
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector3} a - The transform rotation vector.
     * @param {Phaser.Math.Vector3} b - The target rotation vector.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    rotationTo: function (a, b)
    {
        var dot = a.x * b.x + a.y * b.y + a.z * b.z;

        if (dot < -0.999999)
        {
            if (tmpvec.copy(xUnitVec3).cross(a).length() < EPSILON)
            {
                tmpvec.copy(yUnitVec3).cross(a);
            }

            tmpvec.normalize();

            return this.setAxisAngle(tmpvec, Math.PI);

        }
        else if (dot > 0.999999)
        {
            return this.set(0, 0, 0, 1);
        }
        else
        {
            tmpvec.copy(a).cross(b);

            this._x = tmpvec.x;
            this._y = tmpvec.y;
            this._z = tmpvec.z;
            this._w = 1 + dot;

            return this.normalize();
        }
    },

    /**
     * Set the axes of this Quaternion.
     *
     * @method Phaser.Math.Quaternion#setAxes
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector3} view - The view axis.
     * @param {Phaser.Math.Vector3} right - The right axis.
     * @param {Phaser.Math.Vector3} up - The upwards axis.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    setAxes: function (view, right, up)
    {
        var m = tmpMat3.val;

        m[0] = right.x;
        m[3] = right.y;
        m[6] = right.z;

        m[1] = up.x;
        m[4] = up.y;
        m[7] = up.z;

        m[2] = -view.x;
        m[5] = -view.y;
        m[8] = -view.z;

        return this.fromMat3(tmpMat3).normalize();
    },

    /**
     * Reset this Matrix to an identity (default) Quaternion.
     *
     * @method Phaser.Math.Quaternion#identity
     * @since 3.0.0
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    identity: function ()
    {
        return this.set(0, 0, 0, 1);
    },

    /**
     * Set the axis angle of this Quaternion.
     *
     * @method Phaser.Math.Quaternion#setAxisAngle
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector3} axis - The axis.
     * @param {number} rad - The angle in radians.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    setAxisAngle: function (axis, rad)
    {
        rad = rad * 0.5;

        var s = Math.sin(rad);

        return this.set(
            s * axis.x,
            s * axis.y,
            s * axis.z,
            Math.cos(rad)
        );
    },

    /**
     * Multiply this Quaternion by the given Quaternion or Vector.
     *
     * @method Phaser.Math.Quaternion#multiply
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} b - The Quaternion or Vector to multiply this Quaternion by.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    multiply: function (b)
    {
        var ax = this.x;
        var ay = this.y;
        var az = this.z;
        var aw = this.w;

        var bx = b.x;
        var by = b.y;
        var bz = b.z;
        var bw = b.w;

        return this.set(
            ax * bw + aw * bx + ay * bz - az * by,
            ay * bw + aw * by + az * bx - ax * bz,
            az * bw + aw * bz + ax * by - ay * bx,
            aw * bw - ax * bx - ay * by - az * bz
        );
    },

    /**
     * Smoothly linearly interpolate this Quaternion towards the given Quaternion or Vector.
     *
     * @method Phaser.Math.Quaternion#slerp
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} b - The Quaternion or Vector to interpolate towards.
     * @param {number} t - The percentage of interpolation.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    slerp: function (b, t)
    {
        // benchmarks: http://jsperf.com/quaternion-slerp-implementations

        var ax = this.x;
        var ay = this.y;
        var az = this.z;
        var aw = this.w;

        var bx = b.x;
        var by = b.y;
        var bz = b.z;
        var bw = b.w;

        // calc cosine
        var cosom = ax * bx + ay * by + az * bz + aw * bw;

        // adjust signs (if necessary)
        if (cosom < 0)
        {
            cosom = -cosom;
            bx = - bx;
            by = - by;
            bz = - bz;
            bw = - bw;
        }

        // "from" and "to" quaternions are very close
        //  ... so we can do a linear interpolation
        var scale0 = 1 - t;
        var scale1 = t;

        // calculate coefficients
        if ((1 - cosom) > EPSILON)
        {
            // standard case (slerp)
            var omega = Math.acos(cosom);
            var sinom = Math.sin(omega);

            scale0 = Math.sin((1.0 - t) * omega) / sinom;
            scale1 = Math.sin(t * omega) / sinom;
        }

        // calculate final values
        return this.set(
            scale0 * ax + scale1 * bx,
            scale0 * ay + scale1 * by,
            scale0 * az + scale1 * bz,
            scale0 * aw + scale1 * bw
        );
    },

    /**
     * Invert this Quaternion.
     *
     * @method Phaser.Math.Quaternion#invert
     * @since 3.0.0
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    invert: function ()
    {
        var a0 = this.x;
        var a1 = this.y;
        var a2 = this.z;
        var a3 = this.w;

        var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
        var invDot = (dot) ? 1 / dot : 0;

        return this.set(
            -a0 * invDot,
            -a1 * invDot,
            -a2 * invDot,
            a3 * invDot
        );
    },

    /**
     * Convert this Quaternion into its conjugate.
     *
     * Sets the x, y and z components.
     *
     * @method Phaser.Math.Quaternion#conjugate
     * @since 3.0.0
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    conjugate: function ()
    {
        this._x = -this.x;
        this._y = -this.y;
        this._z = -this.z;

        this.onChangeCallback(this);

        return this;
    },

    /**
     * Rotate this Quaternion on the X axis.
     *
     * @method Phaser.Math.Quaternion#rotateX
     * @since 3.0.0
     *
     * @param {number} rad - The rotation angle in radians.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    rotateX: function (rad)
    {
        rad *= 0.5;

        var ax = this.x;
        var ay = this.y;
        var az = this.z;
        var aw = this.w;

        var bx = Math.sin(rad);
        var bw = Math.cos(rad);

        return this.set(
            ax * bw + aw * bx,
            ay * bw + az * bx,
            az * bw - ay * bx,
            aw * bw - ax * bx
        );
    },

    /**
     * Rotate this Quaternion on the Y axis.
     *
     * @method Phaser.Math.Quaternion#rotateY
     * @since 3.0.0
     *
     * @param {number} rad - The rotation angle in radians.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    rotateY: function (rad)
    {
        rad *= 0.5;

        var ax = this.x;
        var ay = this.y;
        var az = this.z;
        var aw = this.w;

        var by = Math.sin(rad);
        var bw = Math.cos(rad);

        return this.set(
            ax * bw - az * by,
            ay * bw + aw * by,
            az * bw + ax * by,
            aw * bw - ay * by
        );
    },

    /**
     * Rotate this Quaternion on the Z axis.
     *
     * @method Phaser.Math.Quaternion#rotateZ
     * @since 3.0.0
     *
     * @param {number} rad - The rotation angle in radians.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    rotateZ: function (rad)
    {
        rad *= 0.5;

        var ax = this.x;
        var ay = this.y;
        var az = this.z;
        var aw = this.w;

        var bz = Math.sin(rad);
        var bw = Math.cos(rad);

        return this.set(
            ax * bw + ay * bz,
            ay * bw - ax * bz,
            az * bw + aw * bz,
            aw * bw - az * bz
        );
    },

    /**
     * Create a unit (or rotation) Quaternion from its x, y, and z components.
     *
     * Sets the w component.
     *
     * @method Phaser.Math.Quaternion#calculateW
     * @since 3.0.0
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    calculateW: function ()
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;

        this.w = -Math.sqrt(1.0 - x * x - y * y - z * z);

        return this;
    },

    /**
     * Set this Quaternion from the given Euler, based on Euler order.
     *
     * @method Phaser.Math.Quaternion#setFromEuler
     * @since 3.50.0
     *
     * @param {Phaser.Math.Euler} euler - The Euler to convert from.
     * @param {boolean} [update=true] - Run the `onChangeCallback`?
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    setFromEuler: function (euler, update)
    {
        var x = euler.x / 2;
        var y = euler.y / 2;
        var z = euler.z / 2;

        var c1 = Math.cos(x);
        var c2 = Math.cos(y);
        var c3 = Math.cos(z);

        var s1 = Math.sin(x);
        var s2 = Math.sin(y);
        var s3 = Math.sin(z);

        switch (euler.order)
        {
            case 'XYZ':
            {
                this.set(
                    s1 * c2 * c3 + c1 * s2 * s3,
                    c1 * s2 * c3 - s1 * c2 * s3,
                    c1 * c2 * s3 + s1 * s2 * c3,
                    c1 * c2 * c3 - s1 * s2 * s3,
                    update
                );

                break;
            }

            case 'YXZ':
            {
                this.set(
                    s1 * c2 * c3 + c1 * s2 * s3,
                    c1 * s2 * c3 - s1 * c2 * s3,
                    c1 * c2 * s3 - s1 * s2 * c3,
                    c1 * c2 * c3 + s1 * s2 * s3,
                    update
                );

                break;
            }

            case 'ZXY':
            {
                this.set(
                    s1 * c2 * c3 - c1 * s2 * s3,
                    c1 * s2 * c3 + s1 * c2 * s3,
                    c1 * c2 * s3 + s1 * s2 * c3,
                    c1 * c2 * c3 - s1 * s2 * s3,
                    update
                );

                break;
            }

            case 'ZYX':
            {
                this.set(
                    s1 * c2 * c3 - c1 * s2 * s3,
                    c1 * s2 * c3 + s1 * c2 * s3,
                    c1 * c2 * s3 - s1 * s2 * c3,
                    c1 * c2 * c3 + s1 * s2 * s3,
                    update
                );

                break;
            }

            case 'YZX':
            {
                this.set(
                    s1 * c2 * c3 + c1 * s2 * s3,
                    c1 * s2 * c3 + s1 * c2 * s3,
                    c1 * c2 * s3 - s1 * s2 * c3,
                    c1 * c2 * c3 - s1 * s2 * s3,
                    update
                );

                break;
            }

            case 'XZY':
            {
                this.set(
                    s1 * c2 * c3 - c1 * s2 * s3,
                    c1 * s2 * c3 - s1 * c2 * s3,
                    c1 * c2 * s3 + s1 * s2 * c3,
                    c1 * c2 * c3 + s1 * s2 * s3,
                    update
                );

                break;
            }
        }

        return this;
    },

    /**
     * Sets the rotation of this Quaternion from the given Matrix4.
     *
     * @method Phaser.Math.Quaternion#setFromRotationMatrix
     * @since 3.50.0
     *
     * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to set the rotation from.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    setFromRotationMatrix: function (mat4)
    {
        var m = mat4.val;

        var m11 = m[0];
        var m12 = m[4];
        var m13 = m[8];
        var m21 = m[1];
        var m22 = m[5];
        var m23 = m[9];
        var m31 = m[2];
        var m32 = m[6];
        var m33 = m[10];

        var trace = m11 + m22 + m33;
        var s;

        if (trace > 0)
        {
            s = 0.5 / Math.sqrt(trace + 1.0);

            this.set(
                (m32 - m23) * s,
                (m13 - m31) * s,
                (m21 - m12) * s,
                0.25 / s
            );
        }
        else if (m11 > m22 && m11 > m33)
        {
            s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);

            this.set(
                0.25 * s,
                (m12 + m21) / s,
                (m13 + m31) / s,
                (m32 - m23) / s
            );
        }
        else if (m22 > m33)
        {
            s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);

            this.set(
                (m12 + m21) / s,
                0.25 * s,
                (m23 + m32) / s,
                (m13 - m31) / s
            );
        }
        else
        {
            s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);

            this.set(
                (m13 + m31) / s,
                (m23 + m32) / s,
                0.25 * s,
                (m21 - m12) / s
            );
        }

        return this;
    },

    /**
     * Convert the given Matrix into this Quaternion.
     *
     * @method Phaser.Math.Quaternion#fromMat3
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix3} mat - The Matrix to convert from.
     *
     * @return {Phaser.Math.Quaternion} This Quaternion.
     */
    fromMat3: function (mat)
    {
        // benchmarks:
        //    http://jsperf.com/typed-array-access-speed
        //    http://jsperf.com/conversion-of-3x3-matrix-to-quaternion

        // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
        // article "Quaternion Calculus and Fast Animation".
        var m = mat.val;
        var fTrace = m[0] + m[4] + m[8];
        var fRoot;

        if (fTrace > 0)
        {
            // |w| > 1/2, may as well choose w > 1/2
            fRoot = Math.sqrt(fTrace + 1.0); // 2w

            this.w = 0.5 * fRoot;

            fRoot = 0.5 / fRoot; // 1/(4w)

            this._x = (m[7] - m[5]) * fRoot;
            this._y = (m[2] - m[6]) * fRoot;
            this._z = (m[3] - m[1]) * fRoot;
        }
        else
        {
            // |w| <= 1/2
            var i = 0;

            if (m[4] > m[0])
            {
                i = 1;
            }

            if (m[8] > m[i * 3 + i])
            {
                i = 2;
            }

            var j = siNext[i];
            var k = siNext[j];

            //  This isn't quite as clean without array access
            fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1);
            tmp[i] = 0.5 * fRoot;

            fRoot = 0.5 / fRoot;

            tmp[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;
            tmp[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot;

            this._x = tmp[0];
            this._y = tmp[1];
            this._z = tmp[2];
            this._w = (m[k * 3 + j] - m[j * 3 + k]) * fRoot;
        }

        this.onChangeCallback(this);

        return this;
    }

});

module.exports = Quaternion;


/***/ }),

/***/ 4208:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var CONST = __webpack_require__(7425);

/**
 * Convert the given angle in radians, to the equivalent angle in degrees.
 *
 * @function Phaser.Math.RadToDeg
 * @since 3.0.0
 *
 * @param {number} radians - The angle in radians to convert ot degrees.
 *
 * @return {number} The given angle converted to degrees.
 */
var RadToDeg = function (radians)
{
    return radians * CONST.RAD_TO_DEG;
};

module.exports = RadToDeg;


/***/ }),

/***/ 1705:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Compute a random unit vector.
 *
 * Computes random values for the given vector between -1 and 1 that can be used to represent a direction.
 *
 * Optionally accepts a scale value to scale the resulting vector by.
 *
 * @function Phaser.Math.RandomXY
 * @since 3.0.0
 *
 * @param {Phaser.Math.Vector2} vector - The Vector to compute random values for.
 * @param {number} [scale=1] - The scale of the random values.
 *
 * @return {Phaser.Math.Vector2} The given Vector.
 */
var RandomXY = function (vector, scale)
{
    if (scale === undefined) { scale = 1; }

    var r = Math.random() * 2 * Math.PI;

    vector.x = Math.cos(r) * scale;
    vector.y = Math.sin(r) * scale;

    return vector;
};

module.exports = RandomXY;


/***/ }),

/***/ 6650:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Compute a random position vector in a spherical area, optionally defined by the given radius.
 *
 * @function Phaser.Math.RandomXYZ
 * @since 3.0.0
 *
 * @param {Phaser.Math.Vector3} vec3 - The Vector to compute random values for.
 * @param {number} [radius=1] - The radius.
 *
 * @return {Phaser.Math.Vector3} The given Vector.
 */
var RandomXYZ = function (vec3, radius)
{
    if (radius === undefined) { radius = 1; }

    var r = Math.random() * 2 * Math.PI;
    var z = (Math.random() * 2) - 1;
    var zScale = Math.sqrt(1 - z * z) * radius;

    vec3.x = Math.cos(r) * zScale;
    vec3.y = Math.sin(r) * zScale;
    vec3.z = z * radius;

    return vec3;
};

module.exports = RandomXYZ;


/***/ }),

/***/ 2037:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Compute a random four-dimensional vector.
 *
 * @function Phaser.Math.RandomXYZW
 * @since 3.0.0
 *
 * @param {Phaser.Math.Vector4} vec4 - The Vector to compute random values for.
 * @param {number} [scale=1] - The scale of the random values.
 *
 * @return {Phaser.Math.Vector4} The given Vector.
 */
var RandomXYZW = function (vec4, scale)
{
    if (scale === undefined) { scale = 1; }

    vec4.x = (Math.random() * 2 - 1) * scale;
    vec4.y = (Math.random() * 2 - 1) * scale;
    vec4.z = (Math.random() * 2 - 1) * scale;
    vec4.w = (Math.random() * 2 - 1) * scale;

    return vec4;
};

module.exports = RandomXYZW;


/***/ }),

/***/ 6283:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Rotate a given point by a given angle around the origin (0, 0), in an anti-clockwise direction.
 *
 * @function Phaser.Math.Rotate
 * @since 3.0.0
 *
 * @param {(Phaser.Geom.Point|object)} point - The point to be rotated.
 * @param {number} angle - The angle to be rotated by in an anticlockwise direction.
 *
 * @return {Phaser.Geom.Point} The given point, rotated by the given angle in an anticlockwise direction.
 */
var Rotate = function (point, angle)
{
    var x = point.x;
    var y = point.y;

    point.x = (x * Math.cos(angle)) - (y * Math.sin(angle));
    point.y = (x * Math.sin(angle)) + (y * Math.cos(angle));

    return point;
};

module.exports = Rotate;


/***/ }),

/***/ 9876:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Rotate a `point` around `x` and `y` to the given `angle`, at the same distance.
 *
 * In polar notation, this maps a point from (r, t) to (r, angle), vs. the origin (x, y).
 *
 * @function Phaser.Math.RotateAround
 * @since 3.0.0
 *
 * @generic {Phaser.Types.Math.Vector2Like} T - [point,$return]
 *
 * @param {(Phaser.Geom.Point|object)} point - The point to be rotated.
 * @param {number} x - The horizontal coordinate to rotate around.
 * @param {number} y - The vertical coordinate to rotate around.
 * @param {number} angle - The angle of rotation in radians.
 *
 * @return {Phaser.Types.Math.Vector2Like} The given point.
 */
var RotateAround = function (point, x, y, angle)
{
    var c = Math.cos(angle);
    var s = Math.sin(angle);

    var tx = point.x - x;
    var ty = point.y - y;

    point.x = tx * c - ty * s + x;
    point.y = tx * s + ty * c + y;

    return point;
};

module.exports = RotateAround;


/***/ }),

/***/ 8348:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Rotate a `point` around `x` and `y` by the given `angle` and `distance`.
 *
 * In polar notation, this maps a point from (r, t) to (distance, t + angle), vs. the origin (x, y).
 *
 * @function Phaser.Math.RotateAroundDistance
 * @since 3.0.0
 *
 * @generic {Phaser.Types.Math.Vector2Like} T - [point,$return]
 *
 * @param {(Phaser.Geom.Point|object)} point - The point to be rotated.
 * @param {number} x - The horizontal coordinate to rotate around.
 * @param {number} y - The vertical coordinate to rotate around.
 * @param {number} angle - The angle of rotation in radians.
 * @param {number} distance - The distance from (x, y) to place the point at.
 *
 * @return {Phaser.Types.Math.Vector2Like} The given point.
 */
var RotateAroundDistance = function (point, x, y, angle, distance)
{
    var t = angle + Math.atan2(point.y - y, point.x - x);

    point.x = x + (distance * Math.cos(t));
    point.y = y + (distance * Math.sin(t));

    return point;
};

module.exports = RotateAroundDistance;


/***/ }),

/***/ 4497:
/***/ ((module) => {

/**
 * @author       samme
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Position a `point` at the given `angle` and `distance` to (`x`, `y`).
 *
 * @function Phaser.Math.RotateTo
 * @since 3.24.0
 *
 * @generic {Phaser.Types.Math.Vector2Like} T - [point,$return]
 *
 * @param {Phaser.Types.Math.Vector2Like} point - The point to be positioned.
 * @param {number} x - The horizontal coordinate to position from.
 * @param {number} y - The vertical coordinate to position from.
 * @param {number} angle - The angle of rotation in radians.
 * @param {number} distance - The distance from (x, y) to place the point at.
 *
 * @return {Phaser.Types.Math.Vector2Like} The given point.
 */
var RotateTo = function (point, x, y, angle, distance)
{
    point.x = x + (distance * Math.cos(angle));
    point.y = y + (distance * Math.sin(angle));

    return point;
};

module.exports = RotateTo;


/***/ }),

/***/ 9640:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Vector3 = __webpack_require__(5689);
var Matrix4 = __webpack_require__(9652);
var Quaternion = __webpack_require__(372);

var tmpMat4 = new Matrix4();
var tmpQuat = new Quaternion();
var tmpVec3 = new Vector3();

/**
 * Rotates a vector in place by axis angle.
 *
 * This is the same as transforming a point by an
 * axis-angle quaternion, but it has higher precision.
 *
 * @function Phaser.Math.RotateVec3
 * @since 3.0.0
 *
 * @param {Phaser.Math.Vector3} vec - The vector to be rotated.
 * @param {Phaser.Math.Vector3} axis - The axis to rotate around.
 * @param {number} radians - The angle of rotation in radians.
 *
 * @return {Phaser.Math.Vector3} The given vector.
 */
var RotateVec3 = function (vec, axis, radians)
{
    //  Set the quaternion to our axis angle
    tmpQuat.setAxisAngle(axis, radians);

    //  Create a rotation matrix from the axis angle
    tmpMat4.fromRotationTranslation(tmpQuat, tmpVec3.set(0, 0, 0));

    //  Multiply our vector by the rotation matrix
    return vec.transformMat4(tmpMat4);
};

module.exports = RotateVec3;


/***/ }),

/***/ 4078:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Round a given number so it is further away from zero. That is, positive numbers are rounded up, and negative numbers are rounded down.
 *
 * @function Phaser.Math.RoundAwayFromZero
 * @since 3.0.0
 *
 * @param {number} value - The number to round.
 *
 * @return {number} The rounded number, rounded away from zero.
 */
var RoundAwayFromZero = function (value)
{
    // "Opposite" of truncate.
    return (value > 0) ? Math.ceil(value) : Math.floor(value);
};

module.exports = RoundAwayFromZero;


/***/ }),

/***/ 855:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Round a value to the given precision.
 *
 * For example:
 *
 * ```javascript
 * RoundTo(123.456, 0) = 123
 * RoundTo(123.456, 1) = 120
 * RoundTo(123.456, 2) = 100
 * ```
 *
 * To round the decimal, i.e. to round to precision, pass in a negative `place`:
 *
 * ```javascript
 * RoundTo(123.456789, 0) = 123
 * RoundTo(123.456789, -1) = 123.5
 * RoundTo(123.456789, -2) = 123.46
 * RoundTo(123.456789, -3) = 123.457
 * ```
 *
 * @function Phaser.Math.RoundTo
 * @since 3.0.0
 *
 * @param {number} value - The value to round.
 * @param {number} [place=0] - The place to round to. Positive to round the units, negative to round the decimal.
 * @param {number} [base=10] - The base to round in. Default is 10 for decimal.
 *
 * @return {number} The rounded value.
 */
var RoundTo = function (value, place, base)
{
    if (place === undefined) { place = 0; }
    if (base === undefined) { base = 10; }

    var p = Math.pow(base, -place);

    return Math.round(value * p) / p;
};

module.exports = RoundTo;


/***/ }),

/***/ 4936:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Generate a series of sine and cosine values.
 *
 * @function Phaser.Math.SinCosTableGenerator
 * @since 3.0.0
 *
 * @param {number} length - The number of values to generate.
 * @param {number} [sinAmp=1] - The sine value amplitude.
 * @param {number} [cosAmp=1] - The cosine value amplitude.
 * @param {number} [frequency=1] - The frequency of the values.
 *
 * @return {Phaser.Types.Math.SinCosTable} The generated values.
 */
var SinCosTableGenerator = function (length, sinAmp, cosAmp, frequency)
{
    if (sinAmp === undefined) { sinAmp = 1; }
    if (cosAmp === undefined) { cosAmp = 1; }
    if (frequency === undefined) { frequency = 1; }

    frequency *= Math.PI / length;

    var cos = [];
    var sin = [];

    for (var c = 0; c < length; c++)
    {
        cosAmp -= sinAmp * frequency;
        sinAmp += cosAmp * frequency;

        cos[c] = cosAmp;
        sin[c] = sinAmp;
    }

    return {
        sin: sin,
        cos: cos,
        length: length
    };
};

module.exports = SinCosTableGenerator;


/***/ }),

/***/ 2733:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate a smooth interpolation percentage of `x` between `min` and `max`.
 *
 * The function receives the number `x` as an argument and returns 0 if `x` is less than or equal to the left edge,
 * 1 if `x` is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial,
 * between 0 and 1 otherwise.
 *
 * @function Phaser.Math.SmoothStep
 * @since 3.0.0
 * @see {@link https://en.wikipedia.org/wiki/Smoothstep}
 *
 * @param {number} x - The input value.
 * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'.
 * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'.
 *
 * @return {number} The percentage of interpolation, between 0 and 1.
 */
var SmoothStep = function (x, min, max)
{
    if (x <= min)
    {
        return 0;
    }

    if (x >= max)
    {
        return 1;
    }

    x = (x - min) / (max - min);

    return x * x * (3 - 2 * x);
};

module.exports = SmoothStep;


/***/ }),

/***/ 278:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate a smoother interpolation percentage of `x` between `min` and `max`.
 *
 * The function receives the number `x` as an argument and returns 0 if `x` is less than or equal to the left edge,
 * 1 if `x` is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial,
 * between 0 and 1 otherwise.
 *
 * Produces an even smoother interpolation than {@link Phaser.Math.SmoothStep}.
 *
 * @function Phaser.Math.SmootherStep
 * @since 3.0.0
 * @see {@link https://en.wikipedia.org/wiki/Smoothstep#Variations}
 *
 * @param {number} x - The input value.
 * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'.
 * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'.
 *
 * @return {number} The percentage of interpolation, between 0 and 1.
 */
var SmootherStep = function (x, min, max)
{
    x = Math.max(0, Math.min(1, (x - min) / (max - min)));

    return x * x * x * (x * (x * 6 - 15) + 10);
};

module.exports = SmootherStep;


/***/ }),

/***/ 163:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Vector2 = __webpack_require__(2529);

/**
 * Returns a Vector2 containing the x and y position of the given index in a `width` x `height` sized grid.
 *
 * For example, in a 6 x 4 grid, index 16 would equal x: 4 y: 2.
 *
 * If the given index is out of range an empty Vector2 is returned.
 *
 * @function Phaser.Math.ToXY
 * @since 3.19.0
 *
 * @param {number} index - The position within the grid to get the x/y value for.
 * @param {number} width - The width of the grid.
 * @param {number} height - The height of the grid.
 * @param {Phaser.Math.Vector2} [out] - An optional Vector2 to store the result in. If not given, a new Vector2 instance will be created.
 *
 * @return {Phaser.Math.Vector2} A Vector2 where the x and y properties contain the given grid index.
 */
var ToXY = function (index, width, height, out)
{
    if (out === undefined) { out = new Vector2(); }

    var x = 0;
    var y = 0;
    var total = width * height;

    if (index > 0 && index <= total)
    {
        if (index > width - 1)
        {
            y = Math.floor(index / width);
            x = index - (y * width);
        }
        else
        {
            x = index;
        }
    }

    return out.set(x, y);
};

module.exports = ToXY;


/***/ }),

/***/ 7556:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Vector2 = __webpack_require__(2529);

/**
 * Takes the `x` and `y` coordinates and transforms them into the same space as
 * defined by the position, rotation and scale values.
 *
 * @function Phaser.Math.TransformXY
 * @since 3.0.0
 *
 * @param {number} x - The x coordinate to be transformed.
 * @param {number} y - The y coordinate to be transformed.
 * @param {number} positionX - Horizontal position of the transform point.
 * @param {number} positionY - Vertical position of the transform point.
 * @param {number} rotation - Rotation of the transform point, in radians.
 * @param {number} scaleX - Horizontal scale of the transform point.
 * @param {number} scaleY - Vertical scale of the transform point.
 * @param {(Phaser.Math.Vector2|Phaser.Geom.Point|object)} [output] - The output vector, point or object for the translated coordinates.
 *
 * @return {(Phaser.Math.Vector2|Phaser.Geom.Point|object)} The translated point.
 */
var TransformXY = function (x, y, positionX, positionY, rotation, scaleX, scaleY, output)
{
    if (output === undefined) { output = new Vector2(); }

    var radianSin = Math.sin(rotation);
    var radianCos = Math.cos(rotation);

    // Rotate and Scale
    var a = radianCos * scaleX;
    var b = radianSin * scaleX;
    var c = -radianSin * scaleY;
    var d = radianCos * scaleY;

    //  Invert
    var id = 1 / ((a * d) + (c * -b));

    output.x = (d * id * x) + (-c * id * y) + (((positionY * c) - (positionX * d)) * id);
    output.y = (a * id * y) + (-b * id * x) + (((-positionY * a) + (positionX * b)) * id);

    return output;
};

module.exports = TransformXY;


/***/ }),

/***/ 2529:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

//  Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
//  and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl

var Class = __webpack_require__(7473);
var FuzzyEqual = __webpack_require__(12);

/**
 * @classdesc
 * A representation of a vector in 2D space.
 *
 * A two-component vector.
 *
 * @class Vector2
 * @memberof Phaser.Math
 * @constructor
 * @since 3.0.0
 *
 * @param {number|Phaser.Types.Math.Vector2Like} [x=0] - The x component, or an object with `x` and `y` properties.
 * @param {number} [y=x] - The y component.
 */
var Vector2 = new Class({

    initialize:

    function Vector2 (x, y)
    {
        /**
         * The x component of this Vector.
         *
         * @name Phaser.Math.Vector2#x
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.x = 0;

        /**
         * The y component of this Vector.
         *
         * @name Phaser.Math.Vector2#y
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.y = 0;

        if (typeof x === 'object')
        {
            this.x = x.x || 0;
            this.y = x.y || 0;
        }
        else
        {
            if (y === undefined) { y = x; }

            this.x = x || 0;
            this.y = y || 0;
        }
    },

    /**
     * Make a clone of this Vector2.
     *
     * @method Phaser.Math.Vector2#clone
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} A clone of this Vector2.
     */
    clone: function ()
    {
        return new Vector2(this.x, this.y);
    },

    /**
     * Copy the components of a given Vector into this Vector.
     *
     * @method Phaser.Math.Vector2#copy
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} src - The Vector to copy the components from.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    copy: function (src)
    {
        this.x = src.x || 0;
        this.y = src.y || 0;

        return this;
    },

    /**
     * Set the component values of this Vector from a given Vector2Like object.
     *
     * @method Phaser.Math.Vector2#setFromObject
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} obj - The object containing the component values to set for this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    setFromObject: function (obj)
    {
        this.x = obj.x || 0;
        this.y = obj.y || 0;

        return this;
    },

    /**
     * Set the `x` and `y` components of the this Vector to the given `x` and `y` values.
     *
     * @method Phaser.Math.Vector2#set
     * @since 3.0.0
     *
     * @param {number} x - The x value to set for this Vector.
     * @param {number} [y=x] - The y value to set for this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    set: function (x, y)
    {
        if (y === undefined) { y = x; }

        this.x = x;
        this.y = y;

        return this;
    },

    /**
     * This method is an alias for `Vector2.set`.
     *
     * @method Phaser.Math.Vector2#setTo
     * @since 3.4.0
     *
     * @param {number} x - The x value to set for this Vector.
     * @param {number} [y=x] - The y value to set for this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    setTo: function (x, y)
    {
        return this.set(x, y);
    },

    /**
     * Sets the `x` and `y` values of this object from a given polar coordinate.
     *
     * @method Phaser.Math.Vector2#setToPolar
     * @since 3.0.0
     *
     * @param {number} azimuth - The angular coordinate, in radians.
     * @param {number} [radius=1] - The radial coordinate (length).
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    setToPolar: function (azimuth, radius)
    {
        if (radius == null) { radius = 1; }

        this.x = Math.cos(azimuth) * radius;
        this.y = Math.sin(azimuth) * radius;

        return this;
    },

    /**
     * Check whether this Vector is equal to a given Vector.
     *
     * Performs a strict equality check against each Vector's components.
     *
     * @method Phaser.Math.Vector2#equals
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} v - The vector to compare with this Vector.
     *
     * @return {boolean} Whether the given Vector is equal to this Vector.
     */
    equals: function (v)
    {
        return ((this.x === v.x) && (this.y === v.y));
    },

    /**
     * Check whether this Vector is approximately equal to a given Vector.
     *
     * @method Phaser.Math.Vector2#fuzzyEquals
     * @since 3.23.0
     *
     * @param {Phaser.Types.Math.Vector2Like} v - The vector to compare with this Vector.
     * @param {number} [epsilon=0.0001] - The tolerance value.
     *
     * @return {boolean} Whether both absolute differences of the x and y components are smaller than `epsilon`.
     */
    fuzzyEquals: function (v, epsilon)
    {
        return (FuzzyEqual(this.x, v.x, epsilon) && FuzzyEqual(this.y, v.y, epsilon));
    },

    /**
     * Calculate the angle between this Vector and the positive x-axis, in radians.
     *
     * @method Phaser.Math.Vector2#angle
     * @since 3.0.0
     *
     * @return {number} The angle between this Vector, and the positive x-axis, given in radians.
     */
    angle: function ()
    {
        // computes the angle in radians with respect to the positive x-axis

        var angle = Math.atan2(this.y, this.x);

        if (angle < 0)
        {
            angle += 2 * Math.PI;
        }

        return angle;
    },

    /**
     * Set the angle of this Vector.
     *
     * @method Phaser.Math.Vector2#setAngle
     * @since 3.23.0
     *
     * @param {number} angle - The angle, in radians.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    setAngle: function (angle)
    {
        return this.setToPolar(angle, this.length());
    },

    /**
     * Add a given Vector to this Vector. Addition is component-wise.
     *
     * @method Phaser.Math.Vector2#add
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} src - The Vector to add to this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    add: function (src)
    {
        this.x += src.x;
        this.y += src.y;

        return this;
    },

    /**
     * Subtract the given Vector from this Vector. Subtraction is component-wise.
     *
     * @method Phaser.Math.Vector2#subtract
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} src - The Vector to subtract from this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    subtract: function (src)
    {
        this.x -= src.x;
        this.y -= src.y;

        return this;
    },

    /**
     * Perform a component-wise multiplication between this Vector and the given Vector.
     *
     * Multiplies this Vector by the given Vector.
     *
     * @method Phaser.Math.Vector2#multiply
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} src - The Vector to multiply this Vector by.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    multiply: function (src)
    {
        this.x *= src.x;
        this.y *= src.y;

        return this;
    },

    /**
     * Scale this Vector by the given value.
     *
     * @method Phaser.Math.Vector2#scale
     * @since 3.0.0
     *
     * @param {number} value - The value to scale this Vector by.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    scale: function (value)
    {
        if (isFinite(value))
        {
            this.x *= value;
            this.y *= value;
        }
        else
        {
            this.x = 0;
            this.y = 0;
        }

        return this;
    },

    /**
     * Perform a component-wise division between this Vector and the given Vector.
     *
     * Divides this Vector by the given Vector.
     *
     * @method Phaser.Math.Vector2#divide
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} src - The Vector to divide this Vector by.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    divide: function (src)
    {
        this.x /= src.x;
        this.y /= src.y;

        return this;
    },

    /**
     * Negate the `x` and `y` components of this Vector.
     *
     * @method Phaser.Math.Vector2#negate
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    negate: function ()
    {
        this.x = -this.x;
        this.y = -this.y;

        return this;
    },

    /**
     * Calculate the distance between this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector2#distance
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} src - The Vector to calculate the distance to.
     *
     * @return {number} The distance from this Vector to the given Vector.
     */
    distance: function (src)
    {
        var dx = src.x - this.x;
        var dy = src.y - this.y;

        return Math.sqrt(dx * dx + dy * dy);
    },

    /**
     * Calculate the distance between this Vector and the given Vector, squared.
     *
     * @method Phaser.Math.Vector2#distanceSq
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} src - The Vector to calculate the distance to.
     *
     * @return {number} The distance from this Vector to the given Vector, squared.
     */
    distanceSq: function (src)
    {
        var dx = src.x - this.x;
        var dy = src.y - this.y;

        return dx * dx + dy * dy;
    },

    /**
     * Calculate the length (or magnitude) of this Vector.
     *
     * @method Phaser.Math.Vector2#length
     * @since 3.0.0
     *
     * @return {number} The length of this Vector.
     */
    length: function ()
    {
        var x = this.x;
        var y = this.y;

        return Math.sqrt(x * x + y * y);
    },

    /**
     * Set the length (or magnitude) of this Vector.
     *
     * @method Phaser.Math.Vector2#setLength
     * @since 3.23.0
     *
     * @param {number} length
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    setLength: function (length)
    {
        return this.normalize().scale(length);
    },

    /**
     * Calculate the length of this Vector squared.
     *
     * @method Phaser.Math.Vector2#lengthSq
     * @since 3.0.0
     *
     * @return {number} The length of this Vector, squared.
     */
    lengthSq: function ()
    {
        var x = this.x;
        var y = this.y;

        return x * x + y * y;
    },

    /**
     * Normalize this Vector.
     *
     * Makes the vector a unit length vector (magnitude of 1) in the same direction.
     *
     * @method Phaser.Math.Vector2#normalize
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    normalize: function ()
    {
        var x = this.x;
        var y = this.y;
        var len = x * x + y * y;

        if (len > 0)
        {
            len = 1 / Math.sqrt(len);

            this.x = x * len;
            this.y = y * len;
        }

        return this;
    },

    /**
     * Rotate this Vector to its perpendicular, in the positive direction.
     *
     * @method Phaser.Math.Vector2#normalizeRightHand
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    normalizeRightHand: function ()
    {
        var x = this.x;

        this.x = this.y * -1;
        this.y = x;

        return this;
    },

    /**
     * Rotate this Vector to its perpendicular, in the negative direction.
     *
     * @method Phaser.Math.Vector2#normalizeLeftHand
     * @since 3.23.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    normalizeLeftHand: function ()
    {
        var x = this.x;

        this.x = this.y;
        this.y = x * -1;

        return this;
    },

    /**
     * Calculate the dot product of this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector2#dot
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to dot product with this Vector2.
     *
     * @return {number} The dot product of this Vector and the given Vector.
     */
    dot: function (src)
    {
        return this.x * src.x + this.y * src.y;
    },

    /**
     * Calculate the cross product of this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector2#cross
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to cross with this Vector2.
     *
     * @return {number} The cross product of this Vector and the given Vector.
     */
    cross: function (src)
    {
        return this.x * src.y - this.y * src.x;
    },

    /**
     * Linearly interpolate between this Vector and the given Vector.
     *
     * Interpolates this Vector towards the given Vector.
     *
     * @method Phaser.Math.Vector2#lerp
     * @since 3.0.0
     *
     * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to interpolate towards.
     * @param {number} [t=0] - The interpolation percentage, between 0 and 1.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    lerp: function (src, t)
    {
        if (t === undefined) { t = 0; }

        var ax = this.x;
        var ay = this.y;

        this.x = ax + t * (src.x - ax);
        this.y = ay + t * (src.y - ay);

        return this;
    },

    /**
     * Transform this Vector with the given Matrix.
     *
     * @method Phaser.Math.Vector2#transformMat3
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector2 with.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    transformMat3: function (mat)
    {
        var x = this.x;
        var y = this.y;
        var m = mat.val;

        this.x = m[0] * x + m[3] * y + m[6];
        this.y = m[1] * x + m[4] * y + m[7];

        return this;
    },

    /**
     * Transform this Vector with the given Matrix.
     *
     * @method Phaser.Math.Vector2#transformMat4
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector2 with.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    transformMat4: function (mat)
    {
        var x = this.x;
        var y = this.y;
        var m = mat.val;

        this.x = m[0] * x + m[4] * y + m[12];
        this.y = m[1] * x + m[5] * y + m[13];

        return this;
    },

    /**
     * Make this Vector the zero vector (0, 0).
     *
     * @method Phaser.Math.Vector2#reset
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    reset: function ()
    {
        this.x = 0;
        this.y = 0;

        return this;
    },

    /**
     * Limit the length (or magnitude) of this Vector.
     *
     * @method Phaser.Math.Vector2#limit
     * @since 3.23.0
     *
     * @param {number} max - The maximum length.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    limit: function (max)
    {
        var len = this.length();

        if (len && len > max)
        {
            this.scale(max / len);
        }

        return this;
    },

    /**
     * Reflect this Vector off a line defined by a normal.
     *
     * @method Phaser.Math.Vector2#reflect
     * @since 3.23.0
     *
     * @param {Phaser.Math.Vector2} normal - A vector perpendicular to the line.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    reflect: function (normal)
    {
        normal = normal.clone().normalize();

        return this.subtract(normal.scale(2 * this.dot(normal)));
    },

    /**
     * Reflect this Vector across another.
     *
     * @method Phaser.Math.Vector2#mirror
     * @since 3.23.0
     *
     * @param {Phaser.Math.Vector2} axis - A vector to reflect across.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    mirror: function (axis)
    {
        return this.reflect(axis).negate();
    },

    /**
     * Rotate this Vector by an angle amount.
     *
     * @method Phaser.Math.Vector2#rotate
     * @since 3.23.0
     *
     * @param {number} delta - The angle to rotate by, in radians.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    rotate: function (delta)
    {
        var cos = Math.cos(delta);
        var sin = Math.sin(delta);

        return this.set(cos * this.x - sin * this.y, sin * this.x + cos * this.y);
    },

    /**
     * Project this Vector onto another.
     *
     * @method Phaser.Math.Vector2#project
     * @since 3.60.0
     *
     * @param {Phaser.Math.Vector2} src - The vector to project onto.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    project: function (src)
    {
        var scalar = this.dot(src) / src.dot(src);

        return this.copy(src).scale(scalar);
    }

});

/**
 * A static zero Vector2 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector2.ZERO
 * @type {Phaser.Math.Vector2}
 * @since 3.1.0
 */
Vector2.ZERO = new Vector2();

/**
 * A static right Vector2 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector2.RIGHT
 * @type {Phaser.Math.Vector2}
 * @since 3.16.0
 */
Vector2.RIGHT = new Vector2(1, 0);

/**
 * A static left Vector2 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector2.LEFT
 * @type {Phaser.Math.Vector2}
 * @since 3.16.0
 */
Vector2.LEFT = new Vector2(-1, 0);

/**
 * A static up Vector2 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector2.UP
 * @type {Phaser.Math.Vector2}
 * @since 3.16.0
 */
Vector2.UP = new Vector2(0, -1);

/**
 * A static down Vector2 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector2.DOWN
 * @type {Phaser.Math.Vector2}
 * @since 3.16.0
 */
Vector2.DOWN = new Vector2(0, 1);

/**
 * A static one Vector2 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector2.ONE
 * @type {Phaser.Math.Vector2}
 * @since 3.16.0
 */
Vector2.ONE = new Vector2(1, 1);

module.exports = Vector2;


/***/ }),

/***/ 5689:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

//  Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
//  and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl

var Class = __webpack_require__(7473);

/**
 * @classdesc
 * A representation of a vector in 3D space.
 *
 * A three-component vector.
 *
 * @class Vector3
 * @memberof Phaser.Math
 * @constructor
 * @since 3.0.0
 *
 * @param {number} [x] - The x component.
 * @param {number} [y] - The y component.
 * @param {number} [z] - The z component.
 */
var Vector3 = new Class({

    initialize:

    function Vector3 (x, y, z)
    {
        /**
         * The x component of this Vector.
         *
         * @name Phaser.Math.Vector3#x
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.x = 0;

        /**
         * The y component of this Vector.
         *
         * @name Phaser.Math.Vector3#y
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.y = 0;

        /**
         * The z component of this Vector.
         *
         * @name Phaser.Math.Vector3#z
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.z = 0;

        if (typeof x === 'object')
        {
            this.x = x.x || 0;
            this.y = x.y || 0;
            this.z = x.z || 0;
        }
        else
        {
            this.x = x || 0;
            this.y = y || 0;
            this.z = z || 0;
        }
    },

    /**
     * Set this Vector to point up.
     *
     * Sets the y component of the vector to 1, and the others to 0.
     *
     * @method Phaser.Math.Vector3#up
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    up: function ()
    {
        this.x = 0;
        this.y = 1;
        this.z = 0;

        return this;
    },

    /**
     * Sets the components of this Vector to be the `Math.min` result from the given vector.
     *
     * @method Phaser.Math.Vector3#min
     * @since 3.50.0
     *
     * @param {Phaser.Math.Vector3} v - The Vector3 to check the minimum values against.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    min: function (v)
    {
        this.x = Math.min(this.x, v.x);
        this.y = Math.min(this.y, v.y);
        this.z = Math.min(this.z, v.z);

        return this;
    },

    /**
     * Sets the components of this Vector to be the `Math.max` result from the given vector.
     *
     * @method Phaser.Math.Vector3#max
     * @since 3.50.0
     *
     * @param {Phaser.Math.Vector3} v - The Vector3 to check the maximum values against.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    max: function (v)
    {
        this.x = Math.max(this.x, v.x);
        this.y = Math.max(this.y, v.y);
        this.z = Math.max(this.z, v.z);

        return this;
    },

    /**
     * Make a clone of this Vector3.
     *
     * @method Phaser.Math.Vector3#clone
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector3} A new Vector3 object containing this Vectors values.
     */
    clone: function ()
    {
        return new Vector3(this.x, this.y, this.z);
    },

    /**
     * Adds the two given Vector3s and sets the results into this Vector3.
     *
     * @method Phaser.Math.Vector3#addVectors
     * @since 3.50.0
     *
     * @param {Phaser.Math.Vector3} a - The first Vector to add.
     * @param {Phaser.Math.Vector3} b - The second Vector to add.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    addVectors: function (a, b)
    {
        this.x = a.x + b.x;
        this.y = a.y + b.y;
        this.z = a.z + b.z;

        return this;
    },

    /**
     * Calculate the cross (vector) product of two given Vectors.
     *
     * @method Phaser.Math.Vector3#crossVectors
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector3} a - The first Vector to multiply.
     * @param {Phaser.Math.Vector3} b - The second Vector to multiply.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    crossVectors: function (a, b)
    {
        var ax = a.x;
        var ay = a.y;
        var az = a.z;
        var bx = b.x;
        var by = b.y;
        var bz = b.z;

        this.x = ay * bz - az * by;
        this.y = az * bx - ax * bz;
        this.z = ax * by - ay * bx;

        return this;
    },

    /**
     * Check whether this Vector is equal to a given Vector.
     *
     * Performs a strict equality check against each Vector's components.
     *
     * @method Phaser.Math.Vector3#equals
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector3} v - The Vector3 to compare against.
     *
     * @return {boolean} True if the two vectors strictly match, otherwise false.
     */
    equals: function (v)
    {
        return ((this.x === v.x) && (this.y === v.y) && (this.z === v.z));
    },

    /**
     * Copy the components of a given Vector into this Vector.
     *
     * @method Phaser.Math.Vector3#copy
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} src - The Vector to copy the components from.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    copy: function (src)
    {
        this.x = src.x;
        this.y = src.y;
        this.z = src.z || 0;

        return this;
    },

    /**
     * Set the `x`, `y`, and `z` components of this Vector to the given `x`, `y`, and `z` values.
     *
     * @method Phaser.Math.Vector3#set
     * @since 3.0.0
     *
     * @param {(number|object)} x - The x value to set for this Vector, or an object containing x, y and z components.
     * @param {number} [y] - The y value to set for this Vector.
     * @param {number} [z] - The z value to set for this Vector.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    set: function (x, y, z)
    {
        if (typeof x === 'object')
        {
            this.x = x.x || 0;
            this.y = x.y || 0;
            this.z = x.z || 0;
        }
        else
        {
            this.x = x || 0;
            this.y = y || 0;
            this.z = z || 0;
        }

        return this;
    },

    /**
     * Sets the components of this Vector3 from the position of the given Matrix4.
     *
     * @method Phaser.Math.Vector3#setFromMatrixPosition
     * @since 3.50.0
     *
     * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to get the position from.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    setFromMatrixPosition: function (m)
    {
        return this.fromArray(m.val, 12);
    },

    /**
     * Sets the components of this Vector3 from the Matrix4 column specified.
     *
     * @method Phaser.Math.Vector3#setFromMatrixColumn
     * @since 3.50.0
     *
     * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to get the column from.
     * @param {number} index - The column index.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    setFromMatrixColumn: function (mat4, index)
    {
        return this.fromArray(mat4.val, index * 4);
    },

    /**
     * Sets the components of this Vector3 from the given array, based on the offset.
     *
     * Vector3.x = array[offset]
     * Vector3.y = array[offset + 1]
     * Vector3.z = array[offset + 2]
     *
     * @method Phaser.Math.Vector3#fromArray
     * @since 3.50.0
     *
     * @param {number[]} array - The array of values to get this Vector from.
     * @param {number} [offset=0] - The offset index into the array.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    fromArray: function (array, offset)
    {
        if (offset === undefined) { offset = 0; }

        this.x = array[offset];
        this.y = array[offset + 1];
        this.z = array[offset + 2];

        return this;
    },

    /**
     * Add a given Vector to this Vector. Addition is component-wise.
     *
     * @method Phaser.Math.Vector3#add
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to add to this Vector.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    add: function (v)
    {
        this.x += v.x;
        this.y += v.y;
        this.z += v.z || 0;

        return this;
    },

    /**
     * Add the given value to each component of this Vector.
     *
     * @method Phaser.Math.Vector3#addScalar
     * @since 3.50.0
     *
     * @param {number} s - The amount to add to this Vector.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    addScalar: function (s)
    {
        this.x += s;
        this.y += s;
        this.z += s;

        return this;
    },

    /**
     * Add and scale a given Vector to this Vector. Addition is component-wise.
     *
     * @method Phaser.Math.Vector3#addScale
     * @since 3.50.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to add to this Vector.
     * @param {number} scale - The amount to scale `v` by.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    addScale: function (v, scale)
    {
        this.x += v.x * scale;
        this.y += v.y * scale;
        this.z += v.z * scale || 0;

        return this;
    },

    /**
     * Subtract the given Vector from this Vector. Subtraction is component-wise.
     *
     * @method Phaser.Math.Vector3#subtract
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to subtract from this Vector.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    subtract: function (v)
    {
        this.x -= v.x;
        this.y -= v.y;
        this.z -= v.z || 0;

        return this;
    },

    /**
     * Perform a component-wise multiplication between this Vector and the given Vector.
     *
     * Multiplies this Vector by the given Vector.
     *
     * @method Phaser.Math.Vector3#multiply
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to multiply this Vector by.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    multiply: function (v)
    {
        this.x *= v.x;
        this.y *= v.y;
        this.z *= v.z || 1;

        return this;
    },

    /**
     * Scale this Vector by the given value.
     *
     * @method Phaser.Math.Vector3#scale
     * @since 3.0.0
     *
     * @param {number} scale - The value to scale this Vector by.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    scale: function (scale)
    {
        if (isFinite(scale))
        {
            this.x *= scale;
            this.y *= scale;
            this.z *= scale;
        }
        else
        {
            this.x = 0;
            this.y = 0;
            this.z = 0;
        }

        return this;
    },

    /**
     * Perform a component-wise division between this Vector and the given Vector.
     *
     * Divides this Vector by the given Vector.
     *
     * @method Phaser.Math.Vector3#divide
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to divide this Vector by.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    divide: function (v)
    {
        this.x /= v.x;
        this.y /= v.y;
        this.z /= v.z || 1;

        return this;
    },

    /**
     * Negate the `x`, `y` and `z` components of this Vector.
     *
     * @method Phaser.Math.Vector3#negate
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    negate: function ()
    {
        this.x = -this.x;
        this.y = -this.y;
        this.z = -this.z;

        return this;
    },

    /**
     * Calculate the distance between this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector3#distance
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to calculate the distance to.
     *
     * @return {number} The distance from this Vector to the given Vector.
     */
    distance: function (v)
    {
        var dx = v.x - this.x;
        var dy = v.y - this.y;
        var dz = v.z - this.z || 0;

        return Math.sqrt(dx * dx + dy * dy + dz * dz);
    },

    /**
     * Calculate the distance between this Vector and the given Vector, squared.
     *
     * @method Phaser.Math.Vector3#distanceSq
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to calculate the distance to.
     *
     * @return {number} The distance from this Vector to the given Vector, squared.
     */
    distanceSq: function (v)
    {
        var dx = v.x - this.x;
        var dy = v.y - this.y;
        var dz = v.z - this.z || 0;

        return dx * dx + dy * dy + dz * dz;
    },

    /**
     * Calculate the length (or magnitude) of this Vector.
     *
     * @method Phaser.Math.Vector3#length
     * @since 3.0.0
     *
     * @return {number} The length of this Vector.
     */
    length: function ()
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;

        return Math.sqrt(x * x + y * y + z * z);
    },

    /**
     * Calculate the length of this Vector squared.
     *
     * @method Phaser.Math.Vector3#lengthSq
     * @since 3.0.0
     *
     * @return {number} The length of this Vector, squared.
     */
    lengthSq: function ()
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;

        return x * x + y * y + z * z;
    },

    /**
     * Normalize this Vector.
     *
     * Makes the vector a unit length vector (magnitude of 1) in the same direction.
     *
     * @method Phaser.Math.Vector3#normalize
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    normalize: function ()
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var len = x * x + y * y + z * z;

        if (len > 0)
        {
            len = 1 / Math.sqrt(len);

            this.x = x * len;
            this.y = y * len;
            this.z = z * len;
        }

        return this;
    },

    /**
     * Calculate the dot product of this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector3#dot
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector3} v - The Vector3 to dot product with this Vector3.
     *
     * @return {number} The dot product of this Vector and `v`.
     */
    dot: function (v)
    {
        return this.x * v.x + this.y * v.y + this.z * v.z;
    },

    /**
     * Calculate the cross (vector) product of this Vector (which will be modified) and the given Vector.
     *
     * @method Phaser.Math.Vector3#cross
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector3} v - The Vector to cross product with.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    cross: function (v)
    {
        var ax = this.x;
        var ay = this.y;
        var az = this.z;
        var bx = v.x;
        var by = v.y;
        var bz = v.z;

        this.x = ay * bz - az * by;
        this.y = az * bx - ax * bz;
        this.z = ax * by - ay * bx;

        return this;
    },

    /**
     * Linearly interpolate between this Vector and the given Vector.
     *
     * Interpolates this Vector towards the given Vector.
     *
     * @method Phaser.Math.Vector3#lerp
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector3} v - The Vector3 to interpolate towards.
     * @param {number} [t=0] - The interpolation percentage, between 0 and 1.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    lerp: function (v, t)
    {
        if (t === undefined) { t = 0; }

        var ax = this.x;
        var ay = this.y;
        var az = this.z;

        this.x = ax + t * (v.x - ax);
        this.y = ay + t * (v.y - ay);
        this.z = az + t * (v.z - az);

        return this;
    },

    /**
     * Takes a Matrix3 and applies it to this Vector3.
     *
     * @method Phaser.Math.Vector3#applyMatrix3
     * @since 3.50.0
     *
     * @param {Phaser.Math.Matrix3} mat3 - The Matrix3 to apply to this Vector3.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    applyMatrix3: function (mat3)
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var m = mat3.val;

        this.x = m[0] * x + m[3] * y + m[6] * z;
        this.y = m[1] * x + m[4] * y + m[7] * z;
        this.z = m[2] * x + m[5] * y + m[8] * z;

        return this;
    },

    /**
     * Takes a Matrix4 and applies it to this Vector3.
     *
     * @method Phaser.Math.Vector3#applyMatrix4
     * @since 3.50.0
     *
     * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to apply to this Vector3.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    applyMatrix4: function (mat4)
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var m = mat4.val;

        var w = 1 / (m[3] * x + m[7] * y + m[11] * z + m[15]);

        this.x = (m[0] * x + m[4] * y + m[8] * z + m[12]) * w;
        this.y = (m[1] * x + m[5] * y + m[9] * z + m[13]) * w;
        this.z = (m[2] * x + m[6] * y + m[10] * z + m[14]) * w;

        return this;
    },

    /**
     * Transform this Vector with the given Matrix.
     *
     * @method Phaser.Math.Vector3#transformMat3
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector3 with.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    transformMat3: function (mat)
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var m = mat.val;

        this.x = x * m[0] + y * m[3] + z * m[6];
        this.y = x * m[1] + y * m[4] + z * m[7];
        this.z = x * m[2] + y * m[5] + z * m[8];

        return this;
    },

    /**
     * Transform this Vector with the given Matrix4.
     *
     * @method Phaser.Math.Vector3#transformMat4
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector3 with.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    transformMat4: function (mat)
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var m = mat.val;

        this.x = m[0] * x + m[4] * y + m[8] * z + m[12];
        this.y = m[1] * x + m[5] * y + m[9] * z + m[13];
        this.z = m[2] * x + m[6] * y + m[10] * z + m[14];

        return this;
    },

    /**
     * Transforms the coordinates of this Vector3 with the given Matrix4.
     *
     * @method Phaser.Math.Vector3#transformCoordinates
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector3 with.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    transformCoordinates: function (mat)
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var m = mat.val;

        var tx = (x * m[0]) + (y * m[4]) + (z * m[8]) + m[12];
        var ty = (x * m[1]) + (y * m[5]) + (z * m[9]) + m[13];
        var tz = (x * m[2]) + (y * m[6]) + (z * m[10]) + m[14];
        var tw = (x * m[3]) + (y * m[7]) + (z * m[11]) + m[15];

        this.x = tx / tw;
        this.y = ty / tw;
        this.z = tz / tw;

        return this;
    },

    /**
     * Transform this Vector with the given Quaternion.
     *
     * @method Phaser.Math.Vector3#transformQuat
     * @since 3.0.0
     *
     * @param {Phaser.Math.Quaternion} q - The Quaternion to transform this Vector with.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    transformQuat: function (q)
    {
        // benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var qx = q.x;
        var qy = q.y;
        var qz = q.z;
        var qw = q.w;

        // calculate quat * vec
        var ix = qw * x + qy * z - qz * y;
        var iy = qw * y + qz * x - qx * z;
        var iz = qw * z + qx * y - qy * x;
        var iw = -qx * x - qy * y - qz * z;

        // calculate result * inverse quat
        this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
        this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
        this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;

        return this;
    },

    /**
     * Multiplies this Vector3 by the specified matrix, applying a W divide. This is useful for projection,
     * e.g. unprojecting a 2D point into 3D space.
     *
     * @method Phaser.Math.Vector3#project
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} mat - The Matrix4 to multiply this Vector3 with.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    project: function (mat)
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var m = mat.val;

        var a00 = m[0];
        var a01 = m[1];
        var a02 = m[2];
        var a03 = m[3];
        var a10 = m[4];
        var a11 = m[5];
        var a12 = m[6];
        var a13 = m[7];
        var a20 = m[8];
        var a21 = m[9];
        var a22 = m[10];
        var a23 = m[11];
        var a30 = m[12];
        var a31 = m[13];
        var a32 = m[14];
        var a33 = m[15];

        var lw = 1 / (x * a03 + y * a13 + z * a23 + a33);

        this.x = (x * a00 + y * a10 + z * a20 + a30) * lw;
        this.y = (x * a01 + y * a11 + z * a21 + a31) * lw;
        this.z = (x * a02 + y * a12 + z * a22 + a32) * lw;

        return this;
    },

    /**
     * Multiplies this Vector3 by the given view and projection matrices.
     *
     * @method Phaser.Math.Vector3#projectViewMatrix
     * @since 3.50.0
     *
     * @param {Phaser.Math.Matrix4} viewMatrix - A View Matrix.
     * @param {Phaser.Math.Matrix4} projectionMatrix - A Projection Matrix.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    projectViewMatrix: function (viewMatrix, projectionMatrix)
    {
        return this.applyMatrix4(viewMatrix).applyMatrix4(projectionMatrix);
    },

    /**
     * Multiplies this Vector3 by the given inversed projection matrix and world matrix.
     *
     * @method Phaser.Math.Vector3#unprojectViewMatrix
     * @since 3.50.0
     *
     * @param {Phaser.Math.Matrix4} projectionMatrix - An inversed Projection Matrix.
     * @param {Phaser.Math.Matrix4} worldMatrix - A World View Matrix.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    unprojectViewMatrix: function (projectionMatrix, worldMatrix)
    {
        return this.applyMatrix4(projectionMatrix).applyMatrix4(worldMatrix);
    },

    /**
     * Unproject this point from 2D space to 3D space.
     * The point should have its x and y properties set to
     * 2D screen space, and the z either at 0 (near plane)
     * or 1 (far plane). The provided matrix is assumed to already
     * be combined, i.e. projection * view * model.
     *
     * After this operation, this vector's (x, y, z) components will
     * represent the unprojected 3D coordinate.
     *
     * @method Phaser.Math.Vector3#unproject
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector4} viewport - Screen x, y, width and height in pixels.
     * @param {Phaser.Math.Matrix4} invProjectionView - Combined projection and view matrix.
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    unproject: function (viewport, invProjectionView)
    {
        var viewX = viewport.x;
        var viewY = viewport.y;
        var viewWidth = viewport.z;
        var viewHeight = viewport.w;

        var x = this.x - viewX;
        var y = (viewHeight - this.y - 1) - viewY;
        var z = this.z;

        this.x = (2 * x) / viewWidth - 1;
        this.y = (2 * y) / viewHeight - 1;
        this.z = 2 * z - 1;

        return this.project(invProjectionView);
    },

    /**
     * Make this Vector the zero vector (0, 0, 0).
     *
     * @method Phaser.Math.Vector3#reset
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector3} This Vector3.
     */
    reset: function ()
    {
        this.x = 0;
        this.y = 0;
        this.z = 0;

        return this;
    }

});

/**
 * A static zero Vector3 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector3.ZERO
 * @type {Phaser.Math.Vector3}
 * @since 3.16.0
 */
Vector3.ZERO = new Vector3();

/**
 * A static right Vector3 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector3.RIGHT
 * @type {Phaser.Math.Vector3}
 * @since 3.16.0
 */
Vector3.RIGHT = new Vector3(1, 0, 0);

/**
 * A static left Vector3 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector3.LEFT
 * @type {Phaser.Math.Vector3}
 * @since 3.16.0
 */
Vector3.LEFT = new Vector3(-1, 0, 0);

/**
 * A static up Vector3 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector3.UP
 * @type {Phaser.Math.Vector3}
 * @since 3.16.0
 */
Vector3.UP = new Vector3(0, -1, 0);

/**
 * A static down Vector3 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector3.DOWN
 * @type {Phaser.Math.Vector3}
 * @since 3.16.0
 */
Vector3.DOWN = new Vector3(0, 1, 0);

/**
 * A static forward Vector3 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector3.FORWARD
 * @type {Phaser.Math.Vector3}
 * @since 3.16.0
 */
Vector3.FORWARD = new Vector3(0, 0, 1);

/**
 * A static back Vector3 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector3.BACK
 * @type {Phaser.Math.Vector3}
 * @since 3.16.0
 */
Vector3.BACK = new Vector3(0, 0, -1);

/**
 * A static one Vector3 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector3.ONE
 * @type {Phaser.Math.Vector3}
 * @since 3.16.0
 */
Vector3.ONE = new Vector3(1, 1, 1);

module.exports = Vector3;


/***/ }),

/***/ 9279:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

//  Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
//  and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl

var Class = __webpack_require__(7473);

/**
 * @classdesc
 * A representation of a vector in 4D space.
 *
 * A four-component vector.
 *
 * @class Vector4
 * @memberof Phaser.Math
 * @constructor
 * @since 3.0.0
 *
 * @param {number} [x] - The x component.
 * @param {number} [y] - The y component.
 * @param {number} [z] - The z component.
 * @param {number} [w] - The w component.
 */
var Vector4 = new Class({

    initialize:

    function Vector4 (x, y, z, w)
    {
        /**
         * The x component of this Vector.
         *
         * @name Phaser.Math.Vector4#x
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.x = 0;

        /**
         * The y component of this Vector.
         *
         * @name Phaser.Math.Vector4#y
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.y = 0;

        /**
         * The z component of this Vector.
         *
         * @name Phaser.Math.Vector4#z
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.z = 0;

        /**
         * The w component of this Vector.
         *
         * @name Phaser.Math.Vector4#w
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.w = 0;

        if (typeof x === 'object')
        {
            this.x = x.x || 0;
            this.y = x.y || 0;
            this.z = x.z || 0;
            this.w = x.w || 0;
        }
        else
        {
            this.x = x || 0;
            this.y = y || 0;
            this.z = z || 0;
            this.w = w || 0;
        }
    },

    /**
     * Make a clone of this Vector4.
     *
     * @method Phaser.Math.Vector4#clone
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector4} A clone of this Vector4.
     */
    clone: function ()
    {
        return new Vector4(this.x, this.y, this.z, this.w);
    },

    /**
     * Copy the components of a given Vector into this Vector.
     *
     * @method Phaser.Math.Vector4#copy
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector4} src - The Vector to copy the components from.
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    copy: function (src)
    {
        this.x = src.x;
        this.y = src.y;
        this.z = src.z || 0;
        this.w = src.w || 0;

        return this;
    },

    /**
     * Check whether this Vector is equal to a given Vector.
     *
     * Performs a strict quality check against each Vector's components.
     *
     * @method Phaser.Math.Vector4#equals
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector4} v - The vector to check equality with.
     *
     * @return {boolean} A boolean indicating whether the two Vectors are equal or not.
     */
    equals: function (v)
    {
        return ((this.x === v.x) && (this.y === v.y) && (this.z === v.z) && (this.w === v.w));
    },

    /**
     * Set the `x`, `y`, `z` and `w` components of the this Vector to the given `x`, `y`, `z` and `w` values.
     *
     * @method Phaser.Math.Vector4#set
     * @since 3.0.0
     *
     * @param {(number|object)} x - The x value to set for this Vector, or an object containing x, y, z and w components.
     * @param {number} y - The y value to set for this Vector.
     * @param {number} z - The z value to set for this Vector.
     * @param {number} w - The z value to set for this Vector.
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    set: function (x, y, z, w)
    {
        if (typeof x === 'object')
        {
            this.x = x.x || 0;
            this.y = x.y || 0;
            this.z = x.z || 0;
            this.w = x.w || 0;
        }
        else
        {
            this.x = x || 0;
            this.y = y || 0;
            this.z = z || 0;
            this.w = w || 0;
        }

        return this;
    },

    /**
     * Add a given Vector to this Vector. Addition is component-wise.
     *
     * @method Phaser.Math.Vector4#add
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to add to this Vector.
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    add: function (v)
    {
        this.x += v.x;
        this.y += v.y;
        this.z += v.z || 0;
        this.w += v.w || 0;

        return this;
    },

    /**
     * Subtract the given Vector from this Vector. Subtraction is component-wise.
     *
     * @method Phaser.Math.Vector4#subtract
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to subtract from this Vector.
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    subtract: function (v)
    {
        this.x -= v.x;
        this.y -= v.y;
        this.z -= v.z || 0;
        this.w -= v.w || 0;

        return this;
    },

    /**
     * Scale this Vector by the given value.
     *
     * @method Phaser.Math.Vector4#scale
     * @since 3.0.0
     *
     * @param {number} scale - The value to scale this Vector by.
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    scale: function (scale)
    {
        this.x *= scale;
        this.y *= scale;
        this.z *= scale;
        this.w *= scale;

        return this;
    },

    /**
     * Calculate the length (or magnitude) of this Vector.
     *
     * @method Phaser.Math.Vector4#length
     * @since 3.0.0
     *
     * @return {number} The length of this Vector.
     */
    length: function ()
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var w = this.w;

        return Math.sqrt(x * x + y * y + z * z + w * w);
    },

    /**
     * Calculate the length of this Vector squared.
     *
     * @method Phaser.Math.Vector4#lengthSq
     * @since 3.0.0
     *
     * @return {number} The length of this Vector, squared.
     */
    lengthSq: function ()
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var w = this.w;

        return x * x + y * y + z * z + w * w;
    },

    /**
     * Normalize this Vector.
     *
     * Makes the vector a unit length vector (magnitude of 1) in the same direction.
     *
     * @method Phaser.Math.Vector4#normalize
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    normalize: function ()
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var w = this.w;
        var len = x * x + y * y + z * z + w * w;

        if (len > 0)
        {
            len = 1 / Math.sqrt(len);

            this.x = x * len;
            this.y = y * len;
            this.z = z * len;
            this.w = w * len;
        }

        return this;
    },

    /**
     * Calculate the dot product of this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector4#dot
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector4} v - The Vector4 to dot product with this Vector4.
     *
     * @return {number} The dot product of this Vector and the given Vector.
     */
    dot: function (v)
    {
        return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
    },

    /**
     * Linearly interpolate between this Vector and the given Vector.
     *
     * Interpolates this Vector towards the given Vector.
     *
     * @method Phaser.Math.Vector4#lerp
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector4} v - The Vector4 to interpolate towards.
     * @param {number} [t=0] - The interpolation percentage, between 0 and 1.
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    lerp: function (v, t)
    {
        if (t === undefined) { t = 0; }

        var ax = this.x;
        var ay = this.y;
        var az = this.z;
        var aw = this.w;

        this.x = ax + t * (v.x - ax);
        this.y = ay + t * (v.y - ay);
        this.z = az + t * (v.z - az);
        this.w = aw + t * (v.w - aw);

        return this;
    },

    /**
     * Perform a component-wise multiplication between this Vector and the given Vector.
     *
     * Multiplies this Vector by the given Vector.
     *
     * @method Phaser.Math.Vector4#multiply
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to multiply this Vector by.
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    multiply: function (v)
    {
        this.x *= v.x;
        this.y *= v.y;
        this.z *= v.z || 1;
        this.w *= v.w || 1;

        return this;
    },

    /**
     * Perform a component-wise division between this Vector and the given Vector.
     *
     * Divides this Vector by the given Vector.
     *
     * @method Phaser.Math.Vector4#divide
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to divide this Vector by.
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    divide: function (v)
    {
        this.x /= v.x;
        this.y /= v.y;
        this.z /= v.z || 1;
        this.w /= v.w || 1;

        return this;
    },

    /**
     * Calculate the distance between this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector4#distance
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to calculate the distance to.
     *
     * @return {number} The distance from this Vector to the given Vector.
     */
    distance: function (v)
    {
        var dx = v.x - this.x;
        var dy = v.y - this.y;
        var dz = v.z - this.z || 0;
        var dw = v.w - this.w || 0;

        return Math.sqrt(dx * dx + dy * dy + dz * dz + dw * dw);
    },

    /**
     * Calculate the distance between this Vector and the given Vector, squared.
     *
     * @method Phaser.Math.Vector4#distanceSq
     * @since 3.0.0
     *
     * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to calculate the distance to.
     *
     * @return {number} The distance from this Vector to the given Vector, squared.
     */
    distanceSq: function (v)
    {
        var dx = v.x - this.x;
        var dy = v.y - this.y;
        var dz = v.z - this.z || 0;
        var dw = v.w - this.w || 0;

        return dx * dx + dy * dy + dz * dz + dw * dw;
    },

    /**
     * Negate the `x`, `y`, `z` and `w` components of this Vector.
     *
     * @method Phaser.Math.Vector4#negate
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    negate: function ()
    {
        this.x = -this.x;
        this.y = -this.y;
        this.z = -this.z;
        this.w = -this.w;

        return this;
    },

    /**
     * Transform this Vector with the given Matrix.
     *
     * @method Phaser.Math.Vector4#transformMat4
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector4 with.
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    transformMat4: function (mat)
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var w = this.w;
        var m = mat.val;

        this.x = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
        this.y = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
        this.z = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
        this.w = m[3] * x + m[7] * y + m[11] * z + m[15] * w;

        return this;
    },

    /**
     * Transform this Vector with the given Quaternion.
     *
     * @method Phaser.Math.Vector4#transformQuat
     * @since 3.0.0
     *
     * @param {Phaser.Math.Quaternion} q - The Quaternion to transform this Vector with.
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    transformQuat: function (q)
    {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var qx = q.x;
        var qy = q.y;
        var qz = q.z;
        var qw = q.w;

        // calculate quat * vec
        var ix = qw * x + qy * z - qz * y;
        var iy = qw * y + qz * x - qx * z;
        var iz = qw * z + qx * y - qy * x;
        var iw = -qx * x - qy * y - qz * z;

        // calculate result * inverse quat
        this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
        this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
        this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;

        return this;
    },

    /**
     * Make this Vector the zero vector (0, 0, 0, 0).
     *
     * @method Phaser.Math.Vector4#reset
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector4} This Vector4.
     */
    reset: function ()
    {
        this.x = 0;
        this.y = 0;
        this.z = 0;
        this.w = 0;

        return this;
    }

});

Vector4.prototype.sub = Vector4.prototype.subtract;
Vector4.prototype.mul = Vector4.prototype.multiply;
Vector4.prototype.div = Vector4.prototype.divide;
Vector4.prototype.dist = Vector4.prototype.distance;
Vector4.prototype.distSq = Vector4.prototype.distanceSq;
Vector4.prototype.len = Vector4.prototype.length;
Vector4.prototype.lenSq = Vector4.prototype.lengthSq;

module.exports = Vector4;


/***/ }),

/***/ 4119:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Checks if the two values are within the given `tolerance` of each other.
 *
 * @function Phaser.Math.Within
 * @since 3.0.0
 *
 * @param {number} a - The first value to use in the calculation.
 * @param {number} b - The second value to use in the calculation.
 * @param {number} tolerance - The tolerance. Anything equal to or less than this value is considered as being within range.
 *
 * @return {boolean} Returns `true` if `a` is less than or equal to the tolerance of `b`.
 */
var Within = function (a, b, tolerance)
{
    return (Math.abs(a - b) <= tolerance);
};

module.exports = Within;


/***/ }),

/***/ 8445:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Wrap the given `value` between `min` and `max`.
 *
 * @function Phaser.Math.Wrap
 * @since 3.0.0
 *
 * @param {number} value - The value to wrap.
 * @param {number} min - The minimum value.
 * @param {number} max - The maximum value.
 *
 * @return {number} The wrapped value.
 */
var Wrap = function (value, min, max)
{
    var range = max - min;

    return (min + ((((value - min) % range) + range) % range));
};

module.exports = Wrap;


/***/ }),

/***/ 6412:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Find the angle of a segment from (x1, y1) -> (x2, y2).
 *
 * @function Phaser.Math.Angle.Between
 * @since 3.0.0
 *
 * @param {number} x1 - The x coordinate of the first point.
 * @param {number} y1 - The y coordinate of the first point.
 * @param {number} x2 - The x coordinate of the second point.
 * @param {number} y2 - The y coordinate of the second point.
 *
 * @return {number} The angle in radians.
 */
var Between = function (x1, y1, x2, y2)
{
    return Math.atan2(y2 - y1, x2 - x1);
};

module.exports = Between;


/***/ }),

/***/ 760:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Find the angle of a segment from (point1.x, point1.y) -> (point2.x, point2.y).
 *
 * Calculates the angle of the vector from the first point to the second point.
 *
 * @function Phaser.Math.Angle.BetweenPoints
 * @since 3.0.0
 *
 * @param {Phaser.Types.Math.Vector2Like} point1 - The first point.
 * @param {Phaser.Types.Math.Vector2Like} point2 - The second point.
 *
 * @return {number} The angle in radians.
 */
var BetweenPoints = function (point1, point2)
{
    return Math.atan2(point2.y - point1.y, point2.x - point1.x);
};

module.exports = BetweenPoints;


/***/ }),

/***/ 6909:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Find the angle of a segment from (point1.x, point1.y) -> (point2.x, point2.y).
 *
 * The difference between this method and {@link Phaser.Math.Angle.BetweenPoints} is that this assumes the y coordinate
 * travels down the screen.
 *
 * @function Phaser.Math.Angle.BetweenPointsY
 * @since 3.0.0
 *
 * @param {Phaser.Types.Math.Vector2Like} point1 - The first point.
 * @param {Phaser.Types.Math.Vector2Like} point2 - The second point.
 *
 * @return {number} The angle in radians.
 */
var BetweenPointsY = function (point1, point2)
{
    return Math.atan2(point2.x - point1.x, point2.y - point1.y);
};

module.exports = BetweenPointsY;


/***/ }),

/***/ 6947:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Find the angle of a segment from (x1, y1) -> (x2, y2).
 *
 * The difference between this method and {@link Phaser.Math.Angle.Between} is that this assumes the y coordinate
 * travels down the screen.
 *
 * @function Phaser.Math.Angle.BetweenY
 * @since 3.0.0
 *
 * @param {number} x1 - The x coordinate of the first point.
 * @param {number} y1 - The y coordinate of the first point.
 * @param {number} x2 - The x coordinate of the second point.
 * @param {number} y2 - The y coordinate of the second point.
 *
 * @return {number} The angle in radians.
 */
var BetweenY = function (x1, y1, x2, y2)
{
    return Math.atan2(x2 - x1, y2 - y1);
};

module.exports = BetweenY;


/***/ }),

/***/ 3426:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var CONST = __webpack_require__(7425);

/**
 * Takes an angle in Phasers default clockwise format and converts it so that
 * 0 is North, 90 is West, 180 is South and 270 is East,
 * therefore running counter-clockwise instead of clockwise.
 * 
 * You can pass in the angle from a Game Object using:
 * 
 * ```javascript
 * var converted = CounterClockwise(gameobject.rotation);
 * ```
 * 
 * All values for this function are in radians.
 *
 * @function Phaser.Math.Angle.CounterClockwise
 * @since 3.16.0
 *
 * @param {number} angle - The angle to convert, in radians.
 *
 * @return {number} The converted angle, in radians.
 */
var CounterClockwise = function (angle)
{
    if (angle > Math.PI)
    {
        angle -= CONST.PI2;
    }

    return Math.abs((((angle + CONST.TAU) % CONST.PI2) - CONST.PI2) % CONST.PI2);
};

module.exports = CounterClockwise;


/***/ }),

/***/ 6906:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Normalize an angle to the [0, 2pi] range.
 *
 * @function Phaser.Math.Angle.Normalize
 * @since 3.0.0
 *
 * @param {number} angle - The angle to normalize, in radians.
 *
 * @return {number} The normalized angle, in radians.
 */
var Normalize = function (angle)
{
    angle = angle % (2 * Math.PI);

    if (angle >= 0)
    {
        return angle;
    }
    else
    {
        return angle + 2 * Math.PI;
    }
};

module.exports = Normalize;


/***/ }),

/***/ 3270:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       @samme
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var FloatBetween = __webpack_require__(104);

/**
 * Returns a random angle in the range [-pi, pi].
 *
 * @function Phaser.Math.Angle.Random
 * @since 3.23.0
 *
 * @return {number} The angle, in radians.
 */
var Random = function ()
{
    return FloatBetween(-Math.PI, Math.PI);
};

module.exports = Random;


/***/ }),

/***/ 2748:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       @samme
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var FloatBetween = __webpack_require__(104);

/**
 * Returns a random angle in the range [-180, 180].
 *
 * @function Phaser.Math.Angle.RandomDegrees
 * @since 3.23.0
 *
 * @return {number} The angle, in degrees.
 */
var RandomDegrees = function ()
{
    return FloatBetween(-180, 180);
};

module.exports = RandomDegrees;


/***/ }),

/***/ 936:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Normalize = __webpack_require__(6906);

/**
 * Reverse the given angle.
 *
 * @function Phaser.Math.Angle.Reverse
 * @since 3.0.0
 *
 * @param {number} angle - The angle to reverse, in radians.
 *
 * @return {number} The reversed angle, in radians.
 */
var Reverse = function (angle)
{
    return Normalize(angle + Math.PI);
};

module.exports = Reverse;


/***/ }),

/***/ 1935:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var MATH_CONST = __webpack_require__(7425);

/**
 * Rotates `currentAngle` towards `targetAngle`, taking the shortest rotation distance. The `lerp` argument is the amount to rotate by in this call.
 *
 * @function Phaser.Math.Angle.RotateTo
 * @since 3.0.0
 *
 * @param {number} currentAngle - The current angle, in radians.
 * @param {number} targetAngle - The target angle to rotate to, in radians.
 * @param {number} [lerp=0.05] - The lerp value to add to the current angle.
 *
 * @return {number} The adjusted angle.
 */
var RotateTo = function (currentAngle, targetAngle, lerp)
{
    if (lerp === undefined) { lerp = 0.05; }

    if (currentAngle === targetAngle)
    {
        return currentAngle;
    }

    if (Math.abs(targetAngle - currentAngle) <= lerp || Math.abs(targetAngle - currentAngle) >= (MATH_CONST.PI2 - lerp))
    {
        currentAngle = targetAngle;
    }
    else
    {
        if (Math.abs(targetAngle - currentAngle) > Math.PI)
        {
            if (targetAngle < currentAngle)
            {
                targetAngle += MATH_CONST.PI2;
            }
            else
            {
                targetAngle -= MATH_CONST.PI2;
            }
        }

        if (targetAngle > currentAngle)
        {
            currentAngle += lerp;
        }
        else if (targetAngle < currentAngle)
        {
            currentAngle -= lerp;
        }
    }

    return currentAngle;
};

module.exports = RotateTo;


/***/ }),

/***/ 5393:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Gets the shortest angle between `angle1` and `angle2`.
 *
 * Both angles must be in the range -180 to 180, which is the same clamped
 * range that `sprite.angle` uses, so you can pass in two sprite angles to
 * this method and get the shortest angle back between the two of them.
 *
 * The angle returned will be in the same range. If the returned angle is
 * greater than 0 then it's a counter-clockwise rotation, if < 0 then it's
 * a clockwise rotation.
 *
 * @function Phaser.Math.Angle.ShortestBetween
 * @since 3.0.0
 *
 * @param {number} angle1 - The first angle in the range -180 to 180.
 * @param {number} angle2 - The second angle in the range -180 to 180.
 *
 * @return {number} The shortest angle, in degrees. If greater than zero it's a counter-clockwise rotation.
 */
var ShortestBetween = function (angle1, angle2)
{
    var difference = angle2 - angle1;

    if (difference === 0)
    {
        return 0;
    }

    var times = Math.floor((difference - (-180)) / 360);

    return difference - (times * 360);

};

module.exports = ShortestBetween;


/***/ }),

/***/ 3692:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var MathWrap = __webpack_require__(8445);

/**
 * Wrap an angle.
 *
 * Wraps the angle to a value in the range of -PI to PI.
 *
 * @function Phaser.Math.Angle.Wrap
 * @since 3.0.0
 *
 * @param {number} angle - The angle to wrap, in radians.
 *
 * @return {number} The wrapped angle, in radians.
 */
var Wrap = function (angle)
{
    return MathWrap(angle, -Math.PI, Math.PI);
};

module.exports = Wrap;


/***/ }),

/***/ 2820:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Wrap = __webpack_require__(8445);

/**
 * Wrap an angle in degrees.
 *
 * Wraps the angle to a value in the range of -180 to 180.
 *
 * @function Phaser.Math.Angle.WrapDegrees
 * @since 3.0.0
 *
 * @param {number} angle - The angle to wrap, in degrees.
 *
 * @return {number} The wrapped angle, in degrees.
 */
var WrapDegrees = function (angle)
{
    return Wrap(angle, -180, 180);
};

module.exports = WrapDegrees;


/***/ }),

/***/ 1833:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Angle
 */

module.exports = {

    Between: __webpack_require__(6412),
    BetweenPoints: __webpack_require__(760),
    BetweenPointsY: __webpack_require__(6909),
    BetweenY: __webpack_require__(6947),
    CounterClockwise: __webpack_require__(3426),
    Normalize: __webpack_require__(6906),
    Random: __webpack_require__(3270),
    RandomDegrees: __webpack_require__(2748),
    Reverse: __webpack_require__(936),
    RotateTo: __webpack_require__(1935),
    ShortestBetween: __webpack_require__(5393),
    Wrap: __webpack_require__(3692),
    WrapDegrees: __webpack_require__(2820)

};


/***/ }),

/***/ 7425:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var MATH_CONST = {

    /**
     * The value of PI * 2.
     *
     * @name Phaser.Math.PI2
     * @type {number}
     * @since 3.0.0
     */
    PI2: Math.PI * 2,

    /**
     * The value of PI * 0.5.
     *
     * Yes, we understand that this should actually be PI * 2, but
     * it has been like this for so long we can't change it now.
     * If you need PI * 2, use the PI2 constant instead.
     *
     * @name Phaser.Math.TAU
     * @type {number}
     * @since 3.0.0
     */
    TAU: Math.PI * 0.5,

    /**
     * An epsilon value (1.0e-6)
     *
     * @name Phaser.Math.EPSILON
     * @type {number}
     * @since 3.0.0
     */
    EPSILON: 1.0e-6,

    /**
     * For converting degrees to radians (PI / 180)
     *
     * @name Phaser.Math.DEG_TO_RAD
     * @type {number}
     * @since 3.0.0
     */
    DEG_TO_RAD: Math.PI / 180,

    /**
     * For converting radians to degrees (180 / PI)
     *
     * @name Phaser.Math.RAD_TO_DEG
     * @type {number}
     * @since 3.0.0
     */
    RAD_TO_DEG: 180 / Math.PI,

    /**
     * An instance of the Random Number Generator.
     * This is not set until the Game boots.
     *
     * @name Phaser.Math.RND
     * @type {Phaser.Math.RandomDataGenerator}
     * @since 3.0.0
     */
    RND: null,

    /**
     * The minimum safe integer this browser supports.
     * We use a const for backward compatibility with Internet Explorer.
     *
     * @name Phaser.Math.MIN_SAFE_INTEGER
     * @type {number}
     * @since 3.21.0
     */
    MIN_SAFE_INTEGER: Number.MIN_SAFE_INTEGER || -9007199254740991,

    /**
     * The maximum safe integer this browser supports.
     * We use a const for backward compatibility with Internet Explorer.
     *
     * @name Phaser.Math.MAX_SAFE_INTEGER
     * @type {number}
     * @since 3.21.0
     */
    MAX_SAFE_INTEGER: Number.MAX_SAFE_INTEGER || 9007199254740991

};

module.exports = MATH_CONST;


/***/ }),

/***/ 1518:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the distance between two sets of coordinates (points).
 *
 * @function Phaser.Math.Distance.Between
 * @since 3.0.0
 *
 * @param {number} x1 - The x coordinate of the first point.
 * @param {number} y1 - The y coordinate of the first point.
 * @param {number} x2 - The x coordinate of the second point.
 * @param {number} y2 - The y coordinate of the second point.
 *
 * @return {number} The distance between each point.
 */
var DistanceBetween = function (x1, y1, x2, y2)
{
    var dx = x1 - x2;
    var dy = y1 - y2;

    return Math.sqrt(dx * dx + dy * dy);
};

module.exports = DistanceBetween;


/***/ }),

/***/ 5372:
/***/ ((module) => {

/**
 * @author       samme
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the distance between two points.
 *
 * @function Phaser.Math.Distance.BetweenPoints
 * @since 3.22.0
 *
 * @param {Phaser.Types.Math.Vector2Like} a - The first point.
 * @param {Phaser.Types.Math.Vector2Like} b - The second point.
 *
 * @return {number} The distance between the points.
 */
var DistanceBetweenPoints = function (a, b)
{
    var dx = a.x - b.x;
    var dy = a.y - b.y;

    return Math.sqrt(dx * dx + dy * dy);
};

module.exports = DistanceBetweenPoints;


/***/ }),

/***/ 4430:
/***/ ((module) => {

/**
 * @author       samme
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the squared distance between two points.
 *
 * @function Phaser.Math.Distance.BetweenPointsSquared
 * @since 3.22.0
 *
 * @param {Phaser.Types.Math.Vector2Like} a - The first point.
 * @param {Phaser.Types.Math.Vector2Like} b - The second point.
 *
 * @return {number} The squared distance between the points.
 */
var DistanceBetweenPointsSquared = function (a, b)
{
    var dx = a.x - b.x;
    var dy = a.y - b.y;

    return dx * dx + dy * dy;
};

module.exports = DistanceBetweenPointsSquared;


/***/ }),

/***/ 4361:
/***/ ((module) => {

/**
 * @author       samme
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the Chebyshev distance between two sets of coordinates (points).
 *
 * Chebyshev distance (or chessboard distance) is the maximum of the horizontal and vertical distances.
 * It's the effective distance when movement can be horizontal, vertical, or diagonal.
 *
 * @function Phaser.Math.Distance.Chebyshev
 * @since 3.22.0
 *
 * @param {number} x1 - The x coordinate of the first point.
 * @param {number} y1 - The y coordinate of the first point.
 * @param {number} x2 - The x coordinate of the second point.
 * @param {number} y2 - The y coordinate of the second point.
 *
 * @return {number} The distance between each point.
 */
var ChebyshevDistance = function (x1, y1, x2, y2)
{
    return Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2));
};

module.exports = ChebyshevDistance;


/***/ }),

/***/ 7798:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the distance between two sets of coordinates (points) to the power of `pow`.
 *
 * @function Phaser.Math.Distance.Power
 * @since 3.0.0
 *
 * @param {number} x1 - The x coordinate of the first point.
 * @param {number} y1 - The y coordinate of the first point.
 * @param {number} x2 - The x coordinate of the second point.
 * @param {number} y2 - The y coordinate of the second point.
 * @param {number} pow - The exponent.
 *
 * @return {number} The distance between each point.
 */
var DistancePower = function (x1, y1, x2, y2, pow)
{
    if (pow === undefined) { pow = 2; }

    return Math.sqrt(Math.pow(x2 - x1, pow) + Math.pow(y2 - y1, pow));
};

module.exports = DistancePower;


/***/ }),

/***/ 8290:
/***/ ((module) => {

/**
 * @author       samme
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the snake distance between two sets of coordinates (points).
 *
 * Snake distance (rectilinear distance, Manhattan distance) is the sum of the horizontal and vertical distances.
 * It's the effective distance when movement is allowed only horizontally or vertically (but not both).
 *
 * @function Phaser.Math.Distance.Snake
 * @since 3.22.0
 *
 * @param {number} x1 - The x coordinate of the first point.
 * @param {number} y1 - The y coordinate of the first point.
 * @param {number} x2 - The x coordinate of the second point.
 * @param {number} y2 - The y coordinate of the second point.
 *
 * @return {number} The distance between each point.
 */
var SnakeDistance = function (x1, y1, x2, y2)
{
    return Math.abs(x1 - x2) + Math.abs(y1 - y2);
};

module.exports = SnakeDistance;


/***/ }),

/***/ 3788:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the distance between two sets of coordinates (points), squared.
 *
 * @function Phaser.Math.Distance.Squared
 * @since 3.0.0
 *
 * @param {number} x1 - The x coordinate of the first point.
 * @param {number} y1 - The y coordinate of the first point.
 * @param {number} x2 - The x coordinate of the second point.
 * @param {number} y2 - The y coordinate of the second point.
 *
 * @return {number} The distance between each point, squared.
 */
var DistanceSquared = function (x1, y1, x2, y2)
{
    var dx = x1 - x2;
    var dy = y1 - y2;

    return dx * dx + dy * dy;
};

module.exports = DistanceSquared;


/***/ }),

/***/ 6338:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Distance
 */

module.exports = {

    Between: __webpack_require__(1518),
    BetweenPoints: __webpack_require__(5372),
    BetweenPointsSquared: __webpack_require__(4430),
    Chebyshev: __webpack_require__(4361),
    Power: __webpack_require__(7798),
    Snake: __webpack_require__(8290),
    Squared: __webpack_require__(3788)

};


/***/ }),

/***/ 5751:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Back ease-in.
 *
 * @function Phaser.Math.Easing.Back.In
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 * @param {number} [overshoot=1.70158] - The overshoot amount.
 *
 * @return {number} The tweened value.
 */
var In = function (v, overshoot)
{
    if (overshoot === undefined) { overshoot = 1.70158; }

    return v * v * ((overshoot + 1) * v - overshoot);
};

module.exports = In;


/***/ }),

/***/ 6203:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Back ease-in/out.
 *
 * @function Phaser.Math.Easing.Back.InOut
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 * @param {number} [overshoot=1.70158] - The overshoot amount.
 *
 * @return {number} The tweened value.
 */
var InOut = function (v, overshoot)
{
    if (overshoot === undefined) { overshoot = 1.70158; }

    var s = overshoot * 1.525;

    if ((v *= 2) < 1)
    {
        return 0.5 * (v * v * ((s + 1) * v - s));
    }
    else
    {
        return 0.5 * ((v -= 2) * v * ((s + 1) * v + s) + 2);
    }
};

module.exports = InOut;


/***/ }),

/***/ 9103:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Back ease-out.
 *
 * @function Phaser.Math.Easing.Back.Out
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 * @param {number} [overshoot=1.70158] - The overshoot amount.
 *
 * @return {number} The tweened value.
 */
var Out = function (v, overshoot)
{
    if (overshoot === undefined) { overshoot = 1.70158; }

    return --v * v * ((overshoot + 1) * v + overshoot) + 1;
};

module.exports = Out;


/***/ }),

/***/ 4938:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing.Back
 */

module.exports = {

    In: __webpack_require__(5751),
    Out: __webpack_require__(9103),
    InOut: __webpack_require__(6203)

};


/***/ }),

/***/ 8677:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Bounce ease-in.
 *
 * @function Phaser.Math.Easing.Bounce.In
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var In = function (v)
{
    v = 1 - v;

    if (v < 1 / 2.75)
    {
        return 1 - (7.5625 * v * v);
    }
    else if (v < 2 / 2.75)
    {
        return 1 - (7.5625 * (v -= 1.5 / 2.75) * v + 0.75);
    }
    else if (v < 2.5 / 2.75)
    {
        return 1 - (7.5625 * (v -= 2.25 / 2.75) * v + 0.9375);
    }
    else
    {
        return 1 - (7.5625 * (v -= 2.625 / 2.75) * v + 0.984375);
    }
};

module.exports = In;


/***/ }),

/***/ 4649:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Bounce ease-in/out.
 *
 * @function Phaser.Math.Easing.Bounce.InOut
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var InOut = function (v)
{
    var reverse = false;

    if (v < 0.5)
    {
        v = 1 - (v * 2);
        reverse = true;
    }
    else
    {
        v = (v * 2) - 1;
    }

    if (v < 1 / 2.75)
    {
        v = 7.5625 * v * v;
    }
    else if (v < 2 / 2.75)
    {
        v = 7.5625 * (v -= 1.5 / 2.75) * v + 0.75;
    }
    else if (v < 2.5 / 2.75)
    {
        v = 7.5625 * (v -= 2.25 / 2.75) * v + 0.9375;
    }
    else
    {
        v = 7.5625 * (v -= 2.625 / 2.75) * v + 0.984375;
    }

    if (reverse)
    {
        return (1 - v) * 0.5;
    }
    else
    {
        return v * 0.5 + 0.5;
    }
};

module.exports = InOut;


/***/ }),

/***/ 504:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Bounce ease-out.
 *
 * @function Phaser.Math.Easing.Bounce.Out
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var Out = function (v)
{
    if (v < 1 / 2.75)
    {
        return 7.5625 * v * v;
    }
    else if (v < 2 / 2.75)
    {
        return 7.5625 * (v -= 1.5 / 2.75) * v + 0.75;
    }
    else if (v < 2.5 / 2.75)
    {
        return 7.5625 * (v -= 2.25 / 2.75) * v + 0.9375;
    }
    else
    {
        return 7.5625 * (v -= 2.625 / 2.75) * v + 0.984375;
    }
};

module.exports = Out;


/***/ }),

/***/ 8872:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing.Bounce
 */

module.exports = {

    In: __webpack_require__(8677),
    Out: __webpack_require__(504),
    InOut: __webpack_require__(4649)

};


/***/ }),

/***/ 3170:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Circular ease-in.
 *
 * @function Phaser.Math.Easing.Circular.In
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var In = function (v)
{
    return 1 - Math.sqrt(1 - v * v);
};

module.exports = In;


/***/ }),

/***/ 2627:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Circular ease-in/out.
 *
 * @function Phaser.Math.Easing.Circular.InOut
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var InOut = function (v)
{
    if ((v *= 2) < 1)
    {
        return -0.5 * (Math.sqrt(1 - v * v) - 1);
    }
    else
    {
        return 0.5 * (Math.sqrt(1 - (v -= 2) * v) + 1);
    }
};

module.exports = InOut;


/***/ }),

/***/ 1349:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Circular ease-out.
 *
 * @function Phaser.Math.Easing.Circular.Out
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var Out = function (v)
{
    return Math.sqrt(1 - (--v * v));
};

module.exports = Out;


/***/ }),

/***/ 5006:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing.Circular
 */

module.exports = {

    In: __webpack_require__(3170),
    Out: __webpack_require__(1349),
    InOut: __webpack_require__(2627)

};


/***/ }),

/***/ 6046:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Cubic ease-in.
 *
 * @function Phaser.Math.Easing.Cubic.In
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var In = function (v)
{
    return v * v * v;
};

module.exports = In;


/***/ }),

/***/ 9531:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Cubic ease-in/out.
 *
 * @function Phaser.Math.Easing.Cubic.InOut
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var InOut = function (v)
{
    if ((v *= 2) < 1)
    {
        return 0.5 * v * v * v;
    }
    else
    {
        return 0.5 * ((v -= 2) * v * v + 2);
    }
};

module.exports = InOut;


/***/ }),

/***/ 4836:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Cubic ease-out.
 *
 * @function Phaser.Math.Easing.Cubic.Out
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var Out = function (v)
{
    return --v * v * v + 1;
};

module.exports = Out;


/***/ }),

/***/ 875:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing.Cubic
 */

module.exports = {

    In: __webpack_require__(6046),
    Out: __webpack_require__(4836),
    InOut: __webpack_require__(9531)

};


/***/ }),

/***/ 7619:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Elastic ease-in.
 *
 * @function Phaser.Math.Easing.Elastic.In
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 * @param {number} [amplitude=0.1] - The amplitude of the elastic ease.
 * @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles.
 *
 * @return {number} The tweened value.
 */
var In = function (v, amplitude, period)
{
    if (amplitude === undefined) { amplitude = 0.1; }
    if (period === undefined) { period = 0.1; }

    if (v === 0)
    {
        return 0;
    }
    else if (v === 1)
    {
        return 1;
    }
    else
    {
        var s = period / 4;

        if (amplitude < 1)
        {
            amplitude = 1;
        }
        else
        {
            s = period * Math.asin(1 / amplitude) / (2 * Math.PI);
        }

        return -(amplitude * Math.pow(2, 10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period));
    }
};

module.exports = In;


/***/ }),

/***/ 7437:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Elastic ease-in/out.
 *
 * @function Phaser.Math.Easing.Elastic.InOut
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 * @param {number} [amplitude=0.1] - The amplitude of the elastic ease.
 * @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles.
 *
 * @return {number} The tweened value.
 */
var InOut = function (v, amplitude, period)
{
    if (amplitude === undefined) { amplitude = 0.1; }
    if (period === undefined) { period = 0.1; }

    if (v === 0)
    {
        return 0;
    }
    else if (v === 1)
    {
        return 1;
    }
    else
    {
        var s = period / 4;

        if (amplitude < 1)
        {
            amplitude = 1;
        }
        else
        {
            s = period * Math.asin(1 / amplitude) / (2 * Math.PI);
        }

        if ((v *= 2) < 1)
        {
            return -0.5 * (amplitude * Math.pow(2, 10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period));
        }
        else
        {
            return amplitude * Math.pow(2, -10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period) * 0.5 + 1;
        }
    }
};

module.exports = InOut;


/***/ }),

/***/ 8119:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Elastic ease-out.
 *
 * @function Phaser.Math.Easing.Elastic.Out
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 * @param {number} [amplitude=0.1] - The amplitude of the elastic ease.
 * @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles.
 *
 * @return {number} The tweened value.
 */
var Out = function (v, amplitude, period)
{
    if (amplitude === undefined) { amplitude = 0.1; }
    if (period === undefined) { period = 0.1; }

    if (v === 0)
    {
        return 0;
    }
    else if (v === 1)
    {
        return 1;
    }
    else
    {
        var s = period / 4;

        if (amplitude < 1)
        {
            amplitude = 1;
        }
        else
        {
            s = period * Math.asin(1 / amplitude) / (2 * Math.PI);
        }

        return (amplitude * Math.pow(2, -10 * v) * Math.sin((v - s) * (2 * Math.PI) / period) + 1);
    }
};

module.exports = Out;


/***/ }),

/***/ 2884:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing.Elastic
 */

module.exports = {

    In: __webpack_require__(7619),
    Out: __webpack_require__(8119),
    InOut: __webpack_require__(7437)

};


/***/ }),

/***/ 5456:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Exponential ease-in.
 *
 * @function Phaser.Math.Easing.Expo.In
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var In = function (v)
{
    return Math.pow(2, 10 * (v - 1)) - 0.001;
};

module.exports = In;


/***/ }),

/***/ 3461:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Exponential ease-in/out.
 *
 * @function Phaser.Math.Easing.Expo.InOut
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var InOut = function (v)
{
    if ((v *= 2) < 1)
    {
        return 0.5 * Math.pow(2, 10 * (v - 1));
    }
    else
    {
        return 0.5 * (2 - Math.pow(2, -10 * (v - 1)));
    }
};

module.exports = InOut;


/***/ }),

/***/ 2711:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Exponential ease-out.
 *
 * @function Phaser.Math.Easing.Expo.Out
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var Out = function (v)
{
    return 1 - Math.pow(2, -10 * v);
};

module.exports = Out;


/***/ }),

/***/ 6287:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing.Expo
 */

module.exports = {

    In: __webpack_require__(5456),
    Out: __webpack_require__(2711),
    InOut: __webpack_require__(3461)

};


/***/ }),

/***/ 8613:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing
 */

module.exports = {

    Back: __webpack_require__(4938),
    Bounce: __webpack_require__(8872),
    Circular: __webpack_require__(5006),
    Cubic: __webpack_require__(875),
    Elastic: __webpack_require__(2884),
    Expo: __webpack_require__(6287),
    Linear: __webpack_require__(4233),
    Quadratic: __webpack_require__(6341),
    Quartic: __webpack_require__(762),
    Quintic: __webpack_require__(345),
    Sine: __webpack_require__(8698),
    Stepped: __webpack_require__(7051)

};


/***/ }),

/***/ 744:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Linear easing (no variation).
 *
 * @function Phaser.Math.Easing.Linear
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var Linear = function (v)
{
    return v;
};

module.exports = Linear;


/***/ }),

/***/ 4233:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

module.exports = __webpack_require__(744);


/***/ }),

/***/ 9810:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Quadratic ease-in.
 *
 * @function Phaser.Math.Easing.Quadratic.In
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var In = function (v)
{
    return v * v;
};

module.exports = In;


/***/ }),

/***/ 8163:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Quadratic ease-in/out.
 *
 * @function Phaser.Math.Easing.Quadratic.InOut
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var InOut = function (v)
{
    if ((v *= 2) < 1)
    {
        return 0.5 * v * v;
    }
    else
    {
        return -0.5 * (--v * (v - 2) - 1);
    }
};

module.exports = InOut;


/***/ }),

/***/ 6123:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Quadratic ease-out.
 *
 * @function Phaser.Math.Easing.Quadratic.Out
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var Out = function (v)
{
    return v * (2 - v);
};

module.exports = Out;


/***/ }),

/***/ 6341:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing.Quadratic
 */

module.exports = {

    In: __webpack_require__(9810),
    Out: __webpack_require__(6123),
    InOut: __webpack_require__(8163)

};


/***/ }),

/***/ 7337:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Quartic ease-in.
 *
 * @function Phaser.Math.Easing.Quartic.In
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var In = function (v)
{
    return v * v * v * v;
};

module.exports = In;


/***/ }),

/***/ 4878:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Quartic ease-in/out.
 *
 * @function Phaser.Math.Easing.Quartic.InOut
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var InOut = function (v)
{
    if ((v *= 2) < 1)
    {
        return 0.5 * v * v * v * v;
    }
    else
    {
        return -0.5 * ((v -= 2) * v * v * v - 2);
    }
};

module.exports = InOut;


/***/ }),

/***/ 9012:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Quartic ease-out.
 *
 * @function Phaser.Math.Easing.Quartic.Out
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var Out = function (v)
{
    return 1 - (--v * v * v * v);
};

module.exports = Out;


/***/ }),

/***/ 762:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing.Quartic
 */

module.exports = {

    In: __webpack_require__(7337),
    Out: __webpack_require__(9012),
    InOut: __webpack_require__(4878)

};


/***/ }),

/***/ 303:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Quintic ease-in.
 *
 * @function Phaser.Math.Easing.Quintic.In
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var In = function (v)
{
    return v * v * v * v * v;
};

module.exports = In;


/***/ }),

/***/ 553:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Quintic ease-in/out.
 *
 * @function Phaser.Math.Easing.Quintic.InOut
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var InOut = function (v)
{
    if ((v *= 2) < 1)
    {
        return 0.5 * v * v * v * v * v;
    }
    else
    {
        return 0.5 * ((v -= 2) * v * v * v * v + 2);
    }
};

module.exports = InOut;


/***/ }),

/***/ 1632:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Quintic ease-out.
 *
 * @function Phaser.Math.Easing.Quintic.Out
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var Out = function (v)
{
    return --v * v * v * v * v + 1;
};

module.exports = Out;


/***/ }),

/***/ 345:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing.Quintic
 */

module.exports = {

    In: __webpack_require__(303),
    Out: __webpack_require__(1632),
    InOut: __webpack_require__(553)

};


/***/ }),

/***/ 8455:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Sinusoidal ease-in.
 *
 * @function Phaser.Math.Easing.Sine.In
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var In = function (v)
{
    if (v === 0)
    {
        return 0;
    }
    else if (v === 1)
    {
        return 1;
    }
    else
    {
        return 1 - Math.cos(v * Math.PI / 2);
    }
};

module.exports = In;


/***/ }),

/***/ 1844:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Sinusoidal ease-in/out.
 *
 * @function Phaser.Math.Easing.Sine.InOut
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var InOut = function (v)
{
    if (v === 0)
    {
        return 0;
    }
    else if (v === 1)
    {
        return 1;
    }
    else
    {
        return 0.5 * (1 - Math.cos(Math.PI * v));
    }
};

module.exports = InOut;


/***/ }),

/***/ 990:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Sinusoidal ease-out.
 *
 * @function Phaser.Math.Easing.Sine.Out
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 *
 * @return {number} The tweened value.
 */
var Out = function (v)
{
    if (v === 0)
    {
        return 0;
    }
    else if (v === 1)
    {
        return 1;
    }
    else
    {
        return Math.sin(v * Math.PI / 2);
    }
};

module.exports = Out;


/***/ }),

/***/ 8698:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing.Sine
 */

module.exports = {

    In: __webpack_require__(8455),
    Out: __webpack_require__(990),
    InOut: __webpack_require__(1844)

};


/***/ }),

/***/ 6745:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Stepped easing.
 *
 * @function Phaser.Math.Easing.Stepped
 * @since 3.0.0
 *
 * @param {number} v - The value to be tweened.
 * @param {number} [steps=1] - The number of steps in the ease.
 *
 * @return {number} The tweened value.
 */
var Stepped = function (v, steps)
{
    if (steps === undefined) { steps = 1; }

    if (v <= 0)
    {
        return 0;
    }
    else if (v >= 1)
    {
        return 1;
    }
    else
    {
        return (((steps * v) | 0) + 1) * (1 / steps);
    }
};

module.exports = Stepped;


/***/ }),

/***/ 7051:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Easing.Stepped
 */

module.exports = __webpack_require__(6745);


/***/ }),

/***/ 3158:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the fuzzy ceiling of the given value.
 *
 * @function Phaser.Math.Fuzzy.Ceil
 * @since 3.0.0
 *
 * @param {number} value - The value.
 * @param {number} [epsilon=0.0001] - The epsilon.
 *
 * @return {number} The fuzzy ceiling of the value.
 */
var Ceil = function (value, epsilon)
{
    if (epsilon === undefined) { epsilon = 0.0001; }

    return Math.ceil(value - epsilon);
};

module.exports = Ceil;


/***/ }),

/***/ 12:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Check whether the given values are fuzzily equal.
 *
 * Two numbers are fuzzily equal if their difference is less than `epsilon`.
 *
 * @function Phaser.Math.Fuzzy.Equal
 * @since 3.0.0
 *
 * @param {number} a - The first value.
 * @param {number} b - The second value.
 * @param {number} [epsilon=0.0001] - The epsilon.
 *
 * @return {boolean} `true` if the values are fuzzily equal, otherwise `false`.
 */
var Equal = function (a, b, epsilon)
{
    if (epsilon === undefined) { epsilon = 0.0001; }

    return Math.abs(a - b) < epsilon;
};

module.exports = Equal;


/***/ }),

/***/ 1326:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Calculate the fuzzy floor of the given value.
 *
 * @function Phaser.Math.Fuzzy.Floor
 * @since 3.0.0
 *
 * @param {number} value - The value.
 * @param {number} [epsilon=0.0001] - The epsilon.
 *
 * @return {number} The floor of the value.
 */
var Floor = function (value, epsilon)
{
    if (epsilon === undefined) { epsilon = 0.0001; }

    return Math.floor(value + epsilon);
};

module.exports = Floor;


/***/ }),

/***/ 7373:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Check whether `a` is fuzzily greater than `b`.
 *
 * `a` is fuzzily greater than `b` if it is more than `b - epsilon`.
 *
 * @function Phaser.Math.Fuzzy.GreaterThan
 * @since 3.0.0
 *
 * @param {number} a - The first value.
 * @param {number} b - The second value.
 * @param {number} [epsilon=0.0001] - The epsilon.
 *
 * @return {boolean} `true` if `a` is fuzzily greater than than `b`, otherwise `false`.
 */
var GreaterThan = function (a, b, epsilon)
{
    if (epsilon === undefined) { epsilon = 0.0001; }

    return a > b - epsilon;
};

module.exports = GreaterThan;


/***/ }),

/***/ 2622:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Check whether `a` is fuzzily less than `b`.
 *
 * `a` is fuzzily less than `b` if it is less than `b + epsilon`.
 *
 * @function Phaser.Math.Fuzzy.LessThan
 * @since 3.0.0
 *
 * @param {number} a - The first value.
 * @param {number} b - The second value.
 * @param {number} [epsilon=0.0001] - The epsilon.
 *
 * @return {boolean} `true` if `a` is fuzzily less than `b`, otherwise `false`.
 */
var LessThan = function (a, b, epsilon)
{
    if (epsilon === undefined) { epsilon = 0.0001; }

    return a < b + epsilon;
};

module.exports = LessThan;


/***/ }),

/***/ 7927:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Fuzzy
 */

module.exports = {

    Ceil: __webpack_require__(3158),
    Equal: __webpack_require__(12),
    Floor: __webpack_require__(1326),
    GreaterThan: __webpack_require__(7373),
    LessThan: __webpack_require__(2622)

};


/***/ }),

/***/ 4675:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var CONST = __webpack_require__(7425);
var Extend = __webpack_require__(1030);

/**
 * @namespace Phaser.Math
 */

var PhaserMath = {

    //  Collections of functions
    Angle: __webpack_require__(1833),
    Distance: __webpack_require__(6338),
    Easing: __webpack_require__(8613),
    Fuzzy: __webpack_require__(7927),
    Interpolation: __webpack_require__(2140),
    Pow2: __webpack_require__(7897),
    Snap: __webpack_require__(3943),

    //  Expose the RNG Class
    RandomDataGenerator: __webpack_require__(6957),

    //  Single functions
    Average: __webpack_require__(3136),
    Bernstein: __webpack_require__(785),
    Between: __webpack_require__(7025),
    CatmullRom: __webpack_require__(48),
    CeilTo: __webpack_require__(5035),
    Clamp: __webpack_require__(2915),
    DegToRad: __webpack_require__(7149),
    Difference: __webpack_require__(2975),
    Euler: __webpack_require__(2107),
    Factorial: __webpack_require__(3916),
    FloatBetween: __webpack_require__(104),
    FloorTo: __webpack_require__(4941),
    FromPercent: __webpack_require__(1555),
    GetSpeed: __webpack_require__(5005),
    IsEven: __webpack_require__(3702),
    IsEvenStrict: __webpack_require__(8820),
    Linear: __webpack_require__(1743),
    LinearXY: __webpack_require__(3416),
    MaxAdd: __webpack_require__(3733),
    Median: __webpack_require__(44),
    MinSub: __webpack_require__(5385),
    Percent: __webpack_require__(8585),
    RadToDeg: __webpack_require__(4208),
    RandomXY: __webpack_require__(1705),
    RandomXYZ: __webpack_require__(6650),
    RandomXYZW: __webpack_require__(2037),
    Rotate: __webpack_require__(6283),
    RotateAround: __webpack_require__(9876),
    RotateAroundDistance: __webpack_require__(8348),
    RotateTo: __webpack_require__(4497),
    RoundAwayFromZero: __webpack_require__(4078),
    RoundTo: __webpack_require__(855),
    SinCosTableGenerator: __webpack_require__(4936),
    SmootherStep: __webpack_require__(278),
    SmoothStep: __webpack_require__(2733),
    ToXY: __webpack_require__(163),
    TransformXY: __webpack_require__(7556),
    Within: __webpack_require__(4119),
    Wrap: __webpack_require__(8445),

    //  Vector classes
    Vector2: __webpack_require__(2529),
    Vector3: __webpack_require__(5689),
    Vector4: __webpack_require__(9279),
    Matrix3: __webpack_require__(2149),
    Matrix4: __webpack_require__(9652),
    Quaternion: __webpack_require__(372),
    RotateVec3: __webpack_require__(9640)

};

//   Merge in the consts

PhaserMath = Extend(false, PhaserMath, CONST);

//  Export it

module.exports = PhaserMath;


/***/ }),

/***/ 1640:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Bernstein = __webpack_require__(785);

/**
 * A bezier interpolation method.
 *
 * @function Phaser.Math.Interpolation.Bezier
 * @since 3.0.0
 *
 * @param {number[]} v - The input array of values to interpolate between.
 * @param {number} k - The percentage of interpolation, between 0 and 1.
 *
 * @return {number} The interpolated value.
 */
var BezierInterpolation = function (v, k)
{
    var b = 0;
    var n = v.length - 1;

    for (var i = 0; i <= n; i++)
    {
        b += Math.pow(1 - k, n - i) * Math.pow(k, i) * v[i] * Bernstein(n, i);
    }

    return b;
};

module.exports = BezierInterpolation;


/***/ }),

/***/ 6105:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var CatmullRom = __webpack_require__(48);

/**
 * A Catmull-Rom interpolation method.
 *
 * @function Phaser.Math.Interpolation.CatmullRom
 * @since 3.0.0
 *
 * @param {number[]} v - The input array of values to interpolate between.
 * @param {number} k - The percentage of interpolation, between 0 and 1.
 *
 * @return {number} The interpolated value.
 */
var CatmullRomInterpolation = function (v, k)
{
    var m = v.length - 1;
    var f = m * k;
    var i = Math.floor(f);

    if (v[0] === v[m])
    {
        if (k < 0)
        {
            i = Math.floor(f = m * (1 + k));
        }

        return CatmullRom(f - i, v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m]);
    }
    else
    {
        if (k < 0)
        {
            return v[0] - (CatmullRom(-f, v[0], v[0], v[1], v[1]) - v[0]);
        }

        if (k > 1)
        {
            return v[m] - (CatmullRom(f - m, v[m], v[m], v[m - 1], v[m - 1]) - v[m]);
        }

        return CatmullRom(f - i, v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2]);
    }
};

module.exports = CatmullRomInterpolation;


/***/ }),

/***/ 4002:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @ignore
 */
function P0 (t, p)
{
    var k = 1 - t;

    return k * k * k * p;
}

/**
 * @ignore
 */
function P1 (t, p)
{
    var k = 1 - t;

    return 3 * k * k * t * p;
}

/**
 * @ignore
 */
function P2 (t, p)
{
    return 3 * (1 - t) * t * t * p;
}

/**
 * @ignore
 */
function P3 (t, p)
{
    return t * t * t * p;
}

/**
 * A cubic bezier interpolation method.
 *
 * https://medium.com/@adrian_cooney/bezier-interpolation-13b68563313a
 *
 * @function Phaser.Math.Interpolation.CubicBezier
 * @since 3.0.0
 *
 * @param {number} t - The percentage of interpolation, between 0 and 1.
 * @param {number} p0 - The start point.
 * @param {number} p1 - The first control point.
 * @param {number} p2 - The second control point.
 * @param {number} p3 - The end point.
 *
 * @return {number} The interpolated value.
 */
var CubicBezierInterpolation = function (t, p0, p1, p2, p3)
{
    return P0(t, p0) + P1(t, p1) + P2(t, p2) + P3(t, p3);
};

module.exports = CubicBezierInterpolation;


/***/ }),

/***/ 6765:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Linear = __webpack_require__(1743);

/**
 * A linear interpolation method.
 *
 * @function Phaser.Math.Interpolation.Linear
 * @since 3.0.0
 * @see {@link https://en.wikipedia.org/wiki/Linear_interpolation}
 *
 * @param {number[]} v - The input array of values to interpolate between.
 * @param {!number} k - The percentage of interpolation, between 0 and 1.
 *
 * @return {!number} The interpolated value.
 */
var LinearInterpolation = function (v, k)
{
    var m = v.length - 1;
    var f = m * k;
    var i = Math.floor(f);

    if (k < 0)
    {
        return Linear(v[0], v[1], f);
    }
    else if (k > 1)
    {
        return Linear(v[m], v[m - 1], m - f);
    }
    else
    {
        return Linear(v[i], v[(i + 1 > m) ? m : i + 1], f - i);
    }
};

module.exports = LinearInterpolation;


/***/ }),

/***/ 6388:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @ignore
 */
function P0 (t, p)
{
    var k = 1 - t;

    return k * k * p;
}

/**
 * @ignore
 */
function P1 (t, p)
{
    return 2 * (1 - t) * t * p;
}

/**
 * @ignore
 */
function P2 (t, p)
{
    return t * t * p;
}

// https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js

/**
 * A quadratic bezier interpolation method.
 *
 * @function Phaser.Math.Interpolation.QuadraticBezier
 * @since 3.2.0
 *
 * @param {number} t - The percentage of interpolation, between 0 and 1.
 * @param {number} p0 - The start point.
 * @param {number} p1 - The control point.
 * @param {number} p2 - The end point.
 *
 * @return {number} The interpolated value.
 */
var QuadraticBezierInterpolation = function (t, p0, p1, p2)
{
    return P0(t, p0) + P1(t, p1) + P2(t, p2);
};

module.exports = QuadraticBezierInterpolation;


/***/ }),

/***/ 5735:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var SmoothStep = __webpack_require__(2733);

/**
 * A Smooth Step interpolation method.
 *
 * @function Phaser.Math.Interpolation.SmoothStep
 * @since 3.9.0
 * @see {@link https://en.wikipedia.org/wiki/Smoothstep}
 *
 * @param {number} t - The percentage of interpolation, between 0 and 1.
 * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'.
 * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'.
 *
 * @return {number} The interpolated value.
 */
var SmoothStepInterpolation = function (t, min, max)
{
    return min + (max - min) * SmoothStep(t, 0, 1);
};

module.exports = SmoothStepInterpolation;


/***/ }),

/***/ 8705:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var SmootherStep = __webpack_require__(278);

/**
 * A Smoother Step interpolation method.
 *
 * @function Phaser.Math.Interpolation.SmootherStep
 * @since 3.9.0
 * @see {@link https://en.wikipedia.org/wiki/Smoothstep#Variations}
 *
 * @param {number} t - The percentage of interpolation, between 0 and 1.
 * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'.
 * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'.
 *
 * @return {number} The interpolated value.
 */
var SmootherStepInterpolation = function (t, min, max)
{
    return min + (max - min) * SmootherStep(t, 0, 1);
};

module.exports = SmootherStepInterpolation;


/***/ }),

/***/ 2140:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Interpolation
 */

module.exports = {

    Bezier: __webpack_require__(1640),
    CatmullRom: __webpack_require__(6105),
    CubicBezier: __webpack_require__(4002),
    Linear: __webpack_require__(6765),
    QuadraticBezier: __webpack_require__(6388),
    SmoothStep: __webpack_require__(5735),
    SmootherStep: __webpack_require__(8705)

};


/***/ }),

/***/ 5443:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Returns the nearest power of 2 to the given `value`.
 *
 * @function Phaser.Math.Pow2.GetNext
 * @since 3.0.0
 *
 * @param {number} value - The value.
 *
 * @return {number} The nearest power of 2 to `value`.
 */
var GetPowerOfTwo = function (value)
{
    var index = Math.log(value) / 0.6931471805599453;

    return (1 << Math.ceil(index));
};

module.exports = GetPowerOfTwo;


/***/ }),

/***/ 725:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Checks if the given `width` and `height` are a power of two.
 * Useful for checking texture dimensions.
 *
 * @function Phaser.Math.Pow2.IsSize
 * @since 3.0.0
 *
 * @param {number} width - The width.
 * @param {number} height - The height.
 *
 * @return {boolean} `true` if `width` and `height` are a power of two, otherwise `false`.
 */
var IsSizePowerOfTwo = function (width, height)
{
    return (width > 0 && (width & (width - 1)) === 0 && height > 0 && (height & (height - 1)) === 0);
};

module.exports = IsSizePowerOfTwo;


/***/ }),

/***/ 167:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Tests the value and returns `true` if it is a power of two.
 *
 * @function Phaser.Math.Pow2.IsValue
 * @since 3.0.0
 *
 * @param {number} value - The value to check if it's a power of two.
 *
 * @return {boolean} Returns `true` if `value` is a power of two, otherwise `false`.
 */
var IsValuePowerOfTwo = function (value)
{
    return (value > 0 && (value & (value - 1)) === 0);
};

module.exports = IsValuePowerOfTwo;


/***/ }),

/***/ 7897:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Pow2
 */

module.exports = {

    GetNext: __webpack_require__(5443),
    IsSize: __webpack_require__(725),
    IsValue: __webpack_require__(167)

};


/***/ }),

/***/ 6957:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);

/**
 * @classdesc
 * A seeded Random Data Generator.
 *
 * Access via `Phaser.Math.RND` which is an instance of this class pre-defined
 * by Phaser. Or, create your own instance to use as you require.
 *
 * The `Math.RND` generator is seeded by the Game Config property value `seed`.
 * If no such config property exists, a random number is used.
 *
 * If you create your own instance of this class you should provide a seed for it.
 * If no seed is given it will use a 'random' one based on Date.now.
 *
 * @class RandomDataGenerator
 * @memberof Phaser.Math
 * @constructor
 * @since 3.0.0
 *
 * @param {(string|string[])} [seeds] - The seeds to use for the random number generator.
 */
var RandomDataGenerator = new Class({

    initialize:

    function RandomDataGenerator (seeds)
    {
        if (seeds === undefined) { seeds = [ (Date.now() * Math.random()).toString() ]; }

        /**
         * Internal var.
         *
         * @name Phaser.Math.RandomDataGenerator#c
         * @type {number}
         * @default 1
         * @private
         * @since 3.0.0
         */
        this.c = 1;

        /**
         * Internal var.
         *
         * @name Phaser.Math.RandomDataGenerator#s0
         * @type {number}
         * @default 0
         * @private
         * @since 3.0.0
         */
        this.s0 = 0;

        /**
         * Internal var.
         *
         * @name Phaser.Math.RandomDataGenerator#s1
         * @type {number}
         * @default 0
         * @private
         * @since 3.0.0
         */
        this.s1 = 0;

        /**
         * Internal var.
         *
         * @name Phaser.Math.RandomDataGenerator#s2
         * @type {number}
         * @default 0
         * @private
         * @since 3.0.0
         */
        this.s2 = 0;

        /**
         * Internal var.
         *
         * @name Phaser.Math.RandomDataGenerator#n
         * @type {number}
         * @default 0
         * @private
         * @since 3.2.0
         */
        this.n = 0;

        /**
         * Signs to choose from.
         *
         * @name Phaser.Math.RandomDataGenerator#signs
         * @type {number[]}
         * @since 3.0.0
         */
        this.signs = [ -1, 1 ];

        if (seeds)
        {
            this.init(seeds);
        }
    },

    /**
     * Private random helper.
     *
     * @method Phaser.Math.RandomDataGenerator#rnd
     * @since 3.0.0
     * @private
     *
     * @return {number} A random number.
     */
    rnd: function ()
    {
        var t = 2091639 * this.s0 + this.c * 2.3283064365386963e-10; // 2^-32

        this.c = t | 0;
        this.s0 = this.s1;
        this.s1 = this.s2;
        this.s2 = t - this.c;

        return this.s2;
    },

    /**
     * Internal method that creates a seed hash.
     *
     * @method Phaser.Math.RandomDataGenerator#hash
     * @since 3.0.0
     * @private
     *
     * @param {string} data - The value to hash.
     *
     * @return {number} The hashed value.
     */
    hash: function (data)
    {
        var h;
        var n = this.n;

        data = data.toString();

        for (var i = 0; i < data.length; i++)
        {
            n += data.charCodeAt(i);
            h = 0.02519603282416938 * n;
            n = h >>> 0;
            h -= n;
            h *= n;
            n = h >>> 0;
            h -= n;
            n += h * 0x100000000;// 2^32
        }

        this.n = n;

        return (n >>> 0) * 2.3283064365386963e-10;// 2^-32
    },

    /**
     * Initialize the state of the random data generator.
     *
     * @method Phaser.Math.RandomDataGenerator#init
     * @since 3.0.0
     *
     * @param {(string|string[])} seeds - The seeds to initialize the random data generator with.
     */
    init: function (seeds)
    {
        if (typeof seeds === 'string')
        {
            this.state(seeds);
        }
        else
        {
            this.sow(seeds);
        }
    },

    /**
     * Reset the seed of the random data generator.
     *
     * _Note_: the seed array is only processed up to the first `undefined` (or `null`) value, should such be present.
     *
     * @method Phaser.Math.RandomDataGenerator#sow
     * @since 3.0.0
     *
     * @param {string[]} seeds - The array of seeds: the `toString()` of each value is used.
     */
    sow: function (seeds)
    {
        // Always reset to default seed
        this.n = 0xefc8249d;
        this.s0 = this.hash(' ');
        this.s1 = this.hash(' ');
        this.s2 = this.hash(' ');
        this.c = 1;

        if (!seeds)
        {
            return;
        }

        // Apply any seeds
        for (var i = 0; i < seeds.length && (seeds[i] != null); i++)
        {
            var seed = seeds[i];

            this.s0 -= this.hash(seed);
            this.s0 += ~~(this.s0 < 0);
            this.s1 -= this.hash(seed);
            this.s1 += ~~(this.s1 < 0);
            this.s2 -= this.hash(seed);
            this.s2 += ~~(this.s2 < 0);
        }
    },

    /**
     * Returns a random integer between 0 and 2^32.
     *
     * @method Phaser.Math.RandomDataGenerator#integer
     * @since 3.0.0
     *
     * @return {number} A random integer between 0 and 2^32.
     */
    integer: function ()
    {
        // 2^32
        return this.rnd() * 0x100000000;
    },

    /**
     * Returns a random real number between 0 and 1.
     *
     * @method Phaser.Math.RandomDataGenerator#frac
     * @since 3.0.0
     *
     * @return {number} A random real number between 0 and 1.
     */
    frac: function ()
    {
        // 2^-53
        return this.rnd() + (this.rnd() * 0x200000 | 0) * 1.1102230246251565e-16;
    },

    /**
     * Returns a random real number between 0 and 2^32.
     *
     * @method Phaser.Math.RandomDataGenerator#real
     * @since 3.0.0
     *
     * @return {number} A random real number between 0 and 2^32.
     */
    real: function ()
    {
        return this.integer() + this.frac();
    },

    /**
     * Returns a random integer between and including min and max.
     *
     * @method Phaser.Math.RandomDataGenerator#integerInRange
     * @since 3.0.0
     *
     * @param {number} min - The minimum value in the range.
     * @param {number} max - The maximum value in the range.
     *
     * @return {number} A random number between min and max.
     */
    integerInRange: function (min, max)
    {
        return Math.floor(this.realInRange(0, max - min + 1) + min);
    },

    /**
     * Returns a random integer between and including min and max.
     * This method is an alias for RandomDataGenerator.integerInRange.
     *
     * @method Phaser.Math.RandomDataGenerator#between
     * @since 3.0.0
     *
     * @param {number} min - The minimum value in the range.
     * @param {number} max - The maximum value in the range.
     *
     * @return {number} A random number between min and max.
     */
    between: function (min, max)
    {
        return Math.floor(this.realInRange(0, max - min + 1) + min);
    },

    /**
     * Returns a random real number between min and max.
     *
     * @method Phaser.Math.RandomDataGenerator#realInRange
     * @since 3.0.0
     *
     * @param {number} min - The minimum value in the range.
     * @param {number} max - The maximum value in the range.
     *
     * @return {number} A random number between min and max.
     */
    realInRange: function (min, max)
    {
        return this.frac() * (max - min) + min;
    },

    /**
     * Returns a random real number between -1 and 1.
     *
     * @method Phaser.Math.RandomDataGenerator#normal
     * @since 3.0.0
     *
     * @return {number} A random real number between -1 and 1.
     */
    normal: function ()
    {
        return 1 - (2 * this.frac());
    },

    /**
     * Returns a valid RFC4122 version4 ID hex string from https://gist.github.com/1308368
     *
     * @method Phaser.Math.RandomDataGenerator#uuid
     * @since 3.0.0
     *
     * @return {string} A valid RFC4122 version4 ID hex string
     */
    uuid: function ()
    {
        var a = '';
        var b = '';

        for (b = a = ''; a++ < 36; b += ~a % 5 | a * 3 & 4 ? (a ^ 15 ? 8 ^ this.frac() * (a ^ 20 ? 16 : 4) : 4).toString(16) : '-')
        {
            // eslint-disable-next-line no-empty
        }

        return b;
    },

    /**
     * Returns a random element from within the given array.
     *
     * @method Phaser.Math.RandomDataGenerator#pick
     * @since 3.0.0
     *
     * @generic T
     * @genericUse {T[]} - [array]
     * @genericUse {T} - [$return]
     *
     * @param {T[]} array - The array to pick a random element from.
     *
     * @return {T} A random member of the array.
     */
    pick: function (array)
    {
        return array[this.integerInRange(0, array.length - 1)];
    },

    /**
     * Returns a sign to be used with multiplication operator.
     *
     * @method Phaser.Math.RandomDataGenerator#sign
     * @since 3.0.0
     *
     * @return {number} -1 or +1.
     */
    sign: function ()
    {
        return this.pick(this.signs);
    },

    /**
     * Returns a random element from within the given array, favoring the earlier entries.
     *
     * @method Phaser.Math.RandomDataGenerator#weightedPick
     * @since 3.0.0
     *
     * @generic T
     * @genericUse {T[]} - [array]
     * @genericUse {T} - [$return]
     *
     * @param {T[]} array - The array to pick a random element from.
     *
     * @return {T} A random member of the array.
     */
    weightedPick: function (array)
    {
        return array[~~(Math.pow(this.frac(), 2) * array.length + 0.5)];
    },

    /**
     * Returns a random timestamp between min and max, or between the beginning of 2000 and the end of 2020 if min and max aren't specified.
     *
     * @method Phaser.Math.RandomDataGenerator#timestamp
     * @since 3.0.0
     *
     * @param {number} min - The minimum value in the range.
     * @param {number} max - The maximum value in the range.
     *
     * @return {number} A random timestamp between min and max.
     */
    timestamp: function (min, max)
    {
        return this.realInRange(min || 946684800000, max || 1577862000000);
    },

    /**
     * Returns a random angle between -180 and 180.
     *
     * @method Phaser.Math.RandomDataGenerator#angle
     * @since 3.0.0
     *
     * @return {number} A random number between -180 and 180.
     */
    angle: function ()
    {
        return this.integerInRange(-180, 180);
    },

    /**
     * Returns a random rotation in radians, between -3.141 and 3.141
     *
     * @method Phaser.Math.RandomDataGenerator#rotation
     * @since 3.0.0
     *
     * @return {number} A random number between -3.141 and 3.141
     */
    rotation: function ()
    {
        return this.realInRange(-3.1415926, 3.1415926);
    },

    /**
     * Gets or Sets the state of the generator. This allows you to retain the values
     * that the generator is using between games, i.e. in a game save file.
     *
     * To seed this generator with a previously saved state you can pass it as the
     * `seed` value in your game config, or call this method directly after Phaser has booted.
     *
     * Call this method with no parameters to return the current state.
     *
     * If providing a state it should match the same format that this method
     * returns, which is a string with a header `!rnd` followed by the `c`,
     * `s0`, `s1` and `s2` values respectively, each comma-delimited.
     *
     * @method Phaser.Math.RandomDataGenerator#state
     * @since 3.0.0
     *
     * @param {string} [state] - Generator state to be set.
     *
     * @return {string} The current state of the generator.
     */
    state: function (state)
    {
        if (typeof state === 'string' && state.match(/^!rnd/))
        {
            state = state.split(',');

            this.c = parseFloat(state[1]);
            this.s0 = parseFloat(state[2]);
            this.s1 = parseFloat(state[3]);
            this.s2 = parseFloat(state[4]);
        }

        return [ '!rnd', this.c, this.s0, this.s1, this.s2 ].join(',');
    },

    /**
     * Shuffles the given array, using the current seed.
     *
     * @method Phaser.Math.RandomDataGenerator#shuffle
     * @since 3.7.0
     *
     * @generic T
     * @genericUse {T[]} - [array,$return]
     *
     * @param {T[]} [array] - The array to be shuffled.
     *
     * @return {T[]} The shuffled array.
     */
    shuffle: function (array)
    {
        var len = array.length - 1;

        for (var i = len; i > 0; i--)
        {
            var randomIndex = Math.floor(this.frac() * (i + 1));
            var itemAtIndex = array[randomIndex];

            array[randomIndex] = array[i];
            array[i] = itemAtIndex;
        }

        return array;
    }

});

module.exports = RandomDataGenerator;


/***/ }),

/***/ 5659:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Snap a value to nearest grid slice, using ceil.
 *
 * Example: if you have an interval gap of `5` and a position of `12`... you will snap to `15`.
 * As will `14` snap to `15`... but `16` will snap to `20`.
 *
 * @function Phaser.Math.Snap.Ceil
 * @since 3.0.0
 *
 * @param {number} value - The value to snap.
 * @param {number} gap - The interval gap of the grid.
 * @param {number} [start=0] - Optional starting offset for gap.
 * @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning.
 *
 * @return {number} The snapped value.
 */
var SnapCeil = function (value, gap, start, divide)
{
    if (start === undefined) { start = 0; }

    if (gap === 0)
    {
        return value;
    }

    value -= start;
    value = gap * Math.ceil(value / gap);

    return (divide) ? (start + value) / gap : start + value;
};

module.exports = SnapCeil;


/***/ }),

/***/ 5461:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Snap a value to nearest grid slice, using floor.
 *
 * Example: if you have an interval gap of `5` and a position of `12`... you will snap to `10`.
 * As will `14` snap to `10`... but `16` will snap to `15`.
 *
 * @function Phaser.Math.Snap.Floor
 * @since 3.0.0
 *
 * @param {number} value - The value to snap.
 * @param {number} gap - The interval gap of the grid.
 * @param {number} [start=0] - Optional starting offset for gap.
 * @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning.
 *
 * @return {number} The snapped value.
 */
var SnapFloor = function (value, gap, start, divide)
{
    if (start === undefined) { start = 0; }

    if (gap === 0)
    {
        return value;
    }

    value -= start;
    value = gap * Math.floor(value / gap);

    return (divide) ? (start + value) / gap : start + value;
};

module.exports = SnapFloor;


/***/ }),

/***/ 5131:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Snap a value to nearest grid slice, using rounding.
 *
 * Example: if you have an interval gap of `5` and a position of `12`... you will snap to `10` whereas `14` will snap to `15`.
 *
 * @function Phaser.Math.Snap.To
 * @since 3.0.0
 *
 * @param {number} value - The value to snap.
 * @param {number} gap - The interval gap of the grid.
 * @param {number} [start=0] - Optional starting offset for gap.
 * @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning.
 *
 * @return {number} The snapped value.
 */
var SnapTo = function (value, gap, start, divide)
{
    if (start === undefined) { start = 0; }

    if (gap === 0)
    {
        return value;
    }

    value -= start;
    value = gap * Math.round(value / gap);

    return (divide) ? (start + value) / gap : start + value;
};

module.exports = SnapTo;


/***/ }),

/***/ 3943:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Math.Snap
 */

module.exports = {

    Ceil: __webpack_require__(5659),
    Floor: __webpack_require__(5461),
    To: __webpack_require__(5131)

};


/***/ }),

/***/ 8666:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2013-2023 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser3-plugin-template/blob/master/LICENSE|MIT License}
*/

var Class = __webpack_require__(7473);

/**
 * @classdesc
 * A Global Plugin is installed just once into the Game owned Plugin Manager.
 * It can listen for Game events and respond to them.
 *
 * @class BasePlugin
 * @memberof Phaser.Plugins
 * @constructor
 * @since 3.8.0
 *
 * @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Plugin Manager.
 */
var BasePlugin = new Class({

    initialize:

    function BasePlugin (pluginManager)
    {
        /**
         * A handy reference to the Plugin Manager that is responsible for this plugin.
         * Can be used as a route to gain access to game systems and  events.
         *
         * @name Phaser.Plugins.BasePlugin#pluginManager
         * @type {Phaser.Plugins.PluginManager}
         * @protected
         * @since 3.8.0
         */
        this.pluginManager = pluginManager;

        /**
         * A reference to the Game instance this plugin is running under.
         *
         * @name Phaser.Plugins.BasePlugin#game
         * @type {Phaser.Game}
         * @protected
         * @since 3.8.0
         */
        this.game = pluginManager.game;
    },

    /**
     * The PluginManager calls this method on a Global Plugin when the plugin is first instantiated.
     * It will never be called again on this instance.
     * In here you can set-up whatever you need for this plugin to run.
     * If a plugin is set to automatically start then `BasePlugin.start` will be called immediately after this.
     * On a Scene Plugin, this method is never called. Use {@link Phaser.Plugins.ScenePlugin#boot} instead.
     *
     * @method Phaser.Plugins.BasePlugin#init
     * @since 3.8.0
     *
     * @param {?any} [data] - A value specified by the user, if any, from the `data` property of the plugin's configuration object (if started at game boot) or passed in the PluginManager's `install` method (if started manually).
     */
    init: function ()
    {
    },

    /**
     * The PluginManager calls this method on a Global Plugin when the plugin is started.
     * If a plugin is stopped, and then started again, this will get called again.
     * Typically called immediately after `BasePlugin.init`.
     * On a Scene Plugin, this method is never called.
     *
     * @method Phaser.Plugins.BasePlugin#start
     * @since 3.8.0
     */
    start: function ()
    {
        //  Here are the game-level events you can listen to.
        //  At the very least you should offer a destroy handler for when the game closes down.

        // var eventEmitter = this.game.events;

        // eventEmitter.once('destroy', this.gameDestroy, this);
        // eventEmitter.on('pause', this.gamePause, this);
        // eventEmitter.on('resume', this.gameResume, this);
        // eventEmitter.on('resize', this.gameResize, this);
        // eventEmitter.on('prestep', this.gamePreStep, this);
        // eventEmitter.on('step', this.gameStep, this);
        // eventEmitter.on('poststep', this.gamePostStep, this);
        // eventEmitter.on('prerender', this.gamePreRender, this);
        // eventEmitter.on('postrender', this.gamePostRender, this);
    },

    /**
     * The PluginManager calls this method on a Global Plugin when the plugin is stopped.
     * The game code has requested that your plugin stop doing whatever it does.
     * It is now considered as 'inactive' by the PluginManager.
     * Handle that process here (i.e. stop listening for events, etc)
     * If the plugin is started again then `BasePlugin.start` will be called again.
     * On a Scene Plugin, this method is never called.
     *
     * @method Phaser.Plugins.BasePlugin#stop
     * @since 3.8.0
     */
    stop: function ()
    {
    },

    /**
     * Game instance has been destroyed.
     * You must release everything in here, all references, all objects, free it all up.
     *
     * @method Phaser.Plugins.BasePlugin#destroy
     * @since 3.8.0
     */
    destroy: function ()
    {
        this.pluginManager = null;
        this.game = null;
        this.scene = null;
        this.systems = null;
    }

});

module.exports = BasePlugin;


/***/ }),

/***/ 8456:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

//  Contains the plugins that Phaser uses globally and locally.
//  These are the source objects, not instantiated.
var corePlugins = {};

//  Contains the plugins that the dev has loaded into their game
//  These are the source objects, not instantiated.
var customPlugins = {};

var PluginCache = {};

/**
 * @namespace Phaser.Plugins.PluginCache
 */

/**
 * Static method called directly by the Core internal Plugins.
 * Key is a reference used to get the plugin from the plugins object (i.e. InputPlugin)
 * Plugin is the object to instantiate to create the plugin
 * Mapping is what the plugin is injected into the Scene.Systems as (i.e. input)
 *
 * @method Phaser.Plugins.PluginCache.register
 * @since 3.8.0
 *
 * @param {string} key - A reference used to get this plugin from the plugin cache.
 * @param {function} plugin - The plugin to be stored. Should be the core object, not instantiated.
 * @param {string} mapping - If this plugin is to be injected into the Scene Systems, this is the property key map used.
 * @param {boolean} [custom=false] - Core Scene plugin or a Custom Scene plugin?
 */
PluginCache.register = function (key, plugin, mapping, custom)
{
    if (custom === undefined) { custom = false; }

    corePlugins[key] = { plugin: plugin, mapping: mapping, custom: custom };
};

/**
 * Stores a custom plugin in the global plugin cache.
 * The key must be unique, within the scope of the cache.
 *
 * @method Phaser.Plugins.PluginCache.registerCustom
 * @since 3.8.0
 *
 * @param {string} key - A reference used to get this plugin from the plugin cache.
 * @param {function} plugin - The plugin to be stored. Should be the core object, not instantiated.
 * @param {string} mapping - If this plugin is to be injected into the Scene Systems, this is the property key map used.
 * @param {?any} data - A value to be passed to the plugin's `init` method.
 */
PluginCache.registerCustom = function (key, plugin, mapping, data)
{
    customPlugins[key] = { plugin: plugin, mapping: mapping, data: data };
};

/**
 * Checks if the given key is already being used in the core plugin cache.
 *
 * @method Phaser.Plugins.PluginCache.hasCore
 * @since 3.8.0
 *
 * @param {string} key - The key to check for.
 *
 * @return {boolean} `true` if the key is already in use in the core cache, otherwise `false`.
 */
PluginCache.hasCore = function (key)
{
    return corePlugins.hasOwnProperty(key);
};

/**
 * Checks if the given key is already being used in the custom plugin cache.
 *
 * @method Phaser.Plugins.PluginCache.hasCustom
 * @since 3.8.0
 *
 * @param {string} key - The key to check for.
 *
 * @return {boolean} `true` if the key is already in use in the custom cache, otherwise `false`.
 */
PluginCache.hasCustom = function (key)
{
    return customPlugins.hasOwnProperty(key);
};

/**
 * Returns the core plugin object from the cache based on the given key.
 *
 * @method Phaser.Plugins.PluginCache.getCore
 * @since 3.8.0
 *
 * @param {string} key - The key of the core plugin to get.
 *
 * @return {Phaser.Types.Plugins.CorePluginContainer} The core plugin object.
 */
PluginCache.getCore = function (key)
{
    return corePlugins[key];
};

/**
 * Returns the custom plugin object from the cache based on the given key.
 *
 * @method Phaser.Plugins.PluginCache.getCustom
 * @since 3.8.0
 *
 * @param {string} key - The key of the custom plugin to get.
 *
 * @return {Phaser.Types.Plugins.CustomPluginContainer} The custom plugin object.
 */
PluginCache.getCustom = function (key)
{
    return customPlugins[key];
};

/**
 * Returns an object from the custom cache based on the given key that can be instantiated.
 *
 * @method Phaser.Plugins.PluginCache.getCustomClass
 * @since 3.8.0
 *
 * @param {string} key - The key of the custom plugin to get.
 *
 * @return {function} The custom plugin object.
 */
PluginCache.getCustomClass = function (key)
{
    return (customPlugins.hasOwnProperty(key)) ? customPlugins[key].plugin : null;
};

/**
 * Removes a core plugin based on the given key.
 *
 * @method Phaser.Plugins.PluginCache.remove
 * @since 3.8.0
 *
 * @param {string} key - The key of the core plugin to remove.
 */
PluginCache.remove = function (key)
{
    if (corePlugins.hasOwnProperty(key))
    {
        delete corePlugins[key];
    }
};

/**
 * Removes a custom plugin based on the given key.
 *
 * @method Phaser.Plugins.PluginCache.removeCustom
 * @since 3.8.0
 *
 * @param {string} key - The key of the custom plugin to remove.
 */
PluginCache.removeCustom = function (key)
{
    if (customPlugins.hasOwnProperty(key))
    {
        delete customPlugins[key];
    }
};

/**
 * Removes all Core Plugins.
 *
 * This includes all of the internal system plugins that Phaser needs, like the Input Plugin and Loader Plugin.
 * So be sure you only call this if you do not wish to run Phaser again.
 *
 * @method Phaser.Plugins.PluginCache.destroyCorePlugins
 * @since 3.12.0
 */
PluginCache.destroyCorePlugins = function ()
{
    for (var key in corePlugins)
    {
        if (corePlugins.hasOwnProperty(key))
        {
            delete corePlugins[key];
        }
    }
};

/**
 * Removes all Custom Plugins.
 *
 * @method Phaser.Plugins.PluginCache.destroyCustomPlugins
 * @since 3.12.0
 */
PluginCache.destroyCustomPlugins = function ()
{
    for (var key in customPlugins)
    {
        if (customPlugins.hasOwnProperty(key))
        {
            delete customPlugins[key];
        }
    }
};

module.exports = PluginCache;


/***/ }),

/***/ 5722:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2013-2023 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser3-plugin-template/blob/master/LICENSE|MIT License}
*/

var BasePlugin = __webpack_require__(8666);
var Class = __webpack_require__(7473);
var SceneEvents = __webpack_require__(204);

/**
 * @classdesc
 * A Scene Level Plugin is installed into every Scene and belongs to that Scene.
 * It can listen for Scene events and respond to them.
 * It can map itself to a Scene property, or into the Scene Systems, or both.
 *
 * @class ScenePlugin
 * @memberof Phaser.Plugins
 * @extends Phaser.Plugins.BasePlugin
 * @constructor
 * @since 3.8.0
 *
 * @param {Phaser.Scene} scene - A reference to the Scene that has installed this plugin.
 * @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Plugin Manager.
 * @param {string} pluginKey - The key under which this plugin has been installed into the Scene Systems.
 */
var ScenePlugin = new Class({

    Extends: BasePlugin,

    initialize:

    function ScenePlugin (scene, pluginManager, pluginKey)
    {
        BasePlugin.call(this, pluginManager);

        /**
         * A reference to the Scene that has installed this plugin.
         * Only set if it's a Scene Plugin, otherwise `null`.
         * This property is only set when the plugin is instantiated and added to the Scene, not before.
         * You can use it during the `boot` method.
         *
         * @name Phaser.Plugins.ScenePlugin#scene
         * @type {?Phaser.Scene}
         * @protected
         * @since 3.8.0
         */
        this.scene = scene;

        /**
         * A reference to the Scene Systems of the Scene that has installed this plugin.
         * Only set if it's a Scene Plugin, otherwise `null`.
         * This property is only set when the plugin is instantiated and added to the Scene, not before.
         * You can use it during the `boot` method.
         *
         * @name Phaser.Plugins.ScenePlugin#systems
         * @type {?Phaser.Scenes.Systems}
         * @protected
         * @since 3.8.0
         */
        this.systems = scene.sys;

        /**
         * The key under which this plugin was installed into the Scene Systems.
         *
         * This property is only set when the plugin is instantiated and added to the Scene, not before.
         * You can use it during the `boot` method.
         *
         * @name Phaser.Plugins.ScenePlugin#pluginKey
         * @type {string}
         * @readonly
         * @since 3.54.0
         */
        this.pluginKey = pluginKey;

        scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
    },

    /**
     * This method is called when the Scene boots. It is only ever called once.
     *
     * By this point the plugin properties `scene` and `systems` will have already been set.
     *
     * In here you can listen for {@link Phaser.Scenes.Events Scene events} and set-up whatever you need for this plugin to run.
     * Here are the Scene events you can listen to:
     *
     * - start
     * - ready
     * - preupdate
     * - update
     * - postupdate
     * - resize
     * - pause
     * - resume
     * - sleep
     * - wake
     * - transitioninit
     * - transitionstart
     * - transitioncomplete
     * - transitionout
     * - shutdown
     * - destroy
     *
     * At the very least you should offer a destroy handler for when the Scene closes down, i.e:
     *
     * ```javascript
     * var eventEmitter = this.systems.events;
     * eventEmitter.once('destroy', this.sceneDestroy, this);
     * ```
     *
     * @method Phaser.Plugins.ScenePlugin#boot
     * @since 3.8.0
     */
    boot: function ()
    {
    },

    /**
     * Game instance has been destroyed.
     *
     * You must release everything in here, all references, all objects, free it all up.
     *
     * @method Phaser.Plugins.ScenePlugin#destroy
     * @since 3.8.0
     */
    destroy: function ()
    {
        this.pluginManager = null;
        this.game = null;
        this.scene = null;
        this.systems = null;
    }

});

module.exports = ScenePlugin;


/***/ }),

/***/ 8351:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Phaser Blend Modes.
 *
 * @namespace Phaser.BlendModes
 * @since 3.0.0
 */

module.exports = {

    /**
     * Skips the Blend Mode check in the renderer.
     *
     * @name Phaser.BlendModes.SKIP_CHECK
     * @type {number}
     * @const
     * @since 3.0.0
     */
    SKIP_CHECK: -1,

    /**
     * Normal blend mode. For Canvas and WebGL.
     * This is the default setting and draws new shapes on top of the existing canvas content.
     *
     * @name Phaser.BlendModes.NORMAL
     * @type {number}
     * @const
     * @since 3.0.0
     */
    NORMAL: 0,

    /**
     * Add blend mode. For Canvas and WebGL.
     * Where both shapes overlap the color is determined by adding color values.
     *
     * @name Phaser.BlendModes.ADD
     * @type {number}
     * @const
     * @since 3.0.0
     */
    ADD: 1,

    /**
     * Multiply blend mode. For Canvas and WebGL.
     * The pixels are of the top layer are multiplied with the corresponding pixel of the bottom layer. A darker picture is the result.
     *
     * @name Phaser.BlendModes.MULTIPLY
     * @type {number}
     * @const
     * @since 3.0.0
     */
    MULTIPLY: 2,

    /**
     * Screen blend mode. For Canvas and WebGL.
     * The pixels are inverted, multiplied, and inverted again. A lighter picture is the result (opposite of multiply)
     *
     * @name Phaser.BlendModes.SCREEN
     * @type {number}
     * @const
     * @since 3.0.0
     */
    SCREEN: 3,

    /**
     * Overlay blend mode. For Canvas only.
     * A combination of multiply and screen. Dark parts on the base layer become darker, and light parts become lighter.
     *
     * @name Phaser.BlendModes.OVERLAY
     * @type {number}
     * @const
     * @since 3.0.0
     */
    OVERLAY: 4,

    /**
     * Darken blend mode. For Canvas only.
     * Retains the darkest pixels of both layers.
     *
     * @name Phaser.BlendModes.DARKEN
     * @type {number}
     * @const
     * @since 3.0.0
     */
    DARKEN: 5,

    /**
     * Lighten blend mode. For Canvas only.
     * Retains the lightest pixels of both layers.
     *
     * @name Phaser.BlendModes.LIGHTEN
     * @type {number}
     * @const
     * @since 3.0.0
     */
    LIGHTEN: 6,

    /**
     * Color Dodge blend mode. For Canvas only.
     * Divides the bottom layer by the inverted top layer.
     *
     * @name Phaser.BlendModes.COLOR_DODGE
     * @type {number}
     * @const
     * @since 3.0.0
     */
    COLOR_DODGE: 7,

    /**
     * Color Burn blend mode. For Canvas only.
     * Divides the inverted bottom layer by the top layer, and then inverts the result.
     *
     * @name Phaser.BlendModes.COLOR_BURN
     * @type {number}
     * @const
     * @since 3.0.0
     */
    COLOR_BURN: 8,

    /**
     * Hard Light blend mode. For Canvas only.
     * A combination of multiply and screen like overlay, but with top and bottom layer swapped.
     *
     * @name Phaser.BlendModes.HARD_LIGHT
     * @type {number}
     * @const
     * @since 3.0.0
     */
    HARD_LIGHT: 9,

    /**
     * Soft Light blend mode. For Canvas only.
     * A softer version of hard-light. Pure black or white does not result in pure black or white.
     *
     * @name Phaser.BlendModes.SOFT_LIGHT
     * @type {number}
     * @const
     * @since 3.0.0
     */
    SOFT_LIGHT: 10,

    /**
     * Difference blend mode. For Canvas only.
     * Subtracts the bottom layer from the top layer or the other way round to always get a positive value.
     *
     * @name Phaser.BlendModes.DIFFERENCE
     * @type {number}
     * @const
     * @since 3.0.0
     */
    DIFFERENCE: 11,

    /**
     * Exclusion blend mode. For Canvas only.
     * Like difference, but with lower contrast.
     *
     * @name Phaser.BlendModes.EXCLUSION
     * @type {number}
     * @const
     * @since 3.0.0
     */
    EXCLUSION: 12,

    /**
     * Hue blend mode. For Canvas only.
     * Preserves the luma and chroma of the bottom layer, while adopting the hue of the top layer.
     *
     * @name Phaser.BlendModes.HUE
     * @type {number}
     * @const
     * @since 3.0.0
     */
    HUE: 13,

    /**
     * Saturation blend mode. For Canvas only.
     * Preserves the luma and hue of the bottom layer, while adopting the chroma of the top layer.
     *
     * @name Phaser.BlendModes.SATURATION
     * @type {number}
     * @const
     * @since 3.0.0
     */
    SATURATION: 14,

    /**
     * Color blend mode. For Canvas only.
     * Preserves the luma of the bottom layer, while adopting the hue and chroma of the top layer.
     *
     * @name Phaser.BlendModes.COLOR
     * @type {number}
     * @const
     * @since 3.0.0
     */
    COLOR: 15,

    /**
     * Luminosity blend mode. For Canvas only.
     * Preserves the hue and chroma of the bottom layer, while adopting the luma of the top layer.
     *
     * @name Phaser.BlendModes.LUMINOSITY
     * @type {number}
     * @const
     * @since 3.0.0
     */
    LUMINOSITY: 16,

    /**
     * Alpha erase blend mode. For Canvas and WebGL.
     *
     * @name Phaser.BlendModes.ERASE
     * @type {number}
     * @const
     * @since 3.0.0
     */
    ERASE: 17,

    /**
     * Source-in blend mode. For Canvas only.
     * The new shape is drawn only where both the new shape and the destination canvas overlap. Everything else is made transparent.
     *
     * @name Phaser.BlendModes.SOURCE_IN
     * @type {number}
     * @const
     * @since 3.0.0
     */
    SOURCE_IN: 18,

    /**
     * Source-out blend mode. For Canvas only.
     * The new shape is drawn where it doesn't overlap the existing canvas content.
     *
     * @name Phaser.BlendModes.SOURCE_OUT
     * @type {number}
     * @const
     * @since 3.0.0
     */
    SOURCE_OUT: 19,

    /**
     * Source-out blend mode. For Canvas only.
     * The new shape is only drawn where it overlaps the existing canvas content.
     *
     * @name Phaser.BlendModes.SOURCE_ATOP
     * @type {number}
     * @const
     * @since 3.0.0
     */
    SOURCE_ATOP: 20,

    /**
     * Destination-over blend mode. For Canvas only.
     * New shapes are drawn behind the existing canvas content.
     *
     * @name Phaser.BlendModes.DESTINATION_OVER
     * @type {number}
     * @const
     * @since 3.0.0
     */
    DESTINATION_OVER: 21,

    /**
     * Destination-in blend mode. For Canvas only.
     * The existing canvas content is kept where both the new shape and existing canvas content overlap. Everything else is made transparent.
     *
     * @name Phaser.BlendModes.DESTINATION_IN
     * @type {number}
     * @const
     * @since 3.0.0
     */
    DESTINATION_IN: 22,

    /**
     * Destination-out blend mode. For Canvas only.
     * The existing content is kept where it doesn't overlap the new shape.
     *
     * @name Phaser.BlendModes.DESTINATION_OUT
     * @type {number}
     * @const
     * @since 3.0.0
     */
    DESTINATION_OUT: 23,

    /**
     * Destination-out blend mode. For Canvas only.
     * The existing canvas is only kept where it overlaps the new shape. The new shape is drawn behind the canvas content.
     *
     * @name Phaser.BlendModes.DESTINATION_ATOP
     * @type {number}
     * @const
     * @since 3.0.0
     */
    DESTINATION_ATOP: 24,

    /**
     * Lighten blend mode. For Canvas only.
     * Where both shapes overlap the color is determined by adding color values.
     *
     * @name Phaser.BlendModes.LIGHTER
     * @type {number}
     * @const
     * @since 3.0.0
     */
    LIGHTER: 25,

    /**
     * Copy blend mode. For Canvas only.
     * Only the new shape is shown.
     *
     * @name Phaser.BlendModes.COPY
     * @type {number}
     * @const
     * @since 3.0.0
     */
    COPY: 26,

    /**
     * Xor blend mode. For Canvas only.
     * Shapes are made transparent where both overlap and drawn normal everywhere else.
     *
     * @name Phaser.BlendModes.XOR
     * @type {number}
     * @const
     * @since 3.0.0
     */
    XOR: 27

};


/***/ }),

/***/ 8196:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Phaser Scale Modes.
 *
 * @namespace Phaser.ScaleModes
 * @since 3.0.0
 */

var ScaleModes = {

    /**
     * Default Scale Mode (Linear).
     *
     * @name Phaser.ScaleModes.DEFAULT
     * @type {number}
     * @readonly
     * @since 3.0.0
     */
    DEFAULT: 0,

    /**
     * Linear Scale Mode.
     *
     * @name Phaser.ScaleModes.LINEAR
     * @type {number}
     * @readonly
     * @since 3.0.0
     */
    LINEAR: 0,

    /**
     * Nearest Scale Mode.
     *
     * @name Phaser.ScaleModes.NEAREST
     * @type {number}
     * @readonly
     * @since 3.0.0
     */
    NEAREST: 1

};

module.exports = ScaleModes;


/***/ }),

/***/ 3527:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scale Manager Resize Event.
 *
 * This event is dispatched whenever the Scale Manager detects a resize event from the browser.
 * It sends three parameters to the callback, each of them being Size components. You can read
 * the `width`, `height`, `aspectRatio` and other properties of these components to help with
 * scaling your own game content.
 *
 * @event Phaser.Scale.Events#RESIZE
 * @type {string}
 * @since 3.16.1
 *
 * @param {Phaser.Structs.Size} gameSize - A reference to the Game Size component. This is the un-scaled size of your game canvas.
 * @param {Phaser.Structs.Size} baseSize - A reference to the Base Size component. This is the game size.
 * @param {Phaser.Structs.Size} displaySize - A reference to the Display Size component. This is the scaled canvas size, after applying zoom and scale mode.
 * @param {number} previousWidth - If the `gameSize` has changed, this value contains its previous width, otherwise it contains the current width.
 * @param {number} previousHeight - If the `gameSize` has changed, this value contains its previous height, otherwise it contains the current height.
 */
module.exports = 'resize';


/***/ }),

/***/ 8618:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Game Object Added to Scene Event.
 *
 * This event is dispatched when a Game Object is added to a Scene.
 *
 * Listen for it from a Scene using `this.events.on('addedtoscene', listener)`.
 *
 * @event Phaser.Scenes.Events#ADDED_TO_SCENE
 * @type {string}
 * @since 3.50.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the Scene.
 * @param {Phaser.Scene} scene - The Scene to which the Game Object was added.
 */
module.exports = 'addedtoscene';


/***/ }),

/***/ 4328:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Boot Event.
 *
 * This event is dispatched by a Scene during the Scene Systems boot process. Primarily used by Scene Plugins.
 *
 * Listen to it from a Scene using `this.events.on('boot', listener)`.
 *
 * @event Phaser.Scenes.Events#BOOT
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 */
module.exports = 'boot';


/***/ }),

/***/ 6099:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Create Event.
 *
 * This event is dispatched by a Scene after it has been created by the Scene Manager.
 *
 * If a Scene has a `create` method then this event is emitted _after_ that has run.
 *
 * If there is a transition, this event will be fired after the `TRANSITION_START` event.
 *
 * Listen to it from a Scene using `this.events.on('create', listener)`.
 *
 * @event Phaser.Scenes.Events#CREATE
 * @type {string}
 * @since 3.17.0
 *
 * @param {Phaser.Scene} scene - A reference to the Scene that emitted this event.
 */
module.exports = 'create';


/***/ }),

/***/ 7645:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Destroy Event.
 *
 * This event is dispatched by a Scene during the Scene Systems destroy process.
 *
 * Listen to it from a Scene using `this.events.on('destroy', listener)`.
 *
 * You should destroy any resources that may be in use by your Scene in this event handler.
 *
 * @event Phaser.Scenes.Events#DESTROY
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 */
module.exports = 'destroy';


/***/ }),

/***/ 2710:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Pause Event.
 *
 * This event is dispatched by a Scene when it is paused, either directly via the `pause` method, or as an
 * action from another Scene.
 *
 * Listen to it from a Scene using `this.events.on('pause', listener)`.
 *
 * @event Phaser.Scenes.Events#PAUSE
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 * @param {any} [data] - An optional data object that was passed to this Scene when it was paused.
 */
module.exports = 'pause';


/***/ }),

/***/ 2547:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Post Update Event.
 *
 * This event is dispatched by a Scene during the main game loop step.
 *
 * The event flow for a single step of a Scene is as follows:
 *
 * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE}
 * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE}
 * 3. The `Scene.update` method is called, if it exists
 * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE}
 * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER}
 * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER}
 *
 * Listen to it from a Scene using `this.events.on('postupdate', listener)`.
 *
 * A Scene will only run its step if it is active.
 *
 * @event Phaser.Scenes.Events#POST_UPDATE
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
 * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
 */
module.exports = 'postupdate';


/***/ }),

/***/ 8577:
/***/ ((module) => {

/**
 * @author       samme
 * @copyright    2021 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Pre-Render Event.
 *
 * This event is dispatched by a Scene during the main game loop step.
 *
 * The event flow for a single step of a Scene is as follows:
 *
 * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE}
 * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE}
 * 3. The `Scene.update` method is called, if it exists
 * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE}
 * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER}
 * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER}
 *
 * Listen to this event from a Scene using `this.events.on('prerender', listener)`.
 *
 * A Scene will only render if it is visible.
 *
 * This event is dispatched after the Scene Display List is sorted and before the Scene is rendered.
 *
 * @event Phaser.Scenes.Events#PRE_RENDER
 * @type {string}
 * @since 3.53.0
 *
 * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer that rendered the Scene.
 */
module.exports = 'prerender';


/***/ }),

/***/ 8197:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Pre Update Event.
 *
 * This event is dispatched by a Scene during the main game loop step.
 *
 * The event flow for a single step of a Scene is as follows:
 *
 * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE}
 * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE}
 * 3. The `Scene.update` method is called, if it exists
 * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE}
 * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER}
 * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER}
 *
 * Listen to it from a Scene using `this.events.on('preupdate', listener)`.
 *
 * A Scene will only run its step if it is active.
 *
 * @event Phaser.Scenes.Events#PRE_UPDATE
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
 * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
 */
module.exports = 'preupdate';


/***/ }),

/***/ 8997:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Ready Event.
 *
 * This event is dispatched by a Scene during the Scene Systems start process.
 * By this point in the process the Scene is now fully active and rendering.
 * This event is meant for your game code to use, as all plugins have responded to the earlier 'start' event.
 *
 * Listen to it from a Scene using `this.events.on('ready', listener)`.
 *
 * @event Phaser.Scenes.Events#READY
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 * @param {any} [data] - An optional data object that was passed to this Scene when it was started.
 */
module.exports = 'ready';


/***/ }),

/***/ 7604:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Game Object Removed from Scene Event.
 *
 * This event is dispatched when a Game Object is removed from a Scene.
 *
 * Listen for it from a Scene using `this.events.on('removedfromscene', listener)`.
 *
 * @event Phaser.Scenes.Events#REMOVED_FROM_SCENE
 * @type {string}
 * @since 3.50.0
 *
 * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the Scene.
 * @param {Phaser.Scene} scene - The Scene from which the Game Object was removed.
 */
module.exports = 'removedfromscene';


/***/ }),

/***/ 8999:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Render Event.
 *
 * This event is dispatched by a Scene during the main game loop step.
 *
 * The event flow for a single step of a Scene is as follows:
 *
 * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE}
 * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE}
 * 3. The `Scene.update` method is called, if it exists
 * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE}
 * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER}
 * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER}
 *
 * Listen to it from a Scene using `this.events.on('render', listener)`.
 *
 * A Scene will only render if it is visible.
 *
 * By the time this event is dispatched, the Scene will have already been rendered.
 *
 * @event Phaser.Scenes.Events#RENDER
 * @type {string}
 * @since 3.0.0
 *
 * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer that rendered the Scene.
 */
module.exports = 'render';


/***/ }),

/***/ 9742:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Resume Event.
 *
 * This event is dispatched by a Scene when it is resumed from a paused state, either directly via the `resume` method,
 * or as an action from another Scene.
 *
 * Listen to it from a Scene using `this.events.on('resume', listener)`.
 *
 * @event Phaser.Scenes.Events#RESUME
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 * @param {any} [data] - An optional data object that was passed to this Scene when it was resumed.
 */
module.exports = 'resume';


/***/ }),

/***/ 3667:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Shutdown Event.
 *
 * This event is dispatched by a Scene during the Scene Systems shutdown process.
 *
 * Listen to it from a Scene using `this.events.on('shutdown', listener)`.
 *
 * You should free-up any resources that may be in use by your Scene in this event handler, on the understanding
 * that the Scene may, at any time, become active again. A shutdown Scene is not 'destroyed', it's simply not
 * currently active. Use the [DESTROY]{@linkcode Phaser.Scenes.Events#event:DESTROY} event to completely clear resources.
 *
 * @event Phaser.Scenes.Events#SHUTDOWN
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 * @param {any} [data] - An optional data object that was passed to this Scene when it was shutdown.
 */
module.exports = 'shutdown';


/***/ }),

/***/ 3468:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Sleep Event.
 *
 * This event is dispatched by a Scene when it is sent to sleep, either directly via the `sleep` method,
 * or as an action from another Scene.
 *
 * Listen to it from a Scene using `this.events.on('sleep', listener)`.
 *
 * @event Phaser.Scenes.Events#SLEEP
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 * @param {any} [data] - An optional data object that was passed to this Scene when it was sent to sleep.
 */
module.exports = 'sleep';


/***/ }),

/***/ 7840:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Start Event.
 *
 * This event is dispatched by a Scene during the Scene Systems start process. Primarily used by Scene Plugins.
 *
 * Listen to it from a Scene using `this.events.on('start', listener)`.
 *
 * @event Phaser.Scenes.Events#START
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 */
module.exports = 'start';


/***/ }),

/***/ 9896:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Transition Complete Event.
 *
 * This event is dispatched by the Target Scene of a transition.
 *
 * It happens when the transition process has completed. This occurs when the duration timer equals or exceeds the duration
 * of the transition.
 *
 * Listen to it from a Scene using `this.events.on('transitioncomplete', listener)`.
 *
 * The Scene Transition event flow is as follows:
 *
 * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event.
 * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method.
 * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ...
 * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to.
 * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes.
 *
 * @event Phaser.Scenes.Events#TRANSITION_COMPLETE
 * @type {string}
 * @since 3.5.0
 *
 * @param {Phaser.Scene} scene -The Scene on which the transitioned completed.
 */
module.exports = 'transitioncomplete';


/***/ }),

/***/ 5103:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Transition Init Event.
 *
 * This event is dispatched by the Target Scene of a transition.
 *
 * It happens immediately after the `Scene.init` method is called. If the Scene does not have an `init` method,
 * this event is not dispatched.
 *
 * Listen to it from a Scene using `this.events.on('transitioninit', listener)`.
 *
 * The Scene Transition event flow is as follows:
 *
 * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event.
 * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method.
 * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ...
 * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to.
 * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes.
 *
 * @event Phaser.Scenes.Events#TRANSITION_INIT
 * @type {string}
 * @since 3.5.0
 *
 * @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from.
 * @param {number} duration - The duration of the transition in ms.
 */
module.exports = 'transitioninit';


/***/ }),

/***/ 3162:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Transition Out Event.
 *
 * This event is dispatched by a Scene when it initiates a transition to another Scene.
 *
 * Listen to it from a Scene using `this.events.on('transitionout', listener)`.
 *
 * The Scene Transition event flow is as follows:
 *
 * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event.
 * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method.
 * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ...
 * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to.
 * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes.
 *
 * @event Phaser.Scenes.Events#TRANSITION_OUT
 * @type {string}
 * @since 3.5.0
 *
 * @param {Phaser.Scene} target - A reference to the Scene that is being transitioned to.
 * @param {number} duration - The duration of the transition in ms.
 */
module.exports = 'transitionout';


/***/ }),

/***/ 7841:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Transition Start Event.
 *
 * This event is dispatched by the Target Scene of a transition, only if that Scene was not asleep.
 *
 * It happens immediately after the `Scene.create` method is called. If the Scene does not have a `create` method,
 * this event is dispatched anyway.
 *
 * If the Target Scene was sleeping then the [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} event is
 * dispatched instead of this event.
 *
 * Listen to it from a Scene using `this.events.on('transitionstart', listener)`.
 *
 * The Scene Transition event flow is as follows:
 *
 * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event.
 * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method.
 * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ...
 * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to.
 * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes.
 *
 * @event Phaser.Scenes.Events#TRANSITION_START
 * @type {string}
 * @since 3.5.0
 *
 * @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from.
 * @param {number} duration - The duration of the transition in ms.
 */
module.exports = 'transitionstart';


/***/ }),

/***/ 6454:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Transition Wake Event.
 *
 * This event is dispatched by the Target Scene of a transition, only if that Scene was asleep before
 * the transition began. If the Scene was not asleep the [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} event is dispatched instead.
 *
 * Listen to it from a Scene using `this.events.on('transitionwake', listener)`.
 *
 * The Scene Transition event flow is as follows:
 *
 * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event.
 * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method.
 * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ...
 * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to.
 * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes.
 *
 * @event Phaser.Scenes.Events#TRANSITION_WAKE
 * @type {string}
 * @since 3.5.0
 *
 * @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from.
 * @param {number} duration - The duration of the transition in ms.
 */
module.exports = 'transitionwake';


/***/ }),

/***/ 6536:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Update Event.
 *
 * This event is dispatched by a Scene during the main game loop step.
 *
 * The event flow for a single step of a Scene is as follows:
 *
 * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE}
 * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE}
 * 3. The `Scene.update` method is called, if it exists and the Scene is in a Running state, otherwise this is skipped.
 * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE}
 * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER}
 * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER}
 *
 * Listen to it from a Scene using `this.events.on('update', listener)`.
 *
 * A Scene will only run its step if it is active.
 *
 * @event Phaser.Scenes.Events#UPDATE
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
 * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
 */
module.exports = 'update';


/***/ }),

/***/ 3875:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * The Scene Systems Wake Event.
 *
 * This event is dispatched by a Scene when it is woken from sleep, either directly via the `wake` method,
 * or as an action from another Scene.
 *
 * Listen to it from a Scene using `this.events.on('wake', listener)`.
 *
 * @event Phaser.Scenes.Events#WAKE
 * @type {string}
 * @since 3.0.0
 *
 * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event.
 * @param {any} [data] - An optional data object that was passed to this Scene when it was woken up.
 */
module.exports = 'wake';


/***/ }),

/***/ 204:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Scenes.Events
 */

module.exports = {

    ADDED_TO_SCENE: __webpack_require__(8618),
    BOOT: __webpack_require__(4328),
    CREATE: __webpack_require__(6099),
    DESTROY: __webpack_require__(7645),
    PAUSE: __webpack_require__(2710),
    POST_UPDATE: __webpack_require__(2547),
    PRE_RENDER: __webpack_require__(8577),
    PRE_UPDATE: __webpack_require__(8197),
    READY: __webpack_require__(8997),
    REMOVED_FROM_SCENE: __webpack_require__(7604),
    RENDER: __webpack_require__(8999),
    RESUME: __webpack_require__(9742),
    SHUTDOWN: __webpack_require__(3667),
    SLEEP: __webpack_require__(3468),
    START: __webpack_require__(7840),
    TRANSITION_COMPLETE: __webpack_require__(9896),
    TRANSITION_INIT: __webpack_require__(5103),
    TRANSITION_OUT: __webpack_require__(3162),
    TRANSITION_START: __webpack_require__(7841),
    TRANSITION_WAKE: __webpack_require__(6454),
    UPDATE: __webpack_require__(6536),
    WAKE: __webpack_require__(3875)

};


/***/ }),

/***/ 2362:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = __webpack_require__(7473);
var Clamp = __webpack_require__(2915);
var Extend = __webpack_require__(1030);

/**
 * @classdesc
 * A Frame is a section of a Texture.
 *
 * @class Frame
 * @memberof Phaser.Textures
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Textures.Texture} texture - The Texture this Frame is a part of.
 * @param {(number|string)} name - The name of this Frame. The name is unique within the Texture.
 * @param {number} sourceIndex - The index of the TextureSource that this Frame is a part of.
 * @param {number} x - The x coordinate of the top-left of this Frame.
 * @param {number} y - The y coordinate of the top-left of this Frame.
 * @param {number} width - The width of this Frame.
 * @param {number} height - The height of this Frame.
 */
var Frame = new Class({

    initialize:

    function Frame (texture, name, sourceIndex, x, y, width, height)
    {
        /**
         * The Texture this Frame is a part of.
         *
         * @name Phaser.Textures.Frame#texture
         * @type {Phaser.Textures.Texture}
         * @since 3.0.0
         */
        this.texture = texture;

        /**
         * The name of this Frame.
         * The name is unique within the Texture.
         *
         * @name Phaser.Textures.Frame#name
         * @type {string}
         * @since 3.0.0
         */
        this.name = name;

        /**
         * The TextureSource this Frame is part of.
         *
         * @name Phaser.Textures.Frame#source
         * @type {Phaser.Textures.TextureSource}
         * @since 3.0.0
         */
        this.source = texture.source[sourceIndex];

        /**
         * The index of the TextureSource in the Texture sources array.
         *
         * @name Phaser.Textures.Frame#sourceIndex
         * @type {number}
         * @since 3.0.0
         */
        this.sourceIndex = sourceIndex;

        /**
         * A reference to the Texture Source WebGL Texture that this Frame is using.
         *
         * @name Phaser.Textures.Frame#glTexture
         * @type {?WebGLTexture}
         * @default null
         * @since 3.11.0
         */
        this.glTexture = this.source.glTexture;

        /**
         * X position within the source image to cut from.
         *
         * @name Phaser.Textures.Frame#cutX
         * @type {number}
         * @since 3.0.0
         */
        this.cutX;

        /**
         * Y position within the source image to cut from.
         *
         * @name Phaser.Textures.Frame#cutY
         * @type {number}
         * @since 3.0.0
         */
        this.cutY;

        /**
         * The width of the area in the source image to cut.
         *
         * @name Phaser.Textures.Frame#cutWidth
         * @type {number}
         * @since 3.0.0
         */
        this.cutWidth;

        /**
         * The height of the area in the source image to cut.
         *
         * @name Phaser.Textures.Frame#cutHeight
         * @type {number}
         * @since 3.0.0
         */
        this.cutHeight;

        /**
         * The X rendering offset of this Frame, taking trim into account.
         *
         * @name Phaser.Textures.Frame#x
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.x = 0;

        /**
         * The Y rendering offset of this Frame, taking trim into account.
         *
         * @name Phaser.Textures.Frame#y
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.y = 0;

        /**
         * The rendering width of this Frame, taking trim into account.
         *
         * @name Phaser.Textures.Frame#width
         * @type {number}
         * @since 3.0.0
         */
        this.width;

        /**
         * The rendering height of this Frame, taking trim into account.
         *
         * @name Phaser.Textures.Frame#height
         * @type {number}
         * @since 3.0.0
         */
        this.height;

        /**
         * Half the width, floored.
         * Precalculated for the renderer.
         *
         * @name Phaser.Textures.Frame#halfWidth
         * @type {number}
         * @since 3.0.0
         */
        this.halfWidth;

        /**
         * Half the height, floored.
         * Precalculated for the renderer.
         *
         * @name Phaser.Textures.Frame#halfHeight
         * @type {number}
         * @since 3.0.0
         */
        this.halfHeight;

        /**
         * The x center of this frame, floored.
         *
         * @name Phaser.Textures.Frame#centerX
         * @type {number}
         * @since 3.0.0
         */
        this.centerX;

        /**
         * The y center of this frame, floored.
         *
         * @name Phaser.Textures.Frame#centerY
         * @type {number}
         * @since 3.0.0
         */
        this.centerY;

        /**
         * The horizontal pivot point of this Frame.
         *
         * @name Phaser.Textures.Frame#pivotX
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.pivotX = 0;

        /**
         * The vertical pivot point of this Frame.
         *
         * @name Phaser.Textures.Frame#pivotY
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.pivotY = 0;

        /**
         * Does this Frame have a custom pivot point?
         *
         * @name Phaser.Textures.Frame#customPivot
         * @type {boolean}
         * @default false
         * @since 3.0.0
         */
        this.customPivot = false;

        /**
         * **CURRENTLY UNSUPPORTED**
         *
         * Is this frame is rotated or not in the Texture?
         * Rotation allows you to use rotated frames in texture atlas packing.
         * It has nothing to do with Sprite rotation.
         *
         * @name Phaser.Textures.Frame#rotated
         * @type {boolean}
         * @default false
         * @since 3.0.0
         */
        this.rotated = false;

        /**
         * Over-rides the Renderer setting.
         * -1 = use Renderer Setting
         * 0 = No rounding
         * 1 = Round
         *
         * @name Phaser.Textures.Frame#autoRound
         * @type {number}
         * @default -1
         * @since 3.0.0
         */
        this.autoRound = -1;

        /**
         * Any Frame specific custom data can be stored here.
         *
         * @name Phaser.Textures.Frame#customData
         * @type {object}
         * @since 3.0.0
         */
        this.customData = {};

        /**
         * WebGL UV u0 value.
         *
         * @name Phaser.Textures.Frame#u0
         * @type {number}
         * @default 0
         * @since 3.11.0
         */
        this.u0 = 0;

        /**
         * WebGL UV v0 value.
         *
         * @name Phaser.Textures.Frame#v0
         * @type {number}
         * @default 0
         * @since 3.11.0
         */
        this.v0 = 0;

        /**
         * WebGL UV u1 value.
         *
         * @name Phaser.Textures.Frame#u1
         * @type {number}
         * @default 0
         * @since 3.11.0
         */
        this.u1 = 0;

        /**
         * WebGL UV v1 value.
         *
         * @name Phaser.Textures.Frame#v1
         * @type {number}
         * @default 0
         * @since 3.11.0
         */
        this.v1 = 0;

        /**
         * The un-modified source frame, trim and UV data.
         *
         * @name Phaser.Textures.Frame#data
         * @type {object}
         * @private
         * @since 3.0.0
         */
        this.data = {
            cut: {
                x: 0,
                y: 0,
                w: 0,
                h: 0,
                r: 0,
                b: 0
            },
            trim: false,
            sourceSize: {
                w: 0,
                h: 0
            },
            spriteSourceSize: {
                x: 0,
                y: 0,
                w: 0,
                h: 0,
                r: 0,
                b: 0
            },
            radius: 0,
            drawImage: {
                x: 0,
                y: 0,
                width: 0,
                height: 0
            },
            is3Slice: false,
            scale9: false,
            scale9Borders: {
                x: 0,
                y: 0,
                w: 0,
                h: 0
            }
        };

        this.setSize(width, height, x, y);
    },

    /**
     * Sets the width, height, x and y of this Frame.
     *
     * This is called automatically by the constructor
     * and should rarely be changed on-the-fly.
     *
     * @method Phaser.Textures.Frame#setSize
     * @since 3.7.0
     *
     * @param {number} width - The width of the frame before being trimmed.
     * @param {number} height - The height of the frame before being trimmed.
     * @param {number} [x=0] - The x coordinate of the top-left of this Frame.
     * @param {number} [y=0] - The y coordinate of the top-left of this Frame.
     *
     * @return {this} This Frame object.
     */
    setSize: function (width, height, x, y)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = 0; }

        this.cutX = x;
        this.cutY = y;
        this.cutWidth = width;
        this.cutHeight = height;

        this.width = width;
        this.height = height;

        this.halfWidth = Math.floor(width * 0.5);
        this.halfHeight = Math.floor(height * 0.5);

        this.centerX = Math.floor(width / 2);
        this.centerY = Math.floor(height / 2);

        var data = this.data;
        var cut = data.cut;

        cut.x = x;
        cut.y = y;
        cut.w = width;
        cut.h = height;
        cut.r = x + width;
        cut.b = y + height;

        data.sourceSize.w = width;
        data.sourceSize.h = height;

        data.spriteSourceSize.w = width;
        data.spriteSourceSize.h = height;

        data.radius = 0.5 * Math.sqrt(width * width + height * height);

        var drawImage = data.drawImage;

        drawImage.x = x;
        drawImage.y = y;
        drawImage.width = width;
        drawImage.height = height;

        return this.updateUVs();
    },

    /**
     * If the frame was trimmed when added to the Texture Atlas, this records the trim and source data.
     *
     * @method Phaser.Textures.Frame#setTrim
     * @since 3.0.0
     *
     * @param {number} actualWidth - The width of the frame before being trimmed.
     * @param {number} actualHeight - The height of the frame before being trimmed.
     * @param {number} destX - The destination X position of the trimmed frame for display.
     * @param {number} destY - The destination Y position of the trimmed frame for display.
     * @param {number} destWidth - The destination width of the trimmed frame for display.
     * @param {number} destHeight - The destination height of the trimmed frame for display.
     *
     * @return {this} This Frame object.
     */
    setTrim: function (actualWidth, actualHeight, destX, destY, destWidth, destHeight)
    {
        var data = this.data;
        var ss = data.spriteSourceSize;

        //  Store actual values

        data.trim = true;

        data.sourceSize.w = actualWidth;
        data.sourceSize.h = actualHeight;

        ss.x = destX;
        ss.y = destY;
        ss.w = destWidth;
        ss.h = destHeight;
        ss.r = destX + destWidth;
        ss.b = destY + destHeight;

        //  Adjust properties
        this.x = destX;
        this.y = destY;

        this.width = destWidth;
        this.height = destHeight;

        this.halfWidth = destWidth * 0.5;
        this.halfHeight = destHeight * 0.5;

        this.centerX = Math.floor(destWidth / 2);
        this.centerY = Math.floor(destHeight / 2);

        return this.updateUVs();
    },

    /**
     * Sets the scale9 center rectangle values.
     *
     * Scale9 is a feature of Texture Packer, allowing you to define a nine-slice scaling grid.
     *
     * This is set automatically by the JSONArray and JSONHash parsers.
     *
     * @method Phaser.Textures.Frame#setScale9
     * @since 3.70.0
     *
     * @param {number} x - The left coordinate of the center scale9 rectangle.
     * @param {number} y - The top coordinate of the center scale9 rectangle.
     * @param {number} width - The width of the center scale9 rectangle.
     * @param {number} height - The height coordinate of the center scale9 rectangle.
     *
     * @return {this} This Frame object.
     */
    setScale9: function (x, y, width, height)
    {
        var data = this.data;

        data.scale9 = true;
        data.is3Slice = (y === 0 && height === this.height);

        data.scale9Borders.x = x;
        data.scale9Borders.y = y;
        data.scale9Borders.w = width;
        data.scale9Borders.h = height;

        return this;
    },

    /**
     * Takes a crop data object and, based on the rectangular region given, calculates the
     * required UV coordinates in order to crop this Frame for WebGL and Canvas rendering.
     *
     * This is called directly by the Game Object Texture Components `setCrop` method.
     * Please use that method to crop a Game Object.
     *
     * @method Phaser.Textures.Frame#setCropUVs
     * @since 3.11.0
     *
     * @param {object} crop - The crop data object. This is the `GameObject._crop` property.
     * @param {number} x - The x coordinate to start the crop from. Cannot be negative or exceed the Frame width.
     * @param {number} y - The y coordinate to start the crop from. Cannot be negative or exceed the Frame height.
     * @param {number} width - The width of the crop rectangle. Cannot exceed the Frame width.
     * @param {number} height - The height of the crop rectangle. Cannot exceed the Frame height.
     * @param {boolean} flipX - Does the parent Game Object have flipX set?
     * @param {boolean} flipY - Does the parent Game Object have flipY set?
     *
     * @return {object} The updated crop data object.
     */
    setCropUVs: function (crop, x, y, width, height, flipX, flipY)
    {
        //  Clamp the input values

        var cx = this.cutX;
        var cy = this.cutY;
        var cw = this.cutWidth;
        var ch = this.cutHeight;
        var rw = this.realWidth;
        var rh = this.realHeight;

        x = Clamp(x, 0, rw);
        y = Clamp(y, 0, rh);

        width = Clamp(width, 0, rw - x);
        height = Clamp(height, 0, rh - y);

        var ox = cx + x;
        var oy = cy + y;
        var ow = width;
        var oh = height;

        var data = this.data;

        if (data.trim)
        {
            var ss = data.spriteSourceSize;

            //  Need to check for intersection between the cut area and the crop area
            //  If there is none, we set UV to be empty, otherwise set it to be the intersection area

            width = Clamp(width, 0, cw - x);
            height = Clamp(height, 0, ch - y);

            var cropRight = x + width;
            var cropBottom = y + height;

            var intersects = !(ss.r < x || ss.b < y || ss.x > cropRight || ss.y > cropBottom);

            if (intersects)
            {
                var ix = Math.max(ss.x, x);
                var iy = Math.max(ss.y, y);
                var iw = Math.min(ss.r, cropRight) - ix;
                var ih = Math.min(ss.b, cropBottom) - iy;

                ow = iw;
                oh = ih;

                if (flipX)
                {
                    ox = cx + (cw - (ix - ss.x) - iw);
                }
                else
                {
                    ox = cx + (ix - ss.x);
                }

                if (flipY)
                {
                    oy = cy + (ch - (iy - ss.y) - ih);
                }
                else
                {
                    oy = cy + (iy - ss.y);
                }

                x = ix;
                y = iy;

                width = iw;
                height = ih;
            }
            else
            {
                ox = 0;
                oy = 0;
                ow = 0;
                oh = 0;
            }
        }
        else
        {
            if (flipX)
            {
                ox = cx + (cw - x - width);
            }

            if (flipY)
            {
                oy = cy + (ch - y - height);
            }
        }

        var tw = this.source.width;
        var th = this.source.height;

        //  Map the given coordinates into UV space, clamping to the 0-1 range.

        crop.u0 = Math.max(0, ox / tw);
        crop.v0 = Math.max(0, oy / th);
        crop.u1 = Math.min(1, (ox + ow) / tw);
        crop.v1 = Math.min(1, (oy + oh) / th);

        crop.x = x;
        crop.y = y;

        crop.cx = ox;
        crop.cy = oy;
        crop.cw = ow;
        crop.ch = oh;

        crop.width = width;
        crop.height = height;

        crop.flipX = flipX;
        crop.flipY = flipY;

        return crop;
    },

    /**
     * Takes a crop data object and recalculates the UVs based on the dimensions inside the crop object.
     * Called automatically by `setFrame`.
     *
     * @method Phaser.Textures.Frame#updateCropUVs
     * @since 3.11.0
     *
     * @param {object} crop - The crop data object. This is the `GameObject._crop` property.
     * @param {boolean} flipX - Does the parent Game Object have flipX set?
     * @param {boolean} flipY - Does the parent Game Object have flipY set?
     *
     * @return {object} The updated crop data object.
     */
    updateCropUVs: function (crop, flipX, flipY)
    {
        return this.setCropUVs(crop, crop.x, crop.y, crop.width, crop.height, flipX, flipY);
    },

    /**
     * Directly sets the canvas and WebGL UV data for this frame.
     *
     * Use this if you need to override the values that are generated automatically
     * when the Frame is created.
     *
     * @method Phaser.Textures.Frame#setUVs
     * @since 3.50.0
     *
     * @param {number} width - Width of this frame for the Canvas data.
     * @param {number} height - Height of this frame for the Canvas data.
     * @param {number} u0 - UV u0 value.
     * @param {number} v0 - UV v0 value.
     * @param {number} u1 - UV u1 value.
     * @param {number} v1 - UV v1 value.
     *
     * @return {this} This Frame object.
     */
    setUVs: function (width, height, u0, v0, u1, v1)
    {
        //  Canvas data

        var cd = this.data.drawImage;

        cd.width = width;
        cd.height = height;

        //  WebGL data

        this.u0 = u0;
        this.v0 = v0;

        this.u1 = u1;
        this.v1 = v1;

        return this;
    },

    /**
     * Updates the internal WebGL UV cache and the drawImage cache.
     *
     * @method Phaser.Textures.Frame#updateUVs
     * @since 3.0.0
     *
     * @return {this} This Frame object.
     */
    updateUVs: function ()
    {
        var cx = this.cutX;
        var cy = this.cutY;
        var cw = this.cutWidth;
        var ch = this.cutHeight;

        //  Canvas data

        var cd = this.data.drawImage;

        cd.width = cw;
        cd.height = ch;

        //  WebGL data

        var tw = this.source.width;
        var th = this.source.height;

        this.u0 = cx / tw;
        this.v0 = cy / th;

        this.u1 = (cx + cw) / tw;
        this.v1 = (cy + ch) / th;

        return this;
    },

    /**
     * Updates the internal WebGL UV cache.
     *
     * @method Phaser.Textures.Frame#updateUVsInverted
     * @since 3.0.0
     *
     * @return {this} This Frame object.
     */
    updateUVsInverted: function ()
    {
        var tw = this.source.width;
        var th = this.source.height;

        this.u0 = (this.cutX + this.cutHeight) / tw;
        this.v0 = this.cutY / th;

        this.u1 = this.cutX / tw;
        this.v1 = (this.cutY + this.cutWidth) / th;

        return this;
    },

    /**
     * Clones this Frame into a new Frame object.
     *
     * @method Phaser.Textures.Frame#clone
     * @since 3.0.0
     *
     * @return {Phaser.Textures.Frame} A clone of this Frame.
     */
    clone: function ()
    {
        var clone = new Frame(this.texture, this.name, this.sourceIndex);

        clone.cutX = this.cutX;
        clone.cutY = this.cutY;
        clone.cutWidth = this.cutWidth;
        clone.cutHeight = this.cutHeight;

        clone.x = this.x;
        clone.y = this.y;

        clone.width = this.width;
        clone.height = this.height;

        clone.halfWidth = this.halfWidth;
        clone.halfHeight = this.halfHeight;

        clone.centerX = this.centerX;
        clone.centerY = this.centerY;

        clone.rotated = this.rotated;

        clone.data = Extend(true, clone.data, this.data);

        clone.updateUVs();

        return clone;
    },

    /**
     * Destroys this Frame by nulling its reference to the parent Texture and and data objects.
     *
     * @method Phaser.Textures.Frame#destroy
     * @since 3.0.0
     */
    destroy: function ()
    {
        this.texture = null;
        this.source = null;
        this.glTexture = null;
        this.customData = null;
        this.data = null;
    },

    /**
     * The width of the Frame in its un-trimmed, un-padded state, as prepared in the art package,
     * before being packed.
     *
     * @name Phaser.Textures.Frame#realWidth
     * @type {number}
     * @readonly
     * @since 3.0.0
     */
    realWidth: {

        get: function ()
        {
            return this.data.sourceSize.w;
        }

    },

    /**
     * The height of the Frame in its un-trimmed, un-padded state, as prepared in the art package,
     * before being packed.
     *
     * @name Phaser.Textures.Frame#realHeight
     * @type {number}
     * @readonly
     * @since 3.0.0
     */
    realHeight: {

        get: function ()
        {
            return this.data.sourceSize.h;
        }

    },

    /**
     * The radius of the Frame (derived from sqrt(w * w + h * h) / 2)
     *
     * @name Phaser.Textures.Frame#radius
     * @type {number}
     * @readonly
     * @since 3.0.0
     */
    radius: {

        get: function ()
        {
            return this.data.radius;
        }

    },

    /**
     * Is the Frame trimmed or not?
     *
     * @name Phaser.Textures.Frame#trimmed
     * @type {boolean}
     * @readonly
     * @since 3.0.0
     */
    trimmed: {

        get: function ()
        {
            return this.data.trim;
        }

    },

    /**
     * Does the Frame have scale9 border data?
     *
     * @name Phaser.Textures.Frame#scale9
     * @type {boolean}
     * @readonly
     * @since 3.70.0
     */
    scale9: {

        get: function ()
        {
            return this.data.scale9;
        }

    },

    /**
     * If the Frame has scale9 border data, is it 3-slice or 9-slice data?
     *
     * @name Phaser.Textures.Frame#is3Slice
     * @type {boolean}
     * @readonly
     * @since 3.70.0
     */
    is3Slice: {

        get: function ()
        {
            return this.data.is3Slice;
        }

    },

    /**
     * The Canvas drawImage data object.
     *
     * @name Phaser.Textures.Frame#canvasData
     * @type {object}
     * @readonly
     * @since 3.0.0
     */
    canvasData: {

        get: function ()
        {
            return this.data.drawImage;
        }

    }

});

module.exports = Frame;


/***/ }),

/***/ 1864:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Retrieves the value of the given key from an object.
 *
 * @function Phaser.Tweens.Builders.GetBoolean
 * @since 3.0.0
 *
 * @param {object} source - The object to retrieve the value from.
 * @param {string} key - The key to look for in the `source` object.
 * @param {boolean} defaultValue - The default value to return if the `key` doesn't exist or if no `source` object is provided.
 *
 * @return {boolean} The retrieved value.
 */
var GetBoolean = function (source, key, defaultValue)
{
    if (!source)
    {
        return defaultValue;
    }
    else if (source.hasOwnProperty(key))
    {
        return source[key];
    }
    else
    {
        return defaultValue;
    }
};

module.exports = GetBoolean;


/***/ }),

/***/ 3747:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Phaser Tween States.
 *
 * @namespace Phaser.Tweens.States
 * @memberof Phaser.Tweens
 * @since 3.60.0
 */

/**
 * Phaser Tween state constants.
 *
 * @typedef {Phaser.Tweens.States} Phaser.Tweens.StateType
 * @memberof Phaser.Tweens
 * @since 3.60.0
 */

var TWEEN_CONST = {

    /**
     * TweenData state.
     *
     * @name Phaser.Tweens.States.CREATED
     * @type {number}
     * @const
     * @since 3.0.0
     */
    CREATED: 0,

    //  1 used to be INIT prior to 3.60

    /**
     * TweenData state.
     *
     * @name Phaser.Tweens.States.DELAY
     * @type {number}
     * @const
     * @since 3.0.0
     */
    DELAY: 2,

    //  3 used to be OFFSET_DELAY prior to 3.60

    /**
     * TweenData state.
     *
     * @name Phaser.Tweens.States.PENDING_RENDER
     * @type {number}
     * @const
     * @since 3.0.0
     */
    PENDING_RENDER: 4,

    /**
     * TweenData state.
     *
     * @name Phaser.Tweens.States.PLAYING_FORWARD
     * @type {number}
     * @const
     * @since 3.0.0
     */
    PLAYING_FORWARD: 5,

    /**
     * TweenData state.
     *
     * @name Phaser.Tweens.States.PLAYING_BACKWARD
     * @type {number}
     * @const
     * @since 3.0.0
     */
    PLAYING_BACKWARD: 6,

    /**
     * TweenData state.
     *
     * @name Phaser.Tweens.States.HOLD_DELAY
     * @type {number}
     * @const
     * @since 3.0.0
     */
    HOLD_DELAY: 7,

    /**
     * TweenData state.
     *
     * @name Phaser.Tweens.States.REPEAT_DELAY
     * @type {number}
     * @const
     * @since 3.0.0
     */
    REPEAT_DELAY: 8,

    /**
     * TweenData state.
     *
     * @name Phaser.Tweens.States.COMPLETE
     * @type {number}
     * @const
     * @since 3.0.0
     */
    COMPLETE: 9,

    //  Tween specific (starts from 20 to cleanly allow extra TweenData consts in the future)

    /**
     * Tween state. The Tween has been created but has not yet been added to the Tween Manager.
     *
     * @name Phaser.Tweens.States.PENDING
     * @type {number}
     * @const
     * @since 3.0.0
     */
    PENDING: 20,

    /**
     * Tween state. The Tween is active within the Tween Manager. This means it is either playing,
     * or was playing and is currently paused, but in both cases it's still being processed by
     * the Tween Manager, so is considered 'active'.
     *
     * @name Phaser.Tweens.States.ACTIVE
     * @type {number}
     * @const
     * @since 3.0.0
     */
    ACTIVE: 21,

    /**
     * Tween state. The Tween is waiting for a loop countdown to elapse.
     *
     * @name Phaser.Tweens.States.LOOP_DELAY
     * @type {number}
     * @const
     * @since 3.0.0
     */
    LOOP_DELAY: 22,

    /**
     * Tween state. The Tween is waiting for a complete delay to elapse.
     *
     * @name Phaser.Tweens.States.COMPLETE_DELAY
     * @type {number}
     * @const
     * @since 3.0.0
     */
    COMPLETE_DELAY: 23,

    /**
     * Tween state. The Tween is waiting for a starting delay to elapse.
     *
     * @name Phaser.Tweens.States.START_DELAY
     * @type {number}
     * @const
     * @since 3.0.0
     */
    START_DELAY: 24,

    /**
     * Tween state. The Tween has finished playback and is waiting to be removed from the Tween Manager.
     *
     * @name Phaser.Tweens.States.PENDING_REMOVE
     * @type {number}
     * @const
     * @since 3.0.0
     */
    PENDING_REMOVE: 25,

    /**
     * Tween state. The Tween has been removed from the Tween Manager.
     *
     * @name Phaser.Tweens.States.REMOVED
     * @type {number}
     * @const
     * @since 3.0.0
     */
    REMOVED: 26,

    /**
     * Tween state. The Tween has finished playback but was flagged as 'persistent' during creation,
     * so will not be automatically removed by the Tween Manager.
     *
     * @name Phaser.Tweens.States.FINISHED
     * @type {number}
     * @const
     * @since 3.60.0
     */
    FINISHED: 27,

    /**
     * Tween state. The Tween has been destroyed and can no longer be played by a Tween Manager.
     *
     * @name Phaser.Tweens.States.DESTROYED
     * @type {number}
     * @const
     * @since 3.60.0
     */
    DESTROYED: 28,

    /**
     * A large integer value used for 'infinite' style countdowns.
     *
     * Similar use-case to Number.MAX_SAFE_INTEGER but we cannot use that because it's not
     * supported on IE.
     *
     * @name Phaser.Tweens.States.MAX
     * @type {number}
     * @const
     * @since 3.60.0
     */
    MAX: 999999999999

};

module.exports = TWEEN_CONST;


/***/ }),

/***/ 7473:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

//  Taken from klasse by mattdesl https://github.com/mattdesl/klasse

function hasGetterOrSetter (def)
{
    return (!!def.get && typeof def.get === 'function') || (!!def.set && typeof def.set === 'function');
}

function getProperty (definition, k, isClassDescriptor)
{
    //  This may be a lightweight object, OR it might be a property that was defined previously.

    //  For simple class descriptors we can just assume its NOT previously defined.
    var def = (isClassDescriptor) ? definition[k] : Object.getOwnPropertyDescriptor(definition, k);

    if (!isClassDescriptor && def.value && typeof def.value === 'object')
    {
        def = def.value;
    }

    //  This might be a regular property, or it may be a getter/setter the user defined in a class.
    if (def && hasGetterOrSetter(def))
    {
        if (typeof def.enumerable === 'undefined')
        {
            def.enumerable = true;
        }

        if (typeof def.configurable === 'undefined')
        {
            def.configurable = true;
        }

        return def;
    }
    else
    {
        return false;
    }
}

function hasNonConfigurable (obj, k)
{
    var prop = Object.getOwnPropertyDescriptor(obj, k);

    if (!prop)
    {
        return false;
    }

    if (prop.value && typeof prop.value === 'object')
    {
        prop = prop.value;
    }

    if (prop.configurable === false)
    {
        return true;
    }

    return false;
}

/**
 * Extends the given `myClass` object's prototype with the properties of `definition`.
 *
 * @function extend
 * @ignore
 * @param {Object} ctor The constructor object to mix into.
 * @param {Object} definition A dictionary of functions for the class.
 * @param {boolean} isClassDescriptor Is the definition a class descriptor?
 * @param {Object} [extend] The parent constructor object.
 */
function extend (ctor, definition, isClassDescriptor, extend)
{
    for (var k in definition)
    {
        if (!definition.hasOwnProperty(k))
        {
            continue;
        }

        var def = getProperty(definition, k, isClassDescriptor);

        if (def !== false)
        {
            //  If Extends is used, we will check its prototype to see if the final variable exists.

            var parent = extend || ctor;

            if (hasNonConfigurable(parent.prototype, k))
            {
                //  Just skip the final property
                if (Class.ignoreFinals)
                {
                    continue;
                }

                //  We cannot re-define a property that is configurable=false.
                //  So we will consider them final and throw an error. This is by
                //  default so it is clear to the developer what is happening.
                //  You can set ignoreFinals to true if you need to extend a class
                //  which has configurable=false; it will simply not re-define final properties.
                throw new Error('cannot override final property \'' + k + '\', set Class.ignoreFinals = true to skip');
            }

            Object.defineProperty(ctor.prototype, k, def);
        }
        else
        {
            ctor.prototype[k] = definition[k];
        }
    }
}

/**
 * Applies the given `mixins` to the prototype of `myClass`.
 *
 * @function mixin
 * @ignore
 * @param {Object} myClass The constructor object to mix into.
 * @param {Object|Array<Object>} mixins The mixins to apply to the constructor.
 */
function mixin (myClass, mixins)
{
    if (!mixins)
    {
        return;
    }

    if (!Array.isArray(mixins))
    {
        mixins = [ mixins ];
    }

    for (var i = 0; i < mixins.length; i++)
    {
        extend(myClass, mixins[i].prototype || mixins[i]);
    }
}

/**
 * Creates a new class with the given descriptor.
 * The constructor, defined by the name `initialize`,
 * is an optional function. If unspecified, an anonymous
 * function will be used which calls the parent class (if
 * one exists).
 *
 * You can also use `Extends` and `Mixins` to provide subclassing
 * and inheritance.
 *
 * @class Phaser.Class
 * @constructor
 * @param {Object} definition a dictionary of functions for the class
 * @example
 *
 *      var MyClass = new Phaser.Class({
 *
 *          initialize: function() {
 *              this.foo = 2.0;
 *          },
 *
 *          bar: function() {
 *              return this.foo + 5;
 *          }
 *      });
 */
function Class (definition)
{
    if (!definition)
    {
        definition = {};
    }

    //  The variable name here dictates what we see in Chrome debugger
    var initialize;
    var Extends;

    if (definition.initialize)
    {
        if (typeof definition.initialize !== 'function')
        {
            throw new Error('initialize must be a function');
        }

        initialize = definition.initialize;

        //  Usually we should avoid 'delete' in V8 at all costs.
        //  However, its unlikely to make any performance difference
        //  here since we only call this on class creation (i.e. not object creation).
        delete definition.initialize;
    }
    else if (definition.Extends)
    {
        var base = definition.Extends;

        initialize = function ()
        {
            base.apply(this, arguments);
        };
    }
    else
    {
        initialize = function () {};
    }

    if (definition.Extends)
    {
        initialize.prototype = Object.create(definition.Extends.prototype);
        initialize.prototype.constructor = initialize;

        //  For getOwnPropertyDescriptor to work, we need to act directly on the Extends (or Mixin)

        Extends = definition.Extends;

        delete definition.Extends;
    }
    else
    {
        initialize.prototype.constructor = initialize;
    }

    //  Grab the mixins, if they are specified...
    var mixins = null;

    if (definition.Mixins)
    {
        mixins = definition.Mixins;
        delete definition.Mixins;
    }

    //  First, mixin if we can.
    mixin(initialize, mixins);

    //  Now we grab the actual definition which defines the overrides.
    extend(initialize, definition, true, Extends);

    return initialize;
}

Class.extend = extend;
Class.mixin = mixin;
Class.ignoreFinals = false;

module.exports = Class;


/***/ }),

/***/ 1984:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * A NOOP (No Operation) callback function.
 *
 * Used internally by Phaser when it's more expensive to determine if a callback exists
 * than it is to just invoke an empty function.
 *
 * @function Phaser.Utils.NOOP
 * @since 3.0.0
 */
var NOOP = function ()
{
    //  NOOP
};

module.exports = NOOP;


/***/ }),

/***/ 1792:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Adds the given item, or array of items, to the array.
 *
 * Each item must be unique within the array.
 *
 * The array is modified in-place and returned.
 *
 * You can optionally specify a limit to the maximum size of the array. If the quantity of items being
 * added will take the array length over this limit, it will stop adding once the limit is reached.
 *
 * You can optionally specify a callback to be invoked for each item successfully added to the array.
 *
 * @function Phaser.Utils.Array.Add
 * @since 3.4.0
 *
 * @param {array} array - The array to be added to.
 * @param {any|any[]} item - The item, or array of items, to add to the array. Each item must be unique within the array.
 * @param {number} [limit] - Optional limit which caps the size of the array.
 * @param {function} [callback] - A callback to be invoked for each item successfully added to the array.
 * @param {object} [context] - The context in which the callback is invoked.
 *
 * @return {array} The input array.
 */
var Add = function (array, item, limit, callback, context)
{
    if (context === undefined) { context = array; }

    if (limit > 0)
    {
        var remaining = limit - array.length;

        //  There's nothing more we can do here, the array is full
        if (remaining <= 0)
        {
            return null;
        }
    }

    //  Fast path to avoid array mutation and iteration
    if (!Array.isArray(item))
    {
        if (array.indexOf(item) === -1)
        {
            array.push(item);

            if (callback)
            {
                callback.call(context, item);
            }

            return item;
        }
        else
        {
            return null;
        }
    }

    //  If we got this far, we have an array of items to insert

    //  Ensure all the items are unique
    var itemLength = item.length - 1;

    while (itemLength >= 0)
    {
        if (array.indexOf(item[itemLength]) !== -1)
        {
            //  Already exists in array, so remove it
            item.splice(itemLength, 1);
        }

        itemLength--;
    }

    //  Anything left?
    itemLength = item.length;

    if (itemLength === 0)
    {
        return null;
    }

    if (limit > 0 && itemLength > remaining)
    {
        item.splice(remaining);

        itemLength = remaining;
    }

    for (var i = 0; i < itemLength; i++)
    {
        var entry = item[i];

        array.push(entry);

        if (callback)
        {
            callback.call(context, entry);
        }
    }

    return item;
};

module.exports = Add;


/***/ }),

/***/ 2280:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Adds the given item, or array of items, to the array starting at the index specified.
 *
 * Each item must be unique within the array.
 *
 * Existing elements in the array are shifted up.
 *
 * The array is modified in-place and returned.
 *
 * You can optionally specify a limit to the maximum size of the array. If the quantity of items being
 * added will take the array length over this limit, it will stop adding once the limit is reached.
 *
 * You can optionally specify a callback to be invoked for each item successfully added to the array.
 *
 * @function Phaser.Utils.Array.AddAt
 * @since 3.4.0
 *
 * @param {array} array - The array to be added to.
 * @param {any|any[]} item - The item, or array of items, to add to the array.
 * @param {number} [index=0] - The index in the array where the item will be inserted.
 * @param {number} [limit] - Optional limit which caps the size of the array.
 * @param {function} [callback] - A callback to be invoked for each item successfully added to the array.
 * @param {object} [context] - The context in which the callback is invoked.
 *
 * @return {array} The input array.
 */
var AddAt = function (array, item, index, limit, callback, context)
{
    if (index === undefined) { index = 0; }
    if (context === undefined) { context = array; }

    if (limit > 0)
    {
        var remaining = limit - array.length;

        //  There's nothing more we can do here, the array is full
        if (remaining <= 0)
        {
            return null;
        }
    }

    //  Fast path to avoid array mutation and iteration
    if (!Array.isArray(item))
    {
        if (array.indexOf(item) === -1)
        {
            array.splice(index, 0, item);

            if (callback)
            {
                callback.call(context, item);
            }

            return item;
        }
        else
        {
            return null;
        }
    }

    //  If we got this far, we have an array of items to insert

    //  Ensure all the items are unique
    var itemLength = item.length - 1;

    while (itemLength >= 0)
    {
        if (array.indexOf(item[itemLength]) !== -1)
        {
            //  Already exists in array, so remove it
            item.pop();
        }

        itemLength--;
    }

    //  Anything left?
    itemLength = item.length;

    if (itemLength === 0)
    {
        return null;
    }

    //  Truncate to the limit
    if (limit > 0 && itemLength > remaining)
    {
        item.splice(remaining);

        itemLength = remaining;
    }

    for (var i = itemLength - 1; i >= 0; i--)
    {
        var entry = item[i];

        array.splice(index, 0, entry);

        if (callback)
        {
            callback.call(context, entry);
        }
    }

    return item;
};

module.exports = AddAt;


/***/ }),

/***/ 2513:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Moves the given element to the top of the array.
 * The array is modified in-place.
 *
 * @function Phaser.Utils.Array.BringToTop
 * @since 3.4.0
 *
 * @param {array} array - The array.
 * @param {*} item - The element to move.
 *
 * @return {*} The element that was moved.
 */
var BringToTop = function (array, item)
{
    var currentIndex = array.indexOf(item);

    if (currentIndex !== -1 && currentIndex < array.length)
    {
        array.splice(currentIndex, 1);
        array.push(item);
    }

    return item;
};

module.exports = BringToTop;


/***/ }),

/***/ 1771:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var SafeRange = __webpack_require__(2497);

/**
 * Returns the total number of elements in the array which have a property matching the given value.
 *
 * @function Phaser.Utils.Array.CountAllMatching
 * @since 3.4.0
 *
 * @param {array} array - The array to search.
 * @param {string} property - The property to test on each array element.
 * @param {*} value - The value to test the property against. Must pass a strict (`===`) comparison check.
 * @param {number} [startIndex] - An optional start index to search from.
 * @param {number} [endIndex] - An optional end index to search to.
 *
 * @return {number} The total number of elements with properties matching the given value.
 */
var CountAllMatching = function (array, property, value, startIndex, endIndex)
{
    if (startIndex === undefined) { startIndex = 0; }
    if (endIndex === undefined) { endIndex = array.length; }

    var total = 0;

    if (SafeRange(array, startIndex, endIndex))
    {
        for (var i = startIndex; i < endIndex; i++)
        {
            var child = array[i];

            if (child[property] === value)
            {
                total++;
            }
        }
    }

    return total;
};

module.exports = CountAllMatching;


/***/ }),

/***/ 7883:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Passes each element in the array to the given callback.
 *
 * @function Phaser.Utils.Array.Each
 * @since 3.4.0
 *
 * @param {array} array - The array to search.
 * @param {function} callback - A callback to be invoked for each item in the array.
 * @param {object} context - The context in which the callback is invoked.
 * @param {...*} [args] - Additional arguments that will be passed to the callback, after the current array item.
 *
 * @return {array} The input array.
 */
var Each = function (array, callback, context)
{
    var i;
    var args = [ null ];

    for (i = 3; i < arguments.length; i++)
    {
        args.push(arguments[i]);
    }

    for (i = 0; i < array.length; i++)
    {
        args[0] = array[i];

        callback.apply(context, args);
    }

    return array;
};

module.exports = Each;


/***/ }),

/***/ 5856:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var SafeRange = __webpack_require__(2497);

/**
 * Passes each element in the array, between the start and end indexes, to the given callback.
 *
 * @function Phaser.Utils.Array.EachInRange
 * @since 3.4.0
 *
 * @param {array} array - The array to search.
 * @param {function} callback - A callback to be invoked for each item in the array.
 * @param {object} context - The context in which the callback is invoked.
 * @param {number} startIndex - The start index to search from.
 * @param {number} endIndex - The end index to search to.
 * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
 *
 * @return {array} The input array.
 */
var EachInRange = function (array, callback, context, startIndex, endIndex)
{
    if (startIndex === undefined) { startIndex = 0; }
    if (endIndex === undefined) { endIndex = array.length; }

    if (SafeRange(array, startIndex, endIndex))
    {
        var i;
        var args = [ null ];

        for (i = 5; i < arguments.length; i++)
        {
            args.push(arguments[i]);
        }

        for (i = startIndex; i < endIndex; i++)
        {
            args[0] = array[i];

            callback.apply(context, args);
        }
    }

    return array;
};

module.exports = EachInRange;


/***/ }),

/***/ 3957:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Searches a pre-sorted array for the closet value to the given number.
 *
 * If the `key` argument is given it will assume the array contains objects that all have the required `key` property name,
 * and will check for the closest value of those to the given number.
 *
 * @function Phaser.Utils.Array.FindClosestInSorted
 * @since 3.0.0
 *
 * @param {number} value - The value to search for in the array.
 * @param {array} array - The array to search, which must be sorted.
 * @param {string} [key] - An optional property key. If specified the array elements property will be checked against value.
 *
 * @return {(number|any)} The nearest value found in the array, or if a `key` was given, the nearest object with the matching property value.
 */
var FindClosestInSorted = function (value, array, key)
{
    if (!array.length)
    {
        return NaN;
    }
    else if (array.length === 1)
    {
        return array[0];
    }

    var i = 1;
    var low;
    var high;

    if (key)
    {
        if (value < array[0][key])
        {
            return array[0];
        }

        while (array[i][key] < value)
        {
            i++;
        }
    }
    else
    {
        while (array[i] < value)
        {
            i++;
        }
    }

    if (i > array.length)
    {
        i = array.length;
    }

    if (key)
    {
        low = array[i - 1][key];
        high = array[i][key];

        return ((high - value) <= (value - low)) ? array[i] : array[i - 1];
    }
    else
    {
        low = array[i - 1];
        high = array[i];

        return ((high - value) <= (value - low)) ? high : low;
    }
};

module.exports = FindClosestInSorted;


/***/ }),

/***/ 4493:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Takes an array and flattens it, returning a shallow-copy flattened array.
 *
 * @function Phaser.Utils.Array.Flatten
 * @since 3.60.0
 *
 * @param {array} array - The array to flatten.
 * @param {array} [output] - An array to hold the results in.
 *
 * @return {array} The flattened output array.
 */
var Flatten = function (array, output)
{
    if (output === undefined) { output = []; }

    for (var i = 0; i < array.length; i++)
    {
        if (Array.isArray(array[i]))
        {
            Flatten(array[i], output);
        }
        else
        {
            output.push(array[i]);
        }
    }

    return output;
};

module.exports = Flatten;


/***/ }),

/***/ 6245:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var SafeRange = __webpack_require__(2497);

/**
 * Returns all elements in the array.
 *
 * You can optionally specify a matching criteria using the `property` and `value` arguments.
 *
 * For example: `getAll('visible', true)` would return only elements that have their visible property set.
 *
 * Optionally you can specify a start and end index. For example if the array had 100 elements,
 * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only
 * the first 50 elements.
 *
 * @function Phaser.Utils.Array.GetAll
 * @since 3.4.0
 *
 * @param {array} array - The array to search.
 * @param {string} [property] - The property to test on each array element.
 * @param {*} [value] - The value to test the property against. Must pass a strict (`===`) comparison check.
 * @param {number} [startIndex] - An optional start index to search from.
 * @param {number} [endIndex] - An optional end index to search to.
 *
 * @return {array} All matching elements from the array.
 */
var GetAll = function (array, property, value, startIndex, endIndex)
{
    if (startIndex === undefined) { startIndex = 0; }
    if (endIndex === undefined) { endIndex = array.length; }

    var output = [];

    if (SafeRange(array, startIndex, endIndex))
    {
        for (var i = startIndex; i < endIndex; i++)
        {
            var child = array[i];

            if (!property ||
                (property && value === undefined && child.hasOwnProperty(property)) ||
                (property && value !== undefined && child[property] === value))
            {
                output.push(child);
            }
        }
    }

    return output;
};

module.exports = GetAll;


/***/ }),

/***/ 1647:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var SafeRange = __webpack_require__(2497);

/**
 * Returns the first element in the array.
 *
 * You can optionally specify a matching criteria using the `property` and `value` arguments.
 *
 * For example: `getAll('visible', true)` would return the first element that had its `visible` property set.
 *
 * Optionally you can specify a start and end index. For example if the array had 100 elements,
 * and you set `startIndex` to 0 and `endIndex` to 50, it would search only the first 50 elements.
 *
 * @function Phaser.Utils.Array.GetFirst
 * @since 3.4.0
 *
 * @param {array} array - The array to search.
 * @param {string} [property] - The property to test on each array element.
 * @param {*} [value] - The value to test the property against. Must pass a strict (`===`) comparison check.
 * @param {number} [startIndex=0] - An optional start index to search from.
 * @param {number} [endIndex=array.length] - An optional end index to search up to (but not included)
 *
 * @return {object} The first matching element from the array, or `null` if no element could be found in the range given.
 */
var GetFirst = function (array, property, value, startIndex, endIndex)
{
    if (startIndex === undefined) { startIndex = 0; }
    if (endIndex === undefined) { endIndex = array.length; }

    if (SafeRange(array, startIndex, endIndex))
    {
        for (var i = startIndex; i < endIndex; i++)
        {
            var child = array[i];

            if (!property ||
                (property && value === undefined && child.hasOwnProperty(property)) ||
                (property && value !== undefined && child[property] === value))
            {
                return child;
            }
        }
    }

    return null;
};

module.exports = GetFirst;


/***/ }),

/***/ 5301:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Returns a Random element from the array.
 *
 * @function Phaser.Utils.Array.GetRandom
 * @since 3.0.0
 *
 * @generic T
 * @genericUse {T[]} - [array]
 * @genericUse {T} - [$return]
 *
 * @param {T[]} array - The array to select the random entry from.
 * @param {number} [startIndex=0] - An optional start index.
 * @param {number} [length=array.length] - An optional length, the total number of elements (from the startIndex) to choose from.
 *
 * @return {T} A random element from the array, or `null` if no element could be found in the range given.
 */
var GetRandom = function (array, startIndex, length)
{
    if (startIndex === undefined) { startIndex = 0; }
    if (length === undefined) { length = array.length; }

    var randomIndex = startIndex + Math.floor(Math.random() * length);

    return (array[randomIndex] === undefined) ? null : array[randomIndex];
};

module.exports = GetRandom;


/***/ }),

/***/ 8683:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Moves the given array element above another one in the array.
 * The array is modified in-place.
 *
 * @function Phaser.Utils.Array.MoveAbove
 * @since 3.55.0
 *
 * @param {array} array - The input array.
 * @param {*} item1 - The element to move above base element.
 * @param {*} item2 - The base element.
 *
 *
 * @return {array} The input array.
 */
var MoveAbove = function (array, item1, item2)
{
    if (item1 === item2)
    {
        return array;
    }

    var currentIndex = array.indexOf(item1);
    var baseIndex = array.indexOf(item2);

    if (currentIndex < 0 || baseIndex < 0)
    {
        throw new Error('Supplied items must be elements of the same array');
    }

    if (currentIndex > baseIndex)
    {
        // item1 is already above item2
        return array;
    }

    //  Remove
    array.splice(currentIndex, 1);

    //  Add in new location
    if (baseIndex === array.length - 1)
    {
        array.push(item1);
    }
    else
    {
        array.splice(baseIndex, 0, item1);
    }

    return array;
};

module.exports = MoveAbove;


/***/ }),

/***/ 546:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Moves the given array element below another one in the array.
 * The array is modified in-place.
 *
 * @function Phaser.Utils.Array.MoveBelow
 * @since 3.55.0
 *
 * @param {array} array - The input array.
 * @param {*} item1 - The element to move below base element.
 * @param {*} item2 - The base element.
 *
 *
 * @return {array} The input array.
 */
var MoveBelow = function (array, item1, item2)
{
    if (item1 === item2)
    {
        return array;
    }

    var currentIndex = array.indexOf(item1);
    var baseIndex = array.indexOf(item2);

    if (currentIndex < 0 || baseIndex < 0)
    {
        throw new Error('Supplied items must be elements of the same array');
    }

    if (currentIndex < baseIndex)
    {
        // item1 is already below item2
        return array;
    }

    //  Remove
    array.splice(currentIndex, 1);

    //  Add in new location
    if (baseIndex === 0)
    {
        array.unshift(item1);
    }
    else
    {
        array.splice(baseIndex, 0, item1);
    }

    return array;
};

module.exports = MoveBelow;


/***/ }),

/***/ 1842:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Moves the given array element down one place in the array.
 * The array is modified in-place.
 *
 * @function Phaser.Utils.Array.MoveDown
 * @since 3.4.0
 *
 * @param {array} array - The input array.
 * @param {*} item - The element to move down the array.
 *
 * @return {array} The input array.
 */
var MoveDown = function (array, item)
{
    var currentIndex = array.indexOf(item);

    if (currentIndex > 0)
    {
        var item2 = array[currentIndex - 1];

        var index2 = array.indexOf(item2);

        array[currentIndex] = item2;
        array[index2] = item;
    }

    return array;
};

module.exports = MoveDown;


/***/ }),

/***/ 1419:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Moves an element in an array to a new position within the same array.
 * The array is modified in-place.
 *
 * @function Phaser.Utils.Array.MoveTo
 * @since 3.4.0
 *
 * @param {array} array - The array.
 * @param {*} item - The element to move.
 * @param {number} index - The new index that the element will be moved to.
 *
 * @return {*} The element that was moved.
 */
var MoveTo = function (array, item, index)
{
    var currentIndex = array.indexOf(item);

    if (currentIndex === -1 || index < 0 || index >= array.length)
    {
        throw new Error('Supplied index out of bounds');
    }

    if (currentIndex !== index)
    {
        //  Remove
        array.splice(currentIndex, 1);

        //  Add in new location
        array.splice(index, 0, item);
    }

    return item;
};

module.exports = MoveTo;


/***/ }),

/***/ 6512:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Moves the given array element up one place in the array.
 * The array is modified in-place.
 *
 * @function Phaser.Utils.Array.MoveUp
 * @since 3.4.0
 *
 * @param {array} array - The input array.
 * @param {*} item - The element to move up the array.
 *
 * @return {array} The input array.
 */
var MoveUp = function (array, item)
{
    var currentIndex = array.indexOf(item);

    if (currentIndex !== -1 && currentIndex < array.length - 1)
    {
        //  The element one above `item` in the array
        var item2 = array[currentIndex + 1];
        var index2 = array.indexOf(item2);

        array[currentIndex] = item2;
        array[index2] = item;
    }

    return array;
};

module.exports = MoveUp;


/***/ }),

/***/ 4130:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Create an array representing the range of numbers (usually integers), between, and inclusive of,
 * the given `start` and `end` arguments. For example:
 *
 * `var array = Phaser.Utils.Array.NumberArray(2, 4); // array = [2, 3, 4]`
 * `var array = Phaser.Utils.Array.NumberArray(0, 9); // array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`
 * `var array = Phaser.Utils.Array.NumberArray(8, 2); // array = [8, 7, 6, 5, 4, 3, 2]`
 *
 * This is equivalent to `Phaser.Utils.Array.NumberArrayStep(start, end, 1)`.
 *
 * You can optionally provide a prefix and / or suffix string. If given the array will contain
 * strings, not integers. For example:
 *
 * `var array = Phaser.Utils.Array.NumberArray(1, 4, 'Level '); // array = ["Level 1", "Level 2", "Level 3", "Level 4"]`
 * `var array = Phaser.Utils.Array.NumberArray(5, 7, 'HD-', '.png'); // array = ["HD-5.png", "HD-6.png", "HD-7.png"]`
 *
 * @function Phaser.Utils.Array.NumberArray
 * @since 3.0.0
 *
 * @param {number} start - The minimum value the array starts with.
 * @param {number} end - The maximum value the array contains.
 * @param {string} [prefix] - Optional prefix to place before the number. If provided the array will contain strings, not integers.
 * @param {string} [suffix] - Optional suffix to place after the number. If provided the array will contain strings, not integers.
 *
 * @return {(number[]|string[])} The array of number values, or strings if a prefix or suffix was provided.
 */
var NumberArray = function (start, end, prefix, suffix)
{
    var result = [];

    var i;
    var asString = false;

    if (prefix || suffix)
    {
        asString = true;

        if (!prefix)
        {
            prefix = '';
        }

        if (!suffix)
        {
            suffix = '';
        }
    }

    if (end < start)
    {
        for (i = start; i >= end; i--)
        {
            if (asString)
            {
                result.push(prefix + i.toString() + suffix);
            }
            else
            {
                result.push(i);
            }
        }
    }
    else
    {
        for (i = start; i <= end; i++)
        {
            if (asString)
            {
                result.push(prefix + i.toString() + suffix);
            }
            else
            {
                result.push(i);
            }
        }
    }

    return result;
};

module.exports = NumberArray;


/***/ }),

/***/ 1316:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var RoundAwayFromZero = __webpack_require__(4078);

/**
 * Create an array of numbers (positive and/or negative) progressing from `start`
 * up to but not including `end` by advancing by `step`.
 *
 * If `start` is less than `end` a zero-length range is created unless a negative `step` is specified.
 *
 * Certain values for `start` and `end` (eg. NaN/undefined/null) are currently coerced to 0;
 * for forward compatibility make sure to pass in actual numbers.
 *
 * @example
 * NumberArrayStep(4);
 * // => [0, 1, 2, 3]
 *
 * NumberArrayStep(1, 5);
 * // => [1, 2, 3, 4]
 *
 * NumberArrayStep(0, 20, 5);
 * // => [0, 5, 10, 15]
 *
 * NumberArrayStep(0, -4, -1);
 * // => [0, -1, -2, -3]
 *
 * NumberArrayStep(1, 4, 0);
 * // => [1, 1, 1]
 *
 * NumberArrayStep(0);
 * // => []
 *
 * @function Phaser.Utils.Array.NumberArrayStep
 * @since 3.0.0
 *
 * @param {number} [start=0] - The start of the range.
 * @param {number} [end=null] - The end of the range.
 * @param {number} [step=1] - The value to increment or decrement by.
 *
 * @return {number[]} The array of number values.
 */
var NumberArrayStep = function (start, end, step)
{
    if (start === undefined) { start = 0; }
    if (end === undefined) { end = null; }
    if (step === undefined) { step = 1; }

    if (end === null)
    {
        end = start;
        start = 0;
    }

    var result = [];

    var total = Math.max(RoundAwayFromZero((end - start) / (step || 1)), 0);

    for (var i = 0; i < total; i++)
    {
        result.push(start);
        start += step;
    }

    return result;
};

module.exports = NumberArrayStep;


/***/ }),

/***/ 9465:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @ignore
 */
function swap (arr, i, j)
{
    var tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

/**
 * @ignore
 */
function defaultCompare (a, b)
{
    return a < b ? -1 : a > b ? 1 : 0;
}

/**
 * A [Floyd-Rivest](https://en.wikipedia.org/wiki/Floyd%E2%80%93Rivest_algorithm) quick selection algorithm.
 *
 * Rearranges the array items so that all items in the [left, k] range are smaller than all items in [k, right];
 * The k-th element will have the (k - left + 1)th smallest value in [left, right].
 *
 * The array is modified in-place.
 *
 * Based on code by [Vladimir Agafonkin](https://www.npmjs.com/~mourner)
 *
 * @function Phaser.Utils.Array.QuickSelect
 * @since 3.0.0
 *
 * @param {array} arr - The array to sort.
 * @param {number} k - The k-th element index.
 * @param {number} [left=0] - The index of the left part of the range.
 * @param {number} [right] - The index of the right part of the range.
 * @param {function} [compare] - An optional comparison function. Is passed two elements and should return 0, 1 or -1.
 */
var QuickSelect = function (arr, k, left, right, compare)
{
    if (left === undefined) { left = 0; }
    if (right === undefined) { right = arr.length - 1; }
    if (compare === undefined) { compare = defaultCompare; }

    while (right > left)
    {
        if (right - left > 600)
        {
            var n = right - left + 1;
            var m = k - left + 1;
            var z = Math.log(n);
            var s = 0.5 * Math.exp(2 * z / 3);
            var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
            var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
            var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));

            QuickSelect(arr, k, newLeft, newRight, compare);
        }

        var t = arr[k];
        var i = left;
        var j = right;

        swap(arr, left, k);

        if (compare(arr[right], t) > 0)
        {
            swap(arr, left, right);
        }

        while (i < j)
        {
            swap(arr, i, j);

            i++;
            j--;

            while (compare(arr[i], t) < 0)
            {
                i++;
            }

            while (compare(arr[j], t) > 0)
            {
                j--;
            }
        }

        if (compare(arr[left], t) === 0)
        {
            swap(arr, left, j);
        }
        else
        {
            j++;
            swap(arr, j, right);
        }

        if (j <= k)
        {
            left = j + 1;
        }

        if (k <= j)
        {
            right = j - 1;
        }
    }
};

module.exports = QuickSelect;


/***/ }),

/***/ 9703:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var GetValue = __webpack_require__(5851);
var Shuffle = __webpack_require__(4912);

var BuildChunk = function (a, b, qty)
{
    var out = [];

    for (var aIndex = 0; aIndex < a.length; aIndex++)
    {
        for (var bIndex = 0; bIndex < b.length; bIndex++)
        {
            for (var i = 0; i < qty; i++)
            {
                out.push({ a: a[aIndex], b: b[bIndex] });
            }
        }
    }

    return out;
};

/**
 * Creates an array populated with a range of values, based on the given arguments and configuration object.
 *
 * Range ([a,b,c], [1,2,3]) =
 * a1, a2, a3, b1, b2, b3, c1, c2, c3
 *
 * Range ([a,b], [1,2,3], qty = 3) =
 * a1, a1, a1, a2, a2, a2, a3, a3, a3, b1, b1, b1, b2, b2, b2, b3, b3, b3
 *
 * Range ([a,b,c], [1,2,3], repeat x1) =
 * a1, a2, a3, b1, b2, b3, c1, c2, c3, a1, a2, a3, b1, b2, b3, c1, c2, c3
 *
 * Range ([a,b], [1,2], repeat -1 = endless, max = 14) =
 * Maybe if max is set then repeat goes to -1 automatically?
 * a1, a2, b1, b2, a1, a2, b1, b2, a1, a2, b1, b2, a1, a2 (capped at 14 elements)
 *
 * Range ([a], [1,2,3,4,5], random = true) =
 * a4, a1, a5, a2, a3
 *
 * Range ([a, b], [1,2,3], random = true) =
 * b3, a2, a1, b1, a3, b2
 *
 * Range ([a, b, c], [1,2,3], randomB = true) =
 * a3, a1, a2, b2, b3, b1, c1, c3, c2
 *
 * Range ([a], [1,2,3,4,5], yoyo = true) =
 * a1, a2, a3, a4, a5, a5, a4, a3, a2, a1
 *
 * Range ([a, b], [1,2,3], yoyo = true) =
 * a1, a2, a3, b1, b2, b3, b3, b2, b1, a3, a2, a1
 *
 * @function Phaser.Utils.Array.Range
 * @since 3.0.0
 *
 * @param {array} a - The first array of range elements.
 * @param {array} b - The second array of range elements.
 * @param {object} [options] - A range configuration object. Can contain: repeat, random, randomB, yoyo, max, qty.
 *
 * @return {array} An array of arranged elements.
 */
var Range = function (a, b, options)
{
    var max = GetValue(options, 'max', 0);
    var qty = GetValue(options, 'qty', 1);
    var random = GetValue(options, 'random', false);
    var randomB = GetValue(options, 'randomB', false);
    var repeat = GetValue(options, 'repeat', 0);
    var yoyo = GetValue(options, 'yoyo', false);

    var out = [];

    if (randomB)
    {
        Shuffle(b);
    }

    //  Endless repeat, so limit by max
    if (repeat === -1)
    {
        if (max === 0)
        {
            repeat = 0;
        }
        else
        {
            //  Work out how many repeats we need
            var total = (a.length * b.length) * qty;

            if (yoyo)
            {
                total *= 2;
            }

            repeat = Math.ceil(max / total);
        }
    }

    for (var i = 0; i <= repeat; i++)
    {
        var chunk = BuildChunk(a, b, qty);

        if (random)
        {
            Shuffle(chunk);
        }

        out = out.concat(chunk);

        if (yoyo)
        {
            chunk.reverse();

            out = out.concat(chunk);
        }
    }

    if (max)
    {
        out.splice(max);
    }

    return out;
};

module.exports = Range;


/***/ }),

/***/ 7161:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var SpliceOne = __webpack_require__(8935);

/**
 * Removes the given item, or array of items, from the array.
 *
 * The array is modified in-place.
 *
 * You can optionally specify a callback to be invoked for each item successfully removed from the array.
 *
 * @function Phaser.Utils.Array.Remove
 * @since 3.4.0
 *
 * @param {array} array - The array to be modified.
 * @param {*|Array.<*>} item - The item, or array of items, to be removed from the array.
 * @param {function} [callback] - A callback to be invoked for each item successfully removed from the array.
 * @param {object} [context] - The context in which the callback is invoked.
 *
 * @return {*|Array.<*>} The item, or array of items, that were successfully removed from the array.
 */
var Remove = function (array, item, callback, context)
{
    if (context === undefined) { context = array; }

    var index;

    //  Fast path to avoid array mutation and iteration
    if (!Array.isArray(item))
    {
        index = array.indexOf(item);

        if (index !== -1)
        {
            SpliceOne(array, index);

            if (callback)
            {
                callback.call(context, item);
            }

            return item;
        }
        else
        {
            return null;
        }
    }

    //  If we got this far, we have an array of items to remove

    var itemLength = item.length - 1;
    var removed = [];

    while (itemLength >= 0)
    {
        var entry = item[itemLength];

        index = array.indexOf(entry);

        if (index !== -1)
        {
            SpliceOne(array, index);

            removed.push(entry);

            if (callback)
            {
                callback.call(context, entry);
            }
        }

        itemLength--;
    }

    return removed;
};

module.exports = Remove;


/***/ }),

/***/ 4725:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var SpliceOne = __webpack_require__(8935);

/**
 * Removes the item from the given position in the array.
 *
 * The array is modified in-place.
 *
 * You can optionally specify a callback to be invoked for the item if it is successfully removed from the array.
 *
 * @function Phaser.Utils.Array.RemoveAt
 * @since 3.4.0
 *
 * @param {array} array - The array to be modified.
 * @param {number} index - The array index to remove the item from. The index must be in bounds or it will throw an error.
 * @param {function} [callback] - A callback to be invoked for the item removed from the array.
 * @param {object} [context] - The context in which the callback is invoked.
 *
 * @return {*} The item that was removed.
 */
var RemoveAt = function (array, index, callback, context)
{
    if (context === undefined) { context = array; }

    if (index < 0 || index > array.length - 1)
    {
        throw new Error('Index out of bounds');
    }

    var item = SpliceOne(array, index);

    if (callback)
    {
        callback.call(context, item);
    }

    return item;
};

module.exports = RemoveAt;


/***/ }),

/***/ 8780:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var SafeRange = __webpack_require__(2497);

/**
 * Removes the item within the given range in the array.
 *
 * The array is modified in-place.
 *
 * You can optionally specify a callback to be invoked for the item/s successfully removed from the array.
 *
 * @function Phaser.Utils.Array.RemoveBetween
 * @since 3.4.0
 *
 * @param {array} array - The array to be modified.
 * @param {number} startIndex - The start index to remove from.
 * @param {number} endIndex - The end index to remove to.
 * @param {function} [callback] - A callback to be invoked for the item removed from the array.
 * @param {object} [context] - The context in which the callback is invoked.
 *
 * @return {Array.<*>} An array of items that were removed.
 */
var RemoveBetween = function (array, startIndex, endIndex, callback, context)
{
    if (startIndex === undefined) { startIndex = 0; }
    if (endIndex === undefined) { endIndex = array.length; }
    if (context === undefined) { context = array; }

    if (SafeRange(array, startIndex, endIndex))
    {
        var size = endIndex - startIndex;

        var removed = array.splice(startIndex, size);

        if (callback)
        {
            for (var i = 0; i < removed.length; i++)
            {
                var entry = removed[i];

                callback.call(context, entry);
            }
        }

        return removed;
    }
    else
    {
        return [];
    }
};

module.exports = RemoveBetween;


/***/ }),

/***/ 5744:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var SpliceOne = __webpack_require__(8935);

/**
 * Removes a random object from the given array and returns it.
 * Will return null if there are no array items that fall within the specified range or if there is no item for the randomly chosen index.
 *
 * @function Phaser.Utils.Array.RemoveRandomElement
 * @since 3.0.0
 *
 * @param {array} array - The array to removed a random element from.
 * @param {number} [start=0] - The array index to start the search from.
 * @param {number} [length=array.length] - Optional restriction on the number of elements to randomly select from.
 *
 * @return {object} The random element that was removed, or `null` if there were no array elements that fell within the given range.
 */
var RemoveRandomElement = function (array, start, length)
{
    if (start === undefined) { start = 0; }
    if (length === undefined) { length = array.length; }

    var randomIndex = start + Math.floor(Math.random() * length);

    return SpliceOne(array, randomIndex);
};

module.exports = RemoveRandomElement;


/***/ }),

/***/ 6960:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Replaces an element of the array with the new element.
 * The new element cannot already be a member of the array.
 * The array is modified in-place.
 *
 * @function Phaser.Utils.Array.Replace
 * @since 3.4.0
 *
 * @param {array} array - The array to search within.
 * @param {*} oldChild - The element in the array that will be replaced.
 * @param {*} newChild - The element to be inserted into the array at the position of `oldChild`.
 *
 * @return {boolean} Returns true if the oldChild was successfully replaced, otherwise returns false.
 */
var Replace = function (array, oldChild, newChild)
{
    var index1 = array.indexOf(oldChild);
    var index2 = array.indexOf(newChild);

    if (index1 !== -1 && index2 === -1)
    {
        array[index1] = newChild;

        return true;
    }
    else
    {
        return false;
    }
};

module.exports = Replace;


/***/ }),

/***/ 1021:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Moves the element at the start of the array to the end, shifting all items in the process.
 * The "rotation" happens to the left.
 *
 * @function Phaser.Utils.Array.RotateLeft
 * @since 3.0.0
 *
 * @param {array} array - The array to shift to the left. This array is modified in place.
 * @param {number} [total=1] - The number of times to shift the array.
 *
 * @return {*} The most recently shifted element.
 */
var RotateLeft = function (array, total)
{
    if (total === undefined) { total = 1; }

    var element = null;

    for (var i = 0; i < total; i++)
    {
        element = array.shift();
        array.push(element);
    }

    return element;
};

module.exports = RotateLeft;


/***/ }),

/***/ 4027:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Moves the element at the end of the array to the start, shifting all items in the process.
 * The "rotation" happens to the right.
 *
 * @function Phaser.Utils.Array.RotateRight
 * @since 3.0.0
 *
 * @param {array} array - The array to shift to the right. This array is modified in place.
 * @param {number} [total=1] - The number of times to shift the array.
 *
 * @return {*} The most recently shifted element.
 */
var RotateRight = function (array, total)
{
    if (total === undefined) { total = 1; }

    var element = null;

    for (var i = 0; i < total; i++)
    {
        element = array.pop();
        array.unshift(element);
    }

    return element;
};

module.exports = RotateRight;


/***/ }),

/***/ 2497:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Tests if the start and end indexes are a safe range for the given array.
 *
 * @function Phaser.Utils.Array.SafeRange
 * @since 3.4.0
 *
 * @param {array} array - The array to check.
 * @param {number} startIndex - The start index.
 * @param {number} endIndex - The end index.
 * @param {boolean} [throwError=true] - Throw an error if the range is out of bounds.
 *
 * @return {boolean} True if the range is safe, otherwise false.
 */
var SafeRange = function (array, startIndex, endIndex, throwError)
{
    var len = array.length;

    if (startIndex < 0 ||
        startIndex > len ||
        startIndex >= endIndex ||
        endIndex > len)
    {
        if (throwError)
        {
            throw new Error('Range Error: Values outside acceptable range');
        }

        return false;
    }
    else
    {
        return true;
    }
};

module.exports = SafeRange;


/***/ }),

/***/ 5361:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Moves the given element to the bottom of the array.
 * The array is modified in-place.
 *
 * @function Phaser.Utils.Array.SendToBack
 * @since 3.4.0
 *
 * @param {array} array - The array.
 * @param {*} item - The element to move.
 *
 * @return {*} The element that was moved.
 */
var SendToBack = function (array, item)
{
    var currentIndex = array.indexOf(item);

    if (currentIndex !== -1 && currentIndex > 0)
    {
        array.splice(currentIndex, 1);
        array.unshift(item);
    }

    return item;
};

module.exports = SendToBack;


/***/ }),

/***/ 3718:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var SafeRange = __webpack_require__(2497);

/**
 * Scans the array for elements with the given property. If found, the property is set to the `value`.
 *
 * For example: `SetAll('visible', true)` would set all elements that have a `visible` property to `false`.
 *
 * Optionally you can specify a start and end index. For example if the array had 100 elements,
 * and you set `startIndex` to 0 and `endIndex` to 50, it would update only the first 50 elements.
 *
 * @function Phaser.Utils.Array.SetAll
 * @since 3.4.0
 *
 * @param {array} array - The array to search.
 * @param {string} property - The property to test for on each array element.
 * @param {*} value - The value to set the property to.
 * @param {number} [startIndex] - An optional start index to search from.
 * @param {number} [endIndex] - An optional end index to search to.
 *
 * @return {array} The input array.
 */
var SetAll = function (array, property, value, startIndex, endIndex)
{
    if (startIndex === undefined) { startIndex = 0; }
    if (endIndex === undefined) { endIndex = array.length; }

    if (SafeRange(array, startIndex, endIndex))
    {
        for (var i = startIndex; i < endIndex; i++)
        {
            var entry = array[i];

            if (entry.hasOwnProperty(property))
            {
                entry[property] = value;
            }
        }
    }

    return array;
};

module.exports = SetAll;


/***/ }),

/***/ 4912:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Shuffles the contents of the given array using the Fisher-Yates implementation.
 *
 * The original array is modified directly and returned.
 *
 * @function Phaser.Utils.Array.Shuffle
 * @since 3.0.0
 *
 * @generic T
 * @genericUse {T[]} - [array,$return]
 *
 * @param {T[]} array - The array to shuffle. This array is modified in place.
 *
 * @return {T[]} The shuffled array.
 */
var Shuffle = function (array)
{
    for (var i = array.length - 1; i > 0; i--)
    {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    return array;
};

module.exports = Shuffle;


/***/ }),

/***/ 2071:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Takes the given array and runs a numeric sort on it, ignoring any non-digits that
 * may be in the entries.
 *
 * You should only run this on arrays containing strings.
 *
 * @function Phaser.Utils.Array.SortByDigits
 * @since 3.50.0
 *
 * @param {string[]} array - The input array of strings.
 *
 * @return {string[]} The sorted input array.
 */
var SortByDigits = function (array)
{
    var re = /\D/g;

    array.sort(function (a, b)
    {
        return (parseInt(a.replace(re, ''), 10) - parseInt(b.replace(re, ''), 10));
    });

    return array;
};

module.exports = SortByDigits;


/***/ }),

/***/ 8935:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Removes a single item from an array and returns it without creating gc, like the native splice does.
 * Based on code by Mike Reinstein.
 *
 * @function Phaser.Utils.Array.SpliceOne
 * @since 3.0.0
 *
 * @param {array} array - The array to splice from.
 * @param {number} index - The index of the item which should be spliced.
 *
 * @return {*} The item which was spliced (removed).
 */
var SpliceOne = function (array, index)
{
    if (index >= array.length)
    {
        return;
    }

    var len = array.length - 1;

    var item = array[index];

    for (var i = index; i < len; i++)
    {
        array[i] = array[i + 1];
    }

    array.length = len;

    return item;
};

module.exports = SpliceOne;


/***/ }),

/***/ 9992:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       Angry Bytes (and contributors)
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Device = __webpack_require__(9356);

/**
 * The comparator function.
 *
 * @ignore
 *
 * @param {*} a - The first item to test.
 * @param {*} b - The second itemt to test.
 *
 * @return {boolean} True if they localCompare, otherwise false.
 */
function Compare (a, b)
{
    return String(a).localeCompare(b);
}

/**
 * Process the array contents.
 *
 * @ignore
 *
 * @param {array} array - The array to process.
 * @param {function} compare - The comparison function.
 *
 * @return {array} - The processed array.
 */
function Process (array, compare)
{
    // Short-circuit when there's nothing to sort.
    var len = array.length;

    if (len <= 1)
    {
        return array;
    }

    // Rather than dividing input, simply iterate chunks of 1, 2, 4, 8, etc.
    // Chunks are the size of the left or right hand in merge sort.
    // Stop when the left-hand covers all of the array.
    var buffer = new Array(len);

    for (var chk = 1; chk < len; chk *= 2)
    {
        RunPass(array, compare, chk, buffer);

        var tmp = array;

        array = buffer;

        buffer = tmp;
    }

    return array;
}

/**
 * Run a single pass with the given chunk size.
 *
 * @ignore
 *
 * @param {array} arr - The array to run the pass on.
 * @param {function} comp - The comparison function.
 * @param {number} chk - The number of iterations.
 * @param {array} result - The array to store the result in.
 */
function RunPass (arr, comp, chk, result)
{
    var len = arr.length;
    var i = 0;

    // Step size / double chunk size.
    var dbl = chk * 2;

    // Bounds of the left and right chunks.
    var l, r, e;

    // Iterators over the left and right chunk.
    var li, ri;

    // Iterate over pairs of chunks.
    for (l = 0; l < len; l += dbl)
    {
        r = l + chk;
        e = r + chk;

        if (r > len)
        {
            r = len;
        }

        if (e > len)
        {
            e = len;
        }

        // Iterate both chunks in parallel.
        li = l;
        ri = r;

        while (true)
        {
            // Compare the chunks.
            if (li < r && ri < e)
            {
                // This works for a regular `sort()` compatible comparator,
                // but also for a simple comparator like: `a > b`
                if (comp(arr[li], arr[ri]) <= 0)
                {
                    result[i++] = arr[li++];
                }
                else
                {
                    result[i++] = arr[ri++];
                }
            }
            else if (li < r)
            {
                // Nothing to compare, just flush what's left.
                result[i++] = arr[li++];
            }
            else if (ri < e)
            {
                result[i++] = arr[ri++];
            }
            else
            {
                // Both iterators are at the chunk ends.
                break;
            }
        }
    }
}

/**
 * An in-place stable array sort, because `Array#sort()` is not guaranteed stable.
 *
 * This is an implementation of merge sort, without recursion.
 *
 * Function based on the Two-Screen/stable sort 0.1.8 from https://github.com/Two-Screen/stable
 *
 * @function Phaser.Utils.Array.StableSort
 * @since 3.0.0
 *
 * @param {array} array - The input array to be sorted.
 * @param {function} [compare] - The comparison function.
 *
 * @return {array} The sorted result.
 */
var StableSort = function (array, compare)
{
    if (compare === undefined) { compare = Compare; }

    // Short-circuit when there's nothing to sort.
    if (!array || array.length < 2)
    {
        return array;
    }

    if (Device.features.stableSort)
    {
        return array.sort(compare);
    }

    var result = Process(array, compare);

    // This simply copies back if the result isn't in the original array, which happens on an odd number of passes.
    if (result !== array)
    {
        RunPass(result, null, array.length, array);
    }

    return array;
};

module.exports = StableSort;


/***/ }),

/***/ 2372:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Swaps the position of two elements in the given array.
 * The elements must exist in the same array.
 * The array is modified in-place.
 *
 * @function Phaser.Utils.Array.Swap
 * @since 3.4.0
 *
 * @param {array} array - The input array.
 * @param {*} item1 - The first element to swap.
 * @param {*} item2 - The second element to swap.
 *
 * @return {array} The input array.
 */
var Swap = function (array, item1, item2)
{
    if (item1 === item2)
    {
        return array;
    }

    var index1 = array.indexOf(item1);
    var index2 = array.indexOf(item2);

    if (index1 < 0 || index2 < 0)
    {
        throw new Error('Supplied items must be elements of the same array');
    }

    array[index1] = item2;
    array[index2] = item1;

    return array;
};

module.exports = Swap;


/***/ }),

/***/ 1953:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Utils.Array
 */

module.exports = {

    Matrix: __webpack_require__(1237),

    Add: __webpack_require__(1792),
    AddAt: __webpack_require__(2280),
    BringToTop: __webpack_require__(2513),
    CountAllMatching: __webpack_require__(1771),
    Each: __webpack_require__(7883),
    EachInRange: __webpack_require__(5856),
    FindClosestInSorted: __webpack_require__(3957),
    Flatten: __webpack_require__(4493),
    GetAll: __webpack_require__(6245),
    GetFirst: __webpack_require__(1647),
    GetRandom: __webpack_require__(5301),
    MoveDown: __webpack_require__(1842),
    MoveTo: __webpack_require__(1419),
    MoveUp: __webpack_require__(6512),
    MoveAbove: __webpack_require__(8683),
    MoveBelow: __webpack_require__(546),
    NumberArray: __webpack_require__(4130),
    NumberArrayStep: __webpack_require__(1316),
    QuickSelect: __webpack_require__(9465),
    Range: __webpack_require__(9703),
    Remove: __webpack_require__(7161),
    RemoveAt: __webpack_require__(4725),
    RemoveBetween: __webpack_require__(8780),
    RemoveRandomElement: __webpack_require__(5744),
    Replace: __webpack_require__(6960),
    RotateLeft: __webpack_require__(1021),
    RotateRight: __webpack_require__(4027),
    SafeRange: __webpack_require__(2497),
    SendToBack: __webpack_require__(5361),
    SetAll: __webpack_require__(3718),
    Shuffle: __webpack_require__(4912),
    SortByDigits: __webpack_require__(2071),
    SpliceOne: __webpack_require__(8935),
    StableSort: __webpack_require__(9992),
    Swap: __webpack_require__(2372)

};


/***/ }),

/***/ 1816:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Checks if an array can be used as a matrix.
 *
 * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
 * have the same length. This is an example matrix:
 *
 * ```
 * [
 *    [ 1, 1, 1, 1, 1, 1 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 2, 0, 1, 2, 0, 4 ],
 *    [ 2, 0, 3, 4, 0, 4 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 3, 3, 3, 3, 3, 3 ]
 * ]
 * ```
 *
 * @function Phaser.Utils.Array.Matrix.CheckMatrix
 * @since 3.0.0
 *
 * @generic T
 * @genericUse {T[][]} - [matrix]
 *
 * @param {T[][]} [matrix] - The array to check.
 *
 * @return {boolean} `true` if the given `matrix` array is a valid matrix.
 */
var CheckMatrix = function (matrix)
{
    if (!Array.isArray(matrix) || !Array.isArray(matrix[0]))
    {
        return false;
    }

    //  How long is the first row?
    var size = matrix[0].length;

    //  Validate the rest of the rows are the same length
    for (var i = 1; i < matrix.length; i++)
    {
        if (matrix[i].length !== size)
        {
            return false;
        }
    }

    return true;
};

module.exports = CheckMatrix;


/***/ }),

/***/ 6655:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Pad = __webpack_require__(7222);
var CheckMatrix = __webpack_require__(1816);

/**
 * Generates a string (which you can pass to console.log) from the given Array Matrix.
 *
 * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
 * have the same length. There must be at least two rows. This is an example matrix:
 *
 * ```
 * [
 *    [ 1, 1, 1, 1, 1, 1 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 2, 0, 1, 2, 0, 4 ],
 *    [ 2, 0, 3, 4, 0, 4 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 3, 3, 3, 3, 3, 3 ]
 * ]
 * ```
 *
 * @function Phaser.Utils.Array.Matrix.MatrixToString
 * @since 3.0.0
 *
 * @generic T
 * @genericUse {T[][]} - [matrix]
 *
 * @param {T[][]} [matrix] - A 2-dimensional array.
 *
 * @return {string} A string representing the matrix.
 */
var MatrixToString = function (matrix)
{
    var str = '';

    if (!CheckMatrix(matrix))
    {
        return str;
    }

    for (var r = 0; r < matrix.length; r++)
    {
        for (var c = 0; c < matrix[r].length; c++)
        {
            var cell = matrix[r][c].toString();

            if (cell !== 'undefined')
            {
                str += Pad(cell, 2);
            }
            else
            {
                str += '?';
            }

            if (c < matrix[r].length - 1)
            {
                str += ' |';
            }
        }

        if (r < matrix.length - 1)
        {
            str += '\n';

            for (var i = 0; i < matrix[r].length; i++)
            {
                str += '---';

                if (i < matrix[r].length - 1)
                {
                    str += '+';
                }
            }

            str += '\n';
        }

    }

    return str;
};

module.exports = MatrixToString;


/***/ }),

/***/ 582:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Reverses the columns in the given Array Matrix.
 *
 * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
 * have the same length. There must be at least two rows. This is an example matrix:
 *
 * ```
 * [
 *    [ 1, 1, 1, 1, 1, 1 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 2, 0, 1, 2, 0, 4 ],
 *    [ 2, 0, 3, 4, 0, 4 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 3, 3, 3, 3, 3, 3 ]
 * ]
 * ```
 *
 * @function Phaser.Utils.Array.Matrix.ReverseColumns
 * @since 3.0.0
 *
 * @generic T
 * @genericUse {T[][]} - [matrix,$return]
 *
 * @param {T[][]} [matrix] - The array matrix to reverse the columns for.
 *
 * @return {T[][]} The column reversed matrix.
 */
var ReverseColumns = function (matrix)
{
    return matrix.reverse();
};

module.exports = ReverseColumns;


/***/ }),

/***/ 6063:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Reverses the rows in the given Array Matrix.
 *
 * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
 * have the same length. There must be at least two rows. This is an example matrix:
 *
 * ```
 * [
 *    [ 1, 1, 1, 1, 1, 1 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 2, 0, 1, 2, 0, 4 ],
 *    [ 2, 0, 3, 4, 0, 4 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 3, 3, 3, 3, 3, 3 ]
 * ]
 * ```
 *
 * @function Phaser.Utils.Array.Matrix.ReverseRows
 * @since 3.0.0
 *
 * @generic T
 * @genericUse {T[][]} - [matrix,$return]
 *
 * @param {T[][]} [matrix] - The array matrix to reverse the rows for.
 *
 * @return {T[][]} The column reversed matrix.
 */
var ReverseRows = function (matrix)
{
    for (var i = 0; i < matrix.length; i++)
    {
        matrix[i].reverse();
    }

    return matrix;
};

module.exports = ReverseRows;


/***/ }),

/***/ 8321:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var RotateMatrix = __webpack_require__(7116);

/**
 * Rotates the array matrix 180 degrees.
 *
 * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
 * have the same length. There must be at least two rows. This is an example matrix:
 *
 * ```
 * [
 *    [ 1, 1, 1, 1, 1, 1 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 2, 0, 1, 2, 0, 4 ],
 *    [ 2, 0, 3, 4, 0, 4 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 3, 3, 3, 3, 3, 3 ]
 * ]
 * ```
 *
 * @function Phaser.Utils.Array.Matrix.Rotate180
 * @since 3.0.0
 *
 * @generic T
 * @genericUse {T[][]} - [matrix,$return]
 *
 * @param {T[][]} [matrix] - The array to rotate.
 *
 * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix.
 */
var Rotate180 = function (matrix)
{
    return RotateMatrix(matrix, 180);
};

module.exports = Rotate180;


/***/ }),

/***/ 2597:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var RotateMatrix = __webpack_require__(7116);

/**
 * Rotates the array matrix to the left (or 90 degrees)
 *
 * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
 * have the same length. There must be at least two rows. This is an example matrix:
 *
 * ```
 * [
 *    [ 1, 1, 1, 1, 1, 1 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 2, 0, 1, 2, 0, 4 ],
 *    [ 2, 0, 3, 4, 0, 4 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 3, 3, 3, 3, 3, 3 ]
 * ]
 * ```
 *
 * @function Phaser.Utils.Array.Matrix.RotateLeft
 * @since 3.0.0
 *
 * @generic T
 * @genericUse {T[][]} - [matrix,$return]
 *
 * @param {T[][]} [matrix] - The array to rotate.
 * @param {number} [amount=1] - The number of times to rotate the matrix.
 *
 * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix.
 */
var RotateLeft = function (matrix, amount)
{
    if (amount === undefined) { amount = 1; }

    for (var i = 0; i < amount; i++)
    {
        matrix = RotateMatrix(matrix, 90);
    }

    return matrix;
};

module.exports = RotateLeft;


/***/ }),

/***/ 7116:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var CheckMatrix = __webpack_require__(1816);
var TransposeMatrix = __webpack_require__(4780);

/**
 * Rotates the array matrix based on the given rotation value.
 *
 * The value can be given in degrees: 90, -90, 270, -270 or 180,
 * or a string command: `rotateLeft`, `rotateRight` or `rotate180`.
 *
 * Based on the routine from {@link http://jsfiddle.net/MrPolywhirl/NH42z/}.
 *
 * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
 * have the same length. There must be at least two rows. This is an example matrix:
 *
 * ```
 * [
 *    [ 1, 1, 1, 1, 1, 1 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 2, 0, 1, 2, 0, 4 ],
 *    [ 2, 0, 3, 4, 0, 4 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 3, 3, 3, 3, 3, 3 ]
 * ]
 * ```
 *
 * @function Phaser.Utils.Array.Matrix.RotateMatrix
 * @since 3.0.0
 *
 * @generic T
 * @genericUse {T[][]} - [matrix,$return]
 *
 * @param {T[][]} [matrix] - The array to rotate.
 * @param {(number|string)} [direction=90] - The amount to rotate the matrix by.
 *
 * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix.
 */
var RotateMatrix = function (matrix, direction)
{
    if (direction === undefined) { direction = 90; }

    if (!CheckMatrix(matrix))
    {
        return null;
    }

    if (typeof direction !== 'string')
    {
        direction = ((direction % 360) + 360) % 360;
    }

    if (direction === 90 || direction === -270 || direction === 'rotateLeft')
    {
        matrix = TransposeMatrix(matrix);
        matrix.reverse();
    }
    else if (direction === -90 || direction === 270 || direction === 'rotateRight')
    {
        matrix.reverse();
        matrix = TransposeMatrix(matrix);
    }
    else if (Math.abs(direction) === 180 || direction === 'rotate180')
    {
        for (var i = 0; i < matrix.length; i++)
        {
            matrix[i].reverse();
        }

        matrix.reverse();
    }

    return matrix;
};

module.exports = RotateMatrix;


/***/ }),

/***/ 6285:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var RotateMatrix = __webpack_require__(7116);

/**
 * Rotates the array matrix to the left (or -90 degrees)
 *
 * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
 * have the same length. There must be at least two rows. This is an example matrix:
 *
 * ```
 * [
 *    [ 1, 1, 1, 1, 1, 1 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 2, 0, 1, 2, 0, 4 ],
 *    [ 2, 0, 3, 4, 0, 4 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 3, 3, 3, 3, 3, 3 ]
 * ]
 * ```
 *
 * @function Phaser.Utils.Array.Matrix.RotateRight
 * @since 3.0.0
 *
 * @generic T
 * @genericUse {T[][]} - [matrix,$return]
 *
 * @param {T[][]} [matrix] - The array to rotate.
 * @param {number} [amount=1] - The number of times to rotate the matrix.
 *
 * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix.
 */
var RotateRight = function (matrix, amount)
{
    if (amount === undefined) { amount = 1; }

    for (var i = 0; i < amount; i++)
    {
        matrix = RotateMatrix(matrix, -90);
    }

    return matrix;
};

module.exports = RotateRight;


/***/ }),

/***/ 7711:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var RotateLeft = __webpack_require__(1021);
var RotateRight = __webpack_require__(4027);

/**
 * Translates the given Array Matrix by shifting each column and row the
 * amount specified.
 *
 * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
 * have the same length. There must be at least two rows. This is an example matrix:
 *
 * ```
 * [
 *    [ 1, 1, 1, 1, 1, 1 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 2, 0, 1, 2, 0, 4 ],
 *    [ 2, 0, 3, 4, 0, 4 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 3, 3, 3, 3, 3, 3 ]
 * ]
 * ```
 *
 * @function Phaser.Utils.Array.Matrix.Translate
 * @since 3.50.0
 *
 * @generic T
 * @genericUse {T[][]} - [matrix,$return]
 *
 * @param {T[][]} [matrix] - The array matrix to translate.
 * @param {number} [x=0] - The amount to horizontally translate the matrix by.
 * @param {number} [y=0] - The amount to vertically translate the matrix by.
 *
 * @return {T[][]} The translated matrix.
 */
var TranslateMatrix = function (matrix, x, y)
{
    if (x === undefined) { x = 0; }
    if (y === undefined) { y = 0; }

    //  Vertical translation

    if (y !== 0)
    {
        if (y < 0)
        {
            //  Shift Up
            RotateLeft(matrix, Math.abs(y));
        }
        else
        {
            //  Shift Down
            RotateRight(matrix, y);
        }
    }

    //  Horizontal translation

    if (x !== 0)
    {
        for (var i = 0; i < matrix.length; i++)
        {
            var row = matrix[i];

            if (x < 0)
            {
                RotateLeft(row, Math.abs(x));
            }
            else
            {
                RotateRight(row, x);
            }
        }
    }

    return matrix;
};

module.exports = TranslateMatrix;


/***/ }),

/***/ 4780:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Transposes the elements of the given matrix (array of arrays).
 *
 * The transpose of a matrix is a new matrix whose rows are the columns of the original.
 *
 * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows)
 * have the same length. There must be at least two rows. This is an example matrix:
 *
 * ```
 * [
 *    [ 1, 1, 1, 1, 1, 1 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 2, 0, 1, 2, 0, 4 ],
 *    [ 2, 0, 3, 4, 0, 4 ],
 *    [ 2, 0, 0, 0, 0, 4 ],
 *    [ 3, 3, 3, 3, 3, 3 ]
 * ]
 * ```
 *
 * @function Phaser.Utils.Array.Matrix.TransposeMatrix
 * @since 3.0.0
 *
 * @generic T
 * @genericUse {T[][]} - [array,$return]
 *
 * @param {T[][]} [array] - The array matrix to transpose.
 *
 * @return {T[][]} A new array matrix which is a transposed version of the given array.
 */
var TransposeMatrix = function (array)
{
    var sourceRowCount = array.length;
    var sourceColCount = array[0].length;

    var result = new Array(sourceColCount);

    for (var i = 0; i < sourceColCount; i++)
    {
        result[i] = new Array(sourceRowCount);

        for (var j = sourceRowCount - 1; j > -1; j--)
        {
            result[i][j] = array[j][i];
        }
    }

    return result;
};

module.exports = TransposeMatrix;


/***/ }),

/***/ 1237:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * @namespace Phaser.Utils.Array.Matrix
 */

module.exports = {

    CheckMatrix: __webpack_require__(1816),
    MatrixToString: __webpack_require__(6655),
    ReverseColumns: __webpack_require__(582),
    ReverseRows: __webpack_require__(6063),
    Rotate180: __webpack_require__(8321),
    RotateLeft: __webpack_require__(2597),
    RotateMatrix: __webpack_require__(7116),
    RotateRight: __webpack_require__(6285),
    Translate: __webpack_require__(7711),
    TransposeMatrix: __webpack_require__(4780)

};


/***/ }),

/***/ 3911:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Deep Copy the given object or array.
 *
 * @function Phaser.Utils.Objects.DeepCopy
 * @since 3.50.0
 *
 * @param {object} obj - The object to deep copy.
 *
 * @return {object} A deep copy of the original object.
 */
var DeepCopy = function (inObject)
{
    var outObject;
    var value;
    var key;

    if (typeof inObject !== 'object' || inObject === null)
    {
        //  inObject is not an object
        return inObject;
    }

    //  Create an array or object to hold the values
    outObject = Array.isArray(inObject) ? [] : {};

    for (key in inObject)
    {
        value = inObject[key];

        //  Recursively (deep) copy for nested objects, including arrays
        outObject[key] = DeepCopy(value);
    }

    return outObject;
};

module.exports = DeepCopy;


/***/ }),

/***/ 1030:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var IsPlainObject = __webpack_require__(2482);

// @param {boolean} deep - Perform a deep copy?
// @param {object} target - The target object to copy to.
// @return {object} The extended object.

/**
 * This is a slightly modified version of http://api.jquery.com/jQuery.extend/
 *
 * @function Phaser.Utils.Objects.Extend
 * @since 3.0.0
 *
 * @param {...*} [args] - The objects that will be mixed.
 *
 * @return {object} The extended object.
 */
var Extend = function ()
{
    var options, name, src, copy, copyIsArray, clone,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false;

    // Handle a deep copy situation
    if (typeof target === 'boolean')
    {
        deep = target;
        target = arguments[1] || {};

        // skip the boolean and the target
        i = 2;
    }

    // extend Phaser if only one argument is passed
    if (length === i)
    {
        target = this;
        --i;
    }

    for (; i < length; i++)
    {
        // Only deal with non-null/undefined values
        if ((options = arguments[i]) != null)
        {
            // Extend the base object
            for (name in options)
            {
                src = target[name];
                copy = options[name];

                // Prevent never-ending loop
                if (target === copy)
                {
                    continue;
                }

                // Recurse if we're merging plain objects or arrays
                if (deep && copy && (IsPlainObject(copy) || (copyIsArray = Array.isArray(copy))))
                {
                    if (copyIsArray)
                    {
                        copyIsArray = false;
                        clone = src && Array.isArray(src) ? src : [];
                    }
                    else
                    {
                        clone = src && IsPlainObject(src) ? src : {};
                    }

                    // Never move original objects, clone them
                    target[name] = Extend(deep, clone, copy);

                // Don't bring in undefined values
                }
                else if (copy !== undefined)
                {
                    target[name] = copy;
                }
            }
        }
    }

    // Return the modified object
    return target;
};

module.exports = Extend;


/***/ }),

/***/ 8361:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var MATH = __webpack_require__(4675);
var GetValue = __webpack_require__(5851);

/**
 * Retrieves a value from an object. Allows for more advanced selection options, including:
 *
 * Allowed types:
 *
 * Explicit:
 * {
 *     x: 4
 * }
 *
 * From function
 * {
 *     x: function ()
 * }
 *
 * Randomly pick one element from the array
 * {
 *     x: [a, b, c, d, e, f]
 * }
 *
 * Random integer between min and max:
 * {
 *     x: { randInt: [min, max] }
 * }
 *
 * Random float between min and max:
 * {
 *     x: { randFloat: [min, max] }
 * }
 *
 *
 * @function Phaser.Utils.Objects.GetAdvancedValue
 * @since 3.0.0
 *
 * @param {object} source - The object to retrieve the value from.
 * @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object.
 * @param {*} defaultValue - The value to return if the `key` isn't found in the `source` object.
 *
 * @return {*} The value of the requested key.
 */
var GetAdvancedValue = function (source, key, defaultValue)
{
    var value = GetValue(source, key, null);

    if (value === null)
    {
        return defaultValue;
    }
    else if (Array.isArray(value))
    {
        return MATH.RND.pick(value);
    }
    else if (typeof value === 'object')
    {
        if (value.hasOwnProperty('randInt'))
        {
            return MATH.RND.integerInRange(value.randInt[0], value.randInt[1]);
        }
        else if (value.hasOwnProperty('randFloat'))
        {
            return MATH.RND.realInRange(value.randFloat[0], value.randFloat[1]);
        }
    }
    else if (typeof value === 'function')
    {
        return value(key);
    }

    return value;
};

module.exports = GetAdvancedValue;


/***/ }),

/***/ 4597:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Finds the key within the top level of the {@link source} object, or returns {@link defaultValue}
 *
 * @function Phaser.Utils.Objects.GetFastValue
 * @since 3.0.0
 *
 * @param {object} source - The object to search
 * @param {string} key - The key for the property on source. Must exist at the top level of the source object (no periods)
 * @param {*} [defaultValue] - The default value to use if the key does not exist.
 *
 * @return {*} The value if found; otherwise, defaultValue (null if none provided)
 */
var GetFastValue = function (source, key, defaultValue)
{
    var t = typeof(source);

    if (!source || t === 'number' || t === 'string')
    {
        return defaultValue;
    }
    else if (source.hasOwnProperty(key) && source[key] !== undefined)
    {
        return source[key];
    }
    else
    {
        return defaultValue;
    }
};

module.exports = GetFastValue;


/***/ }),

/***/ 5851:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Retrieves a value from an object, or an alternative object, falling to a back-up default value if not found.
 *
 * The key is a string, which can be split based on the use of the period character.
 *
 * For example:
 *
 * ```javascript
 * const source = {
 *   lives: 3,
 *   render: {
 *     screen: {
 *       width: 1024
 *     }
 *   }
 * }
 *
 * const lives = GetValue(source, 'lives', 1);
 * const width = GetValue(source, 'render.screen.width', 800);
 * const height = GetValue(source, 'render.screen.height', 600);
 * ```
 *
 * In the code above, `lives` will be 3 because it's defined at the top level of `source`.
 * The `width` value will be 1024 because it can be found inside the `render.screen` object.
 * The `height` value will be 600, the default value, because it is missing from the `render.screen` object.
 *
 * @function Phaser.Utils.Objects.GetValue
 * @since 3.0.0
 *
 * @param {object} source - The primary object to try to retrieve the value from. If not found in here, `altSource` is checked.
 * @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object.
 * @param {*} defaultValue - The value to return if the `key` isn't found in the `source` object.
 * @param {object} [altSource] - An alternative object to retrieve the value from. If the property exists in `source` then `altSource` will not be used.
 *
 * @return {*} The value of the requested key.
 */
var GetValue = function (source, key, defaultValue, altSource)
{
    if ((!source && !altSource) || typeof source === 'number')
    {
        return defaultValue;
    }
    else if (source && source.hasOwnProperty(key))
    {
        return source[key];
    }
    else if (altSource && altSource.hasOwnProperty(key))
    {
        return altSource[key];
    }
    else if (key.indexOf('.') !== -1)
    {
        var keys = key.split('.');
        var parentA = source;
        var parentB = altSource;
        var valueA = defaultValue;
        var valueB = defaultValue;
        var valueAFound = true;
        var valueBFound = true;

        //  Use for loop here so we can break early
        for (var i = 0; i < keys.length; i++)
        {
            if (parentA && parentA.hasOwnProperty(keys[i]))
            {
                //  Yes parentA has a key property, let's carry on down
                valueA = parentA[keys[i]];
                parentA = parentA[keys[i]];
            }
            else
            {
                valueAFound = false;
            }

            if (parentB && parentB.hasOwnProperty(keys[i]))
            {
                //  Yes parentB has a key property, let's carry on down
                valueB = parentB[keys[i]];
                parentB = parentB[keys[i]];
            }
            else
            {
                valueBFound = false;
            }
        }

        if (valueAFound)
        {
            return valueA;
        }
        else if (valueBFound)
        {
            return valueB;
        }
        else
        {
            return defaultValue;
        }
    }
    else
    {
        return defaultValue;
    }
};

module.exports = GetValue;


/***/ }),

/***/ 2482:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * This is a slightly modified version of jQuery.isPlainObject.
 * A plain object is an object whose internal class property is [object Object].
 *
 * @function Phaser.Utils.Objects.IsPlainObject
 * @since 3.0.0
 *
 * @param {object} obj - The object to inspect.
 *
 * @return {boolean} `true` if the object is plain, otherwise `false`.
 */
var IsPlainObject = function (obj)
{
    // Not plain objects:
    // - Any object or value whose internal [[Class]] property is not "[object Object]"
    // - DOM nodes
    // - window
    if (!obj || typeof(obj) !== 'object' || obj.nodeType || obj === obj.window)
    {
        return false;
    }

    // Support: Firefox <20
    // The try/catch suppresses exceptions thrown when attempting to access
    // the "constructor" property of certain host objects, ie. |window.location|
    // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
    try
    {
        if (obj.constructor && !({}).hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf'))
        {
            return false;
        }
    }
    catch (e)
    {
        return false;
    }

    // If the function hasn't returned already, we're confident that
    // |obj| is a plain object, created by {} or constructed with new Object
    return true;
};

module.exports = IsPlainObject;


/***/ }),

/***/ 7222:
/***/ ((module) => {

/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2013-2023 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Takes the given string and pads it out, to the length required, using the character
 * specified. For example if you need a string to be 6 characters long, you can call:
 *
 * `pad('bob', 6, '-', 2)`
 *
 * This would return: `bob---` as it has padded it out to 6 characters, using the `-` on the right.
 *
 * You can also use it to pad numbers (they are always returned as strings):
 *
 * `pad(512, 6, '0', 1)`
 *
 * Would return: `000512` with the string padded to the left.
 *
 * If you don't specify a direction it'll pad to both sides:
 *
 * `pad('c64', 7, '*')`
 *
 * Would return: `**c64**`
 *
 * @function Phaser.Utils.String.Pad
 * @since 3.0.0
 *
 * @param {string|number|object} str - The target string. `toString()` will be called on the string, which means you can also pass in common data types like numbers.
 * @param {number} [len=0] - The number of characters to be added.
 * @param {string} [pad=" "] - The string to pad it out with (defaults to a space).
 * @param {number} [dir=3] - The direction dir = 1 (left), 2 (right), 3 (both).
 *
 * @return {string} The padded string.
 */
var Pad = function (str, len, pad, dir)
{
    if (len === undefined) { len = 0; }
    if (pad === undefined) { pad = ' '; }
    if (dir === undefined) { dir = 3; }

    str = str.toString();

    var padlen = 0;

    if (len + 1 >= str.length)
    {
        switch (dir)
        {
            case 1:
                str = new Array(len + 1 - str.length).join(pad) + str;
                break;

            case 3:
                var right = Math.ceil((padlen = len - str.length) / 2);
                var left = padlen - right;
                str = new Array(left + 1).join(pad) + str + new Array(right + 1).join(pad);
                break;

            default:
                str = str + new Array(len + 1 - str.length).join(pad);
                break;
        }
    }

    return str;
};

module.exports = Pad;


/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	// This entry module is referenced by other modules so it can't be inlined
/******/ 	var __webpack_exports__ = __webpack_require__(4513);
/******/ 	window.SpinePlugin = __webpack_exports__;
/******/ 	
/******/ })()
;