diff --git a/build/player/bodymovin.js b/build/player/bodymovin.js
new file mode 100644
index 0000000..0ad30bc
--- /dev/null
+++ b/build/player/bodymovin.js
@@ -0,0 +1,13435 @@
+(function (root, factory) { if(typeof define === "function" && define.amd) { define( factory); } else if(typeof module === "object" && module.exports) { module.exports = factory(); } else { root.bodymovin = factory(); } }(window, function() {var svgNS = "http://www.w3.org/2000/svg";
+var subframeEnabled = true;
+var expressionsPlugin;
+var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+var cachedColors = {};
+var bm_rounder = Math.round;
+var bm_rnd;
+var bm_pow = Math.pow;
+var bm_sqrt = Math.sqrt;
+var bm_abs = Math.abs;
+var bm_floor = Math.floor;
+var bm_max = Math.max;
+var bm_min = Math.min;
+var blitter = 10;
+
+var BMMath = {};
+(function(){
+    var propertyNames = Object.getOwnPropertyNames(Math);
+    var i, len = propertyNames.length;
+    for(i=0;i<len;i+=1){
+        BMMath[propertyNames[i]] = Math[propertyNames[i]];
+    }
+}());
+
+function ProjectInterface(){return {}};
+
+BMMath.random = Math.random;
+BMMath.abs = function(val){
+    var tOfVal = typeof val;
+    if(tOfVal === 'object' && val.length){
+        var absArr = Array.apply(null,{length:val.length});
+        var i, len = val.length;
+        for(i=0;i<len;i+=1){
+            absArr[i] = Math.abs(val[i]);
+        }
+        return absArr;
+    }
+    return Math.abs(val);
+
+}
+var defaultCurveSegments = 150;
+var degToRads = Math.PI/180;
+var roundCorner = 0.5519;
+
+function roundValues(flag){
+    if(flag){
+        bm_rnd = Math.round;
+    }else{
+        bm_rnd = function(val){
+            return val;
+        };
+    }
+}
+roundValues(false);
+
+function roundTo2Decimals(val){
+    return Math.round(val*10000)/10000;
+}
+
+function roundTo3Decimals(val){
+    return Math.round(val*100)/100;
+}
+
+function styleDiv(element){
+    element.style.position = 'absolute';
+    element.style.top = 0;
+    element.style.left = 0;
+    element.style.display = 'block';
+    element.style.transformOrigin = element.style.webkitTransformOrigin = '0 0';
+    element.style.backfaceVisibility  = element.style.webkitBackfaceVisibility = 'visible';
+    element.style.transformStyle = element.style.webkitTransformStyle = element.style.mozTransformStyle = "preserve-3d";
+}
+
+function styleUnselectableDiv(element){
+    element.style.userSelect = 'none';
+    element.style.MozUserSelect = 'none';
+    element.style.webkitUserSelect = 'none';
+    element.style.oUserSelect = 'none';
+
+}
+
+function BMEnterFrameEvent(n,c,t,d){
+    this.type = n;
+    this.currentTime = c;
+    this.totalTime = t;
+    this.direction = d < 0 ? -1:1;
+}
+
+function BMCompleteEvent(n,d){
+    this.type = n;
+    this.direction = d < 0 ? -1:1;
+}
+
+function BMCompleteLoopEvent(n,c,t,d){
+    this.type = n;
+    this.currentLoop = c;
+    this.totalLoops = t;
+    this.direction = d < 0 ? -1:1;
+}
+
+function BMSegmentStartEvent(n,f,t){
+    this.type = n;
+    this.firstFrame = f;
+    this.totalFrames = t;
+}
+
+function BMDestroyEvent(n,t){
+    this.type = n;
+    this.target = t;
+}
+
+function _addEventListener(eventName, callback){
+
+    if (!this._cbs[eventName]){
+        this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+	return function() {
+		this.removeEventListener(eventName, callback);
+	}.bind(this);
+}
+
+function _removeEventListener(eventName,callback){
+
+    if (!callback){
+        this._cbs[eventName] = null;
+    }else if(this._cbs[eventName]){
+        var i = 0, len = this._cbs[eventName].length;
+        while(i<len){
+            if(this._cbs[eventName][i] === callback){
+                this._cbs[eventName].splice(i,1);
+                i -=1;
+                len -= 1;
+            }
+            i += 1;
+        }
+        if(!this._cbs[eventName].length){
+            this._cbs[eventName] = null;
+        }
+    }
+
+}
+
+function _triggerEvent(eventName, args){
+    if (this._cbs[eventName]) {
+        var len = this._cbs[eventName].length;
+        for (var i = 0; i < len; i++){
+            this._cbs[eventName][i](args);
+        }
+    }
+}
+
+function randomString(length, chars){
+    if(chars === undefined){
+        chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
+    }
+    var i;
+    var result = '';
+    for (i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
+    return result;
+}
+
+function HSVtoRGB(h, s, v) {
+    var r, g, b, i, f, p, q, t;
+    if (arguments.length === 1) {
+        s = h.s, v = h.v, h = h.h;
+    }
+    i = Math.floor(h * 6);
+    f = h * 6 - i;
+    p = v * (1 - s);
+    q = v * (1 - f * s);
+    t = v * (1 - (1 - f) * s);
+    switch (i % 6) {
+        case 0: r = v, g = t, b = p; break;
+        case 1: r = q, g = v, b = p; break;
+        case 2: r = p, g = v, b = t; break;
+        case 3: r = p, g = q, b = v; break;
+        case 4: r = t, g = p, b = v; break;
+        case 5: r = v, g = p, b = q; break;
+    }
+    return [ r,
+        g,
+         b ];
+}
+
+function RGBtoHSV(r, g, b) {
+    if (arguments.length === 1) {
+        g = r.g, b = r.b, r = r.r;
+    }
+    var max = Math.max(r, g, b), min = Math.min(r, g, b),
+        d = max - min,
+        h,
+        s = (max === 0 ? 0 : d / max),
+        v = max / 255;
+
+    switch (max) {
+        case min: h = 0; break;
+        case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break;
+        case g: h = (b - r) + d * 2; h /= 6 * d; break;
+        case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    }
+
+    return [
+         h,
+         s,
+         v
+    ];
+}
+
+function addSaturationToRGB(color,offset){
+    var hsv = RGBtoHSV(color[0]*255,color[1]*255,color[2]*255);
+    hsv[1] += offset;
+    if (hsv[1] > 1) {
+        hsv[1] = 1;
+    }
+    else if (hsv[1] <= 0) {
+        hsv[1] = 0;
+    }
+    return HSVtoRGB(hsv[0],hsv[1],hsv[2]);
+}
+
+function addBrightnessToRGB(color,offset){
+    var hsv = RGBtoHSV(color[0]*255,color[1]*255,color[2]*255);
+    hsv[2] += offset;
+    if (hsv[2] > 1) {
+        hsv[2] = 1;
+    }
+    else if (hsv[2] < 0) {
+        hsv[2] = 0;
+    }
+    return HSVtoRGB(hsv[0],hsv[1],hsv[2]);
+}
+
+function addHueToRGB(color,offset) {
+    var hsv = RGBtoHSV(color[0]*255,color[1]*255,color[2]*255);
+    hsv[0] += offset/360;
+    if (hsv[0] > 1) {
+        hsv[0] -= 1;
+    }
+    else if (hsv[0] < 0) {
+        hsv[0] += 1;
+    }
+    return HSVtoRGB(hsv[0],hsv[1],hsv[2]);
+}
+
+function componentToHex(c) {
+    var hex = c.toString(16);
+    return hex.length == 1 ? '0' + hex : hex;
+}
+
+var rgbToHex = (function(){
+    var colorMap = [];
+    var i;
+    var hex;
+    for(i=0;i<256;i+=1){
+        hex = i.toString(16);
+        colorMap[i] = hex.length == 1 ? '0' + hex : hex;
+    }
+
+    return function(r, g, b) {
+        if(r<0){
+            r = 0;
+        }
+        if(g<0){
+            g = 0;
+        }
+        if(b<0){
+            b = 0;
+        }
+        return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+    };
+}());
+
+function fillToRgba(hex,alpha){
+    if(!cachedColors[hex]){
+        var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+        cachedColors[hex] = parseInt(result[1], 16)+','+parseInt(result[2], 16)+','+parseInt(result[3], 16);
+    }
+    return 'rgba('+cachedColors[hex]+','+alpha+')';
+}
+
+var fillColorToString = (function(){
+
+    var colorMap = [];
+    return function(colorArr,alpha){
+        if(alpha !== undefined){
+            colorArr[3] = alpha;
+        }
+        if(!colorMap[colorArr[0]]){
+            colorMap[colorArr[0]] = {};
+        }
+        if(!colorMap[colorArr[0]][colorArr[1]]){
+            colorMap[colorArr[0]][colorArr[1]] = {};
+        }
+        if(!colorMap[colorArr[0]][colorArr[1]][colorArr[2]]){
+            colorMap[colorArr[0]][colorArr[1]][colorArr[2]] = {};
+        }
+        if(!colorMap[colorArr[0]][colorArr[1]][colorArr[2]][colorArr[3]]){
+            colorMap[colorArr[0]][colorArr[1]][colorArr[2]][colorArr[3]] = 'rgba(' + colorArr.join(',')+')';
+        }
+        return colorMap[colorArr[0]][colorArr[1]][colorArr[2]][colorArr[3]];
+    };
+}());
+
+function RenderedFrame(tr,o) {
+    this.tr = tr;
+    this.o = o;
+}
+
+function LetterProps(o,sw,sc,fc,m,p){
+    this.o = o;
+    this.sw = sw;
+    this.sc = sc;
+    this.fc = fc;
+    this.m = m;
+    this.props = p;
+}
+
+function iterateDynamicProperties(num){
+    var i, len = this.dynamicProperties;
+    for(i=0;i<len;i+=1){
+        this.dynamicProperties[i].getValue(num);
+    }
+}
+
+function reversePath(paths){
+    var newI = [], newO = [], newV = [];
+    var i, len, newPaths = {};
+    var init = 0;
+    if (paths.c) {
+        newI[0] = paths.o[0];
+        newO[0] = paths.i[0];
+        newV[0] = paths.v[0];
+        init = 1;
+    }
+    len = paths.i.length;
+    var cnt = len - 1;
+
+    for (i = init; i < len; i += 1) {
+        newI.push(paths.o[cnt]);
+        newO.push(paths.i[cnt]);
+        newV.push(paths.v[cnt]);
+        cnt -= 1;
+    }
+
+    newPaths.i = newI;
+    newPaths.o = newO;
+    newPaths.v = newV;
+
+    return newPaths;
+}
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+var Matrix = (function(){
+
+    function reset(){
+        this.props[0] = 1;
+        this.props[1] = 0;
+        this.props[2] = 0;
+        this.props[3] = 0;
+        this.props[4] = 0;
+        this.props[5] = 1;
+        this.props[6] = 0;
+        this.props[7] = 0;
+        this.props[8] = 0;
+        this.props[9] = 0;
+        this.props[10] = 1;
+        this.props[11] = 0;
+        this.props[12] = 0;
+        this.props[13] = 0;
+        this.props[14] = 0;
+        this.props[15] = 1;
+        return this;
+    }
+
+    function rotate(angle) {
+        if(angle === 0){
+            return this;
+        }
+        var mCos = Math.cos(angle);
+        var mSin = Math.sin(angle);
+        return this._t(mCos, -mSin,  0, 0
+            , mSin,  mCos, 0, 0
+            , 0,  0,  1, 0
+            , 0, 0, 0, 1);
+    }
+
+    function rotateX(angle){
+        if(angle === 0){
+            return this;
+        }
+        var mCos = Math.cos(angle);
+        var mSin = Math.sin(angle);
+        return this._t(1, 0, 0, 0
+            , 0, mCos, -mSin, 0
+            , 0, mSin,  mCos, 0
+            , 0, 0, 0, 1);
+    }
+
+    function rotateY(angle){
+        if(angle === 0){
+            return this;
+        }
+        var mCos = Math.cos(angle);
+        var mSin = Math.sin(angle);
+        return this._t(mCos,  0,  mSin, 0
+            , 0, 1, 0, 0
+            , -mSin,  0,  mCos, 0
+            , 0, 0, 0, 1);
+    }
+
+    function rotateZ(angle){
+        if(angle === 0){
+            return this;
+        }
+        var mCos = Math.cos(angle);
+        var mSin = Math.sin(angle);
+        return this._t(mCos, -mSin,  0, 0
+            , mSin,  mCos, 0, 0
+            , 0,  0,  1, 0
+            , 0, 0, 0, 1);
+    }
+
+    function shear(sx,sy){
+        return this._t(1, sy, sx, 1, 0, 0);
+    }
+
+    function skew(ax, ay){
+        return this.shear(Math.tan(ax), Math.tan(ay));
+    }
+
+    function skewFromAxis(ax, angle){
+        var mCos = Math.cos(angle);
+        var mSin = Math.sin(angle);
+        return this._t(mCos, mSin,  0, 0
+            , -mSin,  mCos, 0, 0
+            , 0,  0,  1, 0
+            , 0, 0, 0, 1)
+            ._t(1, 0,  0, 0
+            , Math.tan(ax),  1, 0, 0
+            , 0,  0,  1, 0
+            , 0, 0, 0, 1)
+            ._t(mCos, -mSin,  0, 0
+            , mSin,  mCos, 0, 0
+            , 0,  0,  1, 0
+            , 0, 0, 0, 1);
+        //return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, Math.tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+    }
+
+    function scale(sx, sy, sz) {
+        sz = isNaN(sz) ? 1 : sz;
+        if(sx == 1 && sy == 1 && sz == 1){
+            return this;
+        }
+        return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+    }
+
+    function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+        this.props[0] = a;
+        this.props[1] = b;
+        this.props[2] = c;
+        this.props[3] = d;
+        this.props[4] = e;
+        this.props[5] = f;
+        this.props[6] = g;
+        this.props[7] = h;
+        this.props[8] = i;
+        this.props[9] = j;
+        this.props[10] = k;
+        this.props[11] = l;
+        this.props[12] = m;
+        this.props[13] = n;
+        this.props[14] = o;
+        this.props[15] = p;
+        return this;
+    }
+
+    function translate(tx, ty, tz) {
+        tz = tz || 0;
+        if(tx !== 0 || ty !== 0 || tz !== 0){
+            return this._t(1,0,0,0,0,1,0,0,0,0,1,0,tx,ty,tz,1);
+        }
+        return this;
+    }
+
+    function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+
+        if(a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0){
+            if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+
+                this.props[12] = this.props[12] * a2 + this.props[13] * e2 + this.props[14] * i2 + this.props[15] * m2 ;
+                this.props[13] = this.props[12] * b2 + this.props[13] * f2 + this.props[14] * j2 + this.props[15] * n2 ;
+                this.props[14] = this.props[12] * c2 + this.props[13] * g2 + this.props[14] * k2 + this.props[15] * o2 ;
+                this.props[15] = this.props[12] * d2 + this.props[13] * h2 + this.props[14] * l2 + this.props[15] * p2 ;
+            }
+            return this;
+        }
+
+        var a1 = this.props[0];
+        var b1 = this.props[1];
+        var c1 = this.props[2];
+        var d1 = this.props[3];
+        var e1 = this.props[4];
+        var f1 = this.props[5];
+        var g1 = this.props[6];
+        var h1 = this.props[7];
+        var i1 = this.props[8];
+        var j1 = this.props[9];
+        var k1 = this.props[10];
+        var l1 = this.props[11];
+        var m1 = this.props[12];
+        var n1 = this.props[13];
+        var o1 = this.props[14];
+        var p1 = this.props[15];
+
+        /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+        this.props[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+        this.props[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2 ;
+        this.props[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2 ;
+        this.props[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2 ;
+
+        this.props[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2 ;
+        this.props[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2 ;
+        this.props[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2 ;
+        this.props[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2 ;
+
+        this.props[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2 ;
+        this.props[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2 ;
+        this.props[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2 ;
+        this.props[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2 ;
+
+        this.props[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2 ;
+        this.props[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2 ;
+        this.props[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2 ;
+        this.props[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2 ;
+
+        return this;
+    }
+
+    function clone(matr){
+        var i;
+        for(i=0;i<16;i+=1){
+            matr.props[i] = this.props[i];
+        }
+    }
+
+    function cloneFromProps(props){
+        var i;
+        for(i=0;i<16;i+=1){
+            this.props[i] = props[i];
+        }
+    }
+
+    function applyToPoint(x, y, z) {
+
+        return {
+            x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+            y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+            z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]
+        };
+        /*return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         };*/
+    }
+    function applyToX(x, y, z) {
+        return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+    }
+    function applyToY(x, y, z) {
+        return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+    }
+    function applyToZ(x, y, z) {
+        return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+    }
+
+    function inversePoint(pt) {
+        var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+        var a = this.props[5]/determinant;
+        var b = - this.props[1]/determinant;
+        var c = - this.props[4]/determinant;
+        var d = this.props[0]/determinant;
+        var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12])/determinant;
+        var f = - (this.props[0] * this.props[13] - this.props[1] * this.props[12])/determinant;
+        return [pt[0] * a + pt[1] * c + e, pt[0] * b + pt[1] * d + f, 0];
+    }
+
+    function inversePoints(pts){
+        var i, len = pts.length, retPts = [];
+        for(i=0;i<len;i+=1){
+            retPts[i] = inversePoint(pts[i]);
+        }
+        return retPts;
+    }
+
+    function applyToPointArray(x,y,z,dimensions){
+        if(dimensions && dimensions === 2) {
+            var arr = point_pool.newPoint();
+            arr[0] = x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12]; 
+            arr[1] = x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13]; 
+            return arr;    
+        }
+        return [x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]];
+    }
+    function applyToPointStringified(x, y) {
+        return (bm_rnd(x * this.props[0] + y * this.props[4] + this.props[12]))+','+(bm_rnd(x * this.props[1] + y * this.props[5] + this.props[13]));
+    }
+
+    function toArray() {
+        return [this.props[0],this.props[1],this.props[2],this.props[3],this.props[4],this.props[5],this.props[6],this.props[7],this.props[8],this.props[9],this.props[10],this.props[11],this.props[12],this.props[13],this.props[14],this.props[15]];
+    }
+
+    function toCSS() {
+        if(isSafari){
+            return "matrix3d(" + roundTo2Decimals(this.props[0]) + ',' + roundTo2Decimals(this.props[1]) + ',' + roundTo2Decimals(this.props[2]) + ',' + roundTo2Decimals(this.props[3]) + ',' + roundTo2Decimals(this.props[4]) + ',' + roundTo2Decimals(this.props[5]) + ',' + roundTo2Decimals(this.props[6]) + ',' + roundTo2Decimals(this.props[7]) + ',' + roundTo2Decimals(this.props[8]) + ',' + roundTo2Decimals(this.props[9]) + ',' + roundTo2Decimals(this.props[10]) + ',' + roundTo2Decimals(this.props[11]) + ',' + roundTo2Decimals(this.props[12]) + ',' + roundTo2Decimals(this.props[13]) + ',' + roundTo2Decimals(this.props[14]) + ',' + roundTo2Decimals(this.props[15]) + ')';
+        } else {
+            this.cssParts[1] = this.props.join(',');
+            return this.cssParts.join('');
+        }
+    }
+
+    function to2dCSS() {
+        return "matrix(" + this.props[0] + ',' + this.props[1] + ',' + this.props[4] + ',' + this.props[5] + ',' + this.props[12] + ',' + this.props[13] + ")";
+    }
+
+    function toString() {
+        return "" + this.toArray();
+    }
+
+    return function(){
+        this.reset = reset;
+        this.rotate = rotate;
+        this.rotateX = rotateX;
+        this.rotateY = rotateY;
+        this.rotateZ = rotateZ;
+        this.skew = skew;
+        this.skewFromAxis = skewFromAxis;
+        this.shear = shear;
+        this.scale = scale;
+        this.setTransform = setTransform;
+        this.translate = translate;
+        this.transform = transform;
+        this.applyToPoint = applyToPoint;
+        this.applyToX = applyToX;
+        this.applyToY = applyToY;
+        this.applyToZ = applyToZ;
+        this.applyToPointArray = applyToPointArray;
+        this.applyToPointStringified = applyToPointStringified;
+        this.toArray = toArray;
+        this.toCSS = toCSS;
+        this.to2dCSS = to2dCSS;
+        this.toString = toString;
+        this.clone = clone;
+        this.cloneFromProps = cloneFromProps;
+        this.inversePoints = inversePoints;
+        this.inversePoint = inversePoint;
+        this._t = this.transform;
+
+        this.props = [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];
+
+        this.cssParts = ['matrix3d(','',')'];
+    }
+}());
+
+function Matrix() {
+
+
+}
+
+/*
+ Copyright 2014 David Bau.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+(function (pool, math) {
+//
+// The following constants are related to IEEE 754 limits.
+//
+    var global = this,
+        width = 256,        // each RC4 output is 0 <= x < 256
+        chunks = 6,         // at least six RC4 outputs for each double
+        digits = 52,        // there are 52 significant digits in a double
+        rngname = 'random', // rngname: name for Math.random and Math.seedrandom
+        startdenom = math.pow(width, chunks),
+        significance = math.pow(2, digits),
+        overflow = significance * 2,
+        mask = width - 1,
+        nodecrypto;         // node.js crypto module, initialized at the bottom.
+
+//
+// seedrandom()
+// This is the seedrandom function described above.
+//
+    function seedrandom(seed, options, callback) {
+        var key = [];
+        options = (options == true) ? { entropy: true } : (options || {});
+
+        // Flatten the seed string or build one from local entropy if needed.
+        var shortseed = mixkey(flatten(
+            options.entropy ? [seed, tostring(pool)] :
+                (seed == null) ? autoseed() : seed, 3), key);
+
+        // Use the seed to initialize an ARC4 generator.
+        var arc4 = new ARC4(key);
+
+        // This function returns a random double in [0, 1) that contains
+        // randomness in every bit of the mantissa of the IEEE 754 value.
+        var prng = function() {
+            var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48
+                d = startdenom,                 //   and denominator d = 2 ^ 48.
+                x = 0;                          //   and no 'extra last byte'.
+            while (n < significance) {          // Fill up all significant digits by
+                n = (n + x) * width;              //   shifting numerator and
+                d *= width;                       //   denominator and generating a
+                x = arc4.g(1);                    //   new least-significant-byte.
+            }
+            while (n >= overflow) {             // To avoid rounding up, before adding
+                n /= 2;                           //   last byte, shift everything
+                d /= 2;                           //   right using integer math until
+                x >>>= 1;                         //   we have exactly the desired bits.
+            }
+            return (n + x) / d;                 // Form the number within [0, 1).
+        };
+
+        prng.int32 = function() { return arc4.g(4) | 0; }
+        prng.quick = function() { return arc4.g(4) / 0x100000000; }
+        prng.double = prng;
+
+        // Mix the randomness into accumulated entropy.
+        mixkey(tostring(arc4.S), pool);
+
+        // Calling convention: what to return as a function of prng, seed, is_math.
+        return (options.pass || callback ||
+        function(prng, seed, is_math_call, state) {
+            if (state) {
+                // Load the arc4 state from the given state if it has an S array.
+                if (state.S) { copy(state, arc4); }
+                // Only provide the .state method if requested via options.state.
+                prng.state = function() { return copy(arc4, {}); }
+            }
+
+            // If called as a method of Math (Math.seedrandom()), mutate
+            // Math.random because that is how seedrandom.js has worked since v1.0.
+            if (is_math_call) { math[rngname] = prng; return seed; }
+
+            // Otherwise, it is a newer calling convention, so return the
+            // prng directly.
+            else return prng;
+        })(
+            prng,
+            shortseed,
+            'global' in options ? options.global : (this == math),
+            options.state);
+    }
+    math['seed' + rngname] = seedrandom;
+
+//
+// ARC4
+//
+// An ARC4 implementation.  The constructor takes a key in the form of
+// an array of at most (width) integers that should be 0 <= x < (width).
+//
+// The g(count) method returns a pseudorandom integer that concatenates
+// the next (count) outputs from ARC4.  Its return value is a number x
+// that is in the range 0 <= x < (width ^ count).
+//
+    function ARC4(key) {
+        var t, keylen = key.length,
+            me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
+
+        // The empty key [] is treated as [0].
+        if (!keylen) { key = [keylen++]; }
+
+        // Set up S using the standard key scheduling algorithm.
+        while (i < width) {
+            s[i] = i++;
+        }
+        for (i = 0; i < width; i++) {
+            s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
+            s[j] = t;
+        }
+
+        // The "g" method returns the next (count) outputs as one number.
+        (me.g = function(count) {
+            // Using instance members instead of closure state nearly doubles speed.
+            var t, r = 0,
+                i = me.i, j = me.j, s = me.S;
+            while (count--) {
+                t = s[i = mask & (i + 1)];
+                r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
+            }
+            me.i = i; me.j = j;
+            return r;
+            // For robust unpredictability, the function call below automatically
+            // discards an initial batch of values.  This is called RC4-drop[256].
+            // See http://google.com/search?q=rsa+fluhrer+response&btnI
+        })(width);
+    }
+
+//
+// copy()
+// Copies internal state of ARC4 to or from a plain object.
+//
+    function copy(f, t) {
+        t.i = f.i;
+        t.j = f.j;
+        t.S = f.S.slice();
+        return t;
+    };
+
+//
+// flatten()
+// Converts an object tree to nested arrays of strings.
+//
+    function flatten(obj, depth) {
+        var result = [], typ = (typeof obj), prop;
+        if (depth && typ == 'object') {
+            for (prop in obj) {
+                try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
+            }
+        }
+        return (result.length ? result : typ == 'string' ? obj : obj + '\0');
+    }
+
+//
+// mixkey()
+// Mixes a string seed into a key that is an array of integers, and
+// returns a shortened string seed that is equivalent to the result key.
+//
+    function mixkey(seed, key) {
+        var stringseed = seed + '', smear, j = 0;
+        while (j < stringseed.length) {
+            key[mask & j] =
+                mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
+        }
+        return tostring(key);
+    }
+
+//
+// autoseed()
+// Returns an object for autoseeding, using window.crypto and Node crypto
+// module if available.
+//
+    function autoseed() {
+        try {
+            if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); }
+            var out = new Uint8Array(width);
+            (global.crypto || global.msCrypto).getRandomValues(out);
+            return tostring(out);
+        } catch (e) {
+            var browser = global.navigator,
+                plugins = browser && browser.plugins;
+            return [+new Date, global, plugins, global.screen, tostring(pool)];
+        }
+    }
+
+//
+// tostring()
+// Converts an array of charcodes to a string
+//
+    function tostring(a) {
+        return String.fromCharCode.apply(0, a);
+    }
+
+//
+// When seedrandom.js is loaded, we immediately mix a few bits
+// from the built-in RNG into the entropy pool.  Because we do
+// not want to interfere with deterministic PRNG state later,
+// seedrandom will not call math.random on its own again after
+// initialization.
+//
+    mixkey(math.random(), pool);
+
+//
+// Nodejs and AMD support: export the implementation as a module using
+// either convention.
+//
+
+// End anonymous scope, and pass initial values.
+})(
+    [],     // pool: entropy pool starts empty
+    BMMath    // math: package containing random, pow, and seedrandom
+);
+var BezierFactory = (function(){
+    /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+        var ob = {};
+    ob.getBezierEasing = getBezierEasing;
+    var beziers = {};
+
+    function getBezierEasing(a,b,c,d,nm){
+        var str = nm || ('bez_' + a+'_'+b+'_'+c+'_'+d).replace(/\./g, 'p');
+        if(beziers[str]){
+            return beziers[str];
+        }
+        var bezEasing = new BezierEasing([a,b,c,d]);
+        beziers[str] = bezEasing;
+        return bezEasing;
+    }
+
+// These values are established by empiricism with tests (tradeoff: performance VS precision)
+    var NEWTON_ITERATIONS = 4;
+    var NEWTON_MIN_SLOPE = 0.001;
+    var SUBDIVISION_PRECISION = 0.0000001;
+    var SUBDIVISION_MAX_ITERATIONS = 10;
+
+    var kSplineTableSize = 11;
+    var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+    var float32ArraySupported = typeof Float32Array === "function";
+
+    function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+    function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+    function C (aA1)      { return 3.0 * aA1; }
+
+// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+    function calcBezier (aT, aA1, aA2) {
+        return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT;
+    }
+
+// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+    function getSlope (aT, aA1, aA2) {
+        return 3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+    }
+
+    function binarySubdivide (aX, aA, aB, mX1, mX2) {
+        var currentX, currentT, i = 0;
+        do {
+            currentT = aA + (aB - aA) / 2.0;
+            currentX = calcBezier(currentT, mX1, mX2) - aX;
+            if (currentX > 0.0) {
+                aB = currentT;
+            } else {
+                aA = currentT;
+            }
+        } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+        return currentT;
+    }
+
+    function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
+        for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+            var currentSlope = getSlope(aGuessT, mX1, mX2);
+            if (currentSlope === 0.0) return aGuessT;
+            var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+            aGuessT -= currentX / currentSlope;
+        }
+        return aGuessT;
+    }
+
+    /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+    function BezierEasing (points) {
+        this._p = points;
+        this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+        this._precomputed = false;
+
+        this.get = this.get.bind(this);
+    }
+
+    BezierEasing.prototype = {
+
+        get: function (x) {
+            var mX1 = this._p[0],
+                mY1 = this._p[1],
+                mX2 = this._p[2],
+                mY2 = this._p[3];
+            if (!this._precomputed) this._precompute();
+            if (mX1 === mY1 && mX2 === mY2) return x; // linear
+            // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+            if (x === 0) return 0;
+            if (x === 1) return 1;
+            return calcBezier(this._getTForX(x), mY1, mY2);
+        },
+
+        // Private part
+
+        _precompute: function () {
+            var mX1 = this._p[0],
+                mY1 = this._p[1],
+                mX2 = this._p[2],
+                mY2 = this._p[3];
+            this._precomputed = true;
+            if (mX1 !== mY1 || mX2 !== mY2)
+                this._calcSampleValues();
+        },
+
+        _calcSampleValues: function () {
+            var mX1 = this._p[0],
+                mX2 = this._p[2];
+            for (var i = 0; i < kSplineTableSize; ++i) {
+                this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+            }
+        },
+
+        /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+        _getTForX: function (aX) {
+            var mX1 = this._p[0],
+                mX2 = this._p[2],
+                mSampleValues = this._mSampleValues;
+
+            var intervalStart = 0.0;
+            var currentSample = 1;
+            var lastSample = kSplineTableSize - 1;
+
+            for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+                intervalStart += kSampleStepSize;
+            }
+            --currentSample;
+
+            // Interpolate to provide an initial guess for t
+            var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample+1] - mSampleValues[currentSample]);
+            var guessForT = intervalStart + dist * kSampleStepSize;
+
+            var initialSlope = getSlope(guessForT, mX1, mX2);
+            if (initialSlope >= NEWTON_MIN_SLOPE) {
+                return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+            } else if (initialSlope === 0.0) {
+                return guessForT;
+            } else {
+                return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+            }
+        }
+    };
+
+    return ob;
+
+}())
+
+
+function matrixManagerFunction(){
+
+    var mat = new Matrix();
+
+    var returnMatrix2D = function(rX, scaleX, scaleY, tX, tY){
+        return mat.reset().translate(tX,tY).rotate(rX).scale(scaleX,scaleY).toCSS();
+    };
+
+    var getMatrix = function(animData){
+        return returnMatrix2D(animData.tr.r[2],animData.tr.s[0],animData.tr.s[1],animData.tr.p[0],animData.tr.p[1]);
+    };
+
+    return {
+        getMatrix : getMatrix
+    };
+
+}
+var MatrixManager = matrixManagerFunction;
+(function () {
+    var lastTime = 0;
+    var vendors = ['ms', 'moz', 'webkit', 'o'];
+    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
+        window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
+        window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
+    }
+    if(!window.requestAnimationFrame)
+        window.requestAnimationFrame = function (callback, element) {
+            var currTime = new Date().getTime();
+            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
+            var id = window.setTimeout(function () {
+                    callback(currTime + timeToCall);
+                },
+                timeToCall);
+            lastTime = currTime + timeToCall;
+            return id;
+        };
+    if(!window.cancelAnimationFrame)
+        window.cancelAnimationFrame = function (id) {
+            clearTimeout(id);
+        };
+}());
+function createElement(parent,child,params){
+    if(child){
+        child.prototype = Object.create(parent.prototype);
+        child.prototype.constructor = child;
+        child.prototype._parent = parent.prototype;
+    }else{
+        var instance = Object.create(parent.prototype,params);
+        var getType = {};
+        if(instance && getType.toString.call(instance.init) === '[object Function]'){
+            instance.init();
+        }
+        return instance;
+    }
+}
+
+function extendPrototype(source,destination){
+    for (var attr in source.prototype) {
+        if (source.prototype.hasOwnProperty(attr)) destination.prototype[attr] = source.prototype[attr];
+    }
+}
+function bezFunction(){
+
+    var easingFunctions = [];
+    var math = Math;
+
+    function pointOnLine2D(x1,y1, x2,y2, x3,y3){
+        var det1 = (x1*y2) + (y1*x3) + (x2*y3) - (x3*y2) - (y3*x1) - (x2*y1);
+        return det1 > -0.0001 && det1 < 0.0001;
+    }
+
+    function pointOnLine3D(x1,y1,z1, x2,y2,z2, x3,y3,z3){
+        var dist1 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2) + Math.pow(z2 - z1, 2));
+        var dist2 = Math.sqrt(Math.pow(x3 - x1, 2) + Math.pow(y3 - y1, 2) + Math.pow(z3 - z1, 2));
+        var dist3 = Math.sqrt(Math.pow(x3 - x2, 2) + Math.pow(y3 - y2, 2) + Math.pow(z3 - z2, 2));
+        var diffDist;
+        if(dist1 > dist2){
+            if(dist1 > dist3){
+                diffDist = dist1 - dist2 - dist3;
+            } else {
+                diffDist = dist3 - dist2 - dist1;
+            }
+        } else if(dist3 > dist2){
+            diffDist = dist3 - dist2 - dist1;
+        } else {
+            diffDist = dist2 - dist1 - dist3;
+        }
+        return diffDist > -0.0001 && diffDist < 0.0001;
+    }
+
+    /*function getEasingCurve(aa,bb,cc,dd,encodedFuncName) {
+        if(!encodedFuncName){
+            encodedFuncName = ('bez_' + aa+'_'+bb+'_'+cc+'_'+dd).replace(/\./g, 'p');
+        }
+        if(easingFunctions[encodedFuncName]){
+            return easingFunctions[encodedFuncName];
+        }
+        var A0, B0, C0;
+        var A1, B1, C1;
+        easingFunctions[encodedFuncName] = function(tt) {
+            var x = tt;
+            var i = 0, z;
+            while (++i < 20) {
+                C0 = 3 * aa;
+                B0 = 3 * (cc - aa) - C0;
+                A0 = 1 - C0 - B0;
+                z = (x * (C0 + x * (B0 + x * A0))) - tt;
+                if (bm_abs(z) < 1e-3) break;
+                x -= z / (C0 + x * (2 * B0 + 3 * A0 * x));
+            }
+            C1 = 3 * bb;
+            B1 = 3 * (dd - bb) - C1;
+            A1 = 1 - C1 - B1;
+            var polyB = x * (C1 + x * (B1 + x * A1));
+            //return c * polyB + b;
+            return polyB;
+        };
+        return easingFunctions[encodedFuncName];
+    }*/
+    var getBezierLength = (function(){
+
+        function Segment(l,p){
+            this.l = l;
+            this.p = p;
+        }
+
+        return function(pt1,pt2,pt3,pt4){
+            var curveSegments = defaultCurveSegments;
+            var k;
+            var i, len;
+            var ptCoord,perc,addedLength = 0;
+            var ptDistance;
+            var point = [],lastPoint = [];
+            var lengthData = {
+                addedLength: 0,
+                segments: []
+            };
+            len = pt3.length;
+            for(k=0;k<curveSegments;k+=1){
+                perc = k/(curveSegments-1);
+                ptDistance = 0;
+                for(i=0;i<len;i+=1){
+                    ptCoord = bm_pow(1-perc,3)*pt1[i]+3*bm_pow(1-perc,2)*perc*pt3[i]+3*(1-perc)*bm_pow(perc,2)*pt4[i]+bm_pow(perc,3)*pt2[i];
+                    point[i] = ptCoord;
+                    if(lastPoint[i] !== null){
+                        ptDistance += bm_pow(point[i] - lastPoint[i],2);
+                    }
+                    lastPoint[i] = point[i];
+                }
+                if(ptDistance){
+                    ptDistance = bm_sqrt(ptDistance);
+                    addedLength += ptDistance;
+                }
+                lengthData.segments.push(new Segment(addedLength,perc));
+            }
+            lengthData.addedLength = addedLength;
+            return lengthData;
+        };
+    }());
+
+    function BezierData(length){
+        this.segmentLength = 0;
+        this.points = new Array(length);
+    }
+
+    function PointData(partial,point){
+        this.partialLength = partial;
+        this.point = point;
+    }
+
+    var buildBezierData = (function(){
+
+        var storedData = {};
+
+        return function (keyData){
+            var pt1 = keyData.s;
+            var pt2 = keyData.e;
+            var pt3 = keyData.to;
+            var pt4 = keyData.ti;
+            var bezierName = (pt1.join('_')+'_'+pt2.join('_')+'_'+pt3.join('_')+'_'+pt4.join('_')).replace(/\./g, 'p');
+            if(storedData[bezierName]){
+                keyData.bezierData = storedData[bezierName];
+                return;
+            }
+        var curveSegments = defaultCurveSegments;
+        var k, i, len;
+            var ptCoord,perc,addedLength = 0;
+            var ptDistance;
+            var point,lastPoint = null;
+            if(pt1.length === 2 && (pt1[0] != pt2[0] || pt1[1] != pt2[1]) && pointOnLine2D(pt1[0],pt1[1],pt2[0],pt2[1],pt1[0]+pt3[0],pt1[1]+pt3[1]) && pointOnLine2D(pt1[0],pt1[1],pt2[0],pt2[1],pt2[0]+pt4[0],pt2[1]+pt4[1])){
+                curveSegments = 2;
+            }
+            var bezierData = new BezierData(curveSegments);
+            len = pt3.length;
+            for(k=0;k<curveSegments;k+=1){
+            point = new Array(len);
+                perc = k/(curveSegments-1);
+                ptDistance = 0;
+                for(i=0;i<len;i+=1){
+                ptCoord = bm_pow(1-perc,3)*pt1[i]+3*bm_pow(1-perc,2)*perc*(pt1[i] + pt3[i])+3*(1-perc)*bm_pow(perc,2)*(pt2[i] + pt4[i])+bm_pow(perc,3)*pt2[i];
+                point[i] = ptCoord;
+                    if(lastPoint !== null){
+                    ptDistance += bm_pow(point[i] - lastPoint[i],2);
+                    }
+                }
+            ptDistance = bm_sqrt(ptDistance);
+                addedLength += ptDistance;
+                bezierData.points[k] = new PointData(ptDistance,point);
+                lastPoint = point;
+            }
+            bezierData.segmentLength = addedLength;
+            keyData.bezierData = bezierData;
+            storedData[bezierName] = bezierData;
+
+        }
+    }());
+
+    function getDistancePerc(perc,bezierData){
+        var segments = bezierData.segments;
+        var len = segments.length;
+        var initPos = bm_floor((len-1)*perc);
+        var lengthPos = perc*bezierData.addedLength;
+        var lPerc = 0;
+        if(lengthPos == segments[initPos].l){
+            return segments[initPos].p;
+        }else{
+            var dir = segments[initPos].l > lengthPos ? -1 : 1;
+            var flag = true;
+            while(flag){
+                if(segments[initPos].l <= lengthPos && segments[initPos+1].l > lengthPos){
+                    lPerc = (lengthPos - segments[initPos].l)/(segments[initPos+1].l-segments[initPos].l);
+                    flag = false;
+                }else{
+                    initPos += dir;
+                }
+                if(initPos < 0 || initPos >= len - 1){
+                    flag = false;
+                }
+            }
+            return segments[initPos].p + (segments[initPos+1].p - segments[initPos].p)*lPerc;
+        }
+    }
+
+    function SegmentPoints(){
+        this.pt1 = new Array(2);
+        this.pt2 = new Array(2);
+        this.pt3 = new Array(2);
+        this.pt4 = new Array(2);
+    }
+
+    function getNewSegment(pt1,pt2,pt3,pt4,startPerc,endPerc, bezierData){
+
+        var pts = new SegmentPoints();
+        startPerc = startPerc < 0 ? 0 : startPerc > 1 ? 1 : startPerc;
+        var t0 = getDistancePerc(startPerc,bezierData);
+        endPerc = endPerc > 1 ? 1 : endPerc;
+        var t1 = getDistancePerc(endPerc,bezierData);
+        var i, len = pt1.length;
+        var u0 = 1 - t0;
+        var u1 = 1 - t1;
+        //Math.round(num * 100) / 100
+        for(i=0;i<len;i+=1){
+            pts.pt1[i] =  Math.round((u0*u0*u0* pt1[i] + (t0*u0*u0 + u0*t0*u0 + u0*u0*t0) * pt3[i] + (t0*t0*u0 + u0*t0*t0 + t0*u0*t0)* pt4[i] + t0*t0*t0* pt2[i])* 1000) / 1000;
+            pts.pt3[i] = Math.round((u0*u0*u1*pt1[i] + (t0*u0*u1 + u0*t0*u1 + u0*u0*t1)* pt3[i] + (t0*t0*u1 + u0*t0*t1 + t0*u0*t1)* pt4[i] + t0*t0*t1* pt2[i])* 1000) / 1000;
+            pts.pt4[i] = Math.round((u0*u1*u1* pt1[i] + (t0*u1*u1 + u0*t1*u1 + u0*u1*t1)* pt3[i] + (t0*t1*u1 + u0*t1*t1 + t0*u1*t1)* pt4[i] + t0*t1*t1* pt2[i])* 1000) / 1000;
+            pts.pt2[i] = Math.round((u1*u1*u1* pt1[i] + (t1*u1*u1 + u1*t1*u1 + u1*u1*t1)* pt3[i] + (t1*t1*u1 + u1*t1*t1 + t1*u1*t1)*pt4[i] + t1*t1*t1* pt2[i])* 1000) / 1000;
+        }
+        return pts;
+    }
+
+    return {
+        //getEasingCurve : getEasingCurve,
+        getBezierLength : getBezierLength,
+        getNewSegment : getNewSegment,
+        buildBezierData : buildBezierData,
+        pointOnLine2D : pointOnLine2D,
+        pointOnLine3D : pointOnLine3D
+    };
+}
+
+var bez = bezFunction();
+function dataFunctionManager(){
+
+    //var tCanvasHelper = document.createElement('canvas').getContext('2d');
+
+    function completeLayers(layers, comps, fontManager){
+        var layerData;
+        var animArray, lastFrame;
+        var i, len = layers.length;
+        var j, jLen, k, kLen;
+        for(i=0;i<len;i+=1){
+            layerData = layers[i];
+            if(!('ks' in layerData) || layerData.completed){
+                continue;
+            }
+            layerData.completed = true;
+            if(layerData.tt){
+                layers[i-1].td = layerData.tt;
+            }
+            animArray = [];
+            lastFrame = -1;
+            if(layerData.hasMask){
+                var maskProps = layerData.masksProperties;
+                jLen = maskProps.length;
+                for(j=0;j<jLen;j+=1){
+                    if(maskProps[j].pt.k.i){
+                        convertPathsToAbsoluteValues(maskProps[j].pt.k);
+                    }else{
+                        kLen = maskProps[j].pt.k.length;
+                        for(k=0;k<kLen;k+=1){
+                            if(maskProps[j].pt.k[k].s){
+                                convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                            }
+                            if(maskProps[j].pt.k[k].e){
+                                convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                            }
+                        }
+                    }
+                }
+            }
+            if(layerData.ty===0){
+                layerData.layers = findCompLayers(layerData.refId, comps);
+                completeLayers(layerData.layers,comps, fontManager);
+            }else if(layerData.ty === 4){
+                completeShapes(layerData.shapes);
+            }else if(layerData.ty == 5){
+                completeText(layerData, fontManager);
+            }
+        }
+    }
+
+    function findCompLayers(id,comps){
+        var i = 0, len = comps.length;
+        while(i<len){
+            if(comps[i].id === id){
+                return comps[i].layers;
+            }
+            i += 1;
+        }
+    }
+
+    function completeShapes(arr){
+        var i, len = arr.length;
+        var j, jLen;
+        var hasPaths = false;
+        for(i=len-1;i>=0;i-=1){
+            if(arr[i].ty == 'sh'){
+                if(arr[i].ks.k.i){
+                    convertPathsToAbsoluteValues(arr[i].ks.k);
+                }else{
+                    jLen = arr[i].ks.k.length;
+                    for(j=0;j<jLen;j+=1){
+                        if(arr[i].ks.k[j].s){
+                            convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                        }
+                        if(arr[i].ks.k[j].e){
+                            convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                        }
+                    }
+                }
+                hasPaths = true;
+            }else if(arr[i].ty == 'gr'){
+                completeShapes(arr[i].it);
+            }
+        }
+        /*if(hasPaths){
+            //mx: distance
+            //ss: sensitivity
+            //dc: decay
+            arr.splice(arr.length-1,0,{
+                "ty": "ms",
+                "mx":20,
+                "ss":10,
+                 "dc":0.001,
+                "maxDist":200
+            });
+        }*/
+    }
+
+    function convertPathsToAbsoluteValues(path){
+        var i, len = path.i.length;
+        for(i=0;i<len;i+=1){
+            path.i[i][0] += path.v[i][0];
+            path.i[i][1] += path.v[i][1];
+            path.o[i][0] += path.v[i][0];
+            path.o[i][1] += path.v[i][1];
+        }
+    }
+
+    function checkVersion(minimum,animVersionString){
+        var animVersion = animVersionString ? animVersionString.split('.') : [100,100,100];
+        if(minimum[0]>animVersion[0]){
+            return true;
+        } else if(animVersion[0] > minimum[0]){
+            return false;
+        }
+        if(minimum[1]>animVersion[1]){
+            return true;
+        } else if(animVersion[1] > minimum[1]){
+            return false;
+        }
+        if(minimum[2]>animVersion[2]){
+            return true;
+        } else if(animVersion[2] > minimum[2]){
+            return false;
+        }
+    }
+
+    var checkText = (function(){
+        var minimumVersion = [4,4,14];
+
+        function updateTextLayer(textLayer){
+            var documentData = textLayer.t.d;
+            textLayer.t.d = {
+                k: [
+                    {
+                        s:documentData,
+                        t:0
+                    }
+                ]
+            }
+        }
+
+        function iterateLayers(layers){
+            var i, len = layers.length;
+            for(i=0;i<len;i+=1){
+                if(layers[i].ty === 5){
+                    updateTextLayer(layers[i]);
+                }
+            }
+        }
+
+        return function (animationData){
+            if(checkVersion(minimumVersion,animationData.v)){
+                iterateLayers(animationData.layers);
+                if(animationData.assets){
+                    var i, len = animationData.assets.length;
+                    for(i=0;i<len;i+=1){
+                        if(animationData.assets[i].layers){
+                            iterateLayers(animationData.assets[i].layers);
+
+                        }
+                    }
+                }
+            }
+        }
+    }())
+
+    var checkColors = (function(){
+        var minimumVersion = [4,1,9];
+
+        function iterateShapes(shapes){
+            var i, len = shapes.length;
+            var j, jLen;
+            for(i=0;i<len;i+=1){
+                if(shapes[i].ty === 'gr'){
+                    iterateShapes(shapes[i].it);
+                }else if(shapes[i].ty === 'fl' || shapes[i].ty === 'st'){
+                    if(shapes[i].c.k && shapes[i].c.k[0].i){
+                        jLen = shapes[i].c.k.length;
+                        for(j=0;j<jLen;j+=1){
+                            if(shapes[i].c.k[j].s){
+                                shapes[i].c.k[j].s[0] /= 255;
+                                shapes[i].c.k[j].s[1] /= 255;
+                                shapes[i].c.k[j].s[2] /= 255;
+                                shapes[i].c.k[j].s[3] /= 255;
+                            }
+                            if(shapes[i].c.k[j].e){
+                                shapes[i].c.k[j].e[0] /= 255;
+                                shapes[i].c.k[j].e[1] /= 255;
+                                shapes[i].c.k[j].e[2] /= 255;
+                                shapes[i].c.k[j].e[3] /= 255;
+                            }
+                        }
+                    } else {
+                        shapes[i].c.k[0] /= 255;
+                        shapes[i].c.k[1] /= 255;
+                        shapes[i].c.k[2] /= 255;
+                        shapes[i].c.k[3] /= 255;
+                    }
+                }
+            }
+        }
+
+        function iterateLayers(layers){
+            var i, len = layers.length;
+            for(i=0;i<len;i+=1){
+                if(layers[i].ty === 4){
+                    iterateShapes(layers[i].shapes);
+                }
+            }
+        }
+
+        return function (animationData){
+            if(checkVersion(minimumVersion,animationData.v)){
+                iterateLayers(animationData.layers);
+                if(animationData.assets){
+                    var i, len = animationData.assets.length;
+                    for(i=0;i<len;i+=1){
+                        if(animationData.assets[i].layers){
+                            iterateLayers(animationData.assets[i].layers);
+
+                        }
+                    }
+                }
+            }
+        }
+    }());
+
+    var checkShapes = (function(){
+        var minimumVersion = [4,4,18];
+
+
+
+        function completeShapes(arr){
+            var i, len = arr.length;
+            var j, jLen;
+            var hasPaths = false;
+            for(i=len-1;i>=0;i-=1){
+                if(arr[i].ty == 'sh'){
+                    if(arr[i].ks.k.i){
+                        arr[i].ks.k.c = arr[i].closed;
+                    }else{
+                        jLen = arr[i].ks.k.length;
+                        for(j=0;j<jLen;j+=1){
+                            if(arr[i].ks.k[j].s){
+                                arr[i].ks.k[j].s[0].c = arr[i].closed;
+                            }
+                            if(arr[i].ks.k[j].e){
+                                arr[i].ks.k[j].e[0].c = arr[i].closed;
+                            }
+                        }
+                    }
+                    hasPaths = true;
+                }else if(arr[i].ty == 'gr'){
+                    completeShapes(arr[i].it);
+                }
+            }
+        }
+
+        function iterateLayers(layers){
+            var layerData;
+            var i, len = layers.length;
+            var j, jLen, k, kLen;
+            for(i=0;i<len;i+=1){
+                layerData = layers[i];
+                if(layerData.hasMask){
+                    var maskProps = layerData.masksProperties;
+                    jLen = maskProps.length;
+                    for(j=0;j<jLen;j+=1){
+                        if(maskProps[j].pt.k.i){
+                            maskProps[j].pt.k.c = maskProps[j].cl;
+                        }else{
+                            kLen = maskProps[j].pt.k.length;
+                            for(k=0;k<kLen;k+=1){
+                                if(maskProps[j].pt.k[k].s){
+                                    maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                                }
+                                if(maskProps[j].pt.k[k].e){
+                                    maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                                }
+                            }
+                        }
+                    }
+                }
+                if(layerData.ty === 4){
+                    completeShapes(layerData.shapes);
+                }
+            }
+        }
+
+        return function (animationData){
+            if(checkVersion(minimumVersion,animationData.v)){
+                iterateLayers(animationData.layers);
+                if(animationData.assets){
+                    var i, len = animationData.assets.length;
+                    for(i=0;i<len;i+=1){
+                        if(animationData.assets[i].layers){
+                            iterateLayers(animationData.assets[i].layers);
+
+                        }
+                    }
+                }
+            }
+        }
+    }());
+
+    /*function blitPaths(path){
+        var i, len = path.i.length;
+        for(i=0;i<len;i+=1){
+            path.i[i][0] /= blitter;
+            path.i[i][1] /= blitter;
+            path.o[i][0] /= blitter;
+            path.o[i][1] /= blitter;
+            path.v[i][0] /= blitter;
+            path.v[i][1] /= blitter;
+        }
+    }
+
+    function blitShapes(arr){
+        var i, len = arr.length;
+        var j, jLen;
+        var hasPaths = false;
+        for(i=len-1;i>=0;i-=1){
+            if(arr[i].ty == 'sh'){
+                if(arr[i].ks.k.i){
+                    blitPaths(arr[i].ks.k);
+                }else{
+                    jLen = arr[i].ks.k.length;
+                    for(j=0;j<jLen;j+=1){
+                        if(arr[i].ks.k[j].s){
+                            blitPaths(arr[i].ks.k[j].s[0]);
+                        }
+                        if(arr[i].ks.k[j].e){
+                            blitPaths(arr[i].ks.k[j].e[0]);
+                        }
+                    }
+                }
+                hasPaths = true;
+            }else if(arr[i].ty == 'gr'){
+                blitShapes(arr[i].it);
+            }else if(arr[i].ty == 'rc'){
+                blitProperty(arr[i].p);
+                blitProperty(arr[i].s);
+            }else if(arr[i].ty == 'st'){
+                blitProperty(arr[i].w);
+            }else if(arr[i].ty == 'tr'){
+                blitProperty(arr[i].p);
+                blitProperty(arr[i].sk);
+                blitProperty(arr[i].a);
+            }else if(arr[i].ty == 'el'){
+                blitProperty(arr[i].p);
+                blitProperty(arr[i].s);
+            }else if(arr[i].ty == 'rd'){
+                blitProperty(arr[i].r);
+            }else{
+
+                //console.log(arr[i].ty );
+            }
+        }
+    }
+
+    function blitText(data, fontManager){
+
+    }
+
+    function blitValue(val){
+        if(typeof(val) === 'number'){
+            val /= blitter;
+        } else {
+            var i = val.length-1;
+            while(i>=0){
+                val[i] /= blitter;
+                i-=1;
+            }
+        }
+        return val;
+    }
+
+    function blitProperty(data){
+        if(!data.k.length){
+            data.k = blitValue(data.k);
+        }else if(typeof(data.k[0]) === 'number'){
+            data.k = blitValue(data.k);
+        } else {
+            var i, len = data.k.length;
+            for(i=0;i<len;i+=1){
+                if(data.k[i].s){
+                    //console.log('pre S: ', data.k[i].s);
+                    data.k[i].s = blitValue(data.k[i].s);
+                    //console.log('post S: ', data.k[i].s);
+                }
+                if(data.k[i].e){
+                    //console.log('pre E: ', data.k[i].e);
+                    data.k[i].e = blitValue(data.k[i].e);
+                    //console.log('post E: ', data.k[i].e);
+                }
+            }
+        }
+    }
+
+    function blitLayers(layers,comps, fontManager){
+        var layerData;
+        var animArray, lastFrame;
+        var i, len = layers.length;
+        var j, jLen, k, kLen;
+        for(i=0;i<len;i+=1){
+            layerData = layers[i];
+            if(!('ks' in layerData)){
+                continue;
+            }
+            blitProperty(layerData.ks.a);
+            blitProperty(layerData.ks.p);
+            layerData.completed = true;
+            if(layerData.tt){
+                layers[i-1].td = layerData.tt;
+            }
+            animArray = [];
+            lastFrame = -1;
+            if(layerData.hasMask){
+                var maskProps = layerData.masksProperties;
+                jLen = maskProps.length;
+                for(j=0;j<jLen;j+=1){
+                    if(maskProps[j].pt.k.i){
+                        blitPaths(maskProps[j].pt.k);
+                    }else{
+                        kLen = maskProps[j].pt.k.length;
+                        for(k=0;k<kLen;k+=1){
+                            if(maskProps[j].pt.k[k].s){
+                                blitPaths(maskProps[j].pt.k[k].s[0]);
+                            }
+                            if(maskProps[j].pt.k[k].e){
+                                blitPaths(maskProps[j].pt.k[k].e[0]);
+                            }
+                        }
+                    }
+                }
+            }
+            if(layerData.ty===0){
+                layerData.w = Math.round(layerData.w/blitter);
+                layerData.h = Math.round(layerData.h/blitter);
+                blitLayers(layerData.layers,comps, fontManager);
+            }else if(layerData.ty === 4){
+                blitShapes(layerData.shapes);
+            }else if(layerData.ty == 5){
+                blitText(layerData, fontManager);
+            }else if(layerData.ty == 1){
+                layerData.sh /= blitter;
+                layerData.sw /= blitter;
+            } else {
+            }
+        }
+    }
+
+    function blitAnimation(animationData,comps, fontManager){
+        blitLayers(animationData.layers,comps, fontManager);
+    }*/
+
+    function completeData(animationData, fontManager){
+        if(animationData.__complete){
+            return;
+        }
+        checkColors(animationData);
+        checkText(animationData);
+        checkShapes(animationData);
+        completeLayers(animationData.layers, animationData.assets, fontManager);
+        animationData.__complete = true;
+        //blitAnimation(animationData, animationData.assets, fontManager);
+    }
+
+    function completeText(data, fontManager){
+        var letters;
+        var keys = data.t.d.k;
+        var k, kLen = keys.length;
+        for(k=0;k<kLen;k+=1){
+            var documentData = data.t.d.k[k].s;
+            letters = [];
+            var i, len;
+            var newLineFlag, index = 0, val;
+            var anchorGrouping = data.t.m.g;
+            var currentSize = 0, currentPos = 0, currentLine = 0, lineWidths = [];
+            var lineWidth = 0;
+            var maxLineWidth = 0;
+            var j, jLen;
+            var fontData = fontManager.getFontByName(documentData.f);
+            var charData, cLength = 0;
+            var styles = fontData.fStyle.split(' ');
+
+            var fWeight = 'normal', fStyle = 'normal';
+            len = styles.length;
+            for(i=0;i<len;i+=1){
+                if (styles[i].toLowerCase() === 'italic') {
+                    fStyle = 'italic';
+                }else if (styles[i].toLowerCase() === 'bold') {
+                    fWeight = '700';
+                } else if (styles[i].toLowerCase() === 'black') {
+                    fWeight = '900';
+                } else if (styles[i].toLowerCase() === 'medium') {
+                    fWeight = '500';
+                } else if (styles[i].toLowerCase() === 'regular' || styles[i].toLowerCase() === 'normal') {
+                    fWeight = '400';
+                } else if (styles[i].toLowerCase() === 'light' || styles[i].toLowerCase() === 'thin') {
+                    fWeight = '200';
+                }
+            }
+            documentData.fWeight = fWeight;
+            documentData.fStyle = fStyle;
+            len = documentData.t.length;
+            if(documentData.sz){
+                var boxWidth = documentData.sz[0];
+                var lastSpaceIndex = -1;
+                for(i=0;i<len;i+=1){
+                    newLineFlag = false;
+                    if(documentData.t.charAt(i) === ' '){
+                        lastSpaceIndex = i;
+                    }else if(documentData.t.charCodeAt(i) === 13){
+                        lineWidth = 0;
+                        newLineFlag = true;
+                    }
+                    if(fontManager.chars){
+                        charData = fontManager.getCharData(documentData.t.charAt(i), fontData.fStyle, fontData.fFamily);
+                        cLength = newLineFlag ? 0 : charData.w*documentData.s/100;
+                    }else{
+                        //tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+                        cLength = fontManager.measureText(documentData.t.charAt(i), documentData.f, documentData.s);
+                    }
+                    if(lineWidth + cLength > boxWidth){
+                        if(lastSpaceIndex === -1){
+                            //i -= 1;
+                            documentData.t = documentData.t.substr(0,i) + "\r" + documentData.t.substr(i);
+                            len += 1;
+                        } else {
+                            i = lastSpaceIndex;
+                            documentData.t = documentData.t.substr(0,i) + "\r" + documentData.t.substr(i+1);
+                        }
+                        lastSpaceIndex = -1;
+                        lineWidth = 0;
+                    }else {
+                        lineWidth += cLength;
+                    }
+                }
+                len = documentData.t.length;
+            }
+            lineWidth = 0;
+            cLength = 0;
+            for (i = 0;i < len ;i += 1) {
+                newLineFlag = false;
+                if(documentData.t.charAt(i) === ' '){
+                    val = '\u00A0';
+                }else if(documentData.t.charCodeAt(i) === 13){
+                    lineWidths.push(lineWidth);
+                    maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+                    lineWidth = 0;
+                    val = '';
+                    newLineFlag = true;
+                    currentLine += 1;
+                }else{
+                    val = documentData.t.charAt(i);
+                }
+                if(fontManager.chars){
+                    charData = fontManager.getCharData(documentData.t.charAt(i), fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+                    cLength = newLineFlag ? 0 : charData.w*documentData.s/100;
+                }else{
+                    //var charWidth = fontManager.measureText(val, documentData.f, documentData.s);
+                    //tCanvasHelper.font = documentData.s + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+                    cLength = fontManager.measureText(val, documentData.f, documentData.s);
+                }
+
+                //
+                lineWidth += cLength;
+                letters.push({l:cLength,an:cLength,add:currentSize,n:newLineFlag, anIndexes:[], val: val, line: currentLine});
+                if(anchorGrouping == 2){
+                    currentSize += cLength;
+                    if(val == '' || val == '\u00A0' || i == len - 1){
+                        if(val == '' || val == '\u00A0'){
+                            currentSize -= cLength;
+                        }
+                        while(currentPos<=i){
+                            letters[currentPos].an = currentSize;
+                            letters[currentPos].ind = index;
+                            letters[currentPos].extra = cLength;
+                            currentPos += 1;
+                        }
+                        index += 1;
+                        currentSize = 0;
+                    }
+                }else if(anchorGrouping == 3){
+                    currentSize += cLength;
+                    if(val == '' || i == len - 1){
+                        if(val == ''){
+                            currentSize -= cLength;
+                        }
+                        while(currentPos<=i){
+                            letters[currentPos].an = currentSize;
+                            letters[currentPos].ind = index;
+                            letters[currentPos].extra = cLength;
+                            currentPos += 1;
+                        }
+                        currentSize = 0;
+                        index += 1;
+                    }
+                }else{
+                    letters[index].ind = index;
+                    letters[index].extra = 0;
+                    index += 1;
+                }
+            }
+            documentData.l = letters;
+            maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+            lineWidths.push(lineWidth);
+            if(documentData.sz){
+                documentData.boxWidth = documentData.sz[0];
+                documentData.justifyOffset = 0;
+            }else{
+                documentData.boxWidth = maxLineWidth;
+                switch(documentData.j){
+                    case 1:
+                        documentData.justifyOffset = - documentData.boxWidth;
+                        break;
+                    case 2:
+                        documentData.justifyOffset = - documentData.boxWidth/2;
+                        break;
+                    default:
+                        documentData.justifyOffset = 0;
+                }
+            }
+            documentData.lineWidths = lineWidths;
+
+            var animators = data.t.a;
+            jLen = animators.length;
+            var based, ind, indexes = [];
+            for(j=0;j<jLen;j+=1){
+                if(animators[j].a.sc){
+                    documentData.strokeColorAnim = true;
+                }
+                if(animators[j].a.sw){
+                    documentData.strokeWidthAnim = true;
+                }
+                if(animators[j].a.fc || animators[j].a.fh || animators[j].a.fs || animators[j].a.fb){
+                    documentData.fillColorAnim = true;
+                }
+                ind = 0;
+                based = animators[j].s.b;
+                for(i=0;i<len;i+=1){
+                    letters[i].anIndexes[j] = ind;
+                    if((based == 1 && letters[i].val != '') || (based == 2 && letters[i].val != '' && letters[i].val != '\u00A0') || (based == 3 && (letters[i].n || letters[i].val == '\u00A0' || i == len - 1)) || (based == 4 && (letters[i].n || i == len - 1))){
+                        if(animators[j].s.rn === 1){
+                            indexes.push(ind);
+                        }
+                        ind += 1;
+                    }
+                }
+                data.t.a[j].s.totalChars = ind;
+                var currentInd = -1, newInd;
+                if(animators[j].s.rn === 1){
+                    for(i = 0; i < len; i += 1){
+                        if(currentInd != letters[i].anIndexes[j]){
+                            currentInd = letters[i].anIndexes[j];
+                            newInd = indexes.splice(Math.floor(Math.random()*indexes.length),1)[0];
+                        }
+                        letters[i].anIndexes[j] = newInd;
+                    }
+                }
+            }
+            if(jLen === 0 && !('m' in data.t.p)){
+                data.singleShape = true;
+            }
+            documentData.yOffset = documentData.lh || documentData.s*1.2;
+            documentData.ls = documentData.ls || 0;
+            documentData.ascent = fontData.ascent*documentData.s/100;
+        }
+
+    }
+
+    var moduleOb = {};
+    moduleOb.completeData = completeData;
+
+    return moduleOb;
+}
+
+var dataManager = dataFunctionManager();
+var FontManager = (function(){
+
+    var maxWaitingTime = 5000;
+
+    function setUpNode(font, family){
+        var parentNode = document.createElement('span');
+        parentNode.style.fontFamily    = family;
+        var node = document.createElement('span');
+        // Characters that vary significantly among different fonts
+        node.innerHTML = 'giItT1WQy@!-/#';
+        // Visible - so we can measure it - but not on the screen
+        parentNode.style.position      = 'absolute';
+        parentNode.style.left          = '-10000px';
+        parentNode.style.top           = '-10000px';
+        // Large font size makes even subtle changes obvious
+        parentNode.style.fontSize      = '300px';
+        // Reset any font properties
+        parentNode.style.fontVariant   = 'normal';
+        parentNode.style.fontStyle     = 'normal';
+        parentNode.style.fontWeight    = 'normal';
+        parentNode.style.letterSpacing = '0';
+        parentNode.appendChild(node);
+        document.body.appendChild(parentNode);
+
+        // Remember width with no applied web font
+        var width = node.offsetWidth;
+        node.style.fontFamily = font + ', '+family;
+        return {node:node, w:width, parent:parentNode};
+    }
+
+    function checkLoadedFonts() {
+        var i, len = this.fonts.length;
+        var node, w;
+        var loadedCount = len;
+        for(i=0;i<len; i+= 1){
+            if(this.fonts[i].loaded){
+                loadedCount -= 1;
+                continue;
+            }
+            if(this.fonts[i].fOrigin === 't'){
+                if(window.Typekit && window.Typekit.load && this.typekitLoaded === 0){
+                    this.typekitLoaded = 1;
+                    try{window.Typekit.load({
+                        async: true,
+                        active: function() {
+                            this.typekitLoaded = 2;
+                        }.bind(this)
+                    });}catch(e){}
+                }
+                if(this.typekitLoaded === 2) {
+                    this.fonts[i].loaded = true;
+                }
+            } else if(this.fonts[i].fOrigin === 'n'){
+                this.fonts[i].loaded = true;
+            } else{
+                node = this.fonts[i].monoCase.node;
+                w = this.fonts[i].monoCase.w;
+                if(node.offsetWidth !== w){
+                    loadedCount -= 1;
+                    this.fonts[i].loaded = true;
+                }else{
+                    node = this.fonts[i].sansCase.node;
+                    w = this.fonts[i].sansCase.w;
+                    if(node.offsetWidth !== w){
+                        loadedCount -= 1;
+                        this.fonts[i].loaded = true;
+                    }
+                }
+                if(this.fonts[i].loaded){
+                    this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+                    this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+                }
+            }
+        }
+
+        if(loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime){
+            setTimeout(checkLoadedFonts.bind(this),20);
+        }else{
+            setTimeout(function(){this.loaded = true;}.bind(this),0);
+
+        }
+    };
+
+    function createHelper(def, fontData){
+        var tHelper = document.createElementNS(svgNS,'text');
+        tHelper.style.fontSize = '100px';
+        tHelper.style.fontFamily = fontData.fFamily;
+        tHelper.textContent = '1';
+        if(fontData.fClass){
+            tHelper.style.fontFamily = 'inherit';
+            tHelper.className = fontData.fClass;
+        } else {
+            tHelper.style.fontFamily = fontData.fFamily;
+        }
+        def.appendChild(tHelper);
+        var tCanvasHelper = document.createElement('canvas').getContext('2d');
+        tCanvasHelper.font = '100px '+ fontData.fFamily;
+        return tCanvasHelper;
+        return tHelper;
+    }
+
+    function addFonts(fontData, defs){
+        if(!fontData){
+            this.loaded = true;
+            return;
+        }
+        if(this.chars){
+            this.loaded = true;
+            this.fonts = fontData.list;
+            return;
+        }
+
+        var fontArr = fontData.list;
+        var i, len = fontArr.length;
+        for(i=0; i<len; i+= 1){
+            fontArr[i].loaded = false;
+            fontArr[i].monoCase = setUpNode(fontArr[i].fFamily,'monospace');
+            fontArr[i].sansCase = setUpNode(fontArr[i].fFamily,'sans-serif');
+            if(!fontArr[i].fPath) {
+                fontArr[i].loaded = true;
+            }else if(fontArr[i].fOrigin === 'p'){
+                var s = document.createElement('style');
+                s.type = "text/css";
+                s.innerHTML = "@font-face {" + "font-family: "+fontArr[i].fFamily+"; font-style: normal; src: url('"+fontArr[i].fPath+"');}";
+                defs.appendChild(s);
+            } else if(fontArr[i].fOrigin === 'g'){
+                //<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'>
+                var l = document.createElement('link');
+                l.type = "text/css";
+                l.rel = "stylesheet";
+                l.href = fontArr[i].fPath;
+                defs.appendChild(l);
+            } else if(fontArr[i].fOrigin === 't'){
+                //<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'>
+                var sc = document.createElement('script');
+                sc.setAttribute('src',fontArr[i].fPath);
+                defs.appendChild(sc);
+            }
+            fontArr[i].helper = createHelper(defs,fontArr[i]);
+            this.fonts.push(fontArr[i]);
+        }
+        checkLoadedFonts.bind(this)();
+    }
+
+    function addChars(chars){
+        if(!chars){
+            return;
+        }
+        if(!this.chars){
+            this.chars = [];
+        }
+        var i, len = chars.length;
+        var j, jLen = this.chars.length, found;
+        for(i=0;i<len;i+=1){
+            j = 0;
+            found = false;
+            while(j<jLen){
+                if(this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch){
+                    found = true;
+                }
+                j += 1;
+            }
+            if(!found){
+                this.chars.push(chars[i]);
+                jLen += 1;
+            }
+        }
+    }
+
+    function getCharData(char, style, font){
+        var i = 0, len = this.chars.length;
+        while( i < len) {
+            if(this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font){
+                return this.chars[i];
+            }
+            i+= 1;
+        }
+    }
+
+    function measureText(char, fontName, size){
+        var fontData = this.getFontByName(fontName);
+        var tHelper = fontData.helper;
+        //tHelper.textContent = char;
+        return tHelper.measureText(char).width*size/100;
+        //return tHelper.getComputedTextLength()*size/100;
+    }
+
+    function getFontByName(name){
+        var i = 0, len = this.fonts.length;
+        while(i<len){
+            if(this.fonts[i].fName === name) {
+                return this.fonts[i];
+            }
+            i += 1;
+        }
+        return 'sans-serif';
+    }
+
+    var Font = function(){
+        this.fonts = [];
+        this.chars = null;
+        this.typekitLoaded = 0;
+        this.loaded = false;
+        this.initTime = Date.now();
+    };
+    Font.prototype.addChars = addChars;
+    Font.prototype.addFonts = addFonts;
+    Font.prototype.getCharData = getCharData;
+    Font.prototype.getFontByName = getFontByName;
+    Font.prototype.measureText = measureText;
+
+    return Font;
+
+}());
+var PropertyFactory = (function(){
+
+    var initFrame = -999999;
+
+    function getValue(){
+        if(this.elem.globalData.frameId === this.frameId){
+            return;
+        }
+        this.mdf = false;
+        var frameNum = this.comp.renderedFrame - this.offsetTime;
+        if(!(frameNum === this.lastFrame || (this.lastFrame !== initFrame && ((this.lastFrame >= this.keyframes[this.keyframes.length- 1].t-this.offsetTime && frameNum >= this.keyframes[this.keyframes.length- 1].t-this.offsetTime) || (this.lastFrame < this.keyframes[0].t-this.offsetTime && frameNum < this.keyframes[0].t-this.offsetTime))))){
+            var i = this.lastFrame < frameNum ? this._lastIndex : 0;
+            var len = this.keyframes.length- 1,flag = true;
+            var keyData, nextKeyData;
+
+            while(flag){
+                keyData = this.keyframes[i];
+                nextKeyData = this.keyframes[i+1];
+                if(i == len-1 && frameNum >= nextKeyData.t - this.offsetTime){
+                    if(keyData.h){
+                        keyData = nextKeyData;
+                    }
+                    break;
+                }
+                if((nextKeyData.t - this.offsetTime) > frameNum){
+                    break;
+                }
+                if(i < len - 1){
+                    i += 1;
+                }else{
+                    flag = false;
+                }
+            }
+
+            this._lastIndex = i;
+
+            var k, kLen,perc,jLen, j, fnc;
+            if(keyData.to){
+
+                if(!keyData.bezierData){
+                    bez.buildBezierData(keyData);
+                }
+                var bezierData = keyData.bezierData;
+                if(frameNum >= nextKeyData.t-this.offsetTime || frameNum < keyData.t-this.offsetTime){
+                    var ind = frameNum >= nextKeyData.t-this.offsetTime ? bezierData.points.length - 1 : 0;
+                    kLen = bezierData.points[ind].point.length;
+                    for(k = 0; k < kLen; k += 1){
+                        this.pv[k] = bezierData.points[ind].point[k];
+                        this.v[k] = this.mult ? this.pv[k]*this.mult : this.pv[k];
+                        if(this.lastPValue[k] !== this.pv[k]) {
+                            this.mdf = true;
+                            this.lastPValue[k] = this.pv[k];
+                        }
+                    }
+                    this._lastBezierData = null;
+                }else{
+                    if(keyData.__fnct){
+                        fnc = keyData.__fnct;
+                    }else{
+                        fnc = BezierFactory.getBezierEasing(keyData.o.x,keyData.o.y,keyData.i.x,keyData.i.y,keyData.n).get;
+                        keyData.__fnct = fnc;
+                    }
+                    perc = fnc((frameNum-(keyData.t-this.offsetTime))/((nextKeyData.t-this.offsetTime)-(keyData.t-this.offsetTime)));
+                    var distanceInLine = bezierData.segmentLength*perc;
+
+                    var segmentPerc;
+                    var addedLength =  (this.lastFrame < frameNum && this._lastBezierData === bezierData) ? this._lastAddedLength : 0;
+                    j =  (this.lastFrame < frameNum && this._lastBezierData === bezierData) ? this._lastPoint : 0;
+                    flag = true;
+                    jLen = bezierData.points.length;
+                    while(flag){
+                        addedLength +=bezierData.points[j].partialLength;
+                        if(distanceInLine === 0 || perc === 0 || j == bezierData.points.length - 1){
+                            kLen = bezierData.points[j].point.length;
+                            for(k=0;k<kLen;k+=1){
+                                this.pv[k] = bezierData.points[j].point[k];
+                                this.v[k] = this.mult ? this.pv[k]*this.mult : this.pv[k];
+                                if(this.lastPValue[k] !== this.pv[k]) {
+                                    this.mdf = true;
+                                    this.lastPValue[k] = this.pv[k];
+                                }
+                            }
+                            break;
+                        }else if(distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j+1].partialLength){
+                            segmentPerc = (distanceInLine-addedLength)/(bezierData.points[j+1].partialLength);
+                            kLen = bezierData.points[j].point.length;
+                            for(k=0;k<kLen;k+=1){
+                                this.pv[k] = bezierData.points[j].point[k] + (bezierData.points[j+1].point[k] - bezierData.points[j].point[k])*segmentPerc;
+                                this.v[k] = this.mult ? this.pv[k] * this.mult : this.pv[k];
+                                if(this.lastPValue[k] !== this.pv[k]) {
+                                    this.mdf = true;
+                                    this.lastPValue[k] = this.pv[k];
+                                }
+                            }
+                            break;
+                        }
+                        if(j < jLen - 1){
+                            j += 1;
+                        }else{
+                            flag = false;
+                        }
+                    }
+                    this._lastPoint = j;
+                    this._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+                    this._lastBezierData = bezierData;
+                }
+            }else{
+                var outX,outY,inX,inY, keyValue;
+                len = keyData.s.length;
+                for(i=0;i<len;i+=1){
+                    if(keyData.h !== 1){
+                        if(frameNum >= nextKeyData.t-this.offsetTime){
+                            perc = 1;
+                        }else if(frameNum < keyData.t-this.offsetTime){
+                            perc = 0;
+                        }else{
+                            if(keyData.o.x instanceof Array){
+                                if(!keyData.__fnct){
+                                    keyData.__fnct = [];
+                                }
+                                if (!keyData.__fnct[i]) {
+                                    outX = keyData.o.x[i] || keyData.o.x[0];
+                                    outY = keyData.o.y[i] || keyData.o.y[0];
+                                    inX = keyData.i.x[i] || keyData.i.x[0];
+                                    inY = keyData.i.y[i] || keyData.i.y[0];
+                                    fnc = BezierFactory.getBezierEasing(outX,outY,inX,inY).get;
+                                    keyData.__fnct[i] = fnc;
+                                } else {
+                                    fnc = keyData.__fnct[i];
+                                }
+                            } else {
+                                if (!keyData.__fnct) {
+                                    outX = keyData.o.x;
+                                    outY = keyData.o.y;
+                                    inX = keyData.i.x;
+                                    inY = keyData.i.y;
+                                    fnc = BezierFactory.getBezierEasing(outX,outY,inX,inY).get;
+                                    keyData.__fnct = fnc;
+                                } else{
+                                    fnc = keyData.__fnct;
+                                }
+                            }
+                            perc = fnc((frameNum-(keyData.t-this.offsetTime))/((nextKeyData.t-this.offsetTime)-(keyData.t-this.offsetTime)));
+                        }
+                    }
+                    if(this.sh && keyData.h !== 1){
+                        var initP = keyData.s[i];
+                        var endP = keyData.e[i];
+                        if(initP-endP < -180){
+                            initP += 360;
+                        } else if(initP-endP > 180){
+                            initP -= 360;
+                        }
+                        keyValue = initP+(endP-initP)*perc;
+                    } else {
+                        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i]+(keyData.e[i]-keyData.s[i])*perc;
+                    }
+                    if(len === 1){
+                        this.v = this.mult ? keyValue*this.mult : keyValue;
+                        this.pv = keyValue;
+                        if(this.lastPValue != this.pv){
+                            this.mdf = true;
+                            this.lastPValue = this.pv;
+                        }
+                    }else{
+                        this.v[i] = this.mult ? keyValue*this.mult : keyValue;
+                        this.pv[i] = keyValue;
+                        if(this.lastPValue[i] !== this.pv[i]){
+                            this.mdf = true;
+                            this.lastPValue[i] = this.pv[i];
+                        }
+                    }
+                }
+            }
+        }
+        this.lastFrame = frameNum;
+        this.frameId = this.elem.globalData.frameId;
+    }
+
+    function getNoValue(){}
+
+    function ValueProperty(elem,data, mult){
+        this.mult = mult;
+        this.v = mult ? data.k * mult : data.k;
+        this.pv = data.k;
+        this.mdf = false;
+        this.comp = elem.comp;
+        this.k = false;
+        this.kf = false;
+        this.vel = 0;
+        this.getValue = getNoValue;
+    }
+
+    function MultiDimensionalProperty(elem,data, mult){
+        this.mult = mult;
+        this.data = data;
+        this.mdf = false;
+        this.comp = elem.comp;
+        this.k = false;
+        this.kf = false;
+        this.frameId = -1;
+        this.v = Array.apply(null, {length:data.k.length});
+        this.pv = Array.apply(null, {length:data.k.length});
+        this.lastValue = Array.apply(null, {length:data.k.length});
+        var arr = Array.apply(null, {length:data.k.length});
+        this.vel = arr.map(function () { return 0 });
+        var i, len = data.k.length;
+        for(i = 0;i<len;i+=1){
+            this.v[i] = mult ? data.k[i] * mult : data.k[i];
+            this.pv[i] = data.k[i];
+        }
+        this.getValue = getNoValue;
+    }
+
+    function KeyframedValueProperty(elem, data, mult){
+        this.keyframes = data.k;
+        this.offsetTime = elem.data.st;
+        this.lastValue = -99999;
+        this.lastPValue = -99999;
+        this.frameId = -1;
+        this._lastIndex = 0;
+        this.k = true;
+        this.kf = true;
+        this.data = data;
+        this.mult = mult;
+        this.elem = elem;
+        this.comp = elem.comp;
+        this.lastFrame = initFrame;
+        this.v = mult ? data.k[0].s[0]*mult : data.k[0].s[0];
+        this.pv = data.k[0].s[0];
+        this.getValue = getValue;
+    }
+
+    function KeyframedMultidimensionalProperty(elem, data, mult){
+        var i, len = data.k.length;
+        var s, e,to,ti;
+        for(i=0;i<len-1;i+=1){
+            if(data.k[i].to && data.k[i].s && data.k[i].e ){
+                s = data.k[i].s;
+                e = data.k[i].e;
+                to = data.k[i].to;
+                ti = data.k[i].ti;
+                if((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0],s[1],e[0],e[1],s[0] + to[0],s[1] + to[1]) && bez.pointOnLine2D(s[0],s[1],e[0],e[1],e[0] + ti[0],e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0],s[1],s[2],e[0],e[1],e[2],s[0] + to[0],s[1] + to[1],s[2] + to[2]) && bez.pointOnLine3D(s[0],s[1],s[2],e[0],e[1],e[2],e[0] + ti[0],e[1] + ti[1],e[2] + ti[2]))){
+                    data.k[i].to = null;
+                    data.k[i].ti = null;
+                }
+            }
+        }
+        this.keyframes = data.k;
+        this.offsetTime = elem.data.st;
+        this.k = true;
+        this.kf = true;
+        this.mult = mult;
+        this.elem = elem;
+        this.comp = elem.comp;
+        this.getValue = getValue;
+        this.frameId = -1;
+        this._lastIndex = 0;
+        this.v = Array.apply(null, {length:data.k[0].s.length});
+        this.pv = Array.apply(null, {length:data.k[0].s.length});
+        this.lastValue = Array.apply(null, {length:data.k[0].s.length});
+        this.lastPValue = Array.apply(null, {length:data.k[0].s.length});
+        this.lastFrame = initFrame;
+    }
+
+    var TransformProperty = (function() {
+        function positionGetter() {
+            return ExpressionValue(this.p);
+        }
+        function xPositionGetter() {
+            return ExpressionValue(this.px);
+        }
+        function yPositionGetter() {
+            return ExpressionValue(this.py);
+        }
+        function zPositionGetter() {
+            return ExpressionValue(this.pz);
+        }
+        function anchorGetter() {
+            return ExpressionValue(this.a);
+        }
+        function orientationGetter() {
+            return ExpressionValue(this.or);
+        }
+        function rotationGetter() {
+            return ExpressionValue(this.r, 1/degToRads);
+        }
+        function scaleGetter() {
+            return ExpressionValue(this.s, 100);
+        }
+        function opacityGetter() {
+            return ExpressionValue(this.o, 100);
+        }
+        function skewGetter() {
+            return ExpressionValue(this.sk);
+        }
+        function skewAxisGetter() {
+            return ExpressionValue(this.sa);
+        }
+        function applyToMatrix(mat) {
+            var i, len = this.dynamicProperties.length;
+            for(i = 0; i < len; i += 1) {
+                this.dynamicProperties[i].getValue();
+                if (this.dynamicProperties[i].mdf) {
+                    this.mdf = true;
+                }
+            }
+            if (this.a) {
+                mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+            }
+            if (this.s) {
+                mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+            }
+            if (this.r) {
+                mat.rotate(-this.r.v);
+            } else {
+                mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
+            }
+            if (this.data.p.s) {
+                if (this.data.p.z) {
+                    mat.translate(this.px.v, this.py.v, -this.pz.v);
+                } else {
+                    mat.translate(this.px.v, this.py.v, 0);
+                }
+            } else {
+                mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+            }
+        }
+        function processKeys(){
+            if (this.elem.globalData.frameId === this.frameId) {
+                return;
+            }
+
+            this.mdf = false;
+            var i, len = this.dynamicProperties.length;
+
+            for(i = 0; i < len; i += 1) {
+                this.dynamicProperties[i].getValue();
+                if (this.dynamicProperties[i].mdf) {
+                    this.mdf = true;
+                }
+            }
+            if (this.mdf) {
+                this.v.reset();
+                if (this.a) {
+                    this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+                }
+                if(this.s) {
+                    this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+                }
+                if (this.sk) {
+                    this.v.skewFromAxis(-this.sk.v, this.sa.v);
+                }
+                if (this.r) {
+                    this.v.rotate(-this.r.v);
+                } else {
+                    this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
+                }
+                if (this.autoOriented && this.p.keyframes && this.p.getValueAtTime) {
+                    var v1,v2;
+                    if (this.p.lastFrame+this.p.offsetTime <= this.p.keyframes[0].t) {
+                        v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / this.elem.globalData.frameRate,0);
+                        v2 = this.p.getValueAtTime(this.p.keyframes[0].t / this.elem.globalData.frameRate, 0);
+                    } else if(this.p.lastFrame+this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+                        v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / this.elem.globalData.frameRate), 0);
+                        v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.01) / this.elem.globalData.frameRate, 0);
+                    } else {
+                        v1 = this.p.pv;
+                        v2 = this.p.getValueAtTime((this.p.lastFrame+this.p.offsetTime - 0.01) / this.elem.globalData.frameRate, this.p.offsetTime);
+                    }
+                    this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+                }
+                if(this.data.p.s){
+                    if(this.data.p.z) {
+                        this.v.translate(this.px.v, this.py.v, -this.pz.v);
+                    } else {
+                        this.v.translate(this.px.v, this.py.v, 0);
+                    }
+                }else{
+                    this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2]);
+                }
+            }
+            //console.log(this.v.to2dCSS())
+            this.frameId = this.elem.globalData.frameId;
+        }
+
+        function setInverted(){
+            this.inverted = true;
+            this.iv = new Matrix();
+            if(!this.k){
+                if(this.data.p.s){
+                    this.iv.translate(this.px.v,this.py.v,-this.pz.v);
+                }else{
+                    this.iv.translate(this.p.v[0],this.p.v[1],-this.p.v[2]);
+                }
+                if(this.r){
+                    this.iv.rotate(-this.r.v);
+                }else{
+                    this.iv.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
+                }
+                if(this.s){
+                    this.iv.scale(this.s.v[0],this.s.v[1],1);
+                }
+                if(this.a){
+                    this.iv.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]);
+                }
+            }
+        }
+
+        function autoOrient(){
+            //
+            //var prevP = this.getValueAtTime();
+        }
+
+        return function TransformProperty(elem,data,arr){
+            this.elem = elem;
+            this.frameId = -1;
+            this.type = 'transform';
+            this.dynamicProperties = [];
+            this.mdf = false;
+            this.data = data;
+            this.getValue = processKeys;
+            this.applyToMatrix = applyToMatrix;
+            this.setInverted = setInverted;
+            this.autoOrient = autoOrient;
+            this.v = new Matrix();
+            if(data.p.s){
+                this.px = PropertyFactory.getProp(elem,data.p.x,0,0,this.dynamicProperties);
+                this.py = PropertyFactory.getProp(elem,data.p.y,0,0,this.dynamicProperties);
+                if(data.p.z){
+                    this.pz = PropertyFactory.getProp(elem,data.p.z,0,0,this.dynamicProperties);
+                }
+            }else{
+                this.p = PropertyFactory.getProp(elem,data.p,1,0,this.dynamicProperties);
+            }
+            if(data.r) {
+                this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this.dynamicProperties);
+            } else if(data.rx) {
+                this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this.dynamicProperties);
+                this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this.dynamicProperties);
+                this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this.dynamicProperties);
+                this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this.dynamicProperties);
+            }
+            if(data.sk){
+                this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this.dynamicProperties);
+                this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this.dynamicProperties);
+            }
+            if(data.a) {
+                this.a = PropertyFactory.getProp(elem,data.a,1,0,this.dynamicProperties);
+            }
+            if(data.s) {
+                this.s = PropertyFactory.getProp(elem,data.s,1,0.01,this.dynamicProperties);
+            }
+            if(data.o){
+                this.o = PropertyFactory.getProp(elem,data.o,0,0.01,arr);
+            } else {
+                this.o = {mdf:false,v:1};
+            }
+            if(this.dynamicProperties.length){
+                arr.push(this);
+            }else{
+                if(this.a){
+                    this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]);
+                }
+                if(this.s){
+                    this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]);
+                }
+                if(this.sk){
+                    this.v.skewFromAxis(-this.sk.v,this.sa.v);
+                }
+                if(this.r){
+                    this.v.rotate(-this.r.v);
+                }else{
+                    this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
+                }
+                if(this.data.p.s){
+                    if(data.p.z) {
+                        this.v.translate(this.px.v, this.py.v, -this.pz.v);
+                    } else {
+                        this.v.translate(this.px.v, this.py.v, 0);
+                    }
+                }else{
+                    this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2]);
+                }
+            }
+            Object.defineProperty(this, "position", { get: positionGetter});
+            Object.defineProperty(this, "xPosition", { get: xPositionGetter});
+            Object.defineProperty(this, "yPosition", { get: yPositionGetter});
+            Object.defineProperty(this, "orientation", { get: orientationGetter});
+            Object.defineProperty(this, "anchorPoint", { get: anchorGetter});
+            Object.defineProperty(this, "rotation", { get: rotationGetter});
+            Object.defineProperty(this, "scale", { get: scaleGetter});
+            Object.defineProperty(this, "opacity", { get: opacityGetter});
+            Object.defineProperty(this, "skew", { get: skewGetter});
+            Object.defineProperty(this, "skewAxis", { get: skewAxisGetter});
+        }
+    }());
+
+    function getProp(elem,data,type, mult, arr) {
+        var p;
+        if(type === 2){
+            p = new TransformProperty(elem, data, arr);
+        } else if(data.a === 0){
+            if(type === 0) {
+                p = new ValueProperty(elem,data,mult);
+            } else {
+                p = new MultiDimensionalProperty(elem,data, mult);
+            }
+        } else if(data.a === 1){
+            if(type === 0) {
+                p = new KeyframedValueProperty(elem,data,mult);
+            } else {
+                p = new KeyframedMultidimensionalProperty(elem,data, mult);
+            }
+        } else if(!data.k.length){
+            p = new ValueProperty(elem,data, mult);
+        }else if(typeof(data.k[0]) === 'number'){
+            p = new MultiDimensionalProperty(elem,data, mult);
+        }else{
+            switch(type){
+                case 0:
+                    p = new KeyframedValueProperty(elem,data,mult);
+                    break;
+                case 1:
+                    p = new KeyframedMultidimensionalProperty(elem,data,mult);
+                    break;
+            }
+        }
+        if(p.k){
+            arr.push(p);
+        }
+        return p;
+    }
+
+    var getGradientProp = (function(){
+
+        function getValue(forceRender){
+            this.prop.getValue();
+            this.cmdf = false;
+            this.omdf = false;
+            if(this.prop.mdf || forceRender){
+                var i, len = this.data.p*4;
+                var mult, val;
+                for(i=0;i<len;i+=1){
+                    mult = i%4 === 0 ? 100 : 255;
+                    val = Math.round(this.prop.v[i]*mult);
+                    if(this.c[i] !== val){
+                        this.c[i] = val;
+                        this.cmdf = true;
+                    }
+                }
+                if(this.o.length){
+                    len = this.prop.v.length;
+                    for(i=this.data.p*4;i<len;i+=1){
+                        mult = i%2 === 0 ? 100 : 1;
+                        val = i%2 === 0 ?  Math.round(this.prop.v[i]*100):this.prop.v[i];
+                        if(this.o[i-this.data.p*4] !== val){
+                            this.o[i-this.data.p*4] = val;
+                            this.omdf = true;
+                        }
+                    }
+                }
+            }
+
+        }
+
+        function gradientProp(elem,data,arr){
+            this.prop = getProp(elem,data.k,1,null,[]);
+            this.data = data;
+            this.k = this.prop.k;
+            this.c = Array.apply(null,{length:data.p*4});
+            var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p*4) : data.k.k.length - data.p*4;
+            this.o = Array.apply(null,{length:cLength});
+            this.cmdf = false;
+            this.omdf = false;
+            this.getValue = getValue;
+            if(this.prop.k){
+                arr.push(this);
+            }
+            this.getValue(true);
+        }
+
+        return function getGradientProp(elem,data,arr){
+            return new gradientProp(elem,data,arr);
+        }
+    }());
+
+
+
+
+    var DashProperty = (function(){
+
+        function processKeys(forceRender){
+            var i = 0, len = this.dataProps.length;
+
+            if(this.elem.globalData.frameId === this.frameId && !forceRender){
+                return;
+            }
+            this.mdf = false;
+            this.frameId = this.elem.globalData.frameId;
+            while(i<len){
+                if(this.dataProps[i].p.mdf){
+                    this.mdf = true;
+                    break;
+                }
+                i+=1;
+            }
+            if(this.mdf || forceRender){
+                if(this.renderer === 'svg') {
+                    this.dasharray = '';
+                }
+                for(i=0;i<len;i+=1){
+                    if(this.dataProps[i].n != 'o'){
+                        if(this.renderer === 'svg') {
+                            this.dasharray += ' ' + this.dataProps[i].p.v;
+                        }else{
+                            this.dasharray[i] = this.dataProps[i].p.v;
+                        }
+                    }else{
+                        this.dashoffset = this.dataProps[i].p.v;
+                    }
+                }
+            }
+        }
+
+        return function(elem, data,renderer, dynamicProperties){
+            this.elem = elem;
+            this.frameId = -1;
+            this.dataProps = new Array(data.length);
+            this.renderer = renderer;
+            this.mdf = false;
+            this.k = false;
+            if(this.renderer === 'svg'){
+                this.dasharray = '';
+            }else{
+
+                this.dasharray = new Array(data.length - 1);
+            }
+            this.dashoffset = 0;
+            var i, len = data.length, prop;
+            for(i=0;i<len;i+=1){
+                prop = PropertyFactory.getProp(elem,data[i].v,0, 0, dynamicProperties);
+                this.k = prop.k ? true : this.k;
+                this.dataProps[i] = {n:data[i].n,p:prop};
+            }
+            this.getValue = processKeys;
+            if(this.k){
+                dynamicProperties.push(this);
+            }else{
+                this.getValue(true);
+            }
+
+        }
+    }());
+
+    function getDashProp(elem, data,renderer, dynamicProperties) {
+        return new DashProperty(elem, data,renderer, dynamicProperties);
+    };
+
+    var TextSelectorProp = (function(){
+        var max = Math.max;
+        var min = Math.min;
+        var floor = Math.floor;
+        function updateRange(){
+            if(this.dynamicProperties.length){
+                var i, len = this.dynamicProperties.length;
+                for(i=0;i<len;i+=1){
+                    this.dynamicProperties[i].getValue();
+                    if(this.dynamicProperties[i].mdf){
+                        this.mdf = true;
+                    }
+                }
+            }
+            var totalChars = this.data.totalChars;
+            var divisor = this.data.r === 2 ? 1 : 100/totalChars;
+            var o = this.o.v/divisor;
+            var s = this.s.v/divisor + o;
+            var e = (this.e.v/divisor) + o;
+            if(s>e){
+                var _s = s;
+                s = e;
+                e = _s;
+            }
+            this.finalS = s;
+            this.finalE = e;
+        }
+
+        function getMult(ind){
+            //var easer = bez.getEasingCurve(this.ne.v/100,0,1-this.xe.v/100,1);
+            var easer = BezierFactory.getBezierEasing(this.ne.v/100,0,1-this.xe.v/100,1).get;
+            var mult = 0;
+            var s = this.finalS;
+            var e = this.finalE;
+            var type = this.data.sh;
+            if(type == 2){
+                if(e === s){
+                    mult = ind >= e ? 1 : 0;
+                }else{
+                    mult = max(0,min(0.5/(e-s) + (ind-s)/(e-s),1));
+                }
+                mult = easer(mult);
+            }else if(type == 3){
+                if(e === s){
+                    mult = ind >= e ? 0 : 1;
+                }else{
+                    mult = 1 - max(0,min(0.5/(e-s) + (ind-s)/(e-s),1));
+                }
+
+                mult = easer(mult);
+            }else if(type == 4){
+                if(e === s){
+                    mult = 0;
+                }else{
+                    mult = max(0,min(0.5/(e-s) + (ind-s)/(e-s),1));
+                    if(mult<.5){
+                        mult *= 2;
+                    }else{
+                        mult = 1 - 2*(mult-0.5);
+                    }
+                }
+                mult = easer(mult);
+            }else if(type == 5){
+                if(e === s){
+                    mult = 0;
+                }else{
+                    var tot = e - s;
+                    /*ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind;*/
+                    ind = min(max(0,ind+0.5-s),e-s);
+                    var x = -tot/2+ind;
+                    var a = tot/2;
+                    mult = Math.sqrt(1 - (x*x)/(a*a));
+                }
+                mult = easer(mult);
+            }else if(type == 6){
+                if(e === s){
+                    mult = 0;
+                }else{
+                    ind = min(max(0,ind+0.5-s),e-s);
+                    mult = (1+(Math.cos((Math.PI+Math.PI*2*(ind)/(e-s)))))/2;
+                    /*
+                     ind = Math.min(Math.max(s,ind),e-1);
+                     mult = (1+(Math.cos((Math.PI+Math.PI*2*(ind-s)/(e-1-s)))))/2;
+                     mult = Math.max(mult,(1/(e-1-s))/(e-1-s));*/
+                }
+                mult = easer(mult);
+            }else {
+                if(ind >= floor(s)){
+                    if(ind-s < 0){
+                        mult = 1 - (s - ind);
+                    }else{
+                        mult = max(0,min(e-ind,1));
+                    }
+                }
+                mult = easer(mult);
+            }
+            return mult*this.a.v;
+        }
+
+        return function TextSelectorProp(elem,data, arr){
+            this.mdf = false;
+            this.k = false;
+            this.data = data;
+            this.dynamicProperties = [];
+            this.getValue = updateRange;
+            this.getMult = getMult;
+            this.comp = elem.comp;
+            this.finalS = 0;
+            this.finalE = 0;
+            this.s = PropertyFactory.getProp(elem,data.s || {k:0},0,0,this.dynamicProperties);
+            if('e' in data){
+                this.e = PropertyFactory.getProp(elem,data.e,0,0,this.dynamicProperties);
+            }else{
+                this.e = {v:data.r === 2 ? data.totalChars : 100};
+            }
+            this.o = PropertyFactory.getProp(elem,data.o || {k:0},0,0,this.dynamicProperties);
+            this.xe = PropertyFactory.getProp(elem,data.xe || {k:0},0,0,this.dynamicProperties);
+            this.ne = PropertyFactory.getProp(elem,data.ne || {k:0},0,0,this.dynamicProperties);
+            this.a = PropertyFactory.getProp(elem,data.a,0,0.01,this.dynamicProperties);
+            if(this.dynamicProperties.length){
+                arr.push(this);
+            }else{
+                this.getValue();
+            }
+        }
+    }());
+
+    function getTextSelectorProp(elem, data,arr) {
+        return new TextSelectorProp(elem, data, arr);
+    };
+
+    var ob = {};
+    ob.getProp = getProp;
+    ob.getDashProp = getDashProp;
+    ob.getTextSelectorProp = getTextSelectorProp;
+    ob.getGradientProp = getGradientProp;
+    return ob;
+}());
+function ShapePath(){
+	this.c = false;
+	this._length = 0;
+	this._maxLength = 8;
+	this.v = Array.apply(null,{length:this._maxLength});
+	this.o = Array.apply(null,{length:this._maxLength});
+	this.i = Array.apply(null,{length:this._maxLength});
+};
+
+ShapePath.prototype.setPathData = function(closed, len) {
+	this.c = closed;
+	while(len > this._maxLength){
+		this.doubleArrayLength();
+	}
+	var i = 0;
+	while(i < len){
+		this.v[i] = point_pool.newPoint();
+		this.o[i] = point_pool.newPoint();
+		this.i[i] = point_pool.newPoint();
+		i += 1;
+	}
+	this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function() {
+	this.v = this.v.concat(Array.apply(null,{length:this._maxLength}))
+	this.i = this.i.concat(Array.apply(null,{length:this._maxLength}))
+	this.o = this.o.concat(Array.apply(null,{length:this._maxLength}))
+	this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function(x, y, type, pos, replace) {
+	var arr;
+	this._length = Math.max(this._length, pos + 1);
+	if(this._length >= this._maxLength) {
+		this.doubleArrayLength();
+	}
+	switch(type){
+		case 'v':
+			arr = this.v;
+			break;
+		case 'i':
+			arr = this.i;
+			break;
+		case 'o':
+			arr = this.o;
+			break;
+	}
+	if(!arr[pos] || (arr[pos] && !replace)){
+		arr[pos] = point_pool.newPoint();
+	}
+	arr[pos][0] = x;
+	arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function(vX,vY,oX,oY,iX,iY,pos, replace) {
+	this.setXYAt(vX,vY,'v',pos, replace);
+	this.setXYAt(oX,oY,'o',pos, replace);
+	this.setXYAt(iX,iY,'i',pos, replace);
+};
+var ShapePropertyFactory = (function(){
+
+    var initFrame = -999999;
+
+    function interpolateShape() {
+        if(this.elem.globalData.frameId === this.frameId){
+            return;
+        }
+        this.mdf = false;
+        var frameNum = this.comp.renderedFrame - this.offsetTime;
+        if(!((this.lastFrame !== initFrame && ((this.lastFrame < this.keyframes[0].t-this.offsetTime && frameNum < this.keyframes[0].t-this.offsetTime) || (this.lastFrame > this.keyframes[this.keyframes.length - 1].t-this.offsetTime && frameNum > this.keyframes[this.keyframes.length - 1].t-this.offsetTime))))){
+            var keyPropS,keyPropE,isHold;
+            if(frameNum < this.keyframes[0].t-this.offsetTime){
+                keyPropS = this.keyframes[0].s[0];
+                isHold = true;
+                this._lastIndex = 0;
+            }else if(frameNum >= this.keyframes[this.keyframes.length - 1].t-this.offsetTime){
+                if(this.keyframes[this.keyframes.length - 2].h === 1){
+                    keyPropS = this.keyframes[this.keyframes.length - 1].s[0];
+                }else{
+                    keyPropS = this.keyframes[this.keyframes.length - 2].e[0];
+                }
+                isHold = true;
+            }else{
+                var i = this.lastFrame < initFrame ? this._lastIndex : 0;
+                var len = this.keyframes.length- 1,flag = true,keyData,nextKeyData, j, jLen, k, kLen;
+                while(flag){
+                    keyData = this.keyframes[i];
+                    nextKeyData = this.keyframes[i+1];
+                    if((nextKeyData.t - this.offsetTime) > frameNum){
+                        break;
+                    }
+                    if(i < len - 1){
+                        i += 1;
+                    }else{
+                        flag = false;
+                    }
+                }
+                isHold = keyData.h === 1;
+                this._lastIndex = i;
+
+                var perc;
+                if(!isHold){
+                    if(frameNum >= nextKeyData.t-this.offsetTime){
+                        perc = 1;
+                    }else if(frameNum < keyData.t-this.offsetTime){
+                        perc = 0;
+                    }else{
+                        var fnc;
+                        if(keyData.__fnct){
+                            fnc = keyData.__fnct;
+                        }else{
+                            fnc = BezierFactory.getBezierEasing(keyData.o.x,keyData.o.y,keyData.i.x,keyData.i.y).get;
+                            keyData.__fnct = fnc;
+                        }
+                        perc = fnc((frameNum-(keyData.t-this.offsetTime))/((nextKeyData.t-this.offsetTime)-(keyData.t-this.offsetTime)));
+                    }
+                    keyPropE = keyData.e[0];
+                }
+                keyPropS = keyData.s[0];
+            }
+            jLen = this.v._length;
+            kLen = keyPropS.i[0].length;
+            var hasModified = false;
+            var vertexValue;
+            for(j=0;j<jLen;j+=1){
+                for(k=0;k<kLen;k+=1){
+                    if(isHold){
+                        vertexValue = keyPropS.i[j][k];
+                        if(this.v.i[j][k] !== vertexValue){
+                            this.v.i[j][k] = vertexValue;
+                            this.pv.i[j][k] = vertexValue;
+                            hasModified = true;
+                        }
+                        vertexValue = keyPropS.o[j][k];
+                        if(this.v.o[j][k] !== vertexValue){
+                            this.v.o[j][k] = vertexValue;
+                            this.pv.o[j][k] = vertexValue;
+                            hasModified = true;
+                        }
+                        vertexValue = keyPropS.v[j][k];
+                        if(this.v.v[j][k] !== vertexValue){
+                            this.v.v[j][k] = vertexValue;
+                            this.pv.v[j][k] = vertexValue;
+                            hasModified = true;
+                        }
+                    }else{
+                        vertexValue = keyPropS.i[j][k]+(keyPropE.i[j][k]-keyPropS.i[j][k])*perc;
+                        if(this.v.i[j][k] !== vertexValue){
+                            this.v.i[j][k] = vertexValue;
+                            this.pv.i[j][k] = vertexValue;
+                            hasModified = true;
+                        }
+                        vertexValue = keyPropS.o[j][k]+(keyPropE.o[j][k]-keyPropS.o[j][k])*perc;
+                        if(this.v.o[j][k] !== vertexValue){
+                            this.v.o[j][k] = vertexValue;
+                            this.pv.o[j][k] = vertexValue;
+                            hasModified = true;
+                        }
+                        vertexValue = keyPropS.v[j][k]+(keyPropE.v[j][k]-keyPropS.v[j][k])*perc;
+                        if(this.v.v[j][k] !== vertexValue){
+                            this.v.v[j][k] = vertexValue;
+                            this.pv.v[j][k] = vertexValue;
+                            hasModified = true;
+                        }
+                    }
+                }
+            }
+            this.mdf = hasModified;
+            this.v.c = keyPropS.c;
+            this.paths = this.localShapeCollection;
+        }
+
+        this.lastFrame = frameNum;
+        this.frameId = this.elem.globalData.frameId;
+    }
+
+    function getShapeValue(){
+        return this.v;
+    }
+
+    function resetShape(){
+        this.paths = this.localShapeCollection;
+        if(!this.k){
+            this.mdf = false;
+        }
+    }
+
+    function ShapeProperty(elem, data, type){
+        this.comp = elem.comp;
+        this.k = false;
+        this.mdf = false;
+        this.v = shape_pool.newShape();
+        var pathData = type === 3 ? data.pt.k : data.ks.k;
+        this.v.v = pathData.v;
+        this.v.i = pathData.i;
+        this.v.o = pathData.o;
+        this.v.c = pathData.c;
+        this.v._length = this.v.v.length;
+        this.getValue = getShapeValue;
+        this.pv = shape_pool.clone(this.v);
+        this.localShapeCollection = shapeCollection_pool.newShapeCollection();
+        this.paths = this.localShapeCollection;
+        this.paths.addShape(this.v);
+        this.reset = resetShape;
+    }
+
+    function KeyframedShapeProperty(elem,data,type){
+        this.comp = elem.comp;
+        this.elem = elem;
+        this.offsetTime = elem.data.st;
+        this._lastIndex = 0;
+        this.getValue = interpolateShape;
+        this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+        this.k = true;
+        this.kf = true;
+        var i, len = this.keyframes[0].s[0].i.length;
+        var jLen = this.keyframes[0].s[0].i[0].length;
+        this.v = shape_pool.newShape();
+        this.v.setPathData(this.keyframes[0].s[0].c, len);
+        this.pv = shape_pool.clone(this.v);
+        this.localShapeCollection = shapeCollection_pool.newShapeCollection();
+        this.paths = this.localShapeCollection;
+        this.paths.addShape(this.v);
+        this.lastFrame = initFrame;
+        this.reset = resetShape;
+    }
+
+    var EllShapeProperty = (function(){
+
+        var cPoint = roundCorner;
+
+        function convertEllToPath(){
+            var p0 = this.p.v[0], p1 = this.p.v[1], s0 = this.s.v[0]/2, s1 = this.s.v[1]/2;
+            if(this.d !== 3){
+                this.v.v[0][0] = p0;
+                this.v.v[0][1] = p1-s1;
+                this.v.v[1][0] = p0 + s0;
+                this.v.v[1][1] = p1;
+                this.v.v[2][0] = p0;
+                this.v.v[2][1] = p1+s1;
+                this.v.v[3][0] = p0 - s0;
+                this.v.v[3][1] = p1;
+                this.v.i[0][0] = p0 - s0*cPoint;
+                this.v.i[0][1] = p1 - s1;
+                this.v.i[1][0] = p0 + s0;
+                this.v.i[1][1] = p1 - s1*cPoint;
+                this.v.i[2][0] = p0 + s0*cPoint;
+                this.v.i[2][1] = p1 + s1;
+                this.v.i[3][0] = p0 - s0;
+                this.v.i[3][1] = p1 + s1*cPoint;
+                this.v.o[0][0] = p0 + s0*cPoint;
+                this.v.o[0][1] = p1 - s1;
+                this.v.o[1][0] = p0 + s0;
+                this.v.o[1][1] = p1 + s1*cPoint;
+                this.v.o[2][0] = p0 - s0*cPoint;
+                this.v.o[2][1] = p1 + s1;
+                this.v.o[3][0] = p0 - s0;
+                this.v.o[3][1] = p1 - s1*cPoint;
+            }else{
+                this.v.v[0][0] = p0;
+                this.v.v[0][1] = p1-s1;
+                this.v.v[1][0] = p0 - s0;
+                this.v.v[1][1] = p1;
+                this.v.v[2][0] = p0;
+                this.v.v[2][1] = p1+s1;
+                this.v.v[3][0] = p0 + s0;
+                this.v.v[3][1] = p1;
+                this.v.i[0][0] = p0 + s0*cPoint;
+                this.v.i[0][1] = p1 - s1;
+                this.v.i[1][0] = p0 - s0;
+                this.v.i[1][1] = p1 - s1*cPoint;
+                this.v.i[2][0] = p0 - s0*cPoint;
+                this.v.i[2][1] = p1 + s1;
+                this.v.i[3][0] = p0 + s0;
+                this.v.i[3][1] = p1 + s1*cPoint;
+                this.v.o[0][0] = p0 - s0*cPoint;
+                this.v.o[0][1] = p1 - s1;
+                this.v.o[1][0] = p0 - s0;
+                this.v.o[1][1] = p1 + s1*cPoint;
+                this.v.o[2][0] = p0 + s0*cPoint;
+                this.v.o[2][1] = p1 + s1;
+                this.v.o[3][0] = p0 + s0;
+                this.v.o[3][1] = p1 - s1*cPoint;
+            }
+        }
+
+        function processKeys(frameNum){
+            var i, len = this.dynamicProperties.length;
+            if(this.elem.globalData.frameId === this.frameId){
+                return;
+            }
+            this.mdf = false;
+            this.frameId = this.elem.globalData.frameId;
+
+            for(i=0;i<len;i+=1){
+                this.dynamicProperties[i].getValue(frameNum);
+                if(this.dynamicProperties[i].mdf){
+                    this.mdf = true;
+                }
+            }
+            if(this.mdf){
+                this.convertEllToPath();
+            }
+        }
+
+        return function EllShapeProperty(elem,data) {
+            /*this.v = {
+                v: Array.apply(null,{length:4}),
+                i: Array.apply(null,{length:4}),
+                o: Array.apply(null,{length:4}),
+                c: true
+            };*/
+            this.v = shape_pool.newShape();
+            this.v.setPathData(true, 4);
+            this.localShapeCollection = shapeCollection_pool.newShapeCollection();
+            this.paths = this.localShapeCollection;
+            this.localShapeCollection.addShape(this.v);
+            this.d = data.d;
+            this.dynamicProperties = [];
+            this.elem = elem;
+            this.comp = elem.comp;
+            this.frameId = -1;
+            this.mdf = false;
+            this.getValue = processKeys;
+            this.convertEllToPath = convertEllToPath;
+            this.reset = resetShape;
+            this.p = PropertyFactory.getProp(elem,data.p,1,0,this.dynamicProperties);
+            this.s = PropertyFactory.getProp(elem,data.s,1,0,this.dynamicProperties);
+            if(this.dynamicProperties.length){
+                this.k = true;
+            }else{
+                this.convertEllToPath();
+            }
+        }
+    }());
+
+    var StarShapeProperty = (function() {
+
+        function convertPolygonToPath(){
+            var numPts = Math.floor(this.pt.v);
+            var angle = Math.PI*2/numPts;
+            /*this.v.v.length = numPts;
+            this.v.i.length = numPts;
+            this.v.o.length = numPts;*/
+            var rad = this.or.v;
+            var roundness = this.os.v;
+            var perimSegment = 2*Math.PI*rad/(numPts*4);
+            var i, currentAng = -Math.PI/ 2;
+            var dir = this.data.d === 3 ? -1 : 1;
+            currentAng += this.r.v;
+            this.v._length = 0;
+            for(i=0;i<numPts;i+=1){
+                var x = rad * Math.cos(currentAng);
+                var y = rad * Math.sin(currentAng);
+                var ox = x === 0 && y === 0 ? 0 : y/Math.sqrt(x*x + y*y);
+                var oy = x === 0 && y === 0 ? 0 : -x/Math.sqrt(x*x + y*y);
+                x +=  + this.p.v[0];
+                y +=  + this.p.v[1];
+                this.v.setTripleAt(x,y,x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir,x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir, i, true);
+                /*this.v.v[i] = [x,y];
+                this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];*/
+                currentAng += angle*dir;
+            }
+            this.paths.length = 0;
+            this.paths[0] = this.v;
+        }
+
+        function convertStarToPath() {
+            var numPts = Math.floor(this.pt.v)*2;
+            var angle = Math.PI*2/numPts;
+            /*this.v.v.length = numPts;
+            this.v.i.length = numPts;
+            this.v.o.length = numPts;*/
+            var longFlag = true;
+            var longRad = this.or.v;
+            var shortRad = this.ir.v;
+            var longRound = this.os.v;
+            var shortRound = this.is.v;
+            var longPerimSegment = 2*Math.PI*longRad/(numPts*2);
+            var shortPerimSegment = 2*Math.PI*shortRad/(numPts*2);
+            var i, rad,roundness,perimSegment, currentAng = -Math.PI/ 2;
+            currentAng += this.r.v;
+            var dir = this.data.d === 3 ? -1 : 1;
+            this.v._length = 0;
+            for(i=0;i<numPts;i+=1){
+                rad = longFlag ? longRad : shortRad;
+                roundness = longFlag ? longRound : shortRound;
+                perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+                var x = rad * Math.cos(currentAng);
+                var y = rad * Math.sin(currentAng);
+                var ox = x === 0 && y === 0 ? 0 : y/Math.sqrt(x*x + y*y);
+                var oy = x === 0 && y === 0 ? 0 : -x/Math.sqrt(x*x + y*y);
+                x +=  + this.p.v[0];
+                y +=  + this.p.v[1];
+                this.v.setTripleAt(x,y,x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir,x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir, i, true);
+
+                /*this.v.v[i] = [x,y];
+                this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                this.v._length = numPts;*/
+                longFlag = !longFlag;
+                currentAng += angle*dir;
+            }
+        }
+
+        function processKeys() {
+            if(this.elem.globalData.frameId === this.frameId){
+                return;
+            }
+            this.mdf = false;
+            this.frameId = this.elem.globalData.frameId;
+            var i, len = this.dynamicProperties.length;
+
+            for(i=0;i<len;i+=1){
+                this.dynamicProperties[i].getValue();
+                if(this.dynamicProperties[i].mdf){
+                    this.mdf = true;
+                }
+            }
+            if(this.mdf){
+                this.convertToPath();
+            }
+        }
+
+        return function StarShapeProperty(elem,data) {
+            /*this.v = {
+                v: [],
+                i: [],
+                o: [],
+                c: true
+            };*/
+            this.v = shape_pool.newShape();
+            this.v.setPathData(true, 0);
+            this.elem = elem;
+            this.comp = elem.comp;
+            this.data = data;
+            this.frameId = -1;
+            this.d = data.d;
+            this.dynamicProperties = [];
+            this.mdf = false;
+            this.getValue = processKeys;
+            this.reset = resetShape;
+            if(data.sy === 1){
+                this.ir = PropertyFactory.getProp(elem,data.ir,0,0,this.dynamicProperties);
+                this.is = PropertyFactory.getProp(elem,data.is,0,0.01,this.dynamicProperties);
+                this.convertToPath = convertStarToPath;
+            } else {
+                this.convertToPath = convertPolygonToPath;
+            }
+            this.pt = PropertyFactory.getProp(elem,data.pt,0,0,this.dynamicProperties);
+            this.p = PropertyFactory.getProp(elem,data.p,1,0,this.dynamicProperties);
+            this.r = PropertyFactory.getProp(elem,data.r,0,degToRads,this.dynamicProperties);
+            this.or = PropertyFactory.getProp(elem,data.or,0,0,this.dynamicProperties);
+            this.os = PropertyFactory.getProp(elem,data.os,0,0.01,this.dynamicProperties);
+            this.localShapeCollection = shapeCollection_pool.newShapeCollection();
+            this.localShapeCollection.addShape(this.v);
+            this.paths = this.localShapeCollection;
+            if(this.dynamicProperties.length){
+                this.k = true;
+            }else{
+                this.convertToPath();
+            }
+        }
+    }());
+
+    var RectShapeProperty = (function() {
+        function processKeys(frameNum){
+            if(this.elem.globalData.frameId === this.frameId){
+                return;
+            }
+            this.mdf = false;
+            this.frameId = this.elem.globalData.frameId;
+            var i, len = this.dynamicProperties.length;
+
+            for(i=0;i<len;i+=1){
+                this.dynamicProperties[i].getValue(frameNum);
+                if(this.dynamicProperties[i].mdf){
+                    this.mdf = true;
+                }
+            }
+            if(this.mdf){
+                this.convertRectToPath();
+            }
+
+        }
+
+        function convertRectToPath(){
+            var p0 = this.p.v[0], p1 = this.p.v[1], v0 = this.s.v[0]/2, v1 = this.s.v[1]/2;
+            var round = bm_min(v0,v1,this.r.v);
+            var cPoint = round*(1-roundCorner);
+            this.v._length = 0;
+
+            if(this.d === 2 || this.d === 1) {
+                this.v.setTripleAt(p0+v0, p1-v1+round,p0+v0, p1-v1+round,p0+v0,p1-v1+cPoint,0, true);
+                this.v.setTripleAt(p0+v0, p1+v1-round,p0+v0, p1+v1-cPoint,p0+v0, p1+v1-round,1, true);
+                if(round!== 0){
+                    this.v.setTripleAt(p0+v0-round, p1+v1,p0+v0-round,p1+v1,p0+v0-cPoint,p1+v1,2, true);
+                    this.v.setTripleAt(p0-v0+round,p1+v1,p0-v0+cPoint,p1+v1,p0-v0+round,p1+v1,3, true);
+                    this.v.setTripleAt(p0-v0,p1+v1-round,p0-v0,p1+v1-round,p0-v0,p1+v1-cPoint,4, true);
+                    this.v.setTripleAt(p0-v0,p1-v1+round,p0-v0,p1-v1+cPoint,p0-v0,p1-v1+round,5, true);
+                    this.v.setTripleAt(p0-v0+round,p1-v1,p0-v0+round,p1-v1,p0-v0+cPoint,p1-v1,6, true);
+                    this.v.setTripleAt(p0+v0-round,p1-v1,p0+v0-cPoint,p1-v1,p0+v0-round,p1-v1,7, true);
+                } else {
+                    this.v.setTripleAt(p0-v0,p1+v1,p0-v0+cPoint,p1+v1,p0-v0,p1+v1,2);
+                    this.v.setTripleAt(p0-v0,p1-v1,p0-v0,p1-v1+cPoint,p0-v0,p1-v1,3);
+                }
+            }else{
+                this.v.setTripleAt(p0+v0,p1-v1+round,p0+v0,p1-v1+cPoint,p0+v0,p1-v1+round,0, true);
+                if(round!== 0){
+                    this.v.setTripleAt(p0+v0-round,p1-v1,p0+v0-round,p1-v1,p0+v0-cPoint,p1-v1,1, true);
+                    this.v.setTripleAt(p0-v0+round,p1-v1,p0-v0+cPoint,p1-v1,p0-v0+round,p1-v1,2, true);
+                    this.v.setTripleAt(p0-v0,p1-v1+round,p0-v0,p1-v1+round,p0-v0,p1-v1+cPoint,3, true);
+                    this.v.setTripleAt(p0-v0,p1+v1-round,p0-v0,p1+v1-cPoint,p0-v0,p1+v1-round,4, true);
+                    this.v.setTripleAt(p0-v0+round,p1+v1,p0-v0+round,p1+v1,p0-v0+cPoint,p1+v1,5, true);
+                    this.v.setTripleAt(p0+v0-round,p1+v1,p0+v0-cPoint,p1+v1,p0+v0-round,p1+v1,6, true);
+                    this.v.setTripleAt(p0+v0,p1+v1-round,p0+v0,p1+v1-round,p0+v0,p1+v1-cPoint,7, true);
+                } else {
+                    this.v.setTripleAt(p0-v0,p1-v1,p0-v0+cPoint,p1-v1,p0-v0,p1-v1,1, true);
+                    this.v.setTripleAt(p0-v0,p1+v1,p0-v0,p1+v1-cPoint,p0-v0,p1+v1,2, true);
+                    this.v.setTripleAt(p0+v0,p1+v1,p0+v0-cPoint,p1+v1,p0+v0,p1+v1,3, true);
+
+                }
+            }
+        }
+
+        return function RectShapeProperty(elem,data) {
+            this.v = shape_pool.newShape();
+            this.v.c = true;
+            this.localShapeCollection = shapeCollection_pool.newShapeCollection();
+            this.localShapeCollection.addShape(this.v);
+            this.paths = this.localShapeCollection;
+            this.elem = elem;
+            this.comp = elem.comp;
+            this.frameId = -1;
+            this.d = data.d;
+            this.dynamicProperties = [];
+            this.mdf = false;
+            this.getValue = processKeys;
+            this.convertRectToPath = convertRectToPath;
+            this.reset = resetShape;
+            this.p = PropertyFactory.getProp(elem,data.p,1,0,this.dynamicProperties);
+            this.s = PropertyFactory.getProp(elem,data.s,1,0,this.dynamicProperties);
+            this.r = PropertyFactory.getProp(elem,data.r,0,0,this.dynamicProperties);
+            if(this.dynamicProperties.length){
+                this.k = true;
+            }else{
+                this.convertRectToPath();
+            }
+        }
+    }());
+
+    function getShapeProp(elem,data,type, arr){
+        var prop;
+        if(type === 3 || type === 4){
+            var dataProp = type === 3 ? data.pt : data.ks;
+            var keys = dataProp.k;
+            if(dataProp.a === 1 || keys.length){
+                prop = new KeyframedShapeProperty(elem, data, type);
+            }else{
+                prop = new ShapeProperty(elem, data, type);
+            }
+        }else if(type === 5){
+            prop = new RectShapeProperty(elem, data);
+        }else if(type === 6){
+            prop = new EllShapeProperty(elem, data);
+        }else if(type === 7){
+            prop = new StarShapeProperty(elem, data);
+        }
+        if(prop.k){
+            arr.push(prop);
+        }
+        return prop;
+    }
+
+    var ob = {};
+    ob.getShapeProp = getShapeProp;
+    return ob;
+}());
+var ShapeModifiers = (function(){
+    var ob = {};
+    var modifiers = {};
+    ob.registerModifier = registerModifier;
+    ob.getModifier = getModifier;
+
+    function registerModifier(nm,factory){
+        if(!modifiers[nm]){
+            modifiers[nm] = factory;
+        }
+    }
+
+    function getModifier(nm,elem, data, dynamicProperties){
+        return new modifiers[nm](elem, data, dynamicProperties);
+    }
+
+    return ob;
+}());
+
+function ShapeModifier(){}
+ShapeModifier.prototype.initModifierProperties = function(){};
+ShapeModifier.prototype.addShapeToModifier = function(){};
+ShapeModifier.prototype.addShape = function(data){
+    if(!this.closed){
+        this.shapes.push({shape:data.sh, data: data, localShapeCollection:shapeCollection_pool.newShapeCollection()});
+        this.addShapeToModifier(data.sh);
+    }
+}
+ShapeModifier.prototype.init = function(elem,data,dynamicProperties){
+    this.elem = elem;
+    this.frameId = -1;
+    this.shapes = [];
+    this.dynamicProperties = [];
+    this.mdf = false;
+    this.closed = false;
+    this.k = false;
+    this.isTrimming = false;
+    this.comp = elem.comp;
+    this.initModifierProperties(elem,data);
+    if(this.dynamicProperties.length){
+        this.k = true;
+        dynamicProperties.push(this);
+    }else{
+        this.getValue(true);
+    }
+}
+function TrimModifier(){};
+extendPrototype(ShapeModifier,TrimModifier);
+TrimModifier.prototype.processKeys = function(forceRender){
+    if(this.elem.globalData.frameId === this.frameId && !forceRender){
+        return;
+    }
+    this.mdf = forceRender ? true : false;
+    this.frameId = this.elem.globalData.frameId;
+    var i, len = this.dynamicProperties.length;
+
+    for(i=0;i<len;i+=1){
+        this.dynamicProperties[i].getValue();
+        if(this.dynamicProperties[i].mdf){
+            this.mdf = true;
+        }
+    }
+    if(this.mdf || forceRender){
+        var o = (this.o.v%360)/360;
+        if(o < 0){
+            o += 1;
+        }
+        var s = this.s.v + o;
+        var e = this.e.v + o;
+        if(s == e){
+
+        }
+        if(s>e){
+            var _s = s;
+            s = e;
+            e = _s;
+        }
+        this.sValue = s;
+        this.eValue = e;
+        this.oValue = o;
+    }
+}
+TrimModifier.prototype.initModifierProperties = function(elem,data){
+    this.sValue = 0;
+    this.eValue = 0;
+    this.oValue = 0;
+    this.getValue = this.processKeys;
+    this.s = PropertyFactory.getProp(elem,data.s,0,0.01,this.dynamicProperties);
+    this.e = PropertyFactory.getProp(elem,data.e,0,0.01,this.dynamicProperties);
+    this.o = PropertyFactory.getProp(elem,data.o,0,0,this.dynamicProperties);
+    this.m = data.m;
+    if(!this.dynamicProperties.length){
+        this.getValue(true);
+    }
+};
+
+TrimModifier.prototype.getSegmentsLength = function(shapeData){
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i, len = shapeData._length;
+    var lengths = [];
+    var totalLength = 0;
+    for(i=0;i<len-1;i+=1){
+        lengths[i] = bez.getBezierLength(pathV[i],pathV[i+1],pathO[i],pathI[i+1]);
+        totalLength += lengths[i].addedLength;
+    }
+    if(closed){
+        lengths[i] = bez.getBezierLength(pathV[i],pathV[0],pathO[i],pathI[0]);
+        totalLength += lengths[i].addedLength;
+    }
+    return {lengths:lengths,totalLength:totalLength};
+}
+
+TrimModifier.prototype.calculateShapeEdges = function(s, e, shapeLength, addedLength, totalModifierLength) {
+    var segments = []
+    if(e <= 1){
+        segments.push({
+            s: s,
+            e: e
+        })
+    }else if(s >= 1){
+        segments.push({
+            s: s - 1,
+            e: e - 1
+        })
+    }else{
+        segments.push({
+            s: s,
+            e: 1
+        })
+        segments.push({
+            s: 0,
+            e: e - 1
+        })
+    }
+    var shapeSegments = [];
+    var i, len = segments.length, segmentOb;
+    for(i = 0; i < len; i += 1) {
+        segmentOb = segments[i];
+        if (segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength) {
+            
+        } else {
+            var shapeS, shapeE;
+            if(segmentOb.s * totalModifierLength <= addedLength) {
+                shapeS = 0;
+            } else {
+                shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+            }
+            if(segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+                shapeE = 1;
+            } else {
+                shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+            }
+            shapeSegments.push([shapeS, shapeE]);
+        }
+    }
+    if(!shapeSegments.length){
+        shapeSegments.push([0,0]);
+    }
+    return shapeSegments;
+}
+
+TrimModifier.prototype.processShapes = function(firstFrame){
+    var shapePaths;
+    var i, len = this.shapes.length;
+    var j, jLen;
+    var s = this.sValue;
+    var e = this.eValue;
+    var pathsData,pathData, totalShapeLength, totalModifierLength = 0;
+
+    if(e === s){
+        for(i=0;i<len;i+=1){
+            this.shapes[i].localShapeCollection.releaseShapes();
+            this.shapes[i].shape.mdf = true;
+            this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+        }
+    } else if(!((e === 1 && s === 0) || (e===0 && s === 1))){
+        var segments = [], shapeData, localShapeCollection;
+        for(i=0;i<len;i+=1){
+            shapeData = this.shapes[i];
+            if(!shapeData.shape.mdf && !this.mdf && !firstFrame && this.m !== 2){
+                shapeData.shape.paths = shapeData.localShapeCollection;
+            } else {
+                shapePaths = shapeData.shape.paths;
+                jLen = shapePaths._length;
+                totalShapeLength = 0;
+                if(!shapeData.shape.mdf && shapeData.pathsData){
+                    totalShapeLength = shapeData.totalShapeLength;
+                } else {
+                    pathsData = [];
+                    for(j=0;j<jLen;j+=1){
+                        pathData = this.getSegmentsLength(shapePaths.shapes[j]);
+                        pathsData.push(pathData);
+                        totalShapeLength += pathData.totalLength;
+                    }
+                    shapeData.totalShapeLength = totalShapeLength;
+                    shapeData.pathsData = pathsData;
+                }
+
+                totalModifierLength += totalShapeLength;
+                shapeData.shape.mdf = true;
+            }
+        }
+        var shapeS = s, shapeE = e, addedLength = 0;
+        var j, jLen;
+        for(i = len - 1; i >= 0; i -= 1){
+            shapeData = this.shapes[i];
+            if (shapeData.shape.mdf) {
+                localShapeCollection = shapeData.localShapeCollection;
+                localShapeCollection.releaseShapes();
+                if(this.m === 2 && len > 1) {
+                    var edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+                    addedLength += shapeData.totalShapeLength;
+                } else {
+                    edges = [[shapeS, shapeE]]
+                }
+                jLen = edges.length;
+                for (j = 0; j < jLen; j += 1) {
+                    shapeS = edges[j][0];
+                    shapeE = edges[j][1];
+                    segments.length = 0;
+                    if(shapeE <= 1){
+                        segments.push({
+                            s:shapeData.totalShapeLength * shapeS,
+                            e:shapeData.totalShapeLength * shapeE
+                        })
+                    }else if(shapeS >= 1){
+                        segments.push({
+                            s:shapeData.totalShapeLength * (shapeS - 1),
+                            e:shapeData.totalShapeLength * (shapeE - 1)
+                        })
+                    }else{
+                        segments.push({
+                            s:shapeData.totalShapeLength * shapeS,
+                            e:shapeData.totalShapeLength
+                        })
+                        segments.push({
+                            s:0,
+                            e:shapeData.totalShapeLength*(shapeE - 1)
+                        })
+                    }
+                    var newShapesData = this.addShapes(shapeData,segments[0]);
+                    if (segments[0].s !== segments[0].e) {
+                        var lastPos;
+                        if(segments.length > 1){
+                            if(shapeData.shape.v.c){
+                                var lastShape = newShapesData.pop();
+                                this.addPaths(newShapesData, localShapeCollection);
+                                newShapesData = this.addShapes(shapeData,segments[1], lastShape);
+                            } else {
+                                this.addPaths(newShapesData, localShapeCollection);
+                                newShapesData = this.addShapes(shapeData,segments[1]);
+                            }
+                        } 
+                        this.addPaths(newShapesData, localShapeCollection);
+                    }
+                    
+                }
+                shapeData.shape.paths = localShapeCollection;
+            }
+        }
+    } else if(this.mdf){
+        for(i=0;i<len;i+=1){
+            this.shapes[i].shape.mdf = true;
+        }
+    }
+    if(!this.dynamicProperties.length){
+        this.mdf = false;
+    }
+}
+
+TrimModifier.prototype.addPaths = function(newPaths, localShapeCollection) {
+    var i, len = newPaths.length;
+    for(i = 0; i < len; i += 1) {
+        localShapeCollection.addShape(newPaths[i])
+    }
+}
+
+TrimModifier.prototype.addSegment = function(pt1,pt2,pt3,pt4,shapePath,pos, newShape) {
+    /*console.log(pt1, 'vertex: v, at: ', pos);
+    console.log(pt2, 'vertex: o, at: ', pos);
+    console.log(pt3, 'vertex: i, at: ', pos + 1);
+    console.log(pt4, 'vertex: v, at: ', pos + 1);
+    console.log('newShape: ', newShape);*/
+    shapePath.setXYAt(pt2[0],pt2[1],'o',pos);
+    shapePath.setXYAt(pt3[0],pt3[1],'i',pos + 1);
+    if(newShape){
+        shapePath.setXYAt(pt1[0],pt1[1],'v',pos);
+    }
+    shapePath.setXYAt(pt4[0],pt4[1],'v',pos + 1);
+}
+
+TrimModifier.prototype.addShapes = function(shapeData, shapeSegment, shapePath){
+    var pathsData = shapeData.pathsData;
+    var shapePaths = shapeData.shape.paths.shapes;
+    var i, len = shapeData.shape.paths._length, j, jLen;
+    var addedLength = 0;
+    var currentLengthData,segmentCount;
+    var lengths;
+    var segment;
+    var shapes = [];
+    var initPos;
+    var newShape = true;
+    if(!shapePath){
+        shapePath = shape_pool.newShape();
+        segmentCount = 0;
+        initPos = 0;
+    } else {
+        segmentCount = shapePath._length;
+        initPos = shapePath._length;
+    }
+    shapes.push(shapePath);
+    for(i=0;i<len;i+=1){
+        lengths = pathsData[i].lengths;
+        shapePath.c = shapePaths[i].c;
+        jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+        for(j=1;j<jLen;j+=1){
+            currentLengthData = lengths[j-1];
+            if(addedLength + currentLengthData.addedLength < shapeSegment.s){
+                addedLength += currentLengthData.addedLength;
+                shapePath.c = false;
+            } else if(addedLength > shapeSegment.e){
+                shapePath.c = false;
+                break;
+            } else {
+                if(shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength){
+                    this.addSegment(shapePaths[i].v[j-1],shapePaths[i].o[j-1],shapePaths[i].i[j],shapePaths[i].v[j],shapePath,segmentCount,newShape);
+                    newShape = false;
+                } else {
+                    segment = bez.getNewSegment(shapePaths[i].v[j-1],shapePaths[i].v[j],shapePaths[i].o[j-1],shapePaths[i].i[j], (shapeSegment.s - addedLength)/currentLengthData.addedLength,(shapeSegment.e - addedLength)/currentLengthData.addedLength, lengths[j-1]);
+                    this.addSegment(segment.pt1,segment.pt3,segment.pt4,segment.pt2,shapePath,segmentCount,newShape);
+                    newShape = false;
+                    shapePath.c = false;
+                }
+                addedLength += currentLengthData.addedLength;
+                segmentCount += 1;
+            }
+        }
+        if(shapePaths[i].c){
+            currentLengthData = lengths[j-1];
+            if(addedLength <= shapeSegment.e){
+                var segmentLength = lengths[j-1].addedLength;
+                if(shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength){
+                    this.addSegment(shapePaths[i].v[j-1],shapePaths[i].o[j-1],shapePaths[i].i[0],shapePaths[i].v[0],shapePath,segmentCount,newShape);
+                    newShape = false;
+                }else{
+                    segment = bez.getNewSegment(shapePaths[i].v[j-1],shapePaths[i].v[0],shapePaths[i].o[j-1],shapePaths[i].i[0], (shapeSegment.s - addedLength)/segmentLength,(shapeSegment.e - addedLength)/segmentLength, lengths[j-1]);
+                    this.addSegment(segment.pt1,segment.pt3,segment.pt4,segment.pt2,shapePath,segmentCount,newShape);
+                    newShape = false;
+                    shapePath.c = false;
+                }
+            } else {
+                shapePath.c = false;
+            }
+            addedLength += currentLengthData.addedLength;
+            segmentCount += 1;
+        }
+        if(shapePath._length){
+            shapePath.setXYAt(shapePath.v[initPos][0],shapePath.v[initPos][1],'i',initPos);
+            shapePath.setXYAt(shapePath.v[shapePath._length - 1][0],shapePath.v[shapePath._length - 1][1],'o',shapePath._length - 1);
+        }
+        if(addedLength > shapeSegment.e){
+            break;
+        }
+        if(i<len-1){
+            shapePath = shape_pool.newShape();
+            newShape = true;
+            shapes.push(shapePath);
+            segmentCount = 0;
+        }
+    }
+    return shapes;
+
+}
+
+
+ShapeModifiers.registerModifier('tm',TrimModifier);
+function RoundCornersModifier(){};
+extendPrototype(ShapeModifier,RoundCornersModifier);
+RoundCornersModifier.prototype.processKeys = function(forceRender){
+    if(this.elem.globalData.frameId === this.frameId && !forceRender){
+        return;
+    }
+    this.mdf = forceRender ? true : false;
+    this.frameId = this.elem.globalData.frameId;
+    var i, len = this.dynamicProperties.length;
+
+    for(i=0;i<len;i+=1){
+        this.dynamicProperties[i].getValue();
+        if(this.dynamicProperties[i].mdf){
+            this.mdf = true;
+        }
+    }
+}
+RoundCornersModifier.prototype.initModifierProperties = function(elem,data){
+    this.getValue = this.processKeys;
+    this.rd = PropertyFactory.getProp(elem,data.r,0,null,this.dynamicProperties);
+    if(!this.dynamicProperties.length){
+        this.getValue(true);
+    }
+};
+
+RoundCornersModifier.prototype.processPath = function(path, round){
+    var cloned_path = shape_pool.newShape();
+    cloned_path.c = path.c;
+    var i, len = path._length;
+    var currentV,currentI,currentO,closerV, newV,newO,newI,distance,newPosPerc,index = 0;
+    var vX,vY,oX,oY,iX,iY;
+    for(i=0;i<len;i+=1){
+        currentV = path.v[i];
+        currentO = path.o[i];
+        currentI = path.i[i];
+        if(currentV[0]===currentO[0] && currentV[1]===currentO[1] && currentV[0]===currentI[0] && currentV[1]===currentI[1]){
+            if((i===0 || i === len - 1) && !path.c){
+                cloned_path.setTripleAt(currentV[0],currentV[1],currentO[0],currentO[1],currentI[0],currentI[1],index);
+                /*cloned_path.v[index] = currentV;
+                cloned_path.o[index] = currentO;
+                cloned_path.i[index] = currentI;*/
+                index += 1;
+            } else {
+                if(i===0){
+                    closerV = path.v[len-1];
+                } else {
+                    closerV = path.v[i-1];
+                }
+                distance = Math.sqrt(Math.pow(currentV[0]-closerV[0],2)+Math.pow(currentV[1]-closerV[1],2));
+                newPosPerc = distance ? Math.min(distance/2,round)/distance : 0;
+                vX = iX = currentV[0]+(closerV[0]-currentV[0])*newPosPerc;
+                vY = iY = currentV[1]-(currentV[1]-closerV[1])*newPosPerc;
+                oX = vX-(vX-currentV[0])*roundCorner;
+                oY = vY-(vY-currentV[1])*roundCorner;
+                cloned_path.setTripleAt(vX,vY,oX,oY,iX,iY,index);
+                /*newV = [currentV[0]+(closerV[0]-currentV[0])*newPosPerc,currentV[1]-(currentV[1]-closerV[1])*newPosPerc];
+                newI = newV;
+                newO = [newV[0]-(newV[0]-currentV[0])*roundCorner,newV[1]-(newV[1]-currentV[1])*roundCorner];
+                cloned_path.v[index] = newV;
+                cloned_path.i[index] = newI;
+                cloned_path.o[index] = newO;*/
+                index += 1;
+
+                if(i === len - 1){
+                    closerV = path.v[0];
+                } else {
+                    closerV = path.v[i+1];
+                }
+                distance = Math.sqrt(Math.pow(currentV[0]-closerV[0],2)+Math.pow(currentV[1]-closerV[1],2));
+                newPosPerc = distance ? Math.min(distance/2,round)/distance : 0;
+                vX = oX = currentV[0]+(closerV[0]-currentV[0])*newPosPerc;
+                vY = oY = currentV[1]+(closerV[1]-currentV[1])*newPosPerc;
+                iX = vX-(vX-currentV[0])*roundCorner;
+                iY = vY-(vY-currentV[1])*roundCorner;
+                cloned_path.setTripleAt(vX,vY,oX,oY,iX,iY,index);
+
+                /*newV = [currentV[0]+(closerV[0]-currentV[0])*newPosPerc,currentV[1]+(closerV[1]-currentV[1])*newPosPerc];
+                newI = [newV[0]-(newV[0]-currentV[0])*roundCorner,newV[1]-(newV[1]-currentV[1])*roundCorner];
+                newO = newV;
+                cloned_path.v[index] = newV;
+                cloned_path.i[index] = newI;
+                cloned_path.o[index] = newO;*/
+                index += 1;
+            }
+        } else {
+            /*cloned_path.v[index] = path.v[i];
+            cloned_path.o[index] = path.o[i];
+            cloned_path.i[index] = path.i[i];*/
+            cloned_path.setTripleAt(path.v[i][0],path.v[i][1],path.o[i][0],path.o[i][1],path.i[i][0],path.i[i][1],index);
+            index += 1;
+        }
+    }
+    return cloned_path;
+}
+
+RoundCornersModifier.prototype.processShapes = function(firstFrame){
+    var shapePaths;
+    var i, len = this.shapes.length;
+    var j, jLen;
+    var rd = this.rd.v;
+
+    if(rd !== 0){
+        var shapeData, newPaths, localShapeCollection;
+        for(i=0;i<len;i+=1){
+            shapeData = this.shapes[i];
+            newPaths = shapeData.shape.paths;
+            localShapeCollection = shapeData.localShapeCollection;
+            if(!(!shapeData.shape.mdf && !this.mdf && !firstFrame)){
+                localShapeCollection.releaseShapes();
+                shapeData.shape.mdf = true;
+                shapePaths = shapeData.shape.paths.shapes;
+                jLen = shapeData.shape.paths._length;
+                for(j=0;j<jLen;j+=1){
+                    localShapeCollection.addShape(this.processPath(shapePaths[j],rd));
+                }
+            }
+            shapeData.shape.paths = shapeData.localShapeCollection;
+        }
+
+    }
+    if(!this.dynamicProperties.length){
+        this.mdf = false;
+    }
+}
+
+
+ShapeModifiers.registerModifier('rd',RoundCornersModifier);
+function RepeaterModifier(){};
+extendPrototype(ShapeModifier,RepeaterModifier);
+RepeaterModifier.prototype.processKeys = function(forceRender){
+    if(this.elem.globalData.frameId === this.frameId && !forceRender){
+        return;
+    }
+    this.mdf = forceRender ? true : false;
+    this.frameId = this.elem.globalData.frameId;
+    var i, len = this.dynamicProperties.length;
+
+    for(i=0;i<len;i+=1){
+        this.dynamicProperties[i].getValue();
+        if(this.dynamicProperties[i].mdf){
+            this.mdf = true;
+        }
+    }
+};
+RepeaterModifier.prototype.initModifierProperties = function(elem,data){
+    this.getValue = this.processKeys;
+    this.c = PropertyFactory.getProp(elem,data.c,0,null,this.dynamicProperties);
+    this.o = PropertyFactory.getProp(elem,data.o,0,null,this.dynamicProperties);
+    this.tr = PropertyFactory.getProp(elem,data.tr,2,null,this.dynamicProperties);
+    if(!this.dynamicProperties.length){
+        this.getValue(true);
+    }
+    this.pMatrix = new Matrix();
+    this.rMatrix = new Matrix();
+    this.sMatrix = new Matrix();
+    this.tMatrix = new Matrix();
+    this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function(pMatrix, rMatrix, sMatrix, transform, perc, inv){
+    var dir = inv ? -1 : 1;
+    var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+    var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+    pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+    rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+    rMatrix.rotate(-transform.r.v * dir * perc);
+    rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+    sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+    sMatrix.scale(inv ? 1/scaleX : scaleX, inv ? 1/scaleY : scaleY);
+    sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+}
+
+RepeaterModifier.prototype.processShapes = function(firstFrame){
+    if(!this.dynamicProperties.length){
+        this.mdf = false;
+    }
+    var i, len = this.shapes.length;
+    var j, jLen;
+    var shapeData, localShapeCollection, currentPath;
+    var copies = Math.ceil(this.c.v);
+    var offset = this.o.v;
+    var offsetModulo = offset%1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var k, pathData, shapeCollection, shapeCollectionList;
+    var tMat = this.tr.v.props;
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    var iteration = 0;
+    var l, lLen, tProps,transformers, maxLvl;
+    for(i=0;i<len;i+=1){
+        shapeData = this.shapes[i];
+        localShapeCollection = shapeData.localShapeCollection;
+        if(!(!shapeData.shape.mdf && !this.mdf && !firstFrame)){
+            localShapeCollection.releaseShapes();
+            shapeData.shape.mdf = true;
+            shapeCollection = shapeData.shape.paths;
+            shapeCollectionList = shapeCollection.shapes;
+            jLen = shapeCollection._length;
+            iteration = 0;
+            this.pMatrix.reset();
+            this.rMatrix.reset();
+            this.sMatrix.reset();
+            this.tMatrix.reset();
+            this.matrix.reset();
+
+            if(offset > 0) {
+                while(iteration<roundOffset){
+                    this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+                    iteration += 1;
+                }
+                if(offsetModulo){
+                    this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+                    iteration += offsetModulo;
+                }
+            } else if(roundOffset < 0) {
+                while(iteration>roundOffset){
+                    this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+                    iteration -= 1;
+                }
+                if(offsetModulo){
+                    this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, - offsetModulo, true);
+                    iteration -= offsetModulo;
+                }
+            }
+            for(j=0;j<jLen;j+=1){
+                currentPath = shapeCollectionList[j];
+                for(k=0;k<copies;k+=1) {
+                    if(k !== 0) {
+                        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+                    }
+                    if(shapeData.data.transformers) {
+                        shapeData.data.lvl = 0;
+                        maxLvl = 0;
+                        lLen = shapeData.data.elements.length;
+                        for(l = 0; l < lLen; l += 1) {
+                            maxLvl = Math.max(maxLvl, shapeData.data.elements[l].st.lvl);
+                        } 
+                        transformers = shapeData.data.transformers;
+                        lLen = transformers.length;
+                        for(l = lLen - 1; l >= maxLvl; l -= 1) {
+                            tProps = transformers[l].mProps.v.props;
+                            this.matrix.transform(tProps[0],tProps[1],tProps[2],tProps[3],tProps[4],tProps[5],tProps[6],tProps[7],tProps[8],tProps[9],tProps[10],tProps[11],tProps[12],tProps[13],tProps[14],tProps[15]);
+                        }
+                    }
+                    if(iteration !== 0){
+                        this.matrix.transform(rProps[0],rProps[1],rProps[2],rProps[3],rProps[4],rProps[5],rProps[6],rProps[7],rProps[8],rProps[9],rProps[10],rProps[11],rProps[12],rProps[13],rProps[14],rProps[15]);
+                        this.matrix.transform(sProps[0],sProps[1],sProps[2],sProps[3],sProps[4],sProps[5],sProps[6],sProps[7],sProps[8],sProps[9],sProps[10],sProps[11],sProps[12],sProps[13],sProps[14],sProps[15]);
+                        this.matrix.transform(pProps[0],pProps[1],pProps[2],pProps[3],pProps[4],pProps[5],pProps[6],pProps[7],pProps[8],pProps[9],pProps[10],pProps[11],pProps[12],pProps[13],pProps[14],pProps[15]);
+                    }
+                    localShapeCollection.addShape(this.processPath(currentPath, this.matrix));
+                    this.matrix.reset();
+                    iteration += 1;
+                }
+            }
+        }
+        shapeData.shape.paths = localShapeCollection;
+    }
+};
+
+RepeaterModifier.prototype.processPath = function(path, transform) {
+    var clonedPath = shape_pool.clone(path, transform);
+    return clonedPath;
+};
+
+
+ShapeModifiers.registerModifier('rp',RepeaterModifier);
+function ShapeCollection(){
+	this._length = 0;
+	this._maxLength = 4;
+	this.shapes = Array.apply(null,{length:this._maxLength});
+};
+
+ShapeCollection.prototype.addShape = function(shapeData){
+	if(this._length === this._maxLength){
+		this.shapes = this.shapes.concat(Array.apply(null,{length:this._maxLength}));
+		this._maxLength *= 2;
+	}
+	this.shapes[this._length] = shapeData;
+	this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function(){
+	var i;
+	for(i = 0; i < this._length; i += 1) {
+		shape_pool.release(this.shapes[i]);
+	}
+	this._length = 0;
+};
+var ImagePreloader = (function(){
+
+    function imageLoaded(){
+        this.loadedAssets += 1;
+        if(this.loadedAssets === this.totalImages){
+        }
+    }
+
+    function getAssetsPath(assetData){
+        var path = '';
+        if(this.assetsPath){
+            var imagePath = assetData.p;
+            if(imagePath.indexOf('images/') !== -1){
+                imagePath = imagePath.split('/')[1];
+            }
+            path = this.assetsPath + imagePath;
+        } else {
+            path = this.path;
+            path += assetData.u ? assetData.u : '';
+            path += assetData.p;
+        }
+        return path;
+    }
+
+    function loadImage(path){
+        var img = document.createElement('img');
+        img.addEventListener('load', imageLoaded.bind(this), false);
+        img.addEventListener('error', imageLoaded.bind(this), false);
+        img.src = path;
+    }
+    function loadAssets(assets){
+        this.totalAssets = assets.length;
+        var i;
+        for(i=0;i<this.totalAssets;i+=1){
+            if(!assets[i].layers){
+                loadImage.bind(this)(getAssetsPath.bind(this)(assets[i]));
+                this.totalImages += 1;
+            }
+        }
+    }
+
+    function setPath(path){
+        this.path = path || '';
+    }
+
+    function setAssetsPath(path){
+        this.assetsPath = path || '';
+    }
+
+    return function ImagePreloader(){
+        this.loadAssets = loadAssets;
+        this.setAssetsPath = setAssetsPath;
+        this.setPath = setPath;
+        this.assetsPath = '';
+        this.path = '';
+        this.totalAssets = 0;
+        this.totalImages = 0;
+        this.loadedAssets = 0;
+    }
+}());
+var featureSupport = (function(){
+	var ob = {
+		maskType: true
+	}
+	if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+	   ob.maskType = false;
+	}
+	return ob;
+}());
+var filtersFactory = (function(){
+	var ob = {};
+	ob.createFilter = createFilter;
+	ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+	function createFilter(filId){
+        	var fil = document.createElementNS(svgNS,'filter');
+        	fil.setAttribute('id',filId);
+                fil.setAttribute('filterUnits','objectBoundingBox');
+                fil.setAttribute('x','0%');
+                fil.setAttribute('y','0%');
+                fil.setAttribute('width','100%');
+                fil.setAttribute('height','100%');
+                return fil;
+	}
+
+	function createAlphaToLuminanceFilter(){
+                var feColorMatrix = document.createElementNS(svgNS,'feColorMatrix');
+                feColorMatrix.setAttribute('type','matrix');
+                feColorMatrix.setAttribute('color-interpolation-filters','sRGB');
+                feColorMatrix.setAttribute('values','0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 0 1');
+                return feColorMatrix;
+	}
+
+	return ob;
+}())
+var pooling = (function(){
+
+	function double(arr){
+		return arr.concat(Array.apply(null,{length:arr.length}))
+	}
+
+	return {
+		double: double
+	}
+}());
+var point_pool = (function(){
+	var ob = {
+		newPoint: newPoint,
+		release: release
+		/*,getLength:function(){return _length}
+		,getCont:function(){return cont}*/
+	}
+
+	var _length = 0;
+	var _maxLength = 8;
+	var pool = Array.apply(null,{length:_maxLength});
+
+	//var cont = 0;
+
+	function newPoint(){
+		//window.bm_newPoint = window.bm_newPoint ? window.bm_newPoint + 1 : 1;
+		var point;
+		if(_length){
+			_length -= 1;
+			point = pool[_length];
+			//window.bm_reuse = window.bm_reuse ? window.bm_reuse + 1 : 1;
+		} else {
+			point = [0.1,0.1];
+			//cont++;
+			//console.log('new');
+			//window.bm_new = window.bm_new ? window.bm_new + 1 : 1;
+			//point._tst = cont++;
+		}
+		return point;
+	}
+
+	function release(point) {
+		if(_length === _maxLength) {
+			pool = pooling.double(pool);
+			_maxLength = _maxLength*2;
+		}
+		pool[_length] = point;
+		_length += 1;
+		//window.bm_release = window.bm_release ? window.bm_release + 1 : 1;
+		//console.log('release');
+	}
+
+
+	return ob;
+}());
+var shape_pool = (function(){
+	var ob = {
+		clone: clone,
+		newShape: newShape,
+		release: release,
+		releaseArray: releaseArray
+	}
+
+	var _length = 0;
+	var _maxLength = 4;
+	var pool = Array.apply(null,{length:_maxLength});
+
+	function newShape(){
+		var shapePath;
+		if(_length){
+			_length -= 1;
+			shapePath = pool[_length];
+		} else {
+			shapePath = new ShapePath();
+		}
+		return shapePath;
+	}
+
+	function release(shapePath) {
+		if(_length === _maxLength) {
+			pool = pooling.double(pool);
+			_maxLength = _maxLength*2;
+		}
+		var len = shapePath._length, i;
+		for(i = 0; i < len; i += 1) {
+			point_pool.release(shapePath.v[i]);
+			point_pool.release(shapePath.i[i]);
+			point_pool.release(shapePath.o[i]);
+			shapePath.v[i] = null;
+			shapePath.i[i] = null;
+			shapePath.o[i] = null;
+		}
+		shapePath._length = 0;
+		shapePath.c = false;
+		pool[_length] = shapePath;
+		_length += 1;
+	}
+
+	function releaseArray(shapePathsCollection, length) {
+		while(length--) {
+			release(shapePathsCollection[length]);
+		}
+	}
+
+	function clone(shape, transform) {
+		var i, len = shape._length;
+		var cloned = newShape();
+		cloned._length = shape._length;
+		cloned.c = shape.c;
+
+		var pt;
+		
+		for(i = 0; i < len; i += 1) {
+			if(transform){
+				pt = transform.applyToPointArray(shape.v[i][0],shape.v[i][1],0,2);
+				cloned.setXYAt(pt[0],pt[1],'v',i);
+				point_pool.release(pt);
+				pt = transform.applyToPointArray(shape.o[i][0],shape.o[i][1],0,2);
+				cloned.setXYAt(pt[0],pt[1],'o',i);
+				point_pool.release(pt);
+				pt = transform.applyToPointArray(shape.i[i][0],shape.i[i][1],0,2);
+				cloned.setXYAt(pt[0],pt[1],'i',i);
+				point_pool.release(pt);
+			}else{
+				cloned.setTripleAt(shape.v[i][0],shape.v[i][1],shape.o[i][0],shape.o[i][1],shape.i[i][0],shape.i[i][1], i);
+			}
+		}
+		return cloned
+	}
+
+
+	return ob;
+}());
+var shapeCollection_pool = (function(){
+	var ob = {
+		newShapeCollection: newShapeCollection,
+		release: release,
+		clone: clone
+	}
+
+	var _length = 0;
+	var _maxLength = 4;
+	var pool = Array.apply(null,{length:_maxLength});
+
+	var cont = 0;
+
+	function newShapeCollection(){
+		var shapeCollection;
+		if(_length){
+			_length -= 1;
+			shapeCollection = pool[_length];
+		} else {
+			shapeCollection = new ShapeCollection();
+		}
+		return shapeCollection;
+	}
+
+	function release(shapeCollection) {
+		var i, len = shapeCollection._length;
+		for(i = 0; i < len; i += 1) {
+			shape_pool.release(shapeCollection.shapes[i]);
+		}
+		shapeCollection._length = 0;
+
+		if(_length === _maxLength) {
+			pool = pooling.double(pool);
+			_maxLength = _maxLength*2;
+		}
+		pool[_length] = shapeCollection;
+		_length += 1;
+	}
+
+	function clone(shapeCollection, originCollection) {
+		release(shapeCollection);
+		if(_length === _maxLength) {
+			pool = pooling.double(pool);
+			_maxLength = _maxLength*2;
+		}
+		pool[_length] = shapeCollection;
+		_length += 1;
+	}
+
+
+	return ob;
+}());
+function BaseRenderer(){}
+BaseRenderer.prototype.checkLayers = function(num){
+    var i, len = this.layers.length, data;
+    this.completeLayers = true;
+    for (i = len - 1; i >= 0; i--) {
+        if (!this.elements[i]) {
+            data = this.layers[i];
+            if(data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st))
+            {
+                this.buildItem(i);
+            }
+        }
+        this.completeLayers = this.elements[i] ? this.completeLayers:false;
+    }
+    this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function(layer){
+    switch(layer.ty){
+        case 2:
+            return this.createImage(layer);
+        case 0:
+            return this.createComp(layer);
+        case 1:
+            return this.createSolid(layer);
+        case 4:
+            return this.createShape(layer);
+        case 5:
+            return this.createText(layer);
+        case 13:
+            return this.createCamera(layer);
+        case 99:
+            return null;
+    }
+    return this.createBase(layer);
+};
+
+BaseRenderer.prototype.createCamera = function(){
+    throw new Error('You\'re using a 3d camera. Try the html renderer.');
+}
+
+BaseRenderer.prototype.buildAllItems = function(){
+    var i, len = this.layers.length;
+    for(i=0;i<len;i+=1){
+        this.buildItem(i);
+    }
+    this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function(newLayers){
+    this.completeLayers = false;
+    var i, len = newLayers.length;
+    var j, jLen = this.layers.length;
+    for(i=0;i<len;i+=1){
+        j = 0;
+        while(j<jLen){
+            if(this.layers[j].id == newLayers[i].id){
+                this.layers[j] = newLayers[i];
+                break;
+            }
+            j += 1;
+        }
+    }
+};
+
+BaseRenderer.prototype.setProjectInterface = function(pInterface){
+    this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function(){
+    if(!this.globalData.progressiveLoad){
+        this.buildAllItems();
+    }
+};
+BaseRenderer.prototype.buildElementParenting = function(element, parentName, hierarchy){
+    hierarchy = hierarchy || [];
+    var elements = this.elements;
+    var layers = this.layers;
+    var i=0, len = layers.length;
+    while(i<len){
+        if(layers[i].ind == parentName){
+            if(!elements[i] || elements[i] === true){
+                this.buildItem(i);
+                this.addPendingElement(element);
+            } else if(layers[i].parent !== undefined){
+                hierarchy.push(elements[i]);
+                elements[i]._isParent = true;
+                this.buildElementParenting(element,layers[i].parent, hierarchy);
+            } else {
+                hierarchy.push(elements[i]);
+                elements[i]._isParent = true;
+                element.setHierarchy(hierarchy);
+            }
+
+
+        }
+        i += 1;
+    }
+};
+
+BaseRenderer.prototype.addPendingElement = function(element){
+    this.pendingElements.push(element);
+};
+function SVGRenderer(animationItem, config){
+    this.animationItem = animationItem;
+    this.layers = null;
+    this.renderedFrame = -1;
+    this.globalData = {
+        frameNum: -1
+    };
+    this.renderConfig = {
+        preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+        progressiveLoad: (config && config.progressiveLoad) || false
+    };
+    this.elements = [];
+    this.pendingElements = [];
+    this.destroyed = false;
+
+}
+
+extendPrototype(BaseRenderer,SVGRenderer);
+
+SVGRenderer.prototype.createBase = function (data) {
+    return new SVGBaseElement(data, this.layerElement,this.globalData,this);
+};
+
+SVGRenderer.prototype.createShape = function (data) {
+    return new IShapeElement(data, this.layerElement,this.globalData,this);
+};
+
+SVGRenderer.prototype.createText = function (data) {
+    return new SVGTextElement(data, this.layerElement,this.globalData,this);
+
+};
+
+SVGRenderer.prototype.createImage = function (data) {
+    return new IImageElement(data, this.layerElement,this.globalData,this);
+};
+
+SVGRenderer.prototype.createComp = function (data) {
+    return new ICompElement(data, this.layerElement,this.globalData,this);
+
+};
+
+SVGRenderer.prototype.createSolid = function (data) {
+    return new ISolidElement(data, this.layerElement,this.globalData,this);
+};
+
+SVGRenderer.prototype.configAnimation = function(animData){
+    this.layerElement = document.createElementNS(svgNS,'svg');
+    this.layerElement.setAttribute('xmlns','http://www.w3.org/2000/svg');
+    this.layerElement.setAttribute('width',animData.w);
+    this.layerElement.setAttribute('height',animData.h);
+    this.layerElement.setAttribute('viewBox','0 0 '+animData.w+' '+animData.h);
+    this.layerElement.setAttribute('preserveAspectRatio',this.renderConfig.preserveAspectRatio);
+    this.layerElement.style.width = '100%';
+    this.layerElement.style.height = '100%';
+    //this.layerElement.style.transform = 'translate3d(0,0,0)';
+    //this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+    this.animationItem.wrapper.appendChild(this.layerElement);
+    //Mask animation
+    var defs = document.createElementNS(svgNS, 'defs');
+    this.globalData.defs = defs;
+    this.layerElement.appendChild(defs);
+    this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+    this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+    this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+    this.globalData.frameId = 0;
+    this.globalData.nm = animData.nm;
+    this.globalData.compSize = {
+        w: animData.w,
+        h: animData.h
+    };
+    this.data = animData;
+    this.globalData.frameRate = animData.fr;
+    var maskElement = document.createElementNS(svgNS, 'clipPath');
+    var rect = document.createElementNS(svgNS,'rect');
+    rect.setAttribute('width',animData.w);
+    rect.setAttribute('height',animData.h);
+    rect.setAttribute('x',0);
+    rect.setAttribute('y',0);
+    var maskId = 'animationMask_'+randomString(10);
+    maskElement.setAttribute('id', maskId);
+    maskElement.appendChild(rect);
+    var maskedElement = document.createElementNS(svgNS,'g');
+    maskedElement.setAttribute("clip-path", "url(#"+maskId+")");
+    this.layerElement.appendChild(maskedElement);
+    defs.appendChild(maskElement);
+    this.layerElement = maskedElement;
+    this.layers = animData.layers;
+    this.globalData.fontManager = new FontManager();
+    this.globalData.fontManager.addChars(animData.chars);
+    this.globalData.fontManager.addFonts(animData.fonts,defs);
+    this.elements = Array.apply(null,{length:animData.layers.length});
+};
+
+
+SVGRenderer.prototype.destroy = function () {
+    this.animationItem.wrapper.innerHTML = '';
+    this.layerElement = null;
+    this.globalData.defs = null;
+    var i, len = this.layers ? this.layers.length : 0;
+    for (i = 0; i < len; i++) {
+        if(this.elements[i]){
+            this.elements[i].destroy();
+        }
+    }
+    this.elements.length = 0;
+    this.destroyed = true;
+    this.animationItem = null;
+};
+
+SVGRenderer.prototype.updateContainerSize = function () {
+};
+
+SVGRenderer.prototype.buildItem  = function(pos){
+    var elements = this.elements;
+    if(elements[pos] || this.layers[pos].ty == 99){
+        return;
+    }
+    elements[pos] = true;
+    var element = this.createItem(this.layers[pos]);
+
+    elements[pos] = element;
+    if(expressionsPlugin){
+        if(this.layers[pos].ty === 0){
+            this.globalData.projectInterface.registerComposition(element);
+        }
+        element.initExpressions();
+    }
+    this.appendElementInPos(element,pos);
+    if(this.layers[pos].tt){
+        if(!this.elements[pos - 1] || this.elements[pos - 1] === true){
+            this.buildItem(pos - 1);
+            this.addPendingElement(element);
+        } else {
+            element.setMatte(elements[pos - 1].layerId);
+        }
+    }
+};
+
+SVGRenderer.prototype.checkPendingElements  = function(){
+    while(this.pendingElements.length){
+        var element = this.pendingElements.pop();
+        element.checkParenting();
+        if(element.data.tt){
+            var i = 0, len = this.elements.length;
+            while(i<len){
+                if(this.elements[i] === element){
+                    element.setMatte(this.elements[i - 1].layerId);
+                    break;
+                }
+                i += 1;
+            }
+        }
+    }
+};
+
+SVGRenderer.prototype.renderFrame = function(num){
+    if(this.renderedFrame == num || this.destroyed){
+        return;
+    }
+    if(num === null){
+        num = this.renderedFrame;
+    }else{
+        this.renderedFrame = num;
+    }
+    //clearPoints();
+    /*console.log('-------');
+    console.log('FRAME ',num);*/
+    this.globalData.frameNum = num;
+    this.globalData.frameId += 1;
+    this.globalData.projectInterface.currentFrame = num;
+    var i, len = this.layers.length;
+    if(!this.completeLayers){
+        this.checkLayers(num);
+    }
+    for (i = len - 1; i >= 0; i--) {
+        if(this.completeLayers || this.elements[i]){
+            this.elements[i].prepareFrame(num - this.layers[i].st);
+        }
+    }
+    for (i = len - 1; i >= 0; i--) {
+        if(this.completeLayers || this.elements[i]){
+            this.elements[i].renderFrame();
+        }
+    }
+};
+
+SVGRenderer.prototype.appendElementInPos = function(element, pos){
+    var newElement = element.getBaseElement();
+    if(!newElement){
+        return;
+    }
+    var i = 0;
+    var nextElement;
+    while(i<pos){
+        if(this.elements[i] && this.elements[i]!== true && this.elements[i].getBaseElement()){
+            nextElement = this.elements[i].getBaseElement();
+        }
+        i += 1;
+    }
+    if(nextElement){
+        this.layerElement.insertBefore(newElement, nextElement);
+    } else {
+        this.layerElement.appendChild(newElement);
+    }
+};
+
+SVGRenderer.prototype.hide = function(){
+    this.layerElement.style.display = 'none';
+};
+
+SVGRenderer.prototype.show = function(){
+    this.layerElement.style.display = 'block';
+};
+
+SVGRenderer.prototype.searchExtraCompositions = function(assets){
+    var i, len = assets.length;
+    var floatingContainer = document.createElementNS(svgNS,'g');
+    for(i=0;i<len;i+=1){
+        if(assets[i].xt){
+            var comp = this.createComp(assets[i],floatingContainer,this.globalData.comp,null);
+            comp.initExpressions();
+            //comp.compInterface = CompExpressionInterface(comp);
+            //Expressions.addLayersInterface(comp.elements, this.globalData.projectInterface);
+            this.globalData.projectInterface.registerComposition(comp);
+        }
+    }
+};
+
+function MaskElement(data,element,globalData) {
+    this.dynamicProperties = [];
+    this.data = data;
+    this.element = element;
+    this.globalData = globalData;
+    this.paths = [];
+    this.storedData = [];
+    this.masksProperties = this.data.masksProperties;
+    this.viewData = new Array(this.masksProperties.length);
+    this.maskElement = null;
+    this.firstFrame = true;
+    var defs = this.globalData.defs;
+    var i, len = this.masksProperties.length;
+
+
+    var path, properties = this.masksProperties;
+    var count = 0;
+    var currentMasks = [];
+    var j, jLen;
+    var layerId = randomString(10);
+    var rect, expansor, feMorph,x;
+    var maskType = 'clipPath', maskRef = 'clip-path';
+    for (i = 0; i < len; i++) {
+
+        if((properties[i].mode !== 'a' && properties[i].mode !== 'n')|| properties[i].inv || properties[i].o.k !== 100){
+            maskType = 'mask';
+            maskRef = 'mask';
+        }
+
+        if((properties[i].mode == 's' || properties[i].mode == 'i') && count == 0){
+            rect = document.createElementNS(svgNS, 'rect');
+            rect.setAttribute('fill', '#ffffff');
+            rect.setAttribute('width', this.element.comp.data.w);
+            rect.setAttribute('height', this.element.comp.data.h);
+            currentMasks.push(rect);
+        } else {
+            rect = null;
+        }
+
+        path = document.createElementNS(svgNS, 'path');
+        if(properties[i].mode == 'n') {
+            this.viewData[i] = {
+                op: PropertyFactory.getProp(this.element,properties[i].o,0,0.01,this.dynamicProperties),
+                prop: ShapePropertyFactory.getShapeProp(this.element,properties[i],3,this.dynamicProperties,null),
+                elem: path
+            };
+            defs.appendChild(path);
+            continue;
+        }
+        count += 1;
+
+        if(properties[i].mode == 's'){
+            path.setAttribute('fill', '#000000');
+        }else{
+            path.setAttribute('fill', '#ffffff');
+        }
+        path.setAttribute('clip-rule','nonzero');
+
+        if(properties[i].x.k !== 0){
+            maskType = 'mask';
+            maskRef = 'mask';
+            x = PropertyFactory.getProp(this.element,properties[i].x,0,null,this.dynamicProperties);
+            var filterID = 'fi_'+randomString(10);
+            expansor = document.createElementNS(svgNS,'filter');
+            expansor.setAttribute('id',filterID);
+            feMorph = document.createElementNS(svgNS,'feMorphology');
+            feMorph.setAttribute('operator','dilate');
+            feMorph.setAttribute('in','SourceGraphic');
+            feMorph.setAttribute('radius','0');
+            expansor.appendChild(feMorph);
+            defs.appendChild(expansor);
+            if(properties[i].mode == 's'){
+                path.setAttribute('stroke', '#000000');
+            }else{
+                path.setAttribute('stroke', '#ffffff');
+            }
+        }else{
+            feMorph = null;
+            x = null;
+        }
+
+
+        this.storedData[i] = {
+             elem: path,
+             x: x,
+             expan: feMorph,
+            lastPath: '',
+            lastOperator:'',
+            filterId:filterID,
+            lastRadius:0
+        };
+        if(properties[i].mode == 'i'){
+            jLen = currentMasks.length;
+            var g = document.createElementNS(svgNS,'g');
+            for(j=0;j<jLen;j+=1){
+                g.appendChild(currentMasks[j]);
+            }
+            var mask = document.createElementNS(svgNS,'mask');
+            mask.setAttribute('mask-type','alpha');
+            mask.setAttribute('id',layerId+'_'+count);
+            mask.appendChild(path);
+            defs.appendChild(mask);
+            g.setAttribute('mask','url(#'+layerId+'_'+count+')');
+
+            currentMasks.length = 0;
+            currentMasks.push(g);
+        }else{
+            currentMasks.push(path);
+        }
+        if(properties[i].inv && !this.solidPath){
+            this.solidPath = this.createLayerSolidPath();
+        }
+        this.viewData[i] = {
+            elem: path,
+            lastPath: '',
+            op: PropertyFactory.getProp(this.element,properties[i].o,0,0.01,this.dynamicProperties),
+            prop:ShapePropertyFactory.getShapeProp(this.element,properties[i],3,this.dynamicProperties,null)
+        };
+        if(rect){
+            this.viewData[i].invRect = rect;
+        }
+        if(!this.viewData[i].prop.k){
+            this.drawPath(properties[i],this.viewData[i].prop.v,this.viewData[i]);
+        }
+    }
+
+    this.maskElement = document.createElementNS(svgNS, maskType);
+
+    len = currentMasks.length;
+    for(i=0;i<len;i+=1){
+        this.maskElement.appendChild(currentMasks[i]);
+    }
+
+    this.maskElement.setAttribute('id', layerId);
+    if(count > 0){
+        this.element.maskedElement.setAttribute(maskRef, "url(#" + layerId + ")");
+    }
+
+    defs.appendChild(this.maskElement);
+};
+
+MaskElement.prototype.getMaskProperty = function(pos){
+    return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.prepareFrame = function(){
+    var i, len = this.dynamicProperties.length;
+    for(i=0;i<len;i+=1){
+        this.dynamicProperties[i].getValue();
+
+    }
+};
+
+MaskElement.prototype.renderFrame = function (finalMat) {
+    var i, len = this.masksProperties.length;
+    for (i = 0; i < len; i++) {
+        if(this.viewData[i].prop.mdf || this.firstFrame){
+            this.drawPath(this.masksProperties[i],this.viewData[i].prop.v,this.viewData[i]);
+        }
+        if(this.viewData[i].op.mdf || this.firstFrame){
+            this.viewData[i].elem.setAttribute('fill-opacity',this.viewData[i].op.v);
+        }
+        if(this.masksProperties[i].mode !== 'n'){
+            if(this.viewData[i].invRect && (this.element.finalTransform.mProp.mdf || this.firstFrame)){
+                this.viewData[i].invRect.setAttribute('x', -finalMat.props[12]);
+                this.viewData[i].invRect.setAttribute('y', -finalMat.props[13]);
+            }
+            if(this.storedData[i].x && (this.storedData[i].x.mdf || this.firstFrame)){
+                var feMorph = this.storedData[i].expan;
+                if(this.storedData[i].x.v < 0){
+                    if(this.storedData[i].lastOperator !== 'erode'){
+                        this.storedData[i].lastOperator = 'erode';
+                        this.storedData[i].elem.setAttribute('filter','url(#'+this.storedData[i].filterId+')');
+                    }
+                    feMorph.setAttribute('radius',-this.storedData[i].x.v);
+                }else{
+                    if(this.storedData[i].lastOperator !== 'dilate'){
+                        this.storedData[i].lastOperator = 'dilate';
+                        this.storedData[i].elem.setAttribute('filter',null);
+                    }
+                    this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v*2);
+
+                }
+            }
+        }
+    }
+    this.firstFrame = false;
+};
+
+MaskElement.prototype.getMaskelement = function () {
+    return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function(){
+    var path = 'M0,0 ';
+    path += ' h' + this.globalData.compSize.w ;
+    path += ' v' + this.globalData.compSize.h ;
+    path += ' h-' + this.globalData.compSize.w ;
+    path += ' v-' + this.globalData.compSize.h + ' ';
+    return path;
+};
+
+MaskElement.prototype.drawPath = function(pathData,pathNodes,viewData){
+    var pathString = " M"+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+    var i, len;
+    len = pathNodes._length;
+    for(i=1;i<len;i+=1){
+        //pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+        pathString += " C"+bm_rnd(pathNodes.o[i-1][0])+','+bm_rnd(pathNodes.o[i-1][1]) + " "+bm_rnd(pathNodes.i[i][0])+','+bm_rnd(pathNodes.i[i][1]) + " "+bm_rnd(pathNodes.v[i][0])+','+bm_rnd(pathNodes.v[i][1]);
+    }
+        //pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+    if(pathNodes.c && len > 1){
+        pathString += " C"+bm_rnd(pathNodes.o[i-1][0])+','+bm_rnd(pathNodes.o[i-1][1]) + " "+bm_rnd(pathNodes.i[0][0])+','+bm_rnd(pathNodes.i[0][1]) + " "+bm_rnd(pathNodes.v[0][0])+','+bm_rnd(pathNodes.v[0][1]);
+    }
+    //pathNodes.__renderedString = pathString;
+
+
+    if(viewData.lastPath !== pathString){
+        if(viewData.elem){
+            if(!pathNodes.c){
+                viewData.elem.setAttribute('d','');
+            }else if(pathData.inv){
+                viewData.elem.setAttribute('d',this.solidPath + pathString);
+            }else{
+                viewData.elem.setAttribute('d',pathString);
+            }
+        }
+        viewData.lastPath = pathString;
+    }
+};
+
+MaskElement.prototype.getMask = function(nm){
+    var i = 0, len = this.masksProperties.length;
+    while(i<len){
+        if(this.masksProperties[i].nm === nm){
+            return {
+                maskPath: this.viewData[i].prop.pv
+            }
+        }
+        i += 1;
+    }
+};
+
+MaskElement.prototype.destroy = function(){
+    this.element = null;
+    this.globalData = null;
+    this.maskElement = null;
+    this.data = null;
+    this.paths = null;
+    this.masksProperties = null;
+};
+function BaseElement(){
+};
+BaseElement.prototype.checkMasks = function(){
+    if(!this.data.hasMask){
+        return false;
+    }
+    var i = 0, len = this.data.masksProperties.length;
+    while(i<len) {
+        if((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+            return true;
+        }
+        i += 1;
+    }
+    return false;
+}
+
+BaseElement.prototype.checkParenting = function(){
+    if(this.data.parent !== undefined){
+        this.comp.buildElementParenting(this, this.data.parent);
+    }
+}
+
+BaseElement.prototype.prepareFrame = function(num){
+    if(this.data.ip - this.data.st <= num && this.data.op - this.data.st > num)
+    {
+        if(this.isVisible !== true){
+            this.elemMdf = true;
+            this.globalData.mdf = true;
+            this.isVisible = true;
+            this.firstFrame = true;
+            if(this.data.hasMask){
+                this.maskManager.firstFrame = true;
+            }
+        }
+    }else{
+        if(this.isVisible !== false){
+            this.elemMdf = true;
+            this.globalData.mdf = true;
+            this.isVisible = false;
+        }
+    }
+    var i, len = this.dynamicProperties.length;
+    for(i=0;i<len;i+=1){
+        if(this.isVisible || (this._isParent && this.dynamicProperties[i].type === 'transform')){
+            this.dynamicProperties[i].getValue();
+            if(this.dynamicProperties[i].mdf){
+                this.elemMdf = true;
+                this.globalData.mdf = true;
+            }
+        }
+    }
+    if(this.data.hasMask && this.isVisible){
+        this.maskManager.prepareFrame(num*this.data.sr);
+    }
+    
+    /* TODO check this
+    if(this.data.sy){
+        if(this.data.sy[0].renderedData[num]){
+            if(this.data.sy[0].renderedData[num].c){
+                this.feFlood.setAttribute('flood-color','rgb('+Math.round(this.data.sy[0].renderedData[num].c[0])+','+Math.round(this.data.sy[0].renderedData[num].c[1])+','+Math.round(this.data.sy[0].renderedData[num].c[2])+')');
+            }
+            if(this.data.sy[0].renderedData[num].s){
+                this.feMorph.setAttribute('radius',this.data.sy[0].renderedData[num].s);
+            }
+        }
+    }
+    */
+
+
+    this.currentFrameNum = num*this.data.sr;
+    return this.isVisible;
+};
+
+BaseElement.prototype.globalToLocal = function(pt){
+    var transforms = [];
+    transforms.push(this.finalTransform);
+    var flag = true;
+    var comp = this.comp;
+    while(flag){
+        if(comp.finalTransform){
+            if(comp.data.hasMask){
+                transforms.splice(0,0,comp.finalTransform);
+            }
+            comp = comp.comp;
+        } else {
+            flag = false;
+        }
+    }
+    var i, len = transforms.length,ptNew;
+    for(i=0;i<len;i+=1){
+        ptNew = transforms[i].mat.applyToPointArray(0,0,0);
+        //ptNew = transforms[i].mat.applyToPointArray(pt[0],pt[1],pt[2]);
+        pt = [pt[0] - ptNew[0],pt[1] - ptNew[1],0];
+    }
+    return pt;
+};
+
+BaseElement.prototype.initExpressions = function(){
+    this.layerInterface = LayerExpressionInterface(this);
+    //layers[i].layerInterface = LayerExpressionInterface(layers[i]);
+    //layers[i].layerInterface = LayerExpressionInterface(layers[i]);
+    if(this.data.hasMask){
+        this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this,this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if(this.data.ty === 0 || this.data.xt){
+        this.compInterface = CompExpressionInterface(this);
+    } else if(this.data.ty === 4){
+        this.layerInterface.shapeInterface = ShapeExpressionInterface.createShapeInterface(this.shapesData,this.viewData,this.layerInterface);
+    } else if(this.data.ty === 5){
+        this.layerInterface.textInterface = TextExpressionInterface(this);
+    }
+}
+
+BaseElement.prototype.setBlendMode = function(){
+    var blendModeValue = '';
+    switch(this.data.bm){
+        case 1:
+            blendModeValue = 'multiply';
+            break;
+        case 2:
+            blendModeValue = 'screen';
+            break;
+        case 3:
+            blendModeValue = 'overlay';
+            break;
+        case 4:
+            blendModeValue = 'darken';
+            break;
+        case 5:
+            blendModeValue = 'lighten';
+            break;
+        case 6:
+            blendModeValue = 'color-dodge';
+            break;
+        case 7:
+            blendModeValue = 'color-burn';
+            break;
+        case 8:
+            blendModeValue = 'hard-light';
+            break;
+        case 9:
+            blendModeValue = 'soft-light';
+            break;
+        case 10:
+            blendModeValue = 'difference';
+            break;
+        case 11:
+            blendModeValue = 'exclusion';
+            break;
+        case 12:
+            blendModeValue = 'hue';
+            break;
+        case 13:
+            blendModeValue = 'saturation';
+            break;
+        case 14:
+            blendModeValue = 'color';
+            break;
+        case 15:
+            blendModeValue = 'luminosity';
+            break;
+    }
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+}
+
+BaseElement.prototype.init = function(){
+    if(!this.data.sr){
+        this.data.sr = 1;
+    }
+    this.dynamicProperties = [];
+    if(this.data.ef){
+        this.effects = new EffectsManager(this.data,this,this.dynamicProperties);
+        //this.effect = this.effectsManager.bind(this.effectsManager);
+    }
+    //this.elemInterface = buildLayerExpressionInterface(this);
+    this.hidden = false;
+    this.firstFrame = true;
+    this.isVisible = false;
+    this._isParent = false;
+    this.currentFrameNum = -99999;
+    this.lastNum = -99999;
+    if(this.data.ks){
+        this.finalTransform = {
+            mProp: PropertyFactory.getProp(this,this.data.ks,2,null,this.dynamicProperties),
+            matMdf: false,
+            opMdf: false,
+            mat: new Matrix(),
+            opacity: 1
+        };
+        if(this.data.ao){
+            this.finalTransform.mProp.autoOriented = true;
+        }
+        this.finalTransform.op = this.finalTransform.mProp.o;
+        this.transform = this.finalTransform.mProp;
+        if(this.data.ty !== 11){
+            this.createElements();
+        }
+        if(this.data.hasMask){
+            this.addMasks(this.data);
+        }
+    }
+    this.elemMdf = false;
+};
+BaseElement.prototype.getType = function(){
+    return this.type;
+};
+
+BaseElement.prototype.resetHierarchy = function(){
+    if(!this.hierarchy){
+        this.hierarchy = [];
+    }else{
+        this.hierarchy.length = 0;
+    }
+};
+
+BaseElement.prototype.getHierarchy = function(){
+    if(!this.hierarchy){
+        this.hierarchy = [];
+    }
+    return this.hierarchy;
+};
+
+BaseElement.prototype.setHierarchy = function(hierarchy){
+    this.hierarchy = hierarchy;
+};
+
+BaseElement.prototype.getLayerSize = function(){
+    if(this.data.ty === 5){
+        return {w:this.data.textData.width,h:this.data.textData.height};
+    }else{
+        return {w:this.data.width,h:this.data.height};
+    }
+};
+
+BaseElement.prototype.hide = function(){
+
+};
+
+BaseElement.prototype.mHelper = new Matrix();
+function SVGBaseElement(data,parentContainer,globalData,comp, placeholder){
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.matteElement = null;
+    this.transformedElement = null;
+    this.parentContainer = parentContainer;
+    this.layerId = placeholder ? placeholder.layerId : 'ly_'+randomString(10);
+    this.placeholder = placeholder;
+    this.init();
+};
+
+createElement(BaseElement, SVGBaseElement);
+
+SVGBaseElement.prototype.createElements = function(){
+    this.layerElement = document.createElementNS(svgNS,'g');
+    this.transformedElement = this.layerElement;
+    if(this.data.hasMask){
+        this.maskedElement = this.layerElement;
+    }
+    var layerElementParent = null;
+    if(this.data.td){
+        if(this.data.td == 3 || this.data.td == 1){
+            var masker = document.createElementNS(svgNS,'mask');
+            masker.setAttribute('id',this.layerId);
+            masker.setAttribute('mask-type',this.data.td == 3 ? 'luminance':'alpha');
+            masker.appendChild(this.layerElement);
+            layerElementParent = masker;
+            this.globalData.defs.appendChild(masker);
+            ////// This is only for IE and Edge when mask if of type alpha
+            if(!featureSupport.maskType && this.data.td == 1){
+                masker.setAttribute('mask-type','luminance');
+                var filId = randomString(10);
+                var fil = filtersFactory.createFilter(filId);
+                this.globalData.defs.appendChild(fil);
+                fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+                var gg = document.createElementNS(svgNS,'g');
+                gg.appendChild(this.layerElement);
+                layerElementParent = gg;
+                masker.appendChild(gg);
+                gg.setAttribute('filter','url(#'+filId+')');
+            }
+        }else if(this.data.td == 2){
+            var maskGroup = document.createElementNS(svgNS,'mask');
+            maskGroup.setAttribute('id',this.layerId);
+            maskGroup.setAttribute('mask-type','alpha');
+            var maskGrouper = document.createElementNS(svgNS,'g');
+            maskGroup.appendChild(maskGrouper);
+            var filId = randomString(10);
+            var fil = filtersFactory.createFilter(filId);
+            ////
+
+            var feColorMatrix = document.createElementNS(svgNS,'feColorMatrix');
+            feColorMatrix.setAttribute('type','matrix');
+            feColorMatrix.setAttribute('color-interpolation-filters','sRGB');
+            feColorMatrix.setAttribute('values','1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 -1 1');
+            fil.appendChild(feColorMatrix);
+
+            ////
+            /*var feCTr = document.createElementNS(svgNS,'feComponentTransfer');
+            feCTr.setAttribute('in','SourceGraphic');
+            fil.appendChild(feCTr);
+            var feFunc = document.createElementNS(svgNS,'feFuncA');
+            feFunc.setAttribute('type','table');
+            feFunc.setAttribute('tableValues','1.0 0.0');
+            feCTr.appendChild(feFunc);*/
+            this.globalData.defs.appendChild(fil);
+            var alphaRect = document.createElementNS(svgNS,'rect');
+            alphaRect.setAttribute('width',this.comp.data.w);
+            alphaRect.setAttribute('height',this.comp.data.h);
+            alphaRect.setAttribute('x','0');
+            alphaRect.setAttribute('y','0');
+            alphaRect.setAttribute('fill','#ffffff');
+            alphaRect.setAttribute('opacity','0');
+            maskGrouper.setAttribute('filter','url(#'+filId+')');
+            maskGrouper.appendChild(alphaRect);
+            maskGrouper.appendChild(this.layerElement);
+            layerElementParent = maskGrouper;
+            if(!featureSupport.maskType){
+                maskGroup.setAttribute('mask-type','luminance');
+                fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+                var gg = document.createElementNS(svgNS,'g');
+                maskGrouper.appendChild(alphaRect);
+                gg.appendChild(this.layerElement);
+                layerElementParent = gg;
+                maskGrouper.appendChild(gg);
+            }
+            this.globalData.defs.appendChild(maskGroup);
+        }
+    }else if(this.data.hasMask || this.data.tt){
+        if(this.data.tt){
+            this.matteElement = document.createElementNS(svgNS,'g');
+            this.matteElement.appendChild(this.layerElement);
+            layerElementParent = this.matteElement;
+            this.baseElement = this.matteElement;
+        }else{
+            this.baseElement = this.layerElement;
+        }
+    }else{
+        this.baseElement = this.layerElement;
+    }
+    if((this.data.ln || this.data.cl) && (this.data.ty === 4 || this.data.ty === 0)){
+        if(this.data.ln){
+            this.layerElement.setAttribute('id',this.data.ln);
+        }
+        if(this.data.cl){
+            this.layerElement.setAttribute('class',this.data.cl);
+        }
+    }
+    if(this.data.ty === 0){
+            var cp = document.createElementNS(svgNS, 'clipPath');
+            var pt = document.createElementNS(svgNS,'path');
+            pt.setAttribute('d','M0,0 L'+this.data.w+',0'+' L'+this.data.w+','+this.data.h+' L0,'+this.data.h+'z');
+            var clipId = 'cp_'+randomString(8);
+            cp.setAttribute('id',clipId);
+            cp.appendChild(pt);
+            this.globalData.defs.appendChild(cp);
+        if(this.checkMasks()){
+            var cpGroup = document.createElementNS(svgNS,'g');
+            cpGroup.setAttribute('clip-path','url(#'+clipId+')');
+            cpGroup.appendChild(this.layerElement);
+            this.transformedElement = cpGroup;
+            if(layerElementParent){
+                layerElementParent.appendChild(this.transformedElement);
+            } else {
+                this.baseElement = this.transformedElement;
+            }
+        } else {
+            this.layerElement.setAttribute('clip-path','url(#'+clipId+')');
+        }
+        
+    }
+    if(this.data.bm !== 0){
+        this.setBlendMode();
+    }
+    if(this.layerElement !== this.parentContainer){
+        this.placeholder = null;
+    }
+    /* Todo performance killer
+    if(this.data.sy){
+        var filterID = 'st_'+randomString(10);
+        var c = this.data.sy[0].c.k;
+        var r = this.data.sy[0].s.k;
+        var expansor = document.createElementNS(svgNS,'filter');
+        expansor.setAttribute('id',filterID);
+        var feFlood = document.createElementNS(svgNS,'feFlood');
+        this.feFlood = feFlood;
+        if(!c[0].e){
+            feFlood.setAttribute('flood-color','rgb('+c[0]+','+c[1]+','+c[2]+')');
+        }
+        feFlood.setAttribute('result','base');
+        expansor.appendChild(feFlood);
+        var feMorph = document.createElementNS(svgNS,'feMorphology');
+        feMorph.setAttribute('operator','dilate');
+        feMorph.setAttribute('in','SourceGraphic');
+        feMorph.setAttribute('result','bigger');
+        this.feMorph = feMorph;
+        if(!r.length){
+            feMorph.setAttribute('radius',this.data.sy[0].s.k);
+        }
+        expansor.appendChild(feMorph);
+        var feColorMatrix = document.createElementNS(svgNS,'feColorMatrix');
+        feColorMatrix.setAttribute('result','mask');
+        feColorMatrix.setAttribute('in','bigger');
+        feColorMatrix.setAttribute('type','matrix');
+        feColorMatrix.setAttribute('values','0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0');
+        expansor.appendChild(feColorMatrix);
+        var feComposite = document.createElementNS(svgNS,'feComposite');
+        feComposite.setAttribute('result','drop');
+        feComposite.setAttribute('in','base');
+        feComposite.setAttribute('in2','mask');
+        feComposite.setAttribute('operator','in');
+        expansor.appendChild(feComposite);
+        var feBlend = document.createElementNS(svgNS,'feBlend');
+        feBlend.setAttribute('in','SourceGraphic');
+        feBlend.setAttribute('in2','drop');
+        feBlend.setAttribute('mode','normal');
+        expansor.appendChild(feBlend);
+        this.globalData.defs.appendChild(expansor);
+        var cont = document.createElementNS(svgNS,'g');
+        if(this.layerElement === this.parentContainer){
+            this.layerElement = cont;
+        }else{
+            cont.appendChild(this.layerElement);
+        }
+        cont.setAttribute('filter','url(#'+filterID+')');
+        if(this.data.td){
+            cont.setAttribute('data-td',this.data.td);
+        }
+        if(this.data.td == 3){
+            this.globalData.defs.appendChild(cont);
+        }else if(this.data.td == 2){
+            maskGrouper.appendChild(cont);
+        }else if(this.data.td == 1){
+            masker.appendChild(cont);
+        }else{
+            if(this.data.hasMask && this.data.tt){
+                this.matteElement.appendChild(cont);
+            }else{
+                this.appendNodeToParent(cont);
+            }
+        }
+    }*/
+    if(this.data.ef){
+        this.effectsManager = new SVGEffects(this);
+    }
+    this.checkParenting();
+};
+
+
+SVGBaseElement.prototype.setBlendMode = BaseElement.prototype.setBlendMode;
+
+SVGBaseElement.prototype.renderFrame = function(parentTransform){
+    if(this.data.ty === 3 || this.data.hd || !this.isVisible){
+        return false;
+    }
+
+    this.lastNum = this.currentFrameNum;
+    this.finalTransform.opMdf = this.firstFrame || this.finalTransform.op.mdf;
+    this.finalTransform.matMdf = this.firstFrame || this.finalTransform.mProp.mdf;
+    this.finalTransform.opacity = this.finalTransform.op.v;
+
+    var mat;
+    var finalMat = this.finalTransform.mat;
+
+    if(this.hierarchy){
+        var i = 0, len = this.hierarchy.length;
+        if(!this.finalTransform.matMdf) {
+            while(i < len) {
+                if(this.hierarchy[i].finalTransform.mProp.mdf) {
+                    this.finalTransform.matMdf = true;
+                    break;
+                }
+                i += 1;
+            }
+        }
+        
+        if(this.finalTransform.matMdf) {
+            mat = this.finalTransform.mProp.v.props;
+            finalMat.cloneFromProps(mat);
+            for(i=0;i<len;i+=1){
+                mat = this.hierarchy[i].finalTransform.mProp.v.props;
+                finalMat.transform(mat[0],mat[1],mat[2],mat[3],mat[4],mat[5],mat[6],mat[7],mat[8],mat[9],mat[10],mat[11],mat[12],mat[13],mat[14],mat[15]);
+            }
+        }
+        
+    }else if(this.isVisible){
+        finalMat = this.finalTransform.mProp.v;
+    }
+    if(this.finalTransform.matMdf && this.layerElement){
+        this.transformedElement.setAttribute('transform',finalMat.to2dCSS());
+    }
+    if(this.finalTransform.opMdf && this.layerElement){
+        this.transformedElement.setAttribute('opacity',this.finalTransform.op.v);
+    }
+
+    if(this.data.hasMask){
+        this.maskManager.renderFrame(finalMat);
+    }
+    if(this.effectsManager){
+        this.effectsManager.renderFrame(this.firstFrame);
+    }
+    return this.isVisible;
+};
+
+SVGBaseElement.prototype.destroy = function(){
+    this.layerElement = null;
+    this.parentContainer = null;
+    if(this.matteElement) {
+        this.matteElement = null;
+    }
+    if(this.maskManager) {
+        this.maskManager.destroy();
+    }
+};
+
+SVGBaseElement.prototype.getBaseElement = function(){
+    return this.baseElement;
+};
+SVGBaseElement.prototype.addMasks = function(data){
+    this.maskManager = new MaskElement(data,this,this.globalData);
+};
+
+SVGBaseElement.prototype.setMatte = function(id){
+    if(!this.matteElement){
+        return;
+    }
+    this.matteElement.setAttribute("mask", "url(#" + id + ")");
+};
+
+SVGBaseElement.prototype.setMatte = function(id){
+    if(!this.matteElement){
+        return;
+    }
+    this.matteElement.setAttribute("mask", "url(#" + id + ")");
+};
+
+SVGBaseElement.prototype.hide = function(){
+
+};
+
+function ITextElement(data, animationItem,parentContainer,globalData){
+}
+ITextElement.prototype.init = function(){
+    this._parent.init.call(this);
+
+    this.lettersChangedFlag = false;
+    this.currentTextDocumentData = {};
+    var data = this.data;
+    this.viewData = {
+        m:{
+            a: PropertyFactory.getProp(this,data.t.m.a,1,0,this.dynamicProperties)
+        }
+    };
+    var textData = this.data.t;
+    if(textData.a.length){
+        this.viewData.a = Array.apply(null,{length:textData.a.length});
+        var i, len = textData.a.length, animatorData, animatorProps;
+        for(i=0;i<len;i+=1){
+            animatorProps = textData.a[i];
+            animatorData = {
+                a: {},
+                s: {}
+            };
+            if('r' in animatorProps.a) {
+                animatorData.a.r = PropertyFactory.getProp(this,animatorProps.a.r,0,degToRads,this.dynamicProperties);
+            }
+            if('rx' in animatorProps.a) {
+                animatorData.a.rx = PropertyFactory.getProp(this,animatorProps.a.rx,0,degToRads,this.dynamicProperties);
+            }
+            if('ry' in animatorProps.a) {
+                animatorData.a.ry = PropertyFactory.getProp(this,animatorProps.a.ry,0,degToRads,this.dynamicProperties);
+            }
+            if('sk' in animatorProps.a) {
+                animatorData.a.sk = PropertyFactory.getProp(this,animatorProps.a.sk,0,degToRads,this.dynamicProperties);
+            }
+            if('sa' in animatorProps.a) {
+                animatorData.a.sa = PropertyFactory.getProp(this,animatorProps.a.sa,0,degToRads,this.dynamicProperties);
+            }
+            if('s' in animatorProps.a) {
+                animatorData.a.s = PropertyFactory.getProp(this,animatorProps.a.s,1,0.01,this.dynamicProperties);
+            }
+            if('a' in animatorProps.a) {
+                animatorData.a.a = PropertyFactory.getProp(this,animatorProps.a.a,1,0,this.dynamicProperties);
+            }
+            if('o' in animatorProps.a) {
+                animatorData.a.o = PropertyFactory.getProp(this,animatorProps.a.o,0,0.01,this.dynamicProperties);
+            }
+            if('p' in animatorProps.a) {
+                animatorData.a.p = PropertyFactory.getProp(this,animatorProps.a.p,1,0,this.dynamicProperties);
+            }
+            if('sw' in animatorProps.a) {
+                animatorData.a.sw = PropertyFactory.getProp(this,animatorProps.a.sw,0,0,this.dynamicProperties);
+            }
+            if('sc' in animatorProps.a) {
+                animatorData.a.sc = PropertyFactory.getProp(this,animatorProps.a.sc,1,0,this.dynamicProperties);
+            }
+            if('fc' in animatorProps.a) {
+                animatorData.a.fc = PropertyFactory.getProp(this,animatorProps.a.fc,1,0,this.dynamicProperties);
+            }
+            if('fh' in animatorProps.a) {
+                animatorData.a.fh = PropertyFactory.getProp(this,animatorProps.a.fh,0,0,this.dynamicProperties);
+            }
+            if('fs' in animatorProps.a) {
+                animatorData.a.fs = PropertyFactory.getProp(this,animatorProps.a.fs,0,0.01,this.dynamicProperties);
+            }
+            if('fb' in animatorProps.a) {
+                animatorData.a.fb = PropertyFactory.getProp(this,animatorProps.a.fb,0,0.01,this.dynamicProperties);
+            }
+            if('t' in animatorProps.a) {
+                animatorData.a.t = PropertyFactory.getProp(this,animatorProps.a.t,0,0,this.dynamicProperties);
+            }
+            animatorData.s = PropertyFactory.getTextSelectorProp(this,animatorProps.s,this.dynamicProperties);
+            animatorData.s.t = animatorProps.s.t;
+            this.viewData.a[i] = animatorData;
+        }
+    }else{
+        this.viewData.a = [];
+    }
+    if(textData.p && 'm' in textData.p){
+        this.viewData.p = {
+            f: PropertyFactory.getProp(this,textData.p.f,0,0,this.dynamicProperties),
+            l: PropertyFactory.getProp(this,textData.p.l,0,0,this.dynamicProperties),
+            r: textData.p.r,
+            m: this.maskManager.getMaskProperty(textData.p.m)
+        };
+        this.maskPath = true;
+    } else {
+        this.maskPath = false;
+    }
+};
+ITextElement.prototype.prepareFrame = function(num) {
+    var i = 0, len = this.data.t.d.k.length;
+    var textDocumentData = this.data.t.d.k[i].s;
+    i += 1;
+    while(i<len){
+        if(this.data.t.d.k[i].t > num){
+            break;
+        }
+        textDocumentData = this.data.t.d.k[i].s;
+        i += 1;
+    }
+    this.lettersChangedFlag = false;
+    if(textDocumentData !== this.currentTextDocumentData){
+        this.currentTextDocumentData = textDocumentData;
+        this.lettersChangedFlag = true;
+        this.buildNewText();
+    }
+    this._parent.prepareFrame.call(this, num);
+}
+
+ITextElement.prototype.createPathShape = function(matrixHelper, shapes) {
+    var j,jLen = shapes.length;
+    var k, kLen, pathNodes;
+    var shapeStr = '';
+    for(j=0;j<jLen;j+=1){
+        kLen = shapes[j].ks.k.i.length;
+        pathNodes = shapes[j].ks.k;
+        for(k=1;k<kLen;k+=1){
+            if(k==1){
+                shapeStr += " M"+matrixHelper.applyToPointStringified(pathNodes.v[0][0],pathNodes.v[0][1]);
+            }
+            shapeStr += " C"+matrixHelper.applyToPointStringified(pathNodes.o[k-1][0],pathNodes.o[k-1][1]) + " "+matrixHelper.applyToPointStringified(pathNodes.i[k][0],pathNodes.i[k][1]) + " "+matrixHelper.applyToPointStringified(pathNodes.v[k][0],pathNodes.v[k][1]);
+        }
+        shapeStr += " C"+matrixHelper.applyToPointStringified(pathNodes.o[k-1][0],pathNodes.o[k-1][1]) + " "+matrixHelper.applyToPointStringified(pathNodes.i[0][0],pathNodes.i[0][1]) + " "+matrixHelper.applyToPointStringified(pathNodes.v[0][0],pathNodes.v[0][1]);
+        shapeStr += 'z';
+    }
+    return shapeStr;
+};
+
+ITextElement.prototype.getMeasures = function(){
+
+    var matrixHelper = this.mHelper;
+    var renderType = this.renderType;
+    var data = this.data;
+    var xPos,yPos;
+    var i, len;
+    var documentData = this.currentTextDocumentData;
+    var letters = documentData.l;
+    if(this.maskPath) {
+        var mask = this.viewData.p.m;
+        if(!this.viewData.p.n || this.viewData.p.mdf){
+            var paths = mask.v;
+            if(this.viewData.p.r){
+                paths = reversePath(paths);
+            }
+            var pathInfo = {
+                tLength: 0,
+                segments: []
+            };
+            len = paths.v.length - 1;
+            var pathData;
+            var totalLength = 0;
+            for (i = 0; i < len; i += 1) {
+                pathData = {
+                    s: paths.v[i],
+                    e: paths.v[i + 1],
+                    to: [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+                    ti: [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]
+                };
+                bez.buildBezierData(pathData);
+                pathInfo.tLength += pathData.bezierData.segmentLength;
+                pathInfo.segments.push(pathData);
+                totalLength += pathData.bezierData.segmentLength;
+            }
+            i = len;
+            if (mask.v.c) {
+                pathData = {
+                    s: paths.v[i],
+                    e: paths.v[0],
+                    to: [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+                    ti: [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]
+                };
+                bez.buildBezierData(pathData);
+                pathInfo.tLength += pathData.bezierData.segmentLength;
+                pathInfo.segments.push(pathData);
+                totalLength += pathData.bezierData.segmentLength;
+            }
+            this.viewData.p.pi = pathInfo;
+        }
+        var pathInfo = this.viewData.p.pi;
+
+        var currentLength = this.viewData.p.f.v, segmentInd = 0, pointInd = 1, currentPoint, prevPoint, points;
+        var segmentLength = 0, flag = true;
+        var segments = pathInfo.segments;
+        if (currentLength < 0 && mask.v.c) {
+            if (pathInfo.tLength < Math.abs(currentLength)) {
+                currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+            }
+            segmentInd = segments.length - 1;
+            points = segments[segmentInd].bezierData.points;
+            pointInd = points.length - 1;
+            while (currentLength < 0) {
+                currentLength += points[pointInd].partialLength;
+                pointInd -= 1;
+                if (pointInd < 0) {
+                    segmentInd -= 1;
+                    points = segments[segmentInd].bezierData.points;
+                    pointInd = points.length - 1;
+                }
+            }
+
+        }
+        points = segments[segmentInd].bezierData.points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        var partialLength = currentPoint.partialLength;
+        var perc, tanAngle;
+    }
+
+
+    len = letters.length;
+    xPos = 0;
+    yPos = 0;
+    var yOff = documentData.s*1.2*.714;
+    var firstLine = true;
+    var renderedData = this.viewData, animatorProps, animatorSelector;
+    var j, jLen;
+    var lettersValue = Array.apply(null,{length:len}), letterValue;
+
+    jLen = renderedData.a.length;
+    var lastLetter;
+
+    var mult, ind = -1, offf, xPathPos, yPathPos;
+    var initPathPos = currentLength,initSegmentInd = segmentInd, initPointInd = pointInd, currentLine = -1;
+    var elemOpacity;
+    var sc,sw,fc,k;
+    var lineLength = 0;
+    var letterSw,letterSc,letterFc,letterM,letterP,letterO;
+    for( i = 0; i < len; i += 1) {
+        matrixHelper.reset();
+        elemOpacity = 1;
+        if(letters[i].n) {
+            xPos = 0;
+            yPos += documentData.yOffset;
+            yPos += firstLine ? 1 : 0;
+            currentLength = initPathPos ;
+            firstLine = false;
+            lineLength = 0;
+            if(this.maskPath) {
+                segmentInd = initSegmentInd;
+                pointInd = initPointInd;
+                points = segments[segmentInd].bezierData.points;
+                prevPoint = points[pointInd - 1];
+                currentPoint = points[pointInd];
+                partialLength = currentPoint.partialLength;
+                segmentLength = 0;
+            }
+            lettersValue[i] = this.emptyProp;
+        }else{
+            if(this.maskPath) {
+                if(currentLine !== letters[i].line){
+                    switch(documentData.j){
+                        case 1:
+                            currentLength += totalLength - documentData.lineWidths[letters[i].line];
+                            break;
+                        case 2:
+                            currentLength += (totalLength - documentData.lineWidths[letters[i].line])/2;
+                            break;
+                    }
+                    currentLine = letters[i].line;
+                }
+                if (ind !== letters[i].ind) {
+                    if (letters[ind]) {
+                        currentLength += letters[ind].extra;
+                    }
+                    currentLength += letters[i].an / 2;
+                    ind = letters[i].ind;
+                }
+                currentLength += renderedData.m.a.v[0] * letters[i].an / 200;
+                var animatorOffset = 0;
+                for (j = 0; j < jLen; j += 1) {
+                    animatorProps = renderedData.a[j].a;
+                    if ('p' in animatorProps) {
+                        animatorSelector = renderedData.a[j].s;
+                        mult = animatorSelector.getMult(letters[i].anIndexes[j],data.t.a[j].s.totalChars);
+                        if(mult.length){
+                            animatorOffset += animatorProps.p.v[0] * mult[0];
+                        } else{
+                            animatorOffset += animatorProps.p.v[0] * mult;
+                        }
+
+                    }
+                    if ('a' in animatorProps) {
+                        animatorSelector = renderedData.a[j].s;
+                        mult = animatorSelector.getMult(letters[i].anIndexes[j],data.t.a[j].s.totalChars);
+                        if(mult.length){
+                            animatorOffset += animatorProps.a.v[0] * mult[0];
+                        } else{
+                            animatorOffset += animatorProps.a.v[0] * mult;
+                        }
+
+                    }
+                }
+                flag = true;
+                while (flag) {
+                    if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+                        perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+                        xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+                        yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+                        matrixHelper.translate(-renderedData.m.a.v[0]*letters[i].an/200, -(renderedData.m.a.v[1] * yOff / 100));
+                        flag = false;
+                    } else if (points) {
+                        segmentLength += currentPoint.partialLength;
+                        pointInd += 1;
+                        if (pointInd >= points.length) {
+                            pointInd = 0;
+                            segmentInd += 1;
+                            if (!segments[segmentInd]) {
+                                if (mask.v.c) {
+                                    pointInd = 0;
+                                    segmentInd = 0;
+                                    points = segments[segmentInd].bezierData.points;
+                                } else {
+                                    segmentLength -= currentPoint.partialLength;
+                                    points = null;
+                                }
+                            } else {
+                                points = segments[segmentInd].bezierData.points;
+                            }
+                        }
+                        if (points) {
+                            prevPoint = currentPoint;
+                            currentPoint = points[pointInd];
+                            partialLength = currentPoint.partialLength;
+                        }
+                    }
+                }
+                offf = letters[i].an / 2 - letters[i].add;
+                matrixHelper.translate(-offf, 0, 0);
+            } else {
+                offf = letters[i].an/2 - letters[i].add;
+                matrixHelper.translate(-offf,0,0);
+
+                // Grouping alignment
+                matrixHelper.translate(-renderedData.m.a.v[0]*letters[i].an/200, -renderedData.m.a.v[1]*yOff/100, 0);
+            }
+
+            lineLength += letters[i].l/2;
+            for(j=0;j<jLen;j+=1){
+                animatorProps = renderedData.a[j].a;
+                if ('t' in animatorProps) {
+                    animatorSelector = renderedData.a[j].s;
+                    mult = animatorSelector.getMult(letters[i].anIndexes[j],data.t.a[j].s.totalChars);
+                    if(this.maskPath) {
+                        if(mult.length) {
+                            currentLength += animatorProps.t*mult[0];
+                        } else {
+                            currentLength += animatorProps.t*mult;
+                        }
+                    }else{
+                        if(mult.length) {
+                            xPos += animatorProps.t.v*mult[0];
+                        } else {
+                            xPos += animatorProps.t.v*mult;
+                        }
+                    }
+                }
+            }
+            lineLength += letters[i].l/2;
+            if(documentData.strokeWidthAnim) {
+                sw = documentData.sw || 0;
+            }
+            if(documentData.strokeColorAnim) {
+                if(documentData.sc){
+                    sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+                }else{
+                    sc = [0,0,0];
+                }
+            }
+            if(documentData.fillColorAnim) {
+                fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+            }
+            for(j=0;j<jLen;j+=1){
+                animatorProps = renderedData.a[j].a;
+                if ('a' in animatorProps) {
+                    animatorSelector = renderedData.a[j].s;
+                    mult = animatorSelector.getMult(letters[i].anIndexes[j],data.t.a[j].s.totalChars);
+
+                    if(mult.length){
+                        matrixHelper.translate(-animatorProps.a.v[0]*mult[0], -animatorProps.a.v[1]*mult[1], animatorProps.a.v[2]*mult[2]);
+                    } else {
+                        matrixHelper.translate(-animatorProps.a.v[0]*mult, -animatorProps.a.v[1]*mult, animatorProps.a.v[2]*mult);
+                    }
+                }
+            }
+            for(j=0;j<jLen;j+=1){
+                animatorProps = renderedData.a[j].a;
+                if ('s' in animatorProps) {
+                    animatorSelector = renderedData.a[j].s;
+                    mult = animatorSelector.getMult(letters[i].anIndexes[j],data.t.a[j].s.totalChars);
+                    if(mult.length){
+                        matrixHelper.scale(1+((animatorProps.s.v[0]-1)*mult[0]),1+((animatorProps.s.v[1]-1)*mult[1]),1);
+                    } else {
+                        matrixHelper.scale(1+((animatorProps.s.v[0]-1)*mult),1+((animatorProps.s.v[1]-1)*mult),1);
+                    }
+                }
+            }
+            for(j=0;j<jLen;j+=1) {
+                animatorProps = renderedData.a[j].a;
+                animatorSelector = renderedData.a[j].s;
+                mult = animatorSelector.getMult(letters[i].anIndexes[j],data.t.a[j].s.totalChars);
+                if ('sk' in animatorProps) {
+                    if(mult.length) {
+                        matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+                    } else {
+                        matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+                    }
+                }
+                if ('r' in animatorProps) {
+                    if(mult.length) {
+                        matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+                    } else {
+                        matrixHelper.rotateZ(-animatorProps.r.v * mult);
+                    }
+                }
+                if ('ry' in animatorProps) {
+
+                    if(mult.length) {
+                        matrixHelper.rotateY(animatorProps.ry.v*mult[1]);
+                    }else{
+                        matrixHelper.rotateY(animatorProps.ry.v*mult);
+                    }
+                }
+                if ('rx' in animatorProps) {
+                    if(mult.length) {
+                        matrixHelper.rotateX(animatorProps.rx.v*mult[0]);
+                    } else {
+                        matrixHelper.rotateX(animatorProps.rx.v*mult);
+                    }
+                }
+                if ('o' in animatorProps) {
+                    if(mult.length) {
+                        elemOpacity += ((animatorProps.o.v)*mult[0] - elemOpacity)*mult[0];
+                    } else {
+                        elemOpacity += ((animatorProps.o.v)*mult - elemOpacity)*mult;
+                    }
+                }
+                if (documentData.strokeWidthAnim && 'sw' in animatorProps) {
+                    if(mult.length) {
+                        sw += animatorProps.sw.v*mult[0];
+                    } else {
+                        sw += animatorProps.sw.v*mult;
+                    }
+                }
+                if (documentData.strokeColorAnim && 'sc' in animatorProps) {
+                    for(k=0;k<3;k+=1){
+                        if(mult.length) {
+                            sc[k] = Math.round(255*(sc[k] + (animatorProps.sc.v[k] - sc[k])*mult[0]));
+                        } else {
+                            sc[k] = Math.round(255*(sc[k] + (animatorProps.sc.v[k] - sc[k])*mult));
+                        }
+                    }
+                }
+                if (documentData.fillColorAnim) {
+                    if('fc' in animatorProps){
+                        for(k=0;k<3;k+=1){
+                            if(mult.length) {
+                                fc[k] = fc[k] + (animatorProps.fc.v[k] - fc[k])*mult[0];
+                            } else {
+                                fc[k] = fc[k] + (animatorProps.fc.v[k] - fc[k])*mult;
+                                //console.log('mult',mult);
+                                //console.log(Math.round(fc[k] + (animatorProps.fc.v[k] - fc[k])*mult));
+                            }
+                        }
+                    }
+                    if('fh' in animatorProps){
+                        if(mult.length) {
+                            fc = addHueToRGB(fc,animatorProps.fh.v*mult[0]);
+                        } else {
+                            fc = addHueToRGB(fc,animatorProps.fh.v*mult);
+                        }
+                    }
+                    if('fs' in animatorProps){
+                        if(mult.length) {
+                            fc = addSaturationToRGB(fc,animatorProps.fs.v*mult[0]);
+                        } else {
+                            fc = addSaturationToRGB(fc,animatorProps.fs.v*mult);
+                        }
+                    }
+                    if('fb' in animatorProps){
+                        if(mult.length) {
+                            fc = addBrightnessToRGB(fc,animatorProps.fb.v*mult[0]);
+                        } else {
+                            fc = addBrightnessToRGB(fc,animatorProps.fb.v*mult);
+                        }
+                    }
+                }
+            }
+
+            for(j=0;j<jLen;j+=1){
+                animatorProps = renderedData.a[j].a;
+
+                if ('p' in animatorProps) {
+                    animatorSelector = renderedData.a[j].s;
+                    mult = animatorSelector.getMult(letters[i].anIndexes[j],data.t.a[j].s.totalChars);
+                    if(this.maskPath) {
+                        if(mult.length) {
+                            matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+                        } else {
+                            matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+                        }
+                    }else{
+                        if(mult.length) {
+                            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+                        } else {
+                            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+                        }
+                    }
+                }
+            }
+            if(documentData.strokeWidthAnim){
+                letterSw = sw < 0 ? 0 : sw;
+            }
+            if(documentData.strokeColorAnim){
+                letterSc = 'rgb('+Math.round(sc[0]*255)+','+Math.round(sc[1]*255)+','+Math.round(sc[2]*255)+')';
+            }
+            if(documentData.fillColorAnim){
+                letterFc = 'rgb('+Math.round(fc[0]*255)+','+Math.round(fc[1]*255)+','+Math.round(fc[2]*255)+')';
+            }
+
+            if(this.maskPath) {
+                matrixHelper.translate(0,-documentData.ls);
+
+                matrixHelper.translate(0, renderedData.m.a.v[1]*yOff/100 + yPos,0);
+                if (data.t.p.p) {
+                    tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+                    var rot = Math.atan(tanAngle) * 180 / Math.PI;
+                    if (currentPoint.point[0] < prevPoint.point[0]) {
+                        rot += 180;
+                    }
+                    matrixHelper.rotate(-rot * Math.PI / 180);
+                }
+                matrixHelper.translate(xPathPos, yPathPos, 0);
+                currentLength -= renderedData.m.a.v[0]*letters[i].an/200;
+                if(letters[i+1] && ind !== letters[i+1].ind){
+                    currentLength += letters[i].an / 2;
+                    currentLength += documentData.tr/1000*documentData.s;
+                }
+            }else{
+
+                matrixHelper.translate(xPos,yPos,0);
+
+                if(documentData.ps){
+                    //matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+                    matrixHelper.translate(documentData.ps[0],documentData.ps[1] + documentData.ascent,0);
+                }
+                switch(documentData.j){
+                    case 1:
+                        matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]),0,0);
+                        break;
+                    case 2:
+                        matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line])/2,0,0);
+                        break;
+                }
+                matrixHelper.translate(0,-documentData.ls);
+                matrixHelper.translate(offf,0,0);
+                matrixHelper.translate(renderedData.m.a.v[0]*letters[i].an/200,renderedData.m.a.v[1]*yOff/100,0);
+                xPos += letters[i].l + documentData.tr/1000*documentData.s;
+            }
+            if(renderType === 'html'){
+                letterM = matrixHelper.toCSS();
+            }else if(renderType === 'svg'){
+                letterM = matrixHelper.to2dCSS();
+            }else{
+                letterP = [matrixHelper.props[0],matrixHelper.props[1],matrixHelper.props[2],matrixHelper.props[3],matrixHelper.props[4],matrixHelper.props[5],matrixHelper.props[6],matrixHelper.props[7],matrixHelper.props[8],matrixHelper.props[9],matrixHelper.props[10],matrixHelper.props[11],matrixHelper.props[12],matrixHelper.props[13],matrixHelper.props[14],matrixHelper.props[15]];
+            }
+            letterO = elemOpacity;
+
+            lastLetter = this.renderedLetters[i];
+            if(lastLetter && (lastLetter.o !== letterO || lastLetter.sw !== letterSw || lastLetter.sc !== letterSc || lastLetter.fc !== letterFc)){
+                this.lettersChangedFlag = true;
+                letterValue = new LetterProps(letterO,letterSw,letterSc,letterFc,letterM,letterP);
+            }else{
+                if((renderType === 'svg' || renderType === 'html') && (!lastLetter || lastLetter.m !== letterM)){
+                    this.lettersChangedFlag = true;
+                    letterValue = new LetterProps(letterO,letterSw,letterSc,letterFc,letterM);
+                }else if(renderType === 'canvas' && (!lastLetter || (lastLetter.props[0] !== letterP[0] || lastLetter.props[1] !== letterP[1] || lastLetter.props[4] !== letterP[4] || lastLetter.props[5] !== letterP[5] || lastLetter.props[12] !== letterP[12] || lastLetter.props[13] !== letterP[13]))){
+                    this.lettersChangedFlag = true;
+                    letterValue = new LetterProps(letterO,letterSw,letterSc,letterFc,null,letterP);
+                } else {
+                    letterValue = lastLetter;
+                }
+            }
+            this.renderedLetters[i] = letterValue;
+        }
+    }
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+function SVGTextElement(data,parentContainer,globalData,comp, placeholder){
+    this.textSpans = [];
+    this.renderType = 'svg';
+    this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder);
+}
+createElement(SVGBaseElement, SVGTextElement);
+
+SVGTextElement.prototype.init = ITextElement.prototype.init;
+SVGTextElement.prototype.createPathShape = ITextElement.prototype.createPathShape;
+SVGTextElement.prototype.getMeasures = ITextElement.prototype.getMeasures;
+SVGTextElement.prototype.prepareFrame = ITextElement.prototype.prepareFrame;
+
+SVGTextElement.prototype.createElements = function(){
+
+    this._parent.createElements.call(this);
+
+
+    if(this.data.ln){
+        this.layerElement.setAttribute('id',this.data.ln);
+    }
+    if(this.data.cl){
+        this.layerElement.setAttribute('class',this.data.cl);
+    }
+};
+
+SVGTextElement.prototype.buildNewText = function(){
+    var i, len;
+
+    var documentData = this.currentTextDocumentData;
+    this.renderedLetters = Array.apply(null,{length:this.currentTextDocumentData.l ? this.currentTextDocumentData.l.length : 0});
+    if(documentData.fc) {
+        this.layerElement.setAttribute('fill', 'rgb(' + Math.round(documentData.fc[0]*255) + ',' + Math.round(documentData.fc[1]*255) + ',' + Math.round(documentData.fc[2]*255) + ')');
+    }else{
+        this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+    }
+    if(documentData.sc){
+        this.layerElement.setAttribute('stroke', 'rgb(' + Math.round(documentData.sc[0]*255) + ',' + Math.round(documentData.sc[1]*255) + ',' + Math.round(documentData.sc[2]*255) + ')');
+        this.layerElement.setAttribute('stroke-width', documentData.sw);
+    }
+    this.layerElement.setAttribute('font-size', documentData.s);
+    var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+    if(fontData.fClass){
+        this.layerElement.setAttribute('class',fontData.fClass);
+    } else {
+        this.layerElement.setAttribute('font-family', fontData.fFamily);
+        var fWeight = documentData.fWeight, fStyle = documentData.fStyle;
+        this.layerElement.setAttribute('font-style', fStyle);
+        this.layerElement.setAttribute('font-weight', fWeight);
+    }
+
+
+
+    var letters = documentData.l || [];
+    len = letters.length;
+    if(!len){
+        return;
+    }
+    var tSpan;
+    var matrixHelper = this.mHelper;
+    var shapes, shapeStr = '', singleShape = this.data.singleShape;
+    if (singleShape) {
+        var xPos = 0, yPos = 0, lineWidths = documentData.lineWidths, boxWidth = documentData.boxWidth, firstLine = true;
+    }
+    var cnt = 0;
+    for (i = 0;i < len ;i += 1) {
+        if(this.globalData.fontManager.chars){
+            if(!singleShape || i === 0){
+                tSpan = this.textSpans[cnt] ? this.textSpans[cnt] : document.createElementNS(svgNS,'path');
+            }
+        }else{
+            tSpan = this.textSpans[cnt] ? this.textSpans[cnt] : document.createElementNS(svgNS,'text');
+        }
+        tSpan.style.display = 'inherit';
+        tSpan.setAttribute('stroke-linecap', 'butt');
+        tSpan.setAttribute('stroke-linejoin','round');
+        tSpan.setAttribute('stroke-miterlimit','4');
+        //tSpan.setAttribute('visibility', 'hidden');
+        if(singleShape && letters[i].n) {
+            xPos = 0;
+            yPos += documentData.yOffset;
+            yPos += firstLine ? 1 : 0;
+            firstLine = false;
+        }
+        matrixHelper.reset();
+        if(this.globalData.fontManager.chars) {
+            matrixHelper.scale(documentData.s / 100, documentData.s / 100);
+        }
+        if (singleShape) {
+            if(documentData.ps){
+                matrixHelper.translate(documentData.ps[0],documentData.ps[1] + documentData.ascent,0);
+            }
+            matrixHelper.translate(0,-documentData.ls,0);
+            switch(documentData.j){
+                case 1:
+                    matrixHelper.translate(documentData.justifyOffset + (boxWidth - lineWidths[letters[i].line]),0,0);
+                    break;
+                case 2:
+                    matrixHelper.translate(documentData.justifyOffset + (boxWidth - lineWidths[letters[i].line])/2,0,0);
+                    break;
+            }
+            matrixHelper.translate(xPos, yPos, 0);
+        }
+        if(this.globalData.fontManager.chars){
+            var charData = this.globalData.fontManager.getCharData(documentData.t.charAt(i), fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+            var shapeData;
+            if(charData){
+                shapeData = charData.data;
+            } else {
+                shapeData = null;
+            }
+            if(shapeData && shapeData.shapes){
+                shapes = shapeData.shapes[0].it;
+                if(!singleShape){
+                    shapeStr = '';
+                }
+                shapeStr += this.createPathShape(matrixHelper,shapes);
+                if(!singleShape){
+
+                    tSpan.setAttribute('d',shapeStr);
+                }
+            }
+            if(!singleShape){
+                this.layerElement.appendChild(tSpan);
+            }
+        }else{
+            tSpan.textContent = letters[i].val;
+            tSpan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space","preserve");
+            this.layerElement.appendChild(tSpan);
+            if(singleShape){
+                tSpan.setAttribute('transform',matrixHelper.to2dCSS());
+            }
+        }
+        if(singleShape) {
+            xPos += letters[i].l;
+            xPos += documentData.tr/1000*documentData.s;
+        }
+        //
+        this.textSpans[cnt] = tSpan;
+        cnt += 1;
+    }
+    if(!singleShape){
+        while(cnt < this.textSpans.length){
+            this.textSpans[cnt].style.display = 'none';
+            cnt += 1;
+        }
+    }
+    if(singleShape && this.globalData.fontManager.chars){
+        tSpan.setAttribute('d',shapeStr);
+        this.layerElement.appendChild(tSpan);
+    }
+}
+
+SVGTextElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.layerElement.style.display = 'none';
+        this.hidden = true;
+    }
+};
+
+SVGTextElement.prototype.renderFrame = function(parentMatrix){
+
+    var renderParent = this._parent.renderFrame.call(this,parentMatrix);
+    if(renderParent===false){
+        this.hide();
+        return;
+    }
+    if(this.hidden){
+        this.hidden = false;
+        this.layerElement.style.display = 'block';
+    }
+
+    if(this.data.singleShape){
+        return;
+    }
+    this.getMeasures();
+    if(!this.lettersChangedFlag){
+        return;
+    }
+    var  i,len;
+    var renderedLetters = this.renderedLetters;
+
+    var letters = this.currentTextDocumentData.l;
+
+    len = letters.length;
+    var renderedLetter;
+    for(i=0;i<len;i+=1){
+        if(letters[i].n){
+            continue;
+        }
+        renderedLetter = renderedLetters[i];
+        this.textSpans[i].setAttribute('transform',renderedLetter.m);
+        this.textSpans[i].setAttribute('opacity',renderedLetter.o);
+        if(renderedLetter.sw){
+            this.textSpans[i].setAttribute('stroke-width',renderedLetter.sw);
+        }
+        if(renderedLetter.sc){
+            this.textSpans[i].setAttribute('stroke',renderedLetter.sc);
+        }
+        if(renderedLetter.fc){
+            this.textSpans[i].setAttribute('fill',renderedLetter.fc);
+        }
+    }
+    if(this.firstFrame) {
+        this.firstFrame = false;
+    }
+}
+
+
+SVGTextElement.prototype.destroy = function(){
+    this._parent.destroy.call(this._parent);
+};
+function SVGTintFilter(filter, filterManager){
+    this.filterManager = filterManager;
+    var feColorMatrix = document.createElementNS(svgNS,'feColorMatrix');
+    feColorMatrix.setAttribute('type','matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters','linearRGB');
+    feColorMatrix.setAttribute('values','0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0');
+    feColorMatrix.setAttribute('result','f1');
+    filter.appendChild(feColorMatrix);
+    feColorMatrix = document.createElementNS(svgNS,'feColorMatrix');
+    feColorMatrix.setAttribute('type','matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters','sRGB');
+    feColorMatrix.setAttribute('values','1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+    feColorMatrix.setAttribute('result','f2');
+    filter.appendChild(feColorMatrix);
+    this.matrixFilter = feColorMatrix;
+    if(filterManager.effectElements[2].p.v !== 100 || filterManager.effectElements[2].p.k){
+        var feMerge = document.createElementNS(svgNS,'feMerge');
+        filter.appendChild(feMerge);
+        var feMergeNode;
+        feMergeNode = document.createElementNS(svgNS,'feMergeNode');
+        feMergeNode.setAttribute('in','SourceGraphic');
+        feMerge.appendChild(feMergeNode);
+        feMergeNode = document.createElementNS(svgNS,'feMergeNode');
+        feMergeNode.setAttribute('in','f2');
+        feMerge.appendChild(feMergeNode);
+    }
+}
+
+SVGTintFilter.prototype.renderFrame = function(forceRender){
+    if(forceRender || this.filterManager.mdf){
+        var colorBlack = this.filterManager.effectElements[0].p.v;
+        var colorWhite = this.filterManager.effectElements[1].p.v;
+        var opacity = this.filterManager.effectElements[2].p.v/100;
+        this.matrixFilter.setAttribute('values',(colorWhite[0]- colorBlack[0])+' 0 0 0 '+ colorBlack[0] +' '+ (colorWhite[1]- colorBlack[1]) +' 0 0 0 '+ colorBlack[1] +' '+ (colorWhite[2]- colorBlack[2]) +' 0 0 0 '+ colorBlack[2] +' 0 0 0 ' + opacity + ' 0');
+    }
+};
+function SVGFillFilter(filter, filterManager){
+    this.filterManager = filterManager;
+    var feColorMatrix = document.createElementNS(svgNS,'feColorMatrix');
+    feColorMatrix.setAttribute('type','matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters','sRGB');
+    feColorMatrix.setAttribute('values','1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+    filter.appendChild(feColorMatrix);
+    this.matrixFilter = feColorMatrix;
+}
+SVGFillFilter.prototype.renderFrame = function(forceRender){
+    if(forceRender || this.filterManager.mdf){
+        var color = this.filterManager.effectElements[2].p.v;
+        var opacity = this.filterManager.effectElements[6].p.v;
+        this.matrixFilter.setAttribute('values','0 0 0 0 '+color[0]+' 0 0 0 0 '+color[1]+' 0 0 0 0 '+color[2]+' 0 0 0 '+opacity+' 0');
+    }
+};
+function SVGStrokeEffect(elem, filterManager){
+    this.initialized = false;
+    this.filterManager = filterManager;
+    this.elem = elem;
+    this.paths = [];
+}
+
+SVGStrokeEffect.prototype.initialize = function(){
+
+    var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+    var path,groupPath, i, len;
+    if(this.filterManager.effectElements[1].p.v === 1){
+        len = this.elem.maskManager.masksProperties.length;
+        i = 0;
+    } else {
+        i = this.filterManager.effectElements[0].p.v - 1;
+        len = i + 1;
+    }
+    groupPath = document.createElementNS(svgNS,'g'); 
+    groupPath.setAttribute('fill','none');
+    groupPath.setAttribute('stroke-linecap','round');
+    groupPath.setAttribute('stroke-dashoffset',1);
+    for(i;i<len;i+=1){
+        path = document.createElementNS(svgNS,'path');
+        groupPath.appendChild(path);
+        this.paths.push({p:path,m:i});
+    }
+    if(this.filterManager.effectElements[10].p.v === 3){
+        var mask = document.createElementNS(svgNS,'mask');
+        var id = 'stms_' + randomString(10);
+        mask.setAttribute('id',id);
+        mask.setAttribute('mask-type','alpha');
+        mask.appendChild(groupPath);
+        this.elem.globalData.defs.appendChild(mask);
+        var g = document.createElementNS(svgNS,'g');
+        g.setAttribute('mask','url(#'+id+')');
+        if(elemChildren[0]){
+            g.appendChild(elemChildren[0]);
+        }
+        this.elem.layerElement.appendChild(g);
+        this.masker = mask;
+        groupPath.setAttribute('stroke','#fff');
+    } else if(this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2){
+        if(this.filterManager.effectElements[10].p.v === 2){
+            var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+            while(elemChildren.length){
+                this.elem.layerElement.removeChild(elemChildren[0]);
+            }
+        }
+        this.elem.layerElement.appendChild(groupPath);
+        this.elem.layerElement.removeAttribute('mask');
+        groupPath.setAttribute('stroke','#fff');
+    }
+    this.initialized = true;
+    this.pathMasker = groupPath;
+}
+
+SVGStrokeEffect.prototype.renderFrame = function(forceRender){
+    if(!this.initialized){
+        this.initialize();
+    }
+    var i, len = this.paths.length;
+    var mask, path;
+    for(i=0;i<len;i+=1){
+        mask = this.elem.maskManager.viewData[this.paths[i].m];
+        path = this.paths[i].p;
+        if(forceRender || this.filterManager.mdf || mask.prop.mdf){
+            path.setAttribute('d',mask.lastPath);
+        }
+        if(forceRender || this.filterManager.effectElements[9].p.mdf || this.filterManager.effectElements[4].p.mdf || this.filterManager.effectElements[7].p.mdf || this.filterManager.effectElements[8].p.mdf || mask.prop.mdf){
+            var dasharrayValue;
+            if(this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100){
+                var s = Math.min(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v)/100;
+                var e = Math.max(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v)/100;
+                var l = path.getTotalLength();
+                dasharrayValue = '0 0 0 ' + l*s + ' ';
+                var lineLength = l*(e-s);
+                var segment = 1+this.filterManager.effectElements[4].p.v*2*this.filterManager.effectElements[9].p.v/100;
+                var units = Math.floor(lineLength/segment);
+                var j;
+                for(j=0;j<units;j+=1){
+                    dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v*2*this.filterManager.effectElements[9].p.v/100 + ' ';
+                }
+                dasharrayValue += '0 ' + l*10 + ' 0 0';
+            } else {
+                dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v*2*this.filterManager.effectElements[9].p.v/100;
+            }
+            path.setAttribute('stroke-dasharray',dasharrayValue);
+        }
+    }
+    if(forceRender || this.filterManager.effectElements[4].p.mdf){
+        this.pathMasker.setAttribute('stroke-width',this.filterManager.effectElements[4].p.v*2);
+    }
+    
+    if(forceRender || this.filterManager.effectElements[6].p.mdf){
+        this.pathMasker.setAttribute('opacity',this.filterManager.effectElements[6].p.v);
+    }
+    if(this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2){
+        if(forceRender || this.filterManager.effectElements[3].p.mdf){
+            var color = this.filterManager.effectElements[3].p.v;
+            this.pathMasker.setAttribute('stroke','rgb('+bm_floor(color[0]*255)+','+bm_floor(color[1]*255)+','+bm_floor(color[2]*255)+')');
+        }
+    }
+};
+function SVGTritoneFilter(filter, filterManager){
+    this.filterManager = filterManager;
+    var feColorMatrix = document.createElementNS(svgNS,'feColorMatrix');
+    feColorMatrix.setAttribute('type','matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters','linearRGB');
+    feColorMatrix.setAttribute('values','0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0');
+    feColorMatrix.setAttribute('result','f1');
+    filter.appendChild(feColorMatrix);
+    var feComponentTransfer = document.createElementNS(svgNS,'feComponentTransfer');
+    feComponentTransfer.setAttribute('color-interpolation-filters','sRGB');
+    filter.appendChild(feComponentTransfer);
+    this.matrixFilter = feComponentTransfer;
+    var feFuncR = document.createElementNS(svgNS,'feFuncR');
+    feFuncR.setAttribute('type','table');
+    feComponentTransfer.appendChild(feFuncR);
+    this.feFuncR = feFuncR;
+    var feFuncG = document.createElementNS(svgNS,'feFuncG');
+    feFuncG.setAttribute('type','table');
+    feComponentTransfer.appendChild(feFuncG);
+    this.feFuncG = feFuncG;
+    var feFuncB = document.createElementNS(svgNS,'feFuncB');
+    feFuncB.setAttribute('type','table');
+    feComponentTransfer.appendChild(feFuncB);
+    this.feFuncB = feFuncB;
+}
+
+SVGTritoneFilter.prototype.renderFrame = function(forceRender){
+    if(forceRender || this.filterManager.mdf){
+        var color1 = this.filterManager.effectElements[0].p.v;
+        var color2 = this.filterManager.effectElements[1].p.v;
+        var color3 = this.filterManager.effectElements[2].p.v;
+        var tableR = color3[0] + ' ' + color2[0] + ' ' + color1[0]
+        var tableG = color3[1] + ' ' + color2[1] + ' ' + color1[1]
+        var tableB = color3[2] + ' ' + color2[2] + ' ' + color1[2]
+        this.feFuncR.setAttribute('tableValues', tableR);
+        this.feFuncG.setAttribute('tableValues', tableG);
+        this.feFuncB.setAttribute('tableValues', tableB);
+        //var opacity = this.filterManager.effectElements[2].p.v/100;
+        //this.matrixFilter.setAttribute('values',(colorWhite[0]- colorBlack[0])+' 0 0 0 '+ colorBlack[0] +' '+ (colorWhite[1]- colorBlack[1]) +' 0 0 0 '+ colorBlack[1] +' '+ (colorWhite[2]- colorBlack[2]) +' 0 0 0 '+ colorBlack[2] +' 0 0 0 ' + opacity + ' 0');
+    }
+};
+function SVGProLevelsFilter(filter, filterManager){
+    this.filterManager = filterManager;
+    var effectElements = this.filterManager.effectElements;
+    var feComponentTransfer = document.createElementNS(svgNS,'feComponentTransfer');
+    var feFuncR, feFuncG, feFuncB;
+    
+    if(effectElements[9].p.k || effectElements[9].p.v !== 0 || effectElements[10].p.k || effectElements[10].p.v !== 1 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 0 || effectElements[13].p.k || effectElements[13].p.v !== 1){
+        this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
+    }
+    if(effectElements[16].p.k || effectElements[16].p.v !== 0 || effectElements[17].p.k || effectElements[17].p.v !== 1 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 0 || effectElements[20].p.k || effectElements[20].p.v !== 1){
+        this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
+    }
+    if(effectElements[23].p.k || effectElements[23].p.v !== 0 || effectElements[24].p.k || effectElements[24].p.v !== 1 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 0 || effectElements[27].p.k || effectElements[27].p.v !== 1){
+        this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
+    }
+    if(effectElements[30].p.k || effectElements[30].p.v !== 0 || effectElements[31].p.k || effectElements[31].p.v !== 1 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 0 || effectElements[34].p.k || effectElements[34].p.v !== 1){
+        this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
+    }
+    
+    if(this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA){
+        feComponentTransfer.setAttribute('color-interpolation-filters','sRGB');
+        filter.appendChild(feComponentTransfer);
+        feComponentTransfer = document.createElementNS(svgNS,'feComponentTransfer');
+    }
+
+    if(effectElements[2].p.k || effectElements[2].p.v !== 0 || effectElements[3].p.k || effectElements[3].p.v !== 1 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 0 || effectElements[6].p.k || effectElements[6].p.v !== 1){
+
+        feComponentTransfer.setAttribute('color-interpolation-filters','sRGB');
+        filter.appendChild(feComponentTransfer);
+        this.feFuncRComposed = this.createFeFunc('feFuncR', feComponentTransfer);
+        this.feFuncGComposed = this.createFeFunc('feFuncG', feComponentTransfer);
+        this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
+    }
+}
+
+SVGProLevelsFilter.prototype.createFeFunc = function(type, feComponentTransfer) {
+    var feFunc = document.createElementNS(svgNS,type);
+    feFunc.setAttribute('type','table');
+    feComponentTransfer.appendChild(feFunc);
+    return feFunc;
+};
+
+SVGProLevelsFilter.prototype.getTableValue = function(inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
+    var cnt = 0;
+    var segments = 256;
+    var perc;
+    var min = Math.min(inputBlack, inputWhite);
+    var max = Math.max(inputBlack, inputWhite);
+    var table = Array.call(null,{length:segments});
+    var colorValue;
+    var pos = 0;
+    var outputDelta = outputWhite - outputBlack; 
+    var inputDelta = inputWhite - inputBlack; 
+    while(cnt <= 256) {
+        perc = cnt/256;
+        if(perc <= min){
+            colorValue = inputDelta < 0 ? outputWhite : outputBlack;
+        } else if(perc >= max){
+            colorValue = inputDelta < 0 ? outputBlack : outputWhite;
+        } else {
+            colorValue = (outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma));
+        }
+        table[pos++] = colorValue;
+        cnt += 256/(segments-1);
+    }
+    return table.join(' ');
+};
+
+SVGProLevelsFilter.prototype.renderFrame = function(forceRender){
+    if(forceRender || this.filterManager.mdf){
+        var val, cnt, perc, bezier;
+        var effectElements = this.filterManager.effectElements;
+        if(this.feFuncRComposed && (forceRender || effectElements[2].p.mdf || effectElements[3].p.mdf || effectElements[4].p.mdf || effectElements[5].p.mdf || effectElements[6].p.mdf)){
+            val = this.getTableValue(effectElements[2].p.v,effectElements[3].p.v,effectElements[4].p.v,effectElements[5].p.v,effectElements[6].p.v);
+            this.feFuncRComposed.setAttribute('tableValues',val);
+            this.feFuncGComposed.setAttribute('tableValues',val);
+            this.feFuncBComposed.setAttribute('tableValues',val);
+        }
+
+        if(this.feFuncR && (forceRender || effectElements[9].p.mdf || effectElements[10].p.mdf || effectElements[11].p.mdf || effectElements[12].p.mdf || effectElements[13].p.mdf)){
+            val = this.getTableValue(effectElements[9].p.v,effectElements[10].p.v,effectElements[11].p.v,effectElements[12].p.v,effectElements[13].p.v);
+            this.feFuncR.setAttribute('tableValues',val);
+        }
+
+        if(this.feFuncG && (forceRender || effectElements[16].p.mdf || effectElements[17].p.mdf || effectElements[18].p.mdf || effectElements[19].p.mdf || effectElements[20].p.mdf)){
+            val = this.getTableValue(effectElements[16].p.v,effectElements[17].p.v,effectElements[18].p.v,effectElements[19].p.v,effectElements[20].p.v);
+            this.feFuncG.setAttribute('tableValues',val);
+        }
+
+        if(this.feFuncB && (forceRender || effectElements[23].p.mdf || effectElements[24].p.mdf || effectElements[25].p.mdf || effectElements[26].p.mdf || effectElements[27].p.mdf)){
+            val = this.getTableValue(effectElements[23].p.v,effectElements[24].p.v,effectElements[25].p.v,effectElements[26].p.v,effectElements[27].p.v);
+            this.feFuncB.setAttribute('tableValues',val);
+        }
+
+        if(this.feFuncA && (forceRender || effectElements[30].p.mdf || effectElements[31].p.mdf || effectElements[32].p.mdf || effectElements[33].p.mdf || effectElements[34].p.mdf)){
+            val = this.getTableValue(effectElements[30].p.v,effectElements[31].p.v,effectElements[32].p.v,effectElements[33].p.v,effectElements[34].p.v);
+            this.feFuncA.setAttribute('tableValues',val);
+        }
+        
+    }
+};
+function SVGDropShadowEffect(filter, filterManager){
+    /*<feGaussianBlur in="SourceAlpha" stdDeviation="3"/> <!-- stdDeviation is how much to blur -->
+  <feOffset dx="2" dy="2" result="offsetblur"/> <!-- how much to offset -->
+  <feMerge> 
+    <feMergeNode/> <!-- this contains the offset blurred image -->
+    <feMergeNode in="SourceGraphic"/> <!-- this contains the element that the filter is applied to -->
+  </feMerge>*/
+  /*<feFlood flood-color="#3D4574" flood-opacity="0.5" result="offsetColor"/>*/
+    filter.setAttribute('x','-100%');
+    filter.setAttribute('y','-100%');
+    filter.setAttribute('width','400%');
+    filter.setAttribute('height','400%');
+    this.filterManager = filterManager;
+
+    var feGaussianBlur = document.createElementNS(svgNS,'feGaussianBlur');
+    feGaussianBlur.setAttribute('in','SourceAlpha');
+    feGaussianBlur.setAttribute('result','drop_shadow_1');
+    feGaussianBlur.setAttribute('stdDeviation','0');
+    this.feGaussianBlur = feGaussianBlur;
+    filter.appendChild(feGaussianBlur);
+
+    var feOffset = document.createElementNS(svgNS,'feOffset');
+    feOffset.setAttribute('dx','25');
+    feOffset.setAttribute('dy','0');
+    feOffset.setAttribute('in','drop_shadow_1');
+    feOffset.setAttribute('result','drop_shadow_2');
+    this.feOffset = feOffset;
+    filter.appendChild(feOffset);
+    var feFlood = document.createElementNS(svgNS,'feFlood');
+    feFlood.setAttribute('flood-color','#00ff00');
+    feFlood.setAttribute('flood-opacity','1');
+    feFlood.setAttribute('result','drop_shadow_3');
+    this.feFlood = feFlood;
+    filter.appendChild(feFlood);
+
+    var feComposite = document.createElementNS(svgNS,'feComposite');
+    feComposite.setAttribute('in','drop_shadow_3');
+    feComposite.setAttribute('in2','drop_shadow_2');
+    feComposite.setAttribute('operator','in');
+    feComposite.setAttribute('result','drop_shadow_4');
+    filter.appendChild(feComposite);
+
+
+    var feMerge = document.createElementNS(svgNS,'feMerge');
+    filter.appendChild(feMerge);
+    var feMergeNode;
+    feMergeNode = document.createElementNS(svgNS,'feMergeNode');
+    feMerge.appendChild(feMergeNode);
+    feMergeNode = document.createElementNS(svgNS,'feMergeNode');
+    feMergeNode.setAttribute('in','SourceGraphic');
+    this.feMergeNode = feMergeNode;
+    this.feMerge = feMerge;
+    this.originalNodeAdded = false;
+    feMerge.appendChild(feMergeNode);
+}
+
+SVGDropShadowEffect.prototype.renderFrame = function(forceRender){
+    if(forceRender || this.filterManager.mdf){
+        if(forceRender || this.filterManager.effectElements[4].p.mdf){
+            this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
+        }
+        if(forceRender || this.filterManager.effectElements[0].p.mdf){
+            var col = this.filterManager.effectElements[0].p.v;
+            this.feFlood.setAttribute('flood-color',rgbToHex(Math.round(col[0]*255),Math.round(col[1]*255),Math.round(col[2]*255)));
+        }
+        if(forceRender || this.filterManager.effectElements[1].p.mdf){
+            this.feFlood.setAttribute('flood-opacity',this.filterManager.effectElements[1].p.v/255);
+        }
+        if(forceRender || this.filterManager.effectElements[2].p.mdf || this.filterManager.effectElements[3].p.mdf){
+            var distance = this.filterManager.effectElements[3].p.v
+            var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads
+            var x = distance * Math.cos(angle)
+            var y = distance * Math.sin(angle)
+            this.feOffset.setAttribute('dx', x);
+            this.feOffset.setAttribute('dy', y);
+        }
+        /*if(forceRender || this.filterManager.effectElements[5].p.mdf){
+            if(this.filterManager.effectElements[5].p.v === 1 && this.originalNodeAdded) {
+                this.feMerge.removeChild(this.feMergeNode);
+                this.originalNodeAdded = false;
+            } else if(this.filterManager.effectElements[5].p.v === 0 && !this.originalNodeAdded) {
+                this.feMerge.appendChild(this.feMergeNode);
+                this.originalNodeAdded = true;
+            }
+        }*/
+    }
+};
+function SVGEffects(elem){
+    var i, len = elem.data.ef.length;
+    var filId = randomString(10);
+    var fil = filtersFactory.createFilter(filId);
+    var count = 0;
+    this.filters = [];
+    var filterManager;
+    for(i=0;i<len;i+=1){
+        if(elem.data.ef[i].ty === 20){
+            count += 1;
+            filterManager = new SVGTintFilter(fil, elem.effects.effectElements[i]);
+            this.filters.push(filterManager);
+        }else if(elem.data.ef[i].ty === 21){
+            count += 1;
+            filterManager = new SVGFillFilter(fil, elem.effects.effectElements[i]);
+            this.filters.push(filterManager);
+        }else if(elem.data.ef[i].ty === 22){
+            filterManager = new SVGStrokeEffect(elem, elem.effects.effectElements[i]);
+            this.filters.push(filterManager);
+        }else if(elem.data.ef[i].ty === 23){
+            count += 1;
+            filterManager = new SVGTritoneFilter(fil, elem.effects.effectElements[i]);
+            this.filters.push(filterManager);
+        }else if(elem.data.ef[i].ty === 24){
+            count += 1;
+            filterManager = new SVGProLevelsFilter(fil, elem.effects.effectElements[i]);
+            this.filters.push(filterManager);
+        }else if(elem.data.ef[i].ty === 25){
+            count += 1;
+            filterManager = new SVGDropShadowEffect(fil, elem.effects.effectElements[i]);
+            this.filters.push(filterManager);
+        }
+    }
+    if(count){
+        elem.globalData.defs.appendChild(fil);
+        elem.layerElement.setAttribute('filter','url(#'+filId+')');
+    }
+}
+
+SVGEffects.prototype.renderFrame = function(firstFrame){
+    var i, len = this.filters.length;
+    for(i=0;i<len;i+=1){
+        this.filters[i].renderFrame(firstFrame);
+    }
+};
+function ICompElement(data,parentContainer,globalData,comp, placeholder){
+    this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder);
+    this.layers = data.layers;
+    this.supports3d = true;
+    this.completeLayers = false;
+    this.pendingElements = [];
+    this.elements = this.layers ? Array.apply(null,{length:this.layers.length}) : [];
+    if(this.data.tm){
+        this.tm = PropertyFactory.getProp(this,this.data.tm,0,globalData.frameRate,this.dynamicProperties);
+    }
+    if(this.data.xt){
+        this.layerElement = document.createElementNS(svgNS,'g');
+        this.buildAllItems();
+    } else if(!globalData.progressiveLoad){
+        this.buildAllItems();
+    }
+}
+createElement(SVGBaseElement, ICompElement);
+
+ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+        this.hidden = true;
+    }
+};
+
+ICompElement.prototype.prepareFrame = function(num){
+    this._parent.prepareFrame.call(this,num);
+    if(this.isVisible===false && !this.data.xt){
+        return;
+    }
+
+    if(this.tm){
+        var timeRemapped = this.tm.v;
+        if(timeRemapped === this.data.op){
+            timeRemapped = this.data.op - 1;
+        }
+        this.renderedFrame = timeRemapped;
+    } else {
+        this.renderedFrame = num/this.data.sr;
+    }
+    var i,len = this.elements.length;
+    if(!this.completeLayers){
+        this.checkLayers(this.renderedFrame);
+    }
+    for( i = 0; i < len; i+=1 ){
+        if(this.completeLayers || this.elements[i]){
+            this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+        }
+    }
+};
+
+ICompElement.prototype.renderFrame = function(parentMatrix){
+    var renderParent = this._parent.renderFrame.call(this,parentMatrix);
+    var i,len = this.layers.length;
+    if(renderParent===false){
+        this.hide();
+        return;
+    }
+
+    this.hidden = false;
+    for( i = 0; i < len; i+=1 ){
+        if(this.completeLayers || this.elements[i]){
+            this.elements[i].renderFrame();
+        }
+    }
+    if(this.firstFrame){
+        this.firstFrame = false;
+    }
+};
+
+ICompElement.prototype.setElements = function(elems){
+    this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function(){
+    return this.elements;
+};
+
+ICompElement.prototype.destroy = function(){
+    this._parent.destroy.call(this._parent);
+    var i,len = this.layers.length;
+    for( i = 0; i < len; i+=1 ){
+        if(this.elements[i]){
+            this.elements[i].destroy();
+        }
+    }
+};
+
+ICompElement.prototype.checkLayers = SVGRenderer.prototype.checkLayers;
+ICompElement.prototype.buildItem = SVGRenderer.prototype.buildItem;
+ICompElement.prototype.buildAllItems = SVGRenderer.prototype.buildAllItems;
+ICompElement.prototype.buildElementParenting = SVGRenderer.prototype.buildElementParenting;
+ICompElement.prototype.createItem = SVGRenderer.prototype.createItem;
+ICompElement.prototype.createImage = SVGRenderer.prototype.createImage;
+ICompElement.prototype.createComp = SVGRenderer.prototype.createComp;
+ICompElement.prototype.createSolid = SVGRenderer.prototype.createSolid;
+ICompElement.prototype.createShape = SVGRenderer.prototype.createShape;
+ICompElement.prototype.createText = SVGRenderer.prototype.createText;
+ICompElement.prototype.createBase = SVGRenderer.prototype.createBase;
+ICompElement.prototype.appendElementInPos = SVGRenderer.prototype.appendElementInPos;
+ICompElement.prototype.checkPendingElements = SVGRenderer.prototype.checkPendingElements;
+ICompElement.prototype.addPendingElement = SVGRenderer.prototype.addPendingElement;
+function IImageElement(data,parentContainer,globalData,comp,placeholder){
+    this.assetData = globalData.getAssetData(data.refId);
+    this._parent.constructor.call(this,data,parentContainer,globalData,comp,placeholder);
+}
+createElement(SVGBaseElement, IImageElement);
+
+IImageElement.prototype.createElements = function(){
+
+    var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+    this._parent.createElements.call(this);
+
+    this.innerElem = document.createElementNS(svgNS,'image');
+    this.innerElem.setAttribute('width',this.assetData.w+"px");
+    this.innerElem.setAttribute('height',this.assetData.h+"px");
+    this.innerElem.setAttribute('preserveAspectRatio','xMidYMid slice');
+    this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink','href',assetPath);
+    this.maskedElement = this.innerElem;
+    this.layerElement.appendChild(this.innerElem);
+    if(this.data.ln){
+        this.layerElement.setAttribute('id',this.data.ln);
+    }
+    if(this.data.cl){
+        this.layerElement.setAttribute('class',this.data.cl);
+    }
+
+};
+
+IImageElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.layerElement.style.display = 'none';
+        this.hidden = true;
+    }
+};
+
+IImageElement.prototype.renderFrame = function(parentMatrix){
+    var renderParent = this._parent.renderFrame.call(this,parentMatrix);
+    if(renderParent===false){
+        this.hide();
+        return;
+    }
+    if(this.hidden){
+        this.hidden = false;
+        this.layerElement.style.display = 'block';
+    }
+    if(this.firstFrame){
+        this.firstFrame = false;
+    }
+};
+
+IImageElement.prototype.destroy = function(){
+    this._parent.destroy.call(this._parent);
+    this.innerElem =  null;
+};
+function IShapeElement(data,parentContainer,globalData,comp, placeholder){
+    this.shapes = [];
+    this.shapesData = data.shapes;
+    this.stylesList = [];
+    this.viewData = [];
+    this.shapeModifiers = [];
+    this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder);
+}
+createElement(SVGBaseElement, IShapeElement);
+
+IShapeElement.prototype.lcEnum = {
+    '1': 'butt',
+    '2': 'round',
+    '3': 'butt'
+}
+
+IShapeElement.prototype.ljEnum = {
+    '1': 'miter',
+    '2': 'round',
+    '3': 'butt'
+}
+
+IShapeElement.prototype.buildExpressionInterface = function(){};
+
+IShapeElement.prototype.createElements = function(){
+    //TODO check if I can use symbol so i can set its viewBox
+    this._parent.createElements.call(this);
+    this.searchShapes(this.shapesData,this.viewData,this.layerElement,this.dynamicProperties, 0);
+    if(!this.data.hd || this.data.td){
+        styleUnselectableDiv(this.layerElement);
+    }
+    //this.elemInterface.registerShapeExpressionInterface(ShapeExpressionInterface.createShapeInterface(this.shapesData,this.viewData,this.elemInterface));
+};
+
+IShapeElement.prototype.setGradientData = function(pathElement,arr,data){
+
+    var gradientId = 'gr_'+randomString(10);
+    var gfill;
+    if(arr.t === 1){
+        gfill = document.createElementNS(svgNS,'linearGradient');
+    } else {
+        gfill = document.createElementNS(svgNS,'radialGradient');
+    }
+    gfill.setAttribute('id',gradientId);
+    gfill.setAttribute('spreadMethod','pad');
+    gfill.setAttribute('gradientUnits','userSpaceOnUse');
+    var stops = [];
+    var stop, j, jLen;
+    jLen = arr.g.p*4;
+    for(j=0;j<jLen;j+=4){
+        stop = document.createElementNS(svgNS,'stop');
+        gfill.appendChild(stop);
+        stops.push(stop);
+    }
+    pathElement.setAttribute( arr.ty === 'gf' ? 'fill':'stroke','url(#'+gradientId+')');
+    this.globalData.defs.appendChild(gfill);
+    data.gf = gfill;
+    data.cst = stops;
+}
+
+IShapeElement.prototype.setGradientOpacity = function(arr, data, styleOb){
+    if((arr.g.k.k[0].s && arr.g.k.k[0].s.length > arr.g.p*4) || arr.g.k.k.length > arr.g.p*4){
+        var opFill;
+        var stop, j, jLen;
+        var mask = document.createElementNS(svgNS,"mask");
+        var maskElement = document.createElementNS(svgNS, 'path');
+        mask.appendChild(maskElement);
+        var opacityId = 'op_'+randomString(10);
+        var maskId = 'mk_'+randomString(10);
+        mask.setAttribute('id',maskId);
+        if(arr.t === 1){
+            opFill = document.createElementNS(svgNS,'linearGradient');
+        } else {
+            opFill = document.createElementNS(svgNS,'radialGradient');
+        }
+        opFill.setAttribute('id',opacityId);
+        opFill.setAttribute('spreadMethod','pad');
+        opFill.setAttribute('gradientUnits','userSpaceOnUse');
+        jLen = arr.g.k.k[0].s ? arr.g.k.k[0].s.length : arr.g.k.k.length;
+        var stops = [];
+        for(j=arr.g.p*4;j<jLen;j+=2){
+            stop = document.createElementNS(svgNS,'stop');
+            stop.setAttribute('stop-color','rgb(255,255,255)');
+            //stop.setAttribute('offset',Math.round(arr.y[j][0]*100)+'%');
+            //stop.setAttribute('style','stop-color:rgb(255,255,255);stop-opacity:'+arr.y[j][1]);
+            opFill.appendChild(stop);
+            stops.push(stop);
+        }
+        maskElement.setAttribute( arr.ty === 'gf' ? 'fill':'stroke','url(#'+opacityId+')');
+        this.globalData.defs.appendChild(opFill);
+        this.globalData.defs.appendChild(mask);
+        data.of = opFill;
+        data.ost = stops;
+        styleOb.msElem = maskElement;
+        return maskId;
+    }
+};
+
+IShapeElement.prototype.searchShapes = function(arr,data,container,dynamicProperties, level, transformers){
+    transformers = transformers || [];
+    var ownTransformers = [].concat(transformers);
+    var i, len = arr.length - 1;
+    var j, jLen;
+    var ownArrays = [], ownModifiers = [], styleOb, currentTransform;
+    for(i=len;i>=0;i-=1){
+        if(arr[i].ty == 'fl' || arr[i].ty == 'st' || arr[i].ty == 'gf' || arr[i].ty == 'gs'){
+            data[i] = {};
+            styleOb = {
+                type: arr[i].ty,
+                d: '',
+                ld: '',
+                lvl: level,
+                mdf: false
+            };
+            var pathElement = document.createElementNS(svgNS, "path");
+            data[i].o = PropertyFactory.getProp(this,arr[i].o,0,0.01,dynamicProperties);
+            if(arr[i].ty == 'st' || arr[i].ty == 'gs') {
+                pathElement.setAttribute('stroke-linecap', this.lcEnum[arr[i].lc] || 'round');
+                ////pathElement.style.strokeLinecap = this.lcEnum[arr[i].lc] || 'round';
+                pathElement.setAttribute('stroke-linejoin',this.ljEnum[arr[i].lj] || 'round');
+                ////pathElement.style.strokeLinejoin = this.ljEnum[arr[i].lj] || 'round';
+                pathElement.setAttribute('fill-opacity','0');
+                ////pathElement.style.fillOpacity = 0;
+                if(arr[i].lj == 1) {
+                    pathElement.setAttribute('stroke-miterlimit',arr[i].ml);
+                    ////pathElement.style.strokeMiterlimit = arr[i].ml;
+                }
+
+                data[i].w = PropertyFactory.getProp(this,arr[i].w,0,null,dynamicProperties);
+                if(arr[i].d){
+                    var d = PropertyFactory.getDashProp(this,arr[i].d,'svg',dynamicProperties);
+                    if(!d.k){
+                        pathElement.setAttribute('stroke-dasharray', d.dasharray);
+                        ////pathElement.style.strokeDasharray = d.dasharray;
+                        pathElement.setAttribute('stroke-dashoffset', d.dashoffset);
+                        ////pathElement.style.strokeDashoffset = d.dashoffset;
+                    }
+                    data[i].d = d;
+                }
+
+            }
+            if(arr[i].ty == 'fl' || arr[i].ty == 'st'){
+                data[i].c = PropertyFactory.getProp(this,arr[i].c,1,255,dynamicProperties);
+                container.appendChild(pathElement);
+            } else {
+                data[i].g = PropertyFactory.getGradientProp(this,arr[i].g,dynamicProperties);
+                if(arr[i].t == 2){
+                    data[i].h = PropertyFactory.getProp(this,arr[i].h,1,0.01,dynamicProperties);
+                    data[i].a = PropertyFactory.getProp(this,arr[i].a,1,degToRads,dynamicProperties);
+                }
+                data[i].s = PropertyFactory.getProp(this,arr[i].s,1,null,dynamicProperties);
+                data[i].e = PropertyFactory.getProp(this,arr[i].e,1,null,dynamicProperties);
+                this.setGradientData(pathElement,arr[i],data[i], styleOb);
+                var maskId = this.setGradientOpacity(arr[i],data[i], styleOb);
+                if(maskId){
+                    pathElement.setAttribute('mask','url(#'+maskId+')');
+                }
+                data[i].elem = pathElement;
+                container.appendChild(pathElement);
+            }
+            if(arr[i].r === 2) {
+                pathElement.setAttribute('fill-rule', 'evenodd');
+            }
+
+            if(arr[i].ln){
+                pathElement.setAttribute('id',arr[i].ln);
+            }
+            if(arr[i].cl){
+                pathElement.setAttribute('class',arr[i].cl);
+            }
+            styleOb.pElem = pathElement;
+            this.stylesList.push(styleOb);
+            data[i].style = styleOb;
+            ownArrays.push(styleOb);
+        }else if(arr[i].ty == 'gr'){
+            data[i] = {
+                it: []
+            };
+            var g = document.createElementNS(svgNS,'g');
+            container.appendChild(g);
+            data[i].gr = g;
+            this.searchShapes(arr[i].it,data[i].it,g,dynamicProperties, level + 1, ownTransformers);
+        }else if(arr[i].ty == 'tr'){
+            data[i] = {
+                transform : {
+                    op: PropertyFactory.getProp(this,arr[i].o,0,0.01,dynamicProperties),
+                    mProps: PropertyFactory.getProp(this,arr[i],2,null,dynamicProperties)
+                },
+                elements: []
+            };
+            currentTransform = data[i].transform;
+            ownTransformers.push(currentTransform);
+        }else if(arr[i].ty == 'sh' || arr[i].ty == 'rc' || arr[i].ty == 'el' || arr[i].ty == 'sr'){
+            data[i] = {
+                elements : [],
+                caches:[],
+                styles : [],
+                transformers: ownTransformers,
+                lStr: ''
+            };
+            var ty = 4;
+            if(arr[i].ty == 'rc'){
+                ty = 5;
+            }else if(arr[i].ty == 'el'){
+                ty = 6;
+            }else if(arr[i].ty == 'sr'){
+                ty = 7;
+            }
+            data[i].sh = ShapePropertyFactory.getShapeProp(this,arr[i],ty,dynamicProperties);
+            data[i].lvl = level;
+            this.shapes.push(data[i].sh);
+            this.addShapeToModifiers(data[i]);
+            jLen = this.stylesList.length;
+            for(j=0;j<jLen;j+=1){
+                if(!this.stylesList[j].closed){
+                    data[i].elements.push({
+                        ty:this.stylesList[j].type,
+                        st: this.stylesList[j]
+                    });
+                }
+            }
+        }else if(arr[i].ty == 'tm' || arr[i].ty == 'rd' || arr[i].ty == 'ms' || arr[i].ty == 'rp'){
+            var modifier = ShapeModifiers.getModifier(arr[i].ty);
+            modifier.init(this,arr[i],dynamicProperties);
+            this.shapeModifiers.push(modifier);
+            ownModifiers.push(modifier);
+            data[i] = modifier;
+        }
+    }
+    len = ownArrays.length;
+    for(i=0;i<len;i+=1){
+        ownArrays[i].closed = true;
+    }
+    len = ownModifiers.length;
+    for(i=0;i<len;i+=1){
+        ownModifiers[i].closed = true;
+    }
+};
+
+IShapeElement.prototype.addShapeToModifiers = function(data) {
+    var i, len = this.shapeModifiers.length;
+    for(i=0;i<len;i+=1){
+        this.shapeModifiers[i].addShape(data);
+    }
+};
+
+IShapeElement.prototype.renderModifiers = function() {
+    if(!this.shapeModifiers.length){
+        return;
+    }
+    var i, len = this.shapes.length;
+    for(i=0;i<len;i+=1){
+        this.shapes[i].reset();
+    }
+
+
+    len = this.shapeModifiers.length;
+
+    for(i=len-1;i>=0;i-=1){
+        this.shapeModifiers[i].processShapes(this.firstFrame);
+    }
+};
+
+IShapeElement.prototype.renderFrame = function(parentMatrix){
+    var renderParent = this._parent.renderFrame.call(this,parentMatrix);
+    if(renderParent===false){
+        this.hide();
+        return;
+    }
+    this.globalToLocal([0,0,0]);
+    if(this.hidden){
+        this.layerElement.style.display = 'block';
+        this.hidden = false;
+    }
+    this.renderModifiers();
+    this.renderShape(null,null,true, null);
+};
+
+IShapeElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.layerElement.style.display = 'none';
+        var i, len = this.stylesList.length;
+        for(i=len-1;i>=0;i-=1){
+            if(this.stylesList[i].ld !== '0'){
+                this.stylesList[i].ld = '0';
+                this.stylesList[i].pElem.style.display = 'none';
+                if(this.stylesList[i].pElem.parentNode){
+                    this.stylesList[i].parent = this.stylesList[i].pElem.parentNode;
+                    //this.stylesList[i].pElem.parentNode.removeChild(this.stylesList[i].pElem);
+                }
+            }
+        }
+        this.hidden = true;
+    }
+};
+
+IShapeElement.prototype.renderShape = function(items,data,isMain, container){
+    var i, len;
+    if(!items){
+        items = this.shapesData;
+        len = this.stylesList.length;
+        for(i=0;i<len;i+=1){
+            this.stylesList[i].d = '';
+            this.stylesList[i].mdf = false;
+        }
+    }
+    if(!data){
+        data = this.viewData;
+    }
+    ///
+    ///
+    len = items.length - 1;
+    var ty;
+    for(i=len;i>=0;i-=1){
+        ty = items[i].ty;
+        if(ty == 'tr'){
+            if(this.firstFrame || data[i].transform.op.mdf && container){
+                container.setAttribute('opacity',data[i].transform.op.v);
+            }
+            if(this.firstFrame || data[i].transform.mProps.mdf && container){
+                container.setAttribute('transform',data[i].transform.mProps.v.to2dCSS());
+            }
+        }else if(ty == 'sh' || ty == 'el' || ty == 'rc' || ty == 'sr'){
+            this.renderPath(items[i],data[i]);
+        }else if(ty == 'fl'){
+            this.renderFill(items[i],data[i]);
+        }else if(ty == 'gf'){
+            this.renderGradient(items[i],data[i]);
+        }else if(ty == 'gs'){
+            this.renderGradient(items[i],data[i]);
+            this.renderStroke(items[i],data[i]);
+        }else if(ty == 'st'){
+            this.renderStroke(items[i],data[i]);
+        }else if(ty == 'gr'){
+            this.renderShape(items[i].it,data[i].it,false, data[i].gr);
+        }else if(ty == 'tm'){
+            //
+        }
+    }
+    if(isMain) {
+        len = this.stylesList.length;
+        for (i = 0; i < len; i += 1) {
+            if (this.stylesList[i].ld === '0') {
+                this.stylesList[i].ld = '1';
+                this.stylesList[i].pElem.style.display = 'block';
+                //this.stylesList[i].parent.appendChild(this.stylesList[i].pElem);
+            }
+            if (this.stylesList[i].mdf || this.firstFrame) {
+                this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d);
+                if(this.stylesList[i].msElem){
+                    this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+                }
+            }
+        }
+        if (this.firstFrame) {
+            this.firstFrame = false;
+        }
+    }
+
+};
+
+IShapeElement.prototype.renderPath = function(pathData,viewData){
+    var len, i, j, jLen,pathStringTransformed,redraw,pathNodes,l, lLen = viewData.elements.length;
+    var lvl = viewData.lvl;
+    for(l=0;l<lLen;l+=1){
+        redraw = viewData.sh.mdf || this.firstFrame;
+        pathStringTransformed = 'M0 0';
+        var paths = viewData.sh.paths;
+        jLen = paths._length;
+        if(viewData.elements[l].st.lvl < lvl){
+            var mat = this.mHelper.reset(), props;
+            var iterations = lvl - viewData.elements[l].st.lvl;
+            var k = viewData.transformers.length-1;
+            while(iterations > 0) {
+                redraw = viewData.transformers[k].mProps.mdf || redraw;
+                props = viewData.transformers[k].mProps.v.props;
+                mat.transform(props[0],props[1],props[2],props[3],props[4],props[5],props[6],props[7],props[8],props[9],props[10],props[11],props[12],props[13],props[14],props[15]);
+                iterations --;
+                k --;
+            }
+            if(redraw){
+                for(j=0;j<jLen;j+=1){
+                    pathNodes = paths.shapes[j];
+                    if(pathNodes && pathNodes._length){
+                        len = pathNodes._length;
+                        for (i = 1; i < len; i += 1) {
+                            if (i == 1) {
+                                pathStringTransformed += " M" + mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
+                            }
+                            pathStringTransformed += " C" + mat.applyToPointStringified(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1]) + " " + mat.applyToPointStringified(pathNodes.i[i][0], pathNodes.i[i][1]) + " " + mat.applyToPointStringified(pathNodes.v[i][0], pathNodes.v[i][1]);
+                        }
+                        if (len == 1) {
+                            pathStringTransformed += " M" + mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
+                        }
+                        if (pathNodes.c) {
+                            pathStringTransformed += " C" + mat.applyToPointStringified(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1]) + " " + mat.applyToPointStringified(pathNodes.i[0][0], pathNodes.i[0][1]) + " " + mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
+                            pathStringTransformed += 'z';
+                        }
+                    }
+                }
+                viewData.caches[l] = pathStringTransformed;
+            } else {
+                pathStringTransformed = viewData.caches[l];
+            }
+        } else {
+            if(redraw){
+                for(j=0;j<jLen;j+=1){
+                    pathNodes = paths.shapes[j];
+                    if(pathNodes && pathNodes._length){
+                        len = pathNodes._length;
+                        for (i = 1; i < len; i += 1) {
+                            if (i == 1) {
+                                //pathStringTransformed += " M" + groupTransform.mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
+                                pathStringTransformed += " M" + pathNodes.v[0].join(',');
+                            }
+                            //pathStringTransformed += " C" + groupTransform.mat.applyToPointStringified(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.i[i][0], pathNodes.i[i][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.v[i][0], pathNodes.v[i][1]);
+                            pathStringTransformed += " C" + pathNodes.o[i - 1].join(',') + " " + pathNodes.i[i].join(',') + " " + pathNodes.v[i].join(',');
+                        }
+                        if (len == 1) {
+                            //pathStringTransformed += " M" + groupTransform.mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
+                            pathStringTransformed += " M" + pathNodes.v[0].join(',');
+                        }
+                        if (pathNodes.c && len) {
+                            //pathStringTransformed += " C" + groupTransform.mat.applyToPointStringified(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.i[0][0], pathNodes.i[0][1]) + " " + groupTransform.mat.applyToPointStringified(pathNodes.v[0][0], pathNodes.v[0][1]);
+                            pathStringTransformed += " C" + pathNodes.o[i - 1].join(',') + " " + pathNodes.i[0].join(',') + " " + pathNodes.v[0].join(',');
+                            pathStringTransformed += 'z';
+                        }
+                    }
+                }
+                viewData.caches[l] = pathStringTransformed;
+            } else {
+                pathStringTransformed = viewData.caches[l];
+            }
+        }
+        viewData.elements[l].st.d += pathStringTransformed;
+        viewData.elements[l].st.mdf = redraw || viewData.elements[l].st.mdf;
+    }
+
+};
+
+IShapeElement.prototype.renderFill = function(styleData,viewData){
+    var styleElem = viewData.style;
+
+    if(viewData.c.mdf || this.firstFrame){
+        styleElem.pElem.setAttribute('fill','rgb('+bm_floor(viewData.c.v[0])+','+bm_floor(viewData.c.v[1])+','+bm_floor(viewData.c.v[2])+')');
+        ////styleElem.pElem.style.fill = 'rgb('+bm_floor(viewData.c.v[0])+','+bm_floor(viewData.c.v[1])+','+bm_floor(viewData.c.v[2])+')';
+    }
+    if(viewData.o.mdf || this.firstFrame){
+        styleElem.pElem.setAttribute('fill-opacity',viewData.o.v);
+    }
+};
+
+IShapeElement.prototype.renderGradient = function(styleData,viewData){
+    var gfill = viewData.gf;
+    var opFill = viewData.of;
+    var pt1 = viewData.s.v,pt2 = viewData.e.v;
+
+    if(viewData.o.mdf || this.firstFrame){
+        var attr = styleData.ty === 'gf' ? 'fill-opacity':'stroke-opacity';
+        viewData.elem.setAttribute(attr,viewData.o.v);
+    }
+    //clippedElement.setAttribute('transform','matrix(1,0,0,1,-100,0)');
+    if(viewData.s.mdf || this.firstFrame){
+        var attr1 = styleData.t === 1 ? 'x1':'cx';
+        var attr2 = attr1 === 'x1' ? 'y1':'cy';
+        gfill.setAttribute(attr1,pt1[0]);
+        gfill.setAttribute(attr2,pt1[1]);
+        if(opFill){
+            opFill.setAttribute(attr1,pt1[0]);
+            opFill.setAttribute(attr2,pt1[1]);
+        }
+    }
+    var stops, i, len, stop;
+    if(viewData.g.cmdf || this.firstFrame){
+        stops = viewData.cst;
+        var cValues = viewData.g.c;
+        len = stops.length;
+        for(i=0;i<len;i+=1){
+            stop = stops[i];
+            stop.setAttribute('offset',cValues[i*4]+'%');
+            stop.setAttribute('stop-color','rgb('+cValues[i*4+1]+','+cValues[i*4+2]+','+cValues[i*4+3]+')');
+        }
+    }
+    if(opFill && (viewData.g.omdf || this.firstFrame)){
+        stops = viewData.ost;
+        var oValues = viewData.g.o;
+        len = stops.length;
+        for(i=0;i<len;i+=1){
+            stop = stops[i];
+            stop.setAttribute('offset',oValues[i*2]+'%');
+            stop.setAttribute('stop-opacity',oValues[i*2+1]);
+        }
+    }
+    if(styleData.t === 1){
+        if(viewData.e.mdf  || this.firstFrame){
+            gfill.setAttribute('x2',pt2[0]);
+            gfill.setAttribute('y2',pt2[1]);
+            if(opFill){
+                opFill.setAttribute('x2',pt2[0]);
+                opFill.setAttribute('y2',pt2[1]);
+            }
+        }
+    } else {
+        var rad;
+        if(viewData.s.mdf || viewData.e.mdf || this.firstFrame){
+            rad = Math.sqrt(Math.pow(pt1[0]-pt2[0],2)+Math.pow(pt1[1]-pt2[1],2));
+            gfill.setAttribute('r',rad);
+            if(opFill){
+                opFill.setAttribute('r',rad);
+            }
+        }
+        if(viewData.e.mdf || viewData.h.mdf || viewData.a.mdf || this.firstFrame){
+            if(!rad){
+                rad = Math.sqrt(Math.pow(pt1[0]-pt2[0],2)+Math.pow(pt1[1]-pt2[1],2));
+            }
+            var ang = Math.atan2(pt2[1]-pt1[1], pt2[0]-pt1[0]);
+
+            var percent = viewData.h.v >= 1 ? 0.99 : viewData.h.v <= -1 ? -0.99:viewData.h.v;
+            var dist = rad*percent;
+            var x = Math.cos(ang + viewData.a.v)*dist + pt1[0];
+            var y = Math.sin(ang + viewData.a.v)*dist + pt1[1];
+            gfill.setAttribute('fx',x);
+            gfill.setAttribute('fy',y);
+            if(opFill){
+                opFill.setAttribute('fx',x);
+                opFill.setAttribute('fy',y);
+            }
+        }
+        //gfill.setAttribute('fy','200');
+    }
+};
+
+IShapeElement.prototype.renderStroke = function(styleData,viewData){
+    var styleElem = viewData.style;
+    //TODO fix dashes
+    var d = viewData.d;
+    var dasharray,dashoffset;
+    if(d && d.k && (d.mdf || this.firstFrame)){
+        styleElem.pElem.setAttribute('stroke-dasharray', d.dasharray);
+        ////styleElem.pElem.style.strokeDasharray = d.dasharray;
+        styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset);
+        ////styleElem.pElem.style.strokeDashoffset = d.dashoffset;
+    }
+    if(viewData.c && (viewData.c.mdf || this.firstFrame)){
+        styleElem.pElem.setAttribute('stroke','rgb('+bm_floor(viewData.c.v[0])+','+bm_floor(viewData.c.v[1])+','+bm_floor(viewData.c.v[2])+')');
+        ////styleElem.pElem.style.stroke = 'rgb('+bm_floor(viewData.c.v[0])+','+bm_floor(viewData.c.v[1])+','+bm_floor(viewData.c.v[2])+')';
+    }
+    if(viewData.o.mdf || this.firstFrame){
+        styleElem.pElem.setAttribute('stroke-opacity',viewData.o.v);
+    }
+    if(viewData.w.mdf || this.firstFrame){
+        styleElem.pElem.setAttribute('stroke-width',viewData.w.v);
+        if(styleElem.msElem){
+            styleElem.msElem.setAttribute('stroke-width',viewData.w.v);
+        }
+        ////styleElem.pElem.style.strokeWidth = viewData.w.v;
+    }
+};
+
+IShapeElement.prototype.destroy = function(){
+    this._parent.destroy.call(this._parent);
+    this.shapeData = null;
+    this.viewData = null;
+    this.parentContainer = null;
+    this.placeholder = null;
+};
+
+function ISolidElement(data,parentContainer,globalData,comp, placeholder){
+    this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder);
+}
+createElement(SVGBaseElement, ISolidElement);
+
+ISolidElement.prototype.createElements = function(){
+    this._parent.createElements.call(this);
+
+    var rect = document.createElementNS(svgNS,'rect');
+    ////rect.style.width = this.data.sw;
+    ////rect.style.height = this.data.sh;
+    ////rect.style.fill = this.data.sc;
+    rect.setAttribute('width',this.data.sw);
+    rect.setAttribute('height',this.data.sh);
+    rect.setAttribute('fill',this.data.sc);
+    this.layerElement.appendChild(rect);
+    this.innerElem = rect;
+    if(this.data.ln){
+        this.layerElement.setAttribute('id',this.data.ln);
+    }
+    if(this.data.cl){
+        this.layerElement.setAttribute('class',this.data.cl);
+    }
+};
+
+ISolidElement.prototype.hide = IImageElement.prototype.hide;
+ISolidElement.prototype.renderFrame = IImageElement.prototype.renderFrame;
+ISolidElement.prototype.destroy = IImageElement.prototype.destroy;
+
+var animationManager = (function(){
+    var moduleOb = {};
+    var registeredAnimations = [];
+    var initTime = 0;
+    var len = 0;
+    var idled = true;
+    var playingAnimationsNum = 0;
+
+    function removeElement(ev){
+        var i = 0;
+        var animItem = ev.target;
+        while(i<len) {
+            if (registeredAnimations[i].animation === animItem) {
+                registeredAnimations.splice(i, 1);
+                i -= 1;
+                len -= 1;
+                if(!animItem.isPaused){
+                    subtractPlayingCount();   
+                }
+            }
+            i += 1;
+        }
+    }
+
+    function registerAnimation(element, animationData){
+        if(!element){
+            return null;
+        }
+        var i=0;
+        while(i<len){
+            if(registeredAnimations[i].elem == element && registeredAnimations[i].elem !== null ){
+                return registeredAnimations[i].animation;
+            }
+            i+=1;
+        }
+        var animItem = new AnimationItem();
+        setupAnimation(animItem, element);
+        animItem.setData(element, animationData);
+        return animItem;
+    }
+
+    function addPlayingCount(){
+        playingAnimationsNum += 1;
+        activate();
+    }
+
+    function subtractPlayingCount(){
+        playingAnimationsNum -= 1;
+        if(playingAnimationsNum === 0){
+            idled = true;
+        }
+    }
+
+    function setupAnimation(animItem, element){
+        animItem.addEventListener('destroy',removeElement);
+        animItem.addEventListener('_active',addPlayingCount);
+        animItem.addEventListener('_idle',subtractPlayingCount);
+        registeredAnimations.push({elem: element,animation:animItem});
+        len += 1;
+    }
+
+    function loadAnimation(params){
+        var animItem = new AnimationItem();
+        setupAnimation(animItem, null);
+        animItem.setParams(params);
+        return animItem;
+    }
+
+
+    function setSpeed(val,animation){
+        var i;
+        for(i=0;i<len;i+=1){
+            registeredAnimations[i].animation.setSpeed(val, animation);
+        }
+    }
+
+    function setDirection(val, animation){
+        var i;
+        for(i=0;i<len;i+=1){
+            registeredAnimations[i].animation.setDirection(val, animation);
+        }
+    }
+
+    function play(animation){
+        var i;
+        for(i=0;i<len;i+=1){
+            registeredAnimations[i].animation.play(animation);
+        }
+    }
+
+    function moveFrame (value, animation) {
+        initTime = Date.now();
+        var i;
+        for(i=0;i<len;i+=1){
+            registeredAnimations[i].animation.moveFrame(value,animation);
+        }
+    }
+
+    function resume(nowTime) {
+
+        var elapsedTime = nowTime - initTime;
+        var i;
+        for(i=0;i<len;i+=1){
+            registeredAnimations[i].animation.advanceTime(elapsedTime);
+        }
+        initTime = nowTime;
+        if(!idled) {
+            requestAnimationFrame(resume);
+        }
+    }
+
+    function first(nowTime){
+        initTime = nowTime;
+        requestAnimationFrame(resume);
+    }
+
+    function pause(animation) {
+        var i;
+        for(i=0;i<len;i+=1){
+            registeredAnimations[i].animation.pause(animation);
+        }
+    }
+
+    function goToAndStop(value,isFrame,animation) {
+        var i;
+        for(i=0;i<len;i+=1){
+            registeredAnimations[i].animation.goToAndStop(value,isFrame,animation);
+        }
+    }
+
+    function stop(animation) {
+        var i;
+        for(i=0;i<len;i+=1){
+            registeredAnimations[i].animation.stop(animation);
+        }
+    }
+
+    function togglePause(animation) {
+        var i;
+        for(i=0;i<len;i+=1){
+            registeredAnimations[i].animation.togglePause(animation);
+        }
+    }
+
+    function destroy(animation) {
+        var i;
+        for(i=(len-1);i>=0;i-=1){
+            registeredAnimations[i].animation.destroy(animation);
+        }
+    }
+
+    function searchAnimations(animationData, standalone, renderer){
+        var animElements = document.getElementsByClassName('bodymovin');
+        var i, len = animElements.length;
+        for(i=0;i<len;i+=1){
+            if(renderer){
+                animElements[i].setAttribute('data-bm-type',renderer);
+            }
+            registerAnimation(animElements[i], animationData);
+        }
+        if(standalone && len === 0){
+            if(!renderer){
+                renderer = 'svg';
+            }
+            var body = document.getElementsByTagName('body')[0];
+            body.innerHTML = '';
+            var div = document.createElement('div');
+            div.style.width = '100%';
+            div.style.height = '100%';
+            div.setAttribute('data-bm-type',renderer);
+            body.appendChild(div);
+            registerAnimation(div, animationData);
+        }
+    }
+
+    function resize(){
+        var i;
+        for(i=0;i<len;i+=1){
+            registeredAnimations[i].animation.resize();
+        }
+    }
+
+    function start(){
+        requestAnimationFrame(first);
+    }
+
+    function activate(){
+        if(idled){
+            idled = false;
+            requestAnimationFrame(first);
+        }
+    }
+
+    //start();
+
+    setTimeout(start,0);
+
+    moduleOb.registerAnimation = registerAnimation;
+    moduleOb.loadAnimation = loadAnimation;
+    moduleOb.setSpeed = setSpeed;
+    moduleOb.setDirection = setDirection;
+    moduleOb.play = play;
+    moduleOb.moveFrame = moveFrame;
+    moduleOb.pause = pause;
+    moduleOb.stop = stop;
+    moduleOb.togglePause = togglePause;
+    moduleOb.searchAnimations = searchAnimations;
+    moduleOb.resize = resize;
+    moduleOb.start = start;
+    moduleOb.goToAndStop = goToAndStop;
+    moduleOb.destroy = destroy;
+    return moduleOb;
+}());
+var AnimationItem = function () {
+    this._cbs = [];
+    this.name = '';
+    this.path = '';
+    this.isLoaded = false;
+    this.currentFrame = 0;
+    this.currentRawFrame = 0;
+    this.totalFrames = 0;
+    this.frameRate = 0;
+    this.frameMult = 0;
+    this.playSpeed = 1;
+    this.playDirection = 1;
+    this.pendingElements = 0;
+    this.playCount = 0;
+    this.prerenderFramesFlag = true;
+    this.animationData = {};
+    this.layers = [];
+    this.assets = [];
+    this.isPaused = true;
+    this.autoplay = false;
+    this.loop = true;
+    this.renderer = null;
+    this.animationID = randomString(10);
+    this.scaleMode = 'fit';
+    this.assetsPath = '';
+    this.timeCompleted = 0;
+    this.segmentPos = 0;
+    this.subframeEnabled = subframeEnabled;
+    this.segments = [];
+    this.pendingSegment = false;
+    this._idle = true;
+    this.projectInterface = ProjectInterface();
+};
+
+AnimationItem.prototype.setParams = function(params) {
+    var self = this;
+    if(params.context){
+        this.context = params.context;
+    }
+    if(params.wrapper || params.container){
+        this.wrapper = params.wrapper || params.container;
+    }
+    var animType = params.animType ? params.animType : params.renderer ? params.renderer : 'svg';
+    switch(animType){
+        case 'canvas':
+            this.renderer = new CanvasRenderer(this, params.rendererSettings);
+            break;
+        case 'svg':
+            this.renderer = new SVGRenderer(this, params.rendererSettings);
+            break;
+        case 'hybrid':
+        case 'html':
+        default:
+            this.renderer = new HybridRenderer(this, params.rendererSettings);
+            break;
+    }
+    this.renderer.setProjectInterface(this.projectInterface);
+    this.animType = animType;
+
+    if(params.loop === '' || params.loop === null){
+    }else if(params.loop === false){
+        this.loop = false;
+    }else if(params.loop === true){
+        this.loop = true;
+    }else{
+        this.loop = parseInt(params.loop);
+    }
+    this.autoplay = 'autoplay' in params ? params.autoplay : true;
+    this.name = params.name ? params.name :  '';
+    this.prerenderFramesFlag = 'prerender' in params ? params.prerender : true;
+    this.autoloadSegments = params.hasOwnProperty('autoloadSegments') ? params.autoloadSegments :  true;
+    if(params.animationData){
+        self.configAnimation(params.animationData);
+    }else if(params.path){
+        if(params.path.substr(-4) != 'json'){
+            if (params.path.substr(-1, 1) != '/') {
+                params.path += '/';
+            }
+            params.path += 'data.json';
+        }
+
+        var xhr = new XMLHttpRequest();
+        if(params.path.lastIndexOf('\\') != -1){
+            this.path = params.path.substr(0,params.path.lastIndexOf('\\')+1);
+        }else{
+            this.path = params.path.substr(0,params.path.lastIndexOf('/')+1);
+        }
+        this.assetsPath = params.assetsPath;
+        this.fileName = params.path.substr(params.path.lastIndexOf('/')+1);
+        this.fileName = this.fileName.substr(0,this.fileName.lastIndexOf('.json'));
+        xhr.open('GET', params.path, true);
+        xhr.send();
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                if(xhr.status == 200){
+                    self.configAnimation(JSON.parse(xhr.responseText));
+                }else{
+                    try{
+                        var response = JSON.parse(xhr.responseText);
+                        self.configAnimation(response);
+                    }catch(err){
+                    }
+                }
+            }
+        };
+    }
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+    var params = {
+        wrapper: wrapper,
+        animationData: animationData ? (typeof animationData  === "object") ? animationData : JSON.parse(animationData) : null
+    };
+    var wrapperAttributes = wrapper.attributes;
+
+    params.path = wrapperAttributes.getNamedItem('data-animation-path') ? wrapperAttributes.getNamedItem('data-animation-path').value : wrapperAttributes.getNamedItem('data-bm-path') ? wrapperAttributes.getNamedItem('data-bm-path').value :  wrapperAttributes.getNamedItem('bm-path') ? wrapperAttributes.getNamedItem('bm-path').value : '';
+    params.animType = wrapperAttributes.getNamedItem('data-anim-type') ? wrapperAttributes.getNamedItem('data-anim-type').value : wrapperAttributes.getNamedItem('data-bm-type') ? wrapperAttributes.getNamedItem('data-bm-type').value : wrapperAttributes.getNamedItem('bm-type') ? wrapperAttributes.getNamedItem('bm-type').value :  wrapperAttributes.getNamedItem('data-bm-renderer') ? wrapperAttributes.getNamedItem('data-bm-renderer').value : wrapperAttributes.getNamedItem('bm-renderer') ? wrapperAttributes.getNamedItem('bm-renderer').value : 'canvas';
+
+    var loop = wrapperAttributes.getNamedItem('data-anim-loop') ? wrapperAttributes.getNamedItem('data-anim-loop').value :  wrapperAttributes.getNamedItem('data-bm-loop') ? wrapperAttributes.getNamedItem('data-bm-loop').value :  wrapperAttributes.getNamedItem('bm-loop') ? wrapperAttributes.getNamedItem('bm-loop').value : '';
+    if(loop === ''){
+    }else if(loop === 'false'){
+        params.loop = false;
+    }else if(loop === 'true'){
+        params.loop = true;
+    }else{
+        params.loop = parseInt(loop);
+    }
+    var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') ? wrapperAttributes.getNamedItem('data-anim-autoplay').value :  wrapperAttributes.getNamedItem('data-bm-autoplay') ? wrapperAttributes.getNamedItem('data-bm-autoplay').value :  wrapperAttributes.getNamedItem('bm-autoplay') ? wrapperAttributes.getNamedItem('bm-autoplay').value : true;
+    params.autoplay = autoplay !== "false";
+
+    params.name = wrapperAttributes.getNamedItem('data-name') ? wrapperAttributes.getNamedItem('data-name').value :  wrapperAttributes.getNamedItem('data-bm-name') ? wrapperAttributes.getNamedItem('data-bm-name').value : wrapperAttributes.getNamedItem('bm-name') ? wrapperAttributes.getNamedItem('bm-name').value :  '';
+    var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') ? wrapperAttributes.getNamedItem('data-anim-prerender').value :  wrapperAttributes.getNamedItem('data-bm-prerender') ? wrapperAttributes.getNamedItem('data-bm-prerender').value :  wrapperAttributes.getNamedItem('bm-prerender') ? wrapperAttributes.getNamedItem('bm-prerender').value : '';
+
+    if(prerender === 'false'){
+        params.prerender = false;
+    }
+    this.setParams(params);
+};
+
+AnimationItem.prototype.includeLayers = function(data) {
+    if(data.op > this.animationData.op){
+        this.animationData.op = data.op;
+        this.totalFrames = Math.floor(data.op - this.animationData.ip);
+        this.animationData.tf = this.totalFrames;
+    }
+    var layers = this.animationData.layers;
+    var i, len = layers.length;
+    var newLayers = data.layers;
+    var j, jLen = newLayers.length;
+    for(j=0;j<jLen;j+=1){
+        i = 0;
+        while(i<len){
+            if(layers[i].id == newLayers[j].id){
+                layers[i] = newLayers[j];
+                break;
+            }
+            i += 1;
+        }
+    }
+    if(data.chars || data.fonts){
+        this.renderer.globalData.fontManager.addChars(data.chars);
+        this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+    }
+    if(data.assets){
+        len = data.assets.length;
+        for(i = 0; i < len; i += 1){
+            this.animationData.assets.push(data.assets[i]);
+        }
+    }
+    //this.totalFrames = 50;
+    //this.animationData.tf = 50;
+    this.animationData.__complete = false;
+    dataManager.completeData(this.animationData,this.renderer.globalData.fontManager);
+    this.renderer.includeLayers(data.layers);
+    if(expressionsPlugin){
+        expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.renderFrame(null);
+    this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function() {
+    var segments = this.animationData.segments;
+    if(!segments || segments.length === 0 || !this.autoloadSegments){
+        this.trigger('data_ready');
+        this.timeCompleted = this.animationData.tf;
+        return;
+    }
+    var segment = segments.shift();
+    this.timeCompleted = segment.time * this.frameRate;
+    var xhr = new XMLHttpRequest();
+    var self = this;
+    var segmentPath = this.path+this.fileName+'_' + this.segmentPos + '.json';
+    this.segmentPos += 1;
+    xhr.open('GET', segmentPath, true);
+    xhr.send();
+    xhr.onreadystatechange = function () {
+        if (xhr.readyState == 4) {
+            if(xhr.status == 200){
+                self.includeLayers(JSON.parse(xhr.responseText));
+            }else{
+                try{
+                    var response = JSON.parse(xhr.responseText);
+                    self.includeLayers(response);
+                }catch(err){
+                }
+            }
+        }
+    };
+};
+
+AnimationItem.prototype.loadSegments = function() {
+    var segments = this.animationData.segments;
+    if(!segments) {
+        this.timeCompleted = this.animationData.tf;
+    }
+    this.loadNextSegment();
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+    if(this.renderer && this.renderer.destroyed){
+        return;
+    }
+    //console.log(JSON.parse(JSON.stringify(animData)));
+    //animData.w = Math.round(animData.w/blitter);
+    //animData.h = Math.round(animData.h/blitter);
+    this.animationData = animData;
+    this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+    this.animationData.tf = this.totalFrames;
+    this.renderer.configAnimation(animData);
+    if(!animData.assets){
+        animData.assets = [];
+    }
+    if(animData.comps) {
+        animData.assets = animData.assets.concat(animData.comps);
+        animData.comps = null;
+    }
+    this.renderer.searchExtraCompositions(animData.assets);
+
+    this.layers = this.animationData.layers;
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.firstFrame = Math.round(this.animationData.ip);
+    this.frameMult = this.animationData.fr / 1000;
+    this.trigger('config_ready');
+    this.imagePreloader = new ImagePreloader();
+    this.imagePreloader.setAssetsPath(this.assetsPath);
+    this.imagePreloader.setPath(this.path);
+    this.imagePreloader.loadAssets(animData.assets);
+    this.loadSegments();
+    this.updaFrameModifier();
+    if(this.renderer.globalData.fontManager){
+        this.waitForFontsLoaded();
+    }else{
+        dataManager.completeData(this.animationData,this.renderer.globalData.fontManager);
+        this.checkLoaded();
+    }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = (function(){
+    function checkFontsLoaded(){
+        if(this.renderer.globalData.fontManager.loaded){
+            dataManager.completeData(this.animationData,this.renderer.globalData.fontManager);
+            //this.renderer.buildItems(this.animationData.layers);
+            this.checkLoaded();
+        }else{
+            setTimeout(checkFontsLoaded.bind(this),20);
+        }
+    }
+
+    return function(){
+        checkFontsLoaded.bind(this)();
+    }
+}());
+
+AnimationItem.prototype.addPendingElement = function () {
+    this.pendingElements += 1;
+}
+
+AnimationItem.prototype.elementLoaded = function () {
+    this.pendingElements--;
+    this.checkLoaded();
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+    if (this.pendingElements === 0) {
+        if(expressionsPlugin){
+            expressionsPlugin.initExpressions(this);
+        }
+        this.renderer.initItems();
+        setTimeout(function(){
+            this.trigger('DOMLoaded');
+        }.bind(this),0);
+        this.isLoaded = true;
+        this.gotoFrame();
+        if(this.autoplay){
+            this.play();
+        }
+    }
+};
+
+AnimationItem.prototype.resize = function () {
+    this.renderer.updateContainerSize();
+};
+
+AnimationItem.prototype.setSubframe = function(flag){
+    this.subframeEnabled = flag ? true : false;
+}
+
+AnimationItem.prototype.gotoFrame = function () {
+    if(this.subframeEnabled){
+        this.currentFrame = this.currentRawFrame;
+    }else{
+        this.currentFrame = Math.floor(this.currentRawFrame);
+    }
+
+    if(this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted){
+        this.currentFrame = this.timeCompleted;
+    }
+    this.trigger('enterFrame');
+    this.renderFrame();
+};
+
+AnimationItem.prototype.renderFrame = function () {
+    if(this.isLoaded === false){
+        return;
+    }
+    //console.log('this.currentFrame:',this.currentFrame + this.firstFrame);
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+};
+
+AnimationItem.prototype.play = function (name) {
+    if(name && this.name != name){
+        return;
+    }
+    if(this.isPaused === true){
+        this.isPaused = false;
+        if(this._idle){
+            this._idle = false;
+            this.trigger('_active');
+        }
+    }
+};
+
+AnimationItem.prototype.pause = function (name) {
+    if(name && this.name != name){
+        return;
+    }
+    if(this.isPaused === false){
+        this.isPaused = true;
+        if(!this.pendingSegment){
+            this._idle = true;
+            this.trigger('_idle');
+        }
+    }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+    if(name && this.name != name){
+        return;
+    }
+    if(this.isPaused === true){
+        this.play();
+    }else{
+        this.pause();
+    }
+};
+
+AnimationItem.prototype.stop = function (name) {
+    if(name && this.name != name){
+        return;
+    }
+    this.pause();
+    this.currentFrame = this.currentRawFrame = 0;
+    this.playCount = 0;
+    this.gotoFrame();
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+    if(name && this.name != name){
+        return;
+    }
+    if(isFrame){
+        this.setCurrentRawFrameValue(value);
+    }else{
+        this.setCurrentRawFrameValue(value * this.frameModifier);
+    }
+    this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+    this.goToAndStop(value, isFrame, name);
+    this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+    if(this.pendingSegment){
+        this.pendingSegment = false;
+        this.adjustSegment(this.segments.shift());
+        if(this.isPaused){
+            this.play();
+        }
+        return;
+    }
+    if (this.isPaused === true || this.isLoaded === false) {
+        return;
+    }
+    this.setCurrentRawFrameValue(this.currentRawFrame + value * this.frameModifier);
+};
+
+AnimationItem.prototype.updateAnimation = function (perc) {
+    this.setCurrentRawFrameValue(this.totalFrames * perc);
+};
+
+AnimationItem.prototype.moveFrame = function (value, name) {
+    if(name && this.name != name){
+        return;
+    }
+    this.setCurrentRawFrameValue(this.currentRawFrame+value);
+};
+
+AnimationItem.prototype.adjustSegment = function(arr){
+    this.playCount = 0;
+    if(arr[1] < arr[0]){
+        if(this.frameModifier > 0){
+            if(this.playSpeed < 0){
+                this.setSpeed(-this.playSpeed);
+            } else {
+                this.setDirection(-1);
+            }
+        }
+        this.totalFrames = arr[0] - arr[1];
+        this.firstFrame = arr[1];
+        this.setCurrentRawFrameValue(this.totalFrames - 0.01);
+    } else if(arr[1] > arr[0]){
+        if(this.frameModifier < 0){
+            if(this.playSpeed < 0){
+                this.setSpeed(-this.playSpeed);
+            } else {
+                this.setDirection(1);
+            }
+        }
+        this.totalFrames = arr[1] - arr[0];
+        this.firstFrame = arr[0];
+        this.setCurrentRawFrameValue(0);
+    }
+    this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init,end) {
+    var pendingFrame = -1;
+    if(this.isPaused) {
+        if (this.currentRawFrame + this.firstFrame < init) {
+            pendingFrame = init;
+        } else if (this.currentRawFrame + this.firstFrame > end) {
+            pendingFrame = end - init - 0.01;
+        }
+    }
+
+    this.firstFrame = init;
+    this.totalFrames = end - init;
+    if(pendingFrame !== -1) {
+        this.goToAndStop(pendingFrame,true);
+    }
+}
+
+AnimationItem.prototype.playSegments = function (arr,forceFlag) {
+    if(typeof arr[0] === 'object'){
+        var i, len = arr.length;
+        for(i=0;i<len;i+=1){
+            this.segments.push(arr[i]);
+        }
+    }else{
+        this.segments.push(arr);
+    }
+    if(forceFlag){
+        this.adjustSegment(this.segments.shift());
+    }
+    if(this.isPaused){
+        this.play();
+    }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+    this.segments.length = 0;
+    this.segments.push([this.animationData.ip*this.frameRate,Math.floor(this.animationData.op - this.animationData.ip+this.animationData.ip*this.frameRate)]);
+    if(forceFlag){
+        this.adjustSegment(this.segments.shift());
+    }
+};
+AnimationItem.prototype.checkSegments = function(){
+    if(this.segments.length){
+        this.pendingSegment = true;
+    }
+}
+
+AnimationItem.prototype.remove = function (name) {
+    if(name && this.name != name){
+        return;
+    }
+    this.renderer.destroy();
+};
+
+AnimationItem.prototype.destroy = function (name) {
+    if((name && this.name != name) || (this.renderer && this.renderer.destroyed)){
+        return;
+    }
+    this.renderer.destroy();
+    this.trigger('destroy');
+    this._cbs = null;
+    this.onEnterFrame = this.onLoopComplete = this.onComplete = this.onSegmentStart = this.onDestroy = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function(value){
+    this.currentRawFrame = value;
+    //console.log(this.totalFrames);
+    if (this.currentRawFrame >= this.totalFrames) {
+        this.checkSegments();
+        if(this.loop === false){
+            this.currentRawFrame = this.totalFrames - 0.01;
+            this.gotoFrame();
+            this.pause();
+            this.trigger('complete');
+            return;
+        }else{
+            this.trigger('loopComplete');
+            this.playCount += 1;
+            if((this.loop !== true && this.playCount == this.loop) || this.pendingSegment){
+                this.currentRawFrame = this.totalFrames - 0.01;
+                this.gotoFrame();
+                this.pause();
+                this.trigger('complete');
+                return;
+            } else {
+                this.currentRawFrame = this.currentRawFrame % this.totalFrames;
+            }
+        }
+    } else if (this.currentRawFrame < 0) {
+        this.checkSegments();
+        this.playCount -= 1;
+        if(this.playCount < 0){
+            this.playCount = 0;
+        }
+        if(this.loop === false  || this.pendingSegment){
+            this.currentRawFrame = 0;
+            this.gotoFrame();
+            this.pause();
+            this.trigger('complete');
+            return;
+        }else{
+            this.trigger('loopComplete');
+            this.currentRawFrame = (this.totalFrames + this.currentRawFrame) % this.totalFrames;
+            this.gotoFrame();
+            return;
+        }
+    }
+
+    this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+    this.playSpeed = val;
+    this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+    this.playDirection = val < 0 ? -1 : 1;
+    this.updaFrameModifier();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+    this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+};
+
+AnimationItem.prototype.getPath = function () {
+    return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+    var path = '';
+    if(this.assetsPath){
+        var imagePath = assetData.p;
+        if(imagePath.indexOf('images/') !== -1){
+            imagePath = imagePath.split('/')[1];
+        }
+        path = this.assetsPath + imagePath;
+    } else {
+        path = this.path;
+        path += assetData.u ? assetData.u : '';
+        path += assetData.p;
+    }
+    return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+    var i = 0, len = this.assets.length;
+    while (i < len) {
+        if(id == this.assets[i].id){
+            return this.assets[i];
+        }
+        i += 1;
+    }
+};
+
+AnimationItem.prototype.hide = function () {
+    this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+    this.renderer.show();
+};
+
+AnimationItem.prototype.getAssets = function () {
+    return this.assets;
+};
+
+AnimationItem.prototype.trigger = function(name){
+    if(this._cbs && this._cbs[name]){
+        switch(name){
+            case 'enterFrame':
+                this.triggerEvent(name,new BMEnterFrameEvent(name,this.currentFrame,this.totalFrames,this.frameMult));
+                break;
+            case 'loopComplete':
+                this.triggerEvent(name,new BMCompleteLoopEvent(name,this.loop,this.playCount,this.frameMult));
+                break;
+            case 'complete':
+                this.triggerEvent(name,new BMCompleteEvent(name,this.frameMult));
+                break;
+            case 'segmentStart':
+                this.triggerEvent(name,new BMSegmentStartEvent(name,this.firstFrame,this.totalFrames));
+                break;
+            case 'destroy':
+                this.triggerEvent(name,new BMDestroyEvent(name,this));
+                break;
+            default:
+                this.triggerEvent(name);
+        }
+    }
+    if(name === 'enterFrame' && this.onEnterFrame){
+        this.onEnterFrame.call(this,new BMEnterFrameEvent(name,this.currentFrame,this.totalFrames,this.frameMult));
+    }
+    if(name === 'loopComplete' && this.onLoopComplete){
+        this.onLoopComplete.call(this,new BMCompleteLoopEvent(name,this.loop,this.playCount,this.frameMult));
+    }
+    if(name === 'complete' && this.onComplete){
+        this.onComplete.call(this,new BMCompleteEvent(name,this.frameMult));
+    }
+    if(name === 'segmentStart' && this.onSegmentStart){
+        this.onSegmentStart.call(this,new BMSegmentStartEvent(name,this.firstFrame,this.totalFrames));
+    }
+    if(name === 'destroy' && this.onDestroy){
+        this.onDestroy.call(this,new BMDestroyEvent(name,this));
+    }
+};
+
+AnimationItem.prototype.addEventListener = _addEventListener;
+AnimationItem.prototype.removeEventListener = _removeEventListener;
+AnimationItem.prototype.triggerEvent = _triggerEvent;
+
+function CanvasRenderer(animationItem, config){
+    this.animationItem = animationItem;
+    this.renderConfig = {
+        clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true,
+        context: (config && config.context) || null,
+        progressiveLoad: (config && config.progressiveLoad) || false,
+        preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet'
+    };
+    this.renderConfig.dpr = (config && config.dpr) || 1;
+    if (this.animationItem.wrapper) {
+        this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1;
+    }
+    this.renderedFrame = -1;
+    this.globalData = {
+        frameNum: -1
+    };
+    this.contextData = {
+        saved : Array.apply(null,{length:15}),
+        savedOp: Array.apply(null,{length:15}),
+        cArrPos : 0,
+        cTr : new Matrix(),
+        cO : 1
+    };
+    var i, len = 15;
+    for(i=0;i<len;i+=1){
+        this.contextData.saved[i] = Array.apply(null,{length:16});
+    }
+    this.elements = [];
+    this.pendingElements = [];
+    this.transformMat = new Matrix();
+    this.completeLayers = false;
+}
+extendPrototype(BaseRenderer,CanvasRenderer);
+
+CanvasRenderer.prototype.createBase = function (data) {
+    return new CVBaseElement(data, this, this.globalData);
+};
+
+CanvasRenderer.prototype.createShape = function (data) {
+    return new CVShapeElement(data, this, this.globalData);
+};
+
+CanvasRenderer.prototype.createText = function (data) {
+    return new CVTextElement(data, this, this.globalData);
+};
+
+CanvasRenderer.prototype.createImage = function (data) {
+    return new CVImageElement(data, this, this.globalData);
+};
+
+CanvasRenderer.prototype.createComp = function (data) {
+    return new CVCompElement(data, this, this.globalData);
+};
+
+CanvasRenderer.prototype.createSolid = function (data) {
+    return new CVSolidElement(data, this, this.globalData);
+};
+
+CanvasRenderer.prototype.ctxTransform = function(props){
+    if(props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0){
+        return;
+    }
+    if(!this.renderConfig.clearCanvas){
+        this.canvasContext.transform(props[0],props[1],props[4],props[5],props[12],props[13]);
+        return;
+    }
+    this.transformMat.cloneFromProps(props);
+    this.transformMat.transform(this.contextData.cTr.props[0],this.contextData.cTr.props[1],this.contextData.cTr.props[2],this.contextData.cTr.props[3],this.contextData.cTr.props[4],this.contextData.cTr.props[5],this.contextData.cTr.props[6],this.contextData.cTr.props[7],this.contextData.cTr.props[8],this.contextData.cTr.props[9],this.contextData.cTr.props[10],this.contextData.cTr.props[11],this.contextData.cTr.props[12],this.contextData.cTr.props[13],this.contextData.cTr.props[14],this.contextData.cTr.props[15])
+    //this.contextData.cTr.transform(props[0],props[1],props[2],props[3],props[4],props[5],props[6],props[7],props[8],props[9],props[10],props[11],props[12],props[13],props[14],props[15]);
+    this.contextData.cTr.cloneFromProps(this.transformMat.props);
+    var trProps = this.contextData.cTr.props;
+    this.canvasContext.setTransform(trProps[0],trProps[1],trProps[4],trProps[5],trProps[12],trProps[13]);
+};
+
+CanvasRenderer.prototype.ctxOpacity = function(op){
+    if(op === 1){
+        return;
+    }
+    if(!this.renderConfig.clearCanvas){
+        this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
+        return;
+    }
+    this.contextData.cO *= op < 0 ? 0 : op;
+    this.canvasContext.globalAlpha = this.contextData.cO;
+};
+
+CanvasRenderer.prototype.reset = function(){
+    if(!this.renderConfig.clearCanvas){
+        this.canvasContext.restore();
+        return;
+    }
+    this.contextData.cArrPos = 0;
+    this.contextData.cTr.reset();
+    this.contextData.cO = 1;
+};
+
+CanvasRenderer.prototype.save = function(actionFlag){
+    if(!this.renderConfig.clearCanvas){
+        this.canvasContext.save();
+        return;
+    }
+    if(actionFlag){
+        this.canvasContext.save();
+    }
+    var props = this.contextData.cTr.props;
+    if(this.contextData.saved[this.contextData.cArrPos] === null || this.contextData.saved[this.contextData.cArrPos] === undefined){
+        this.contextData.saved[this.contextData.cArrPos] = new Array(16);
+    }
+    var i,arr = this.contextData.saved[this.contextData.cArrPos];
+    for(i=0;i<16;i+=1){
+        arr[i] = props[i];
+    }
+    this.contextData.savedOp[this.contextData.cArrPos] = this.contextData.cO;
+    this.contextData.cArrPos += 1;
+};
+
+CanvasRenderer.prototype.restore = function(actionFlag){
+    if(!this.renderConfig.clearCanvas){
+        this.canvasContext.restore();
+        return;
+    }
+    if(actionFlag){
+        this.canvasContext.restore();
+    }
+    this.contextData.cArrPos -= 1;
+    var popped = this.contextData.saved[this.contextData.cArrPos];
+    var i,arr = this.contextData.cTr.props;
+    for(i=0;i<16;i+=1){
+        arr[i] = popped[i];
+    }
+    this.canvasContext.setTransform(popped[0],popped[1],popped[4],popped[5],popped[12],popped[13]);
+    popped = this.contextData.savedOp[this.contextData.cArrPos];
+    this.contextData.cO = popped;
+    this.canvasContext.globalAlpha = popped;
+};
+
+CanvasRenderer.prototype.configAnimation = function(animData){
+    if(this.animationItem.wrapper){
+        this.animationItem.container = document.createElement('canvas');
+        this.animationItem.container.style.width = '100%';
+        this.animationItem.container.style.height = '100%';
+        //this.animationItem.container.style.transform = 'translate3d(0,0,0)';
+        //this.animationItem.container.style.webkitTransform = 'translate3d(0,0,0)';
+        this.animationItem.container.style.transformOrigin = this.animationItem.container.style.mozTransformOrigin = this.animationItem.container.style.webkitTransformOrigin = this.animationItem.container.style['-webkit-transform'] = "0px 0px 0px";
+        this.animationItem.wrapper.appendChild(this.animationItem.container);
+        this.canvasContext = this.animationItem.container.getContext('2d');
+    }else{
+        this.canvasContext = this.renderConfig.context;
+    }
+    this.data = animData;
+    this.globalData.canvasContext = this.canvasContext;
+    this.globalData.renderer = this;
+    this.globalData.isDashed = false;
+    this.globalData.totalFrames = Math.floor(animData.tf);
+    this.globalData.compWidth = animData.w;
+    this.globalData.compHeight = animData.h;
+    this.globalData.frameRate = animData.fr;
+    this.globalData.frameId = 0;
+    this.globalData.compSize = {
+        w: animData.w,
+        h: animData.h
+    };
+    this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+    this.layers = animData.layers;
+    this.transformCanvas = {};
+    this.transformCanvas.w = animData.w;
+    this.transformCanvas.h = animData.h;
+    this.globalData.fontManager = new FontManager();
+    this.globalData.fontManager.addChars(animData.chars);
+    this.globalData.fontManager.addFonts(animData.fonts,document.body);
+    this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+    this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+    this.globalData.elementLoaded = this.animationItem.elementLoaded.bind(this.animationItem);
+    this.globalData.addPendingElement = this.animationItem.addPendingElement.bind(this.animationItem);
+    this.globalData.transformCanvas = this.transformCanvas;
+    this.elements = Array.apply(null,{length:animData.layers.length});
+
+    this.updateContainerSize();
+};
+
+CanvasRenderer.prototype.updateContainerSize = function () {
+    var elementWidth,elementHeight;
+    if(this.animationItem.wrapper && this.animationItem.container){
+        elementWidth = this.animationItem.wrapper.offsetWidth;
+        elementHeight = this.animationItem.wrapper.offsetHeight;
+        this.animationItem.container.setAttribute('width',elementWidth * this.renderConfig.dpr );
+        this.animationItem.container.setAttribute('height',elementHeight * this.renderConfig.dpr);
+    }else{
+        elementWidth = this.canvasContext.canvas.width * this.renderConfig.dpr;
+        elementHeight = this.canvasContext.canvas.height * this.renderConfig.dpr;
+    }
+    var elementRel,animationRel;
+    if(this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1){
+        var par = this.renderConfig.preserveAspectRatio.split(' ');
+        var fillType = par[1] || 'meet';
+        var pos = par[0] || 'xMidYMid';
+        var xPos = pos.substr(0,4);
+        var yPos = pos.substr(4);
+        elementRel = elementWidth/elementHeight;
+        animationRel = this.transformCanvas.w/this.transformCanvas.h;
+        if(animationRel>elementRel && fillType === 'meet' || animationRel<elementRel && fillType === 'slice'){
+            this.transformCanvas.sx = elementWidth/(this.transformCanvas.w/this.renderConfig.dpr);
+            this.transformCanvas.sy = elementWidth/(this.transformCanvas.w/this.renderConfig.dpr);
+        }else{
+            this.transformCanvas.sx = elementHeight/(this.transformCanvas.h / this.renderConfig.dpr);
+            this.transformCanvas.sy = elementHeight/(this.transformCanvas.h / this.renderConfig.dpr);
+        }
+
+        if(xPos === 'xMid' && ((animationRel<elementRel && fillType==='meet') || (animationRel>elementRel && fillType === 'slice'))){
+            this.transformCanvas.tx = (elementWidth-this.transformCanvas.w*(elementHeight/this.transformCanvas.h))/2*this.renderConfig.dpr;
+        } else if(xPos === 'xMax' && ((animationRel<elementRel && fillType==='meet') || (animationRel>elementRel && fillType === 'slice'))){
+            this.transformCanvas.tx = (elementWidth-this.transformCanvas.w*(elementHeight/this.transformCanvas.h))*this.renderConfig.dpr;
+        } else {
+            this.transformCanvas.tx = 0;
+        }
+        if(yPos === 'YMid' && ((animationRel>elementRel && fillType==='meet') || (animationRel<elementRel && fillType === 'slice'))){
+            this.transformCanvas.ty = ((elementHeight-this.transformCanvas.h*(elementWidth/this.transformCanvas.w))/2)*this.renderConfig.dpr;
+        } else if(yPos === 'YMax' && ((animationRel>elementRel && fillType==='meet') || (animationRel<elementRel && fillType === 'slice'))){
+            this.transformCanvas.ty = ((elementHeight-this.transformCanvas.h*(elementWidth/this.transformCanvas.w)))*this.renderConfig.dpr;
+        } else {
+            this.transformCanvas.ty = 0;
+        }
+
+    }else if(this.renderConfig.preserveAspectRatio == 'none'){
+        this.transformCanvas.sx = elementWidth/(this.transformCanvas.w/this.renderConfig.dpr);
+        this.transformCanvas.sy = elementHeight/(this.transformCanvas.h/this.renderConfig.dpr);
+        this.transformCanvas.tx = 0;
+        this.transformCanvas.ty = 0;
+    }else{
+        this.transformCanvas.sx = this.renderConfig.dpr;
+        this.transformCanvas.sy = this.renderConfig.dpr;
+        this.transformCanvas.tx = 0;
+        this.transformCanvas.ty = 0;
+    }
+    this.transformCanvas.props = [this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1];
+    var i, len = this.elements.length;
+    for(i=0;i<len;i+=1){
+        if(this.elements[i] && this.elements[i].data.ty === 0){
+            this.elements[i].resize(this.globalData.transformCanvas);
+        }
+    }
+};
+
+CanvasRenderer.prototype.destroy = function () {
+    if(this.renderConfig.clearCanvas) {
+        this.animationItem.wrapper.innerHTML = '';
+    }
+    var i, len = this.layers ? this.layers.length : 0;
+    for (i = len - 1; i >= 0; i-=1) {
+        this.elements[i].destroy();
+    }
+    this.elements.length = 0;
+    this.globalData.canvasContext = null;
+    this.animationItem.container = null;
+    this.destroyed = true;
+};
+
+CanvasRenderer.prototype.renderFrame = function(num){
+    if((this.renderedFrame == num && this.renderConfig.clearCanvas === true) || this.destroyed || num === null){
+        return;
+    }
+    this.renderedFrame = num;
+    this.globalData.frameNum = num - this.animationItem.firstFrame;
+    this.globalData.frameId += 1;
+    this.globalData.projectInterface.currentFrame = num;
+    if(this.renderConfig.clearCanvas === true){
+        this.reset();
+        this.canvasContext.save();
+        //this.canvasContext.canvas.width = this.canvasContext.canvas.width;
+        this.canvasContext.clearRect(this.transformCanvas.tx, this.transformCanvas.ty, this.transformCanvas.w*this.transformCanvas.sx, this.transformCanvas.h*this.transformCanvas.sy);
+    }else{
+        this.save();
+    }
+    this.ctxTransform(this.transformCanvas.props);
+    this.canvasContext.beginPath();
+    this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h);
+    this.canvasContext.closePath();
+    this.canvasContext.clip();
+
+    //console.log('--------');
+    //console.log('NEW: ',num);
+    var i, len = this.layers.length;
+    if(!this.completeLayers){
+        this.checkLayers(num);
+    }
+
+    for (i = 0; i < len; i++) {
+        if(this.completeLayers || this.elements[i]){
+            this.elements[i].prepareFrame(num - this.layers[i].st);
+        }
+    }
+    for (i = len - 1; i >= 0; i-=1) {
+        if(this.completeLayers || this.elements[i]){
+            this.elements[i].renderFrame();
+        }
+    }
+    if(this.renderConfig.clearCanvas !== true){
+        this.restore();
+    } else {
+        this.canvasContext.restore();
+    }
+};
+
+CanvasRenderer.prototype.buildItem = function(pos){
+    var elements = this.elements;
+    if(elements[pos] || this.layers[pos].ty == 99){
+        return;
+    }
+    var element = this.createItem(this.layers[pos], this,this.globalData);
+    elements[pos] = element;
+    element.initExpressions();
+    if(this.layers[pos].ty === 0){
+        element.resize(this.globalData.transformCanvas);
+    }
+};
+
+CanvasRenderer.prototype.checkPendingElements  = function(){
+    while(this.pendingElements.length){
+        var element = this.pendingElements.pop();
+        element.checkParenting();
+    }
+};
+
+CanvasRenderer.prototype.hide = function(){
+    this.animationItem.container.style.display = 'none';
+};
+
+CanvasRenderer.prototype.show = function(){
+    this.animationItem.container.style.display = 'block';
+};
+
+CanvasRenderer.prototype.searchExtraCompositions = function(assets){
+    var i, len = assets.length;
+    var floatingContainer = document.createElementNS(svgNS,'g');
+    for(i=0;i<len;i+=1){
+        if(assets[i].xt){
+            var comp = this.createComp(assets[i],this.globalData.comp,this.globalData);
+            comp.initExpressions();
+            //comp.compInterface = CompExpressionInterface(comp);
+            //Expressions.addLayersInterface(comp.elements, this.globalData.projectInterface);
+            this.globalData.projectInterface.registerComposition(comp);
+        }
+    }
+};
+function HybridRenderer(animationItem){
+    this.animationItem = animationItem;
+    this.layers = null;
+    this.renderedFrame = -1;
+    this.globalData = {
+        frameNum: -1
+    };
+    this.pendingElements = [];
+    this.elements = [];
+    this.threeDElements = [];
+    this.destroyed = false;
+    this.camera = null;
+    this.supports3d = true;
+
+}
+
+extendPrototype(BaseRenderer,HybridRenderer);
+
+HybridRenderer.prototype.buildItem = SVGRenderer.prototype.buildItem;
+
+HybridRenderer.prototype.checkPendingElements  = function(){
+    while(this.pendingElements.length){
+        var element = this.pendingElements.pop();
+        element.checkParenting();
+    }
+};
+
+HybridRenderer.prototype.appendElementInPos = function(element, pos){
+    var newElement = element.getBaseElement();
+    if(!newElement){
+        return;
+    }
+    var layer = this.layers[pos];
+    if(!layer.ddd || !this.supports3d){
+        var i = 0;
+        var nextElement;
+        while(i<pos){
+            if(this.elements[i] && this.elements[i]!== true && this.elements[i].getBaseElement){
+                nextElement = this.elements[i].getBaseElement();
+            }
+            i += 1;
+        }
+        if(nextElement){
+            if(!layer.ddd || !this.supports3d){
+                this.layerElement.insertBefore(newElement, nextElement);
+            }
+        } else {
+            if(!layer.ddd || !this.supports3d){
+                this.layerElement.appendChild(newElement);
+            }
+        }
+    } else {
+        this.addTo3dContainer(newElement,pos);
+    }
+};
+
+
+HybridRenderer.prototype.createBase = function (data) {
+    return new SVGBaseElement(data, this.layerElement,this.globalData,this);
+};
+
+HybridRenderer.prototype.createShape = function (data) {
+    if(!this.supports3d){
+        return new IShapeElement(data, this.layerElement,this.globalData,this);
+    }
+    return new HShapeElement(data, this.layerElement,this.globalData,this);
+};
+
+HybridRenderer.prototype.createText = function (data) {
+    if(!this.supports3d){
+        return new SVGTextElement(data, this.layerElement,this.globalData,this);
+    }
+    return new HTextElement(data, this.layerElement,this.globalData,this);
+};
+
+HybridRenderer.prototype.createCamera = function (data) {
+    this.camera = new HCameraElement(data, this.layerElement,this.globalData,this);
+    return this.camera;
+};
+
+HybridRenderer.prototype.createImage = function (data) {
+    if(!this.supports3d){
+        return new IImageElement(data, this.layerElement,this.globalData,this);
+    }
+    return new HImageElement(data, this.layerElement,this.globalData,this);
+};
+
+HybridRenderer.prototype.createComp = function (data) {
+    if(!this.supports3d){
+        return new ICompElement(data, this.layerElement,this.globalData,this);
+    }
+    return new HCompElement(data, this.layerElement,this.globalData,this);
+
+};
+
+HybridRenderer.prototype.createSolid = function (data) {
+    if(!this.supports3d){
+        return new ISolidElement(data, this.layerElement,this.globalData,this);
+    }
+    return new HSolidElement(data, this.layerElement,this.globalData,this);
+};
+
+HybridRenderer.prototype.getThreeDContainer = function(pos){
+    var perspectiveElem = document.createElement('div');
+    styleDiv(perspectiveElem);
+    perspectiveElem.style.width = this.globalData.compSize.w+'px';
+    perspectiveElem.style.height = this.globalData.compSize.h+'px';
+    perspectiveElem.style.transformOrigin = perspectiveElem.style.mozTransformOrigin = perspectiveElem.style.webkitTransformOrigin = "50% 50%";
+    var container = document.createElement('div');
+    styleDiv(container);
+    container.style.transform = container.style.webkitTransform = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+    perspectiveElem.appendChild(container);
+    this.resizerElem.appendChild(perspectiveElem);
+    var threeDContainerData = {
+        container:container,
+        perspectiveElem:perspectiveElem,
+        startPos: pos,
+        endPos: pos
+    };
+    this.threeDElements.push(threeDContainerData);
+    return threeDContainerData;
+};
+
+HybridRenderer.prototype.build3dContainers = function(){
+    var i, len = this.layers.length;
+    var lastThreeDContainerData;
+    for(i=0;i<len;i+=1){
+        if(this.layers[i].ddd){
+            if(!lastThreeDContainerData){
+                lastThreeDContainerData = this.getThreeDContainer(i);
+            }
+            lastThreeDContainerData.endPos = Math.max(lastThreeDContainerData.endPos,i);
+        } else {
+            lastThreeDContainerData = null;
+        }
+    }
+};
+
+HybridRenderer.prototype.addTo3dContainer = function(elem,pos){
+    var i = 0, len = this.threeDElements.length;
+    while(i<len){
+        if(pos <= this.threeDElements[i].endPos){
+            var j = this.threeDElements[i].startPos;
+            var nextElement;
+            while(j<pos){
+                if(this.elements[j] && this.elements[j].getBaseElement){
+                    nextElement = this.elements[j].getBaseElement();
+                }
+                j += 1;
+            }
+            if(nextElement){
+                this.threeDElements[i].container.insertBefore(elem, nextElement);
+            } else {
+                this.threeDElements[i].container.appendChild(elem);
+            }
+            break;
+        }
+        i += 1;
+    }
+};
+
+HybridRenderer.prototype.configAnimation = function(animData){
+    var resizerElem = document.createElement('div');
+    var wrapper = this.animationItem.wrapper;
+    resizerElem.style.width = animData.w+'px';
+    resizerElem.style.height = animData.h+'px';
+    this.resizerElem = resizerElem;
+    styleDiv(resizerElem);
+    resizerElem.style.transformStyle = resizerElem.style.webkitTransformStyle = resizerElem.style.mozTransformStyle = "flat";
+    wrapper.appendChild(resizerElem);
+
+    resizerElem.style.overflow = 'hidden';
+    var svg = document.createElementNS(svgNS,'svg');
+    svg.setAttribute('width','1');
+    svg.setAttribute('height','1');
+    styleDiv(svg);
+    this.resizerElem.appendChild(svg);
+    var defs = document.createElementNS(svgNS,'defs');
+    svg.appendChild(defs);
+    this.globalData.defs = defs;
+    this.data = animData;
+    //Mask animation
+    this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+    this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+    this.globalData.elementLoaded = this.animationItem.elementLoaded.bind(this.animationItem);
+    this.globalData.frameId = 0;
+    this.globalData.compSize = {
+        w: animData.w,
+        h: animData.h
+    };
+    this.globalData.frameRate = animData.fr;
+    this.layers = animData.layers;
+    this.globalData.fontManager = new FontManager();
+    this.globalData.fontManager.addChars(animData.chars);
+    this.globalData.fontManager.addFonts(animData.fonts,svg);
+    this.layerElement = this.resizerElem;
+    this.build3dContainers();
+    this.updateContainerSize();
+};
+
+HybridRenderer.prototype.destroy = function () {
+    this.animationItem.wrapper.innerHTML = '';
+    this.animationItem.container = null;
+    this.globalData.defs = null;
+    var i, len = this.layers ? this.layers.length : 0;
+    for (i = 0; i < len; i++) {
+        this.elements[i].destroy();
+    }
+    this.elements.length = 0;
+    this.destroyed = true;
+    this.animationItem = null;
+};
+
+HybridRenderer.prototype.updateContainerSize = function () {
+    var elementWidth = this.animationItem.wrapper.offsetWidth;
+    var elementHeight = this.animationItem.wrapper.offsetHeight;
+    var elementRel = elementWidth/elementHeight;
+    var animationRel = this.globalData.compSize.w/this.globalData.compSize.h;
+    var sx,sy,tx,ty;
+    if(animationRel>elementRel){
+        sx = elementWidth/(this.globalData.compSize.w);
+        sy = elementWidth/(this.globalData.compSize.w);
+        tx = 0;
+        ty = ((elementHeight-this.globalData.compSize.h*(elementWidth/this.globalData.compSize.w))/2);
+    }else{
+        sx = elementHeight/(this.globalData.compSize.h);
+        sy = elementHeight/(this.globalData.compSize.h);
+        tx = (elementWidth-this.globalData.compSize.w*(elementHeight/this.globalData.compSize.h))/2;
+        ty = 0;
+    }
+    this.resizerElem.style.transform = this.resizerElem.style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,'+sy+',0,0,0,0,1,0,'+tx+','+ty+',0,1)';
+};
+
+HybridRenderer.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
+
+HybridRenderer.prototype.hide = function(){
+    this.resizerElem.style.display = 'none';
+};
+
+HybridRenderer.prototype.show = function(){
+    this.resizerElem.style.display = 'block';
+};
+
+HybridRenderer.prototype.initItems = function(){
+    this.buildAllItems();
+    if(this.camera){
+        this.camera.setup();
+    } else {
+        var cWidth = this.globalData.compSize.w;
+        var cHeight = this.globalData.compSize.h;
+        var i, len = this.threeDElements.length;
+        for(i=0;i<len;i+=1){
+            this.threeDElements[i].perspectiveElem.style.perspective = this.threeDElements[i].perspectiveElem.style.webkitPerspective = Math.sqrt(Math.pow(cWidth,2) + Math.pow(cHeight,2)) + 'px';
+        }
+    }
+};
+
+HybridRenderer.prototype.searchExtraCompositions = function(assets){
+    var i, len = assets.length;
+    var floatingContainer = document.createElement('div');
+    for(i=0;i<len;i+=1){
+        if(assets[i].xt){
+            var comp = this.createComp(assets[i],floatingContainer,this.globalData.comp,null);
+            comp.initExpressions();
+            this.globalData.projectInterface.registerComposition(comp);
+        }
+    }
+};
+function CVBaseElement(data, comp,globalData){
+    this.globalData = globalData;
+    this.data = data;
+    this.comp = comp;
+    this.canvasContext = globalData.canvasContext;
+    this.init();
+}
+
+createElement(BaseElement, CVBaseElement);
+
+CVBaseElement.prototype.createElements = function(){
+    this.checkParenting();
+};
+
+CVBaseElement.prototype.checkBlendMode = function(globalData){
+    if(globalData.blendMode !== this.data.bm) {
+        globalData.blendMode = this.data.bm;
+
+        var blendModeValue = '';
+        switch (this.data.bm) {
+            case 0:
+                blendModeValue = 'normal';
+                break;
+            case 1:
+                blendModeValue = 'multiply';
+                break;
+            case 2:
+                blendModeValue = 'screen';
+                break;
+            case 3:
+                blendModeValue = 'overlay';
+                break;
+            case 4:
+                blendModeValue = 'darken';
+                break;
+            case 5:
+                blendModeValue = 'lighten';
+                break;
+            case 6:
+                blendModeValue = 'color-dodge';
+                break;
+            case 7:
+                blendModeValue = 'color-burn';
+                break;
+            case 8:
+                blendModeValue = 'hard-light';
+                break;
+            case 9:
+                blendModeValue = 'soft-light';
+                break;
+            case 10:
+                blendModeValue = 'difference';
+                break;
+            case 11:
+                blendModeValue = 'exclusion';
+                break;
+            case 12:
+                blendModeValue = 'hue';
+                break;
+            case 13:
+                blendModeValue = 'saturation';
+                break;
+            case 14:
+                blendModeValue = 'color';
+                break;
+            case 15:
+                blendModeValue = 'luminosity';
+                break;
+        }
+        globalData.canvasContext.globalCompositeOperation = blendModeValue;
+    }
+};
+
+
+CVBaseElement.prototype.renderFrame = function(parentTransform){
+    if(this.data.ty === 3){
+        return false;
+    }
+        this.checkBlendMode(this.data.ty === 0?this.parentGlobalData:this.globalData);
+
+    if(!this.isVisible){
+        return this.isVisible;
+    }
+    this.finalTransform.opMdf = this.finalTransform.op.mdf;
+    this.finalTransform.matMdf = this.finalTransform.mProp.mdf;
+    this.finalTransform.opacity = this.finalTransform.op.v;
+
+    var mat;
+    var finalMat = this.finalTransform.mat;
+
+    if(this.hierarchy){
+        var i, len = this.hierarchy.length;
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for(i=0;i<len;i+=1){
+            this.finalTransform.matMdf = this.hierarchy[i].finalTransform.mProp.mdf ? true : this.finalTransform.matMdf;
+            mat = this.hierarchy[i].finalTransform.mProp.v.props;
+            finalMat.transform(mat[0],mat[1],mat[2],mat[3],mat[4],mat[5],mat[6],mat[7],mat[8],mat[9],mat[10],mat[11],mat[12],mat[13],mat[14],mat[15]);
+        }
+    }else{
+        if(!parentTransform){
+            finalMat.cloneFromProps(this.finalTransform.mProp.v.props);
+        }else{
+            mat = this.finalTransform.mProp.v.props;
+            finalMat.cloneFromProps(mat);
+        }
+    }
+
+    if(parentTransform){
+        mat = parentTransform.mat.props;
+        finalMat.transform(mat[0],mat[1],mat[2],mat[3],mat[4],mat[5],mat[6],mat[7],mat[8],mat[9],mat[10],mat[11],mat[12],mat[13],mat[14],mat[15]);
+        this.finalTransform.opacity *= parentTransform.opacity;
+        this.finalTransform.opMdf = parentTransform.opMdf ? true : this.finalTransform.opMdf;
+        this.finalTransform.matMdf = parentTransform.matMdf ? true : this.finalTransform.matMdf
+    }
+
+    if(this.data.hasMask){
+        this.globalData.renderer.save(true);
+        this.maskManager.renderFrame(this.data.ty === 0?null:finalMat);
+    }
+    if(this.data.hd){
+        this.isVisible = false;
+    }
+    return this.isVisible;
+
+};
+
+CVBaseElement.prototype.addMasks = function(data){
+    this.maskManager = new CVMaskElement(data,this,this.globalData);
+};
+
+
+CVBaseElement.prototype.destroy = function(){
+    this.canvasContext = null;
+    this.data = null;
+    this.globalData = null;
+    if(this.maskManager) {
+        this.maskManager.destroy();
+    }
+};
+
+CVBaseElement.prototype.mHelper = new Matrix();
+
+function CVCompElement(data, comp,globalData){
+    this._parent.constructor.call(this,data, comp,globalData);
+    var compGlobalData = {};
+    for(var s in globalData){
+        if(globalData.hasOwnProperty(s)){
+            compGlobalData[s] = globalData[s];
+        }
+    }
+    compGlobalData.renderer = this;
+    compGlobalData.compHeight = this.data.h;
+    compGlobalData.compWidth = this.data.w;
+    this.renderConfig = {
+        clearCanvas: true
+    };
+    this.contextData = {
+        saved : Array.apply(null,{length:15}),
+        savedOp: Array.apply(null,{length:15}),
+        cArrPos : 0,
+        cTr : new Matrix(),
+        cO : 1
+    };
+    this.completeLayers = false;
+    var i, len = 15;
+    for(i=0;i<len;i+=1){
+        this.contextData.saved[i] = Array.apply(null,{length:16});
+    }
+    this.transformMat = new Matrix();
+    this.parentGlobalData = this.globalData;
+    var cv = document.createElement('canvas');
+    //document.body.appendChild(cv);
+    compGlobalData.canvasContext = cv.getContext('2d');
+    this.canvasContext = compGlobalData.canvasContext;
+    cv.width = this.data.w;
+    cv.height = this.data.h;
+    this.canvas = cv;
+    this.globalData = compGlobalData;
+    this.layers = data.layers;
+    this.pendingElements = [];
+    this.elements = Array.apply(null,{length:this.layers.length});
+    if(this.data.tm){
+        this.tm = PropertyFactory.getProp(this,this.data.tm,0,globalData.frameRate,this.dynamicProperties);
+    }
+    if(this.data.xt || !globalData.progressiveLoad){
+        this.buildAllItems();
+    }
+}
+createElement(CVBaseElement, CVCompElement);
+
+CVCompElement.prototype.ctxTransform = CanvasRenderer.prototype.ctxTransform;
+CVCompElement.prototype.ctxOpacity = CanvasRenderer.prototype.ctxOpacity;
+CVCompElement.prototype.save = CanvasRenderer.prototype.save;
+CVCompElement.prototype.restore = CanvasRenderer.prototype.restore;
+CVCompElement.prototype.reset =  function(){
+    this.contextData.cArrPos = 0;
+    this.contextData.cTr.reset();
+    this.contextData.cO = 1;
+};
+CVCompElement.prototype.resize = function(transformCanvas){
+    var maxScale = Math.max(transformCanvas.sx,transformCanvas.sy);
+    this.canvas.width = this.data.w*maxScale;
+    this.canvas.height = this.data.h*maxScale;
+    this.transformCanvas = {
+        sc:maxScale,
+        w:this.data.w*maxScale,
+        h:this.data.h*maxScale,
+        props:[maxScale,0,0,0,0,maxScale,0,0,0,0,1,0,0,0,0,1]
+    }
+    var i,len = this.elements.length;
+    for( i = 0; i < len; i+=1 ){
+        if(this.elements[i] && this.elements[i].data.ty === 0){
+            this.elements[i].resize(transformCanvas);
+        }
+    }
+};
+
+CVCompElement.prototype.prepareFrame = function(num){
+    this.globalData.frameId = this.parentGlobalData.frameId;
+    this.globalData.mdf = false;
+    this._parent.prepareFrame.call(this,num);
+    if(this.isVisible===false && !this.data.xt){
+        return;
+    }
+    var timeRemapped = num;
+    if(this.tm){
+        timeRemapped = this.tm.v;
+        if(timeRemapped === this.data.op){
+            timeRemapped = this.data.op - 1;
+        }
+    }
+    this.renderedFrame = timeRemapped/this.data.sr;
+    var i,len = this.elements.length;
+
+    if(!this.completeLayers){
+        this.checkLayers(num);
+    }
+
+    for( i = 0; i < len; i+=1 ){
+        if(this.completeLayers || this.elements[i]){
+            this.elements[i].prepareFrame(timeRemapped/this.data.sr - this.layers[i].st);
+            if(this.elements[i].data.ty === 0 && this.elements[i].globalData.mdf){
+                this.globalData.mdf = true;
+            }
+        }
+    }
+    if(this.globalData.mdf && !this.data.xt){
+        this.canvasContext.clearRect(0, 0, this.data.w, this.data.h);
+        this.ctxTransform(this.transformCanvas.props);
+    }
+};
+
+CVCompElement.prototype.renderFrame = function(parentMatrix){
+    if(this._parent.renderFrame.call(this,parentMatrix)===false){
+        return;
+    }
+    if(this.globalData.mdf){
+        var i,len = this.layers.length;
+        for( i = len - 1; i >= 0; i -= 1 ){
+            if(this.completeLayers || this.elements[i]){
+                this.elements[i].renderFrame();
+            }
+        }
+    }
+    if(this.data.hasMask){
+        this.globalData.renderer.restore(true);
+    }
+    if(this.firstFrame){
+        this.firstFrame = false;
+    }
+    this.parentGlobalData.renderer.save();
+    this.parentGlobalData.renderer.ctxTransform(this.finalTransform.mat.props);
+    this.parentGlobalData.renderer.ctxOpacity(this.finalTransform.opacity);
+    this.parentGlobalData.renderer.canvasContext.drawImage(this.canvas,0,0,this.data.w,this.data.h);
+    this.parentGlobalData.renderer.restore();
+
+    if(this.globalData.mdf){
+        this.reset();
+    }
+};
+
+CVCompElement.prototype.setElements = function(elems){
+    this.elements = elems;
+};
+
+CVCompElement.prototype.getElements = function(){
+    return this.elements;
+};
+
+CVCompElement.prototype.destroy = function(){
+    var i,len = this.layers.length;
+    for( i = len - 1; i >= 0; i -= 1 ){
+        this.elements[i].destroy();
+    }
+    this.layers = null;
+    this.elements = null;
+    this._parent.destroy.call(this._parent);
+};
+CVCompElement.prototype.checkLayers = CanvasRenderer.prototype.checkLayers;
+CVCompElement.prototype.buildItem = CanvasRenderer.prototype.buildItem;
+CVCompElement.prototype.checkPendingElements = CanvasRenderer.prototype.checkPendingElements;
+CVCompElement.prototype.addPendingElement = CanvasRenderer.prototype.addPendingElement;
+CVCompElement.prototype.buildAllItems = CanvasRenderer.prototype.buildAllItems;
+CVCompElement.prototype.createItem = CanvasRenderer.prototype.createItem;
+CVCompElement.prototype.createImage = CanvasRenderer.prototype.createImage;
+CVCompElement.prototype.createComp = CanvasRenderer.prototype.createComp;
+CVCompElement.prototype.createSolid = CanvasRenderer.prototype.createSolid;
+CVCompElement.prototype.createShape = CanvasRenderer.prototype.createShape;
+CVCompElement.prototype.createText = CanvasRenderer.prototype.createText;
+CVCompElement.prototype.createBase = CanvasRenderer.prototype.createBase;
+CVCompElement.prototype.buildElementParenting = CanvasRenderer.prototype.buildElementParenting;
+function CVImageElement(data, comp,globalData){
+    this.assetData = globalData.getAssetData(data.refId);
+    this._parent.constructor.call(this,data, comp,globalData);
+    this.globalData.addPendingElement();
+}
+createElement(CVBaseElement, CVImageElement);
+
+CVImageElement.prototype.createElements = function(){
+    var imageLoaded = function(){
+        this.globalData.elementLoaded();
+        if(this.assetData.w !== this.img.width || this.assetData.h !== this.img.height){
+            var canvas = document.createElement('canvas');
+            canvas.width = this.assetData.w;
+            canvas.height = this.assetData.h;
+            var ctx = canvas.getContext('2d');
+
+            var imgW = this.img.width;
+            var imgH = this.img.height;
+            var imgRel = imgW / imgH;
+            var canvasRel = this.assetData.w/this.assetData.h;
+            var widthCrop, heightCrop;
+            if(imgRel>canvasRel){
+                heightCrop = imgH;
+                widthCrop = heightCrop*canvasRel;
+            } else {
+                widthCrop = imgW;
+                heightCrop = widthCrop/canvasRel;
+            }
+            ctx.drawImage(this.img,(imgW-widthCrop)/2,(imgH-heightCrop)/2,widthCrop,heightCrop,0,0,this.assetData.w,this.assetData.h);
+            this.img = canvas;
+        }
+    }.bind(this);
+    var imageFailed = function(){
+        this.failed = true;
+        this.globalData.elementLoaded();
+    }.bind(this);
+
+    this.img = new Image();
+    this.img.addEventListener('load', imageLoaded, false);
+    this.img.addEventListener('error', imageFailed, false);
+    var assetPath = this.globalData.getAssetsPath(this.assetData);
+    this.img.src = assetPath;
+
+    this._parent.createElements.call(this);
+
+};
+
+CVImageElement.prototype.renderFrame = function(parentMatrix){
+    if(this.failed){
+        return;
+    }
+    if(this._parent.renderFrame.call(this,parentMatrix)===false){
+        return;
+    }
+    var ctx = this.canvasContext;
+    this.globalData.renderer.save();
+    var finalMat = this.finalTransform.mat.props;
+    this.globalData.renderer.ctxTransform(finalMat);
+    this.globalData.renderer.ctxOpacity(this.finalTransform.opacity);
+    ctx.drawImage(this.img,0,0);
+    this.globalData.renderer.restore(this.data.hasMask);
+    if(this.firstFrame){
+        this.firstFrame = false;
+    }
+};
+
+CVImageElement.prototype.destroy = function(){
+    this.img = null;
+    this._parent.destroy.call(this._parent);
+};
+
+function CVMaskElement(data,element){
+    this.data = data;
+    this.element = element;
+    this.dynamicProperties = [];
+    this.masksProperties = this.data.masksProperties;
+    this.viewData = new Array(this.masksProperties.length);
+    var i, len = this.masksProperties.length;
+    for (i = 0; i < len; i++) {
+        this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[i],3,this.dynamicProperties,null);
+    }
+}
+
+CVMaskElement.prototype.getMaskProperty = function(pos){
+    return this.viewData[pos];
+};
+
+CVMaskElement.prototype.prepareFrame = function(num){
+    var i, len = this.dynamicProperties.length;
+    for(i=0;i<len;i+=1){
+        this.dynamicProperties[i].getValue(num);
+        if(this.dynamicProperties[i].mdf){
+            this.element.globalData.mdf = true;
+        }
+    }
+};
+
+CVMaskElement.prototype.renderFrame = function (transform) {
+    var ctx = this.element.canvasContext;
+    var i, len = this.data.masksProperties.length;
+    var pt,pt2,pt3,data, hasMasks = false;
+    for (i = 0; i < len; i++) {
+        if(this.masksProperties[i].mode === 'n'){
+            continue;
+        }
+        if(hasMasks === false){
+            ctx.beginPath();
+            hasMasks = true;
+        }
+        if (this.masksProperties[i].inv) {
+            ctx.moveTo(0, 0);
+            ctx.lineTo(this.element.globalData.compWidth, 0);
+            ctx.lineTo(this.element.globalData.compWidth, this.element.globalData.compHeight);
+            ctx.lineTo(0, this.element.globalData.compHeight);
+            ctx.lineTo(0, 0);
+        }
+        data = this.viewData[i].v;
+        pt = transform ? transform.applyToPointArray(data.v[0][0],data.v[0][1],0):data.v[0];
+        ctx.moveTo(pt[0], pt[1]);
+        var j, jLen = data._length;
+        for (j = 1; j < jLen; j++) {
+            pt = transform ? transform.applyToPointArray(data.o[j - 1][0],data.o[j - 1][1],0) : data.o[j - 1];
+            pt2 = transform ? transform.applyToPointArray(data.i[j][0],data.i[j][1],0) : data.i[j];
+            pt3 = transform ? transform.applyToPointArray(data.v[j][0],data.v[j][1],0) : data.v[j];
+            ctx.bezierCurveTo(pt[0], pt[1], pt2[0], pt2[1], pt3[0], pt3[1]);
+        }
+        pt = transform ? transform.applyToPointArray(data.o[j - 1][0],data.o[j - 1][1],0) : data.o[j - 1];
+        pt2 = transform ? transform.applyToPointArray(data.i[0][0],data.i[0][1],0) : data.i[0];
+        pt3 = transform ? transform.applyToPointArray(data.v[0][0],data.v[0][1],0) : data.v[0];
+        ctx.bezierCurveTo(pt[0], pt[1], pt2[0], pt2[1], pt3[0], pt3[1]);
+    }
+    if(hasMasks){
+        ctx.clip();
+    }
+};
+
+CVMaskElement.prototype.getMask = function(nm){
+    var i = 0, len = this.masksProperties.length;
+    while(i<len){
+        if(this.masksProperties[i].nm === nm){
+            return {
+                maskPath: this.viewData[i].pv
+            }
+        }
+        i += 1;
+    }
+};
+
+CVMaskElement.prototype.destroy = function(){
+    this.element = null;
+};
+function CVShapeElement(data, comp,globalData){
+    this.shapes = [];
+    this.stylesList = [];
+    this.viewData = [];
+    this.shapeModifiers = [];
+    this.shapesData = data.shapes;
+    this.firstFrame = true;
+    this._parent.constructor.call(this,data, comp,globalData);
+}
+createElement(CVBaseElement, CVShapeElement);
+
+CVShapeElement.prototype.lcEnum = {
+    '1': 'butt',
+    '2': 'round',
+    '3': 'butt'
+}
+
+CVShapeElement.prototype.ljEnum = {
+    '1': 'miter',
+    '2': 'round',
+    '3': 'butt'
+};
+CVShapeElement.prototype.transformHelper = {opacity:1,mat:new Matrix(),matMdf:false,opMdf:false};
+
+CVShapeElement.prototype.dashResetter = [];
+
+CVShapeElement.prototype.createElements = function(){
+
+    this._parent.createElements.call(this);
+    this.searchShapes(this.shapesData,this.viewData,this.dynamicProperties);
+};
+CVShapeElement.prototype.searchShapes = function(arr,data,dynamicProperties){
+    var i, len = arr.length - 1;
+    var j, jLen;
+    var ownArrays = [], ownModifiers = [], styleElem;
+    for(i=len;i>=0;i-=1){
+        if(arr[i].ty == 'fl' || arr[i].ty == 'st'){
+            styleElem = {
+                type: arr[i].ty,
+                elements: []
+            };
+            data[i] = {};
+            if(arr[i].ty == 'fl' || arr[i].ty == 'st'){
+                data[i].c = PropertyFactory.getProp(this,arr[i].c,1,255,dynamicProperties);
+                if(!data[i].c.k){
+                    styleElem.co = 'rgb('+bm_floor(data[i].c.v[0])+','+bm_floor(data[i].c.v[1])+','+bm_floor(data[i].c.v[2])+')';
+                }
+            }
+            data[i].o = PropertyFactory.getProp(this,arr[i].o,0,0.01,dynamicProperties);
+            if(arr[i].ty == 'st') {
+                styleElem.lc = this.lcEnum[arr[i].lc] || 'round';
+                styleElem.lj = this.ljEnum[arr[i].lj] || 'round';
+                if(arr[i].lj == 1) {
+                    styleElem.ml = arr[i].ml;
+                }
+                data[i].w = PropertyFactory.getProp(this,arr[i].w,0,null,dynamicProperties);
+                if(!data[i].w.k){
+                    styleElem.wi = data[i].w.v;
+                }
+                if(arr[i].d){
+                    var d = PropertyFactory.getDashProp(this,arr[i].d,'canvas',dynamicProperties);
+                    data[i].d = d;
+                    if(!data[i].d.k){
+                        styleElem.da = data[i].d.dasharray;
+                        styleElem.do = data[i].d.dashoffset;
+                    }
+                }
+
+            } else {
+
+                styleElem.r = arr[i].r === 2 ? 'evenodd' : 'nonzero';
+            }
+            this.stylesList.push(styleElem);
+            data[i].style = styleElem;
+            ownArrays.push(data[i].style);
+        }else if(arr[i].ty == 'gr'){
+            data[i] = {
+                it: []
+            };
+            this.searchShapes(arr[i].it,data[i].it,dynamicProperties);
+        }else if(arr[i].ty == 'tr'){
+            data[i] = {
+                transform : {
+                    mat: new Matrix(),
+                    opacity: 1,
+                    matMdf:false,
+                    opMdf:false,
+                    op: PropertyFactory.getProp(this,arr[i].o,0,0.01,dynamicProperties),
+                    mProps: PropertyFactory.getProp(this,arr[i],2,null,dynamicProperties)
+                },
+                elements: []
+            };
+        }else if(arr[i].ty == 'sh' || arr[i].ty == 'rc' || arr[i].ty == 'el' || arr[i].ty == 'sr'){
+            data[i] = {
+                nodes:[],
+                trNodes:[],
+                tr:[0,0,0,0,0,0]
+            };
+            var ty = 4;
+            if(arr[i].ty == 'rc'){
+                ty = 5;
+            }else if(arr[i].ty == 'el'){
+                ty = 6;
+            }else if(arr[i].ty == 'sr'){
+                ty = 7;
+            }
+            data[i].sh = ShapePropertyFactory.getShapeProp(this,arr[i],ty,dynamicProperties);
+            this.shapes.push(data[i].sh);
+            this.addShapeToModifiers(data[i]);
+            jLen = this.stylesList.length;
+            var hasStrokes = false, hasFills = false;
+            for(j=0;j<jLen;j+=1){
+                if(!this.stylesList[j].closed){
+                    this.stylesList[j].elements.push(data[i]);
+                    if(this.stylesList[j].type === 'st'){
+                        hasStrokes = true;
+                    }else{
+                        hasFills = true;
+                    }
+                }
+            }
+            data[i].st = hasStrokes;
+            data[i].fl = hasFills;
+        }else if(arr[i].ty == 'tm' || arr[i].ty == 'rd' || arr[i].ty == 'rp'){
+            var modifier = ShapeModifiers.getModifier(arr[i].ty);
+            modifier.init(this,arr[i],dynamicProperties);
+            this.shapeModifiers.push(modifier);
+            ownModifiers.push(modifier);
+            data[i] = modifier;
+        }
+    }
+    len = ownArrays.length;
+    for(i=0;i<len;i+=1){
+        ownArrays[i].closed = true;
+    }
+    len = ownModifiers.length;
+    for(i=0;i<len;i+=1){
+        ownModifiers[i].closed = true;
+    }
+};
+
+CVShapeElement.prototype.addShapeToModifiers = IShapeElement.prototype.addShapeToModifiers;
+CVShapeElement.prototype.renderModifiers = IShapeElement.prototype.renderModifiers;
+
+CVShapeElement.prototype.renderFrame = function(parentMatrix){
+    if(this._parent.renderFrame.call(this, parentMatrix)===false){
+        return;
+    }
+    this.transformHelper.mat.reset();
+    this.transformHelper.opacity = this.finalTransform.opacity;
+    this.transformHelper.matMdf = false;
+    this.transformHelper.opMdf = this.finalTransform.opMdf;
+    this.renderModifiers();
+    this.renderShape(this.transformHelper,null,null,true);
+    if(this.data.hasMask){
+        this.globalData.renderer.restore(true);
+    }
+};
+
+CVShapeElement.prototype.renderShape = function(parentTransform,items,data,isMain){
+    var i, len;
+    if(!items){
+        items = this.shapesData;
+        len = this.stylesList.length;
+        for(i=0;i<len;i+=1){
+            this.stylesList[i].d = '';
+            this.stylesList[i].mdf = false;
+        }
+    }
+    if(!data){
+        data = this.viewData;
+    }
+    ///
+    ///
+    len = items.length - 1;
+    var groupTransform,groupMatrix;
+    groupTransform = parentTransform;
+    for(i=len;i>=0;i-=1){
+        if(items[i].ty == 'tr'){
+            groupTransform = data[i].transform;
+            var mtArr = data[i].transform.mProps.v.props;
+            groupTransform.matMdf = groupTransform.mProps.mdf;
+            groupTransform.opMdf = groupTransform.op.mdf;
+            groupMatrix = groupTransform.mat;
+            groupMatrix.cloneFromProps(mtArr);
+            if(parentTransform){
+                var props = parentTransform.mat.props;
+                groupTransform.opacity = parentTransform.opacity;
+                groupTransform.opacity *= data[i].transform.op.v;
+                groupTransform.matMdf = parentTransform.matMdf ? true : groupTransform.matMdf;
+                groupTransform.opMdf = parentTransform.opMdf ? true : groupTransform.opMdf;
+                groupMatrix.transform(props[0],props[1],props[2],props[3],props[4],props[5],props[6],props[7],props[8],props[9],props[10],props[11],props[12],props[13],props[14],props[15]);
+            }else{
+                groupTransform.opacity = groupTransform.op.o;
+            }
+        }else if(items[i].ty == 'sh' || items[i].ty == 'el' || items[i].ty == 'rc' || items[i].ty == 'sr'){
+            this.renderPath(items[i],data[i],groupTransform);
+        }else if(items[i].ty == 'fl'){
+            this.renderFill(items[i],data[i],groupTransform);
+        }else if(items[i].ty == 'st'){
+            this.renderStroke(items[i],data[i],groupTransform);
+        }else if(items[i].ty == 'gr'){
+            this.renderShape(groupTransform,items[i].it,data[i].it);
+        }else if(items[i].ty == 'tm'){
+            //
+        }
+    }
+    if(!isMain){
+        return;
+    }
+    len = this.stylesList.length;
+    var j, jLen, k, kLen,elems,nodes, renderer = this.globalData.renderer, ctx = this.globalData.canvasContext, type;
+    renderer.save();
+    renderer.ctxTransform(this.finalTransform.mat.props);
+    for(i=0;i<len;i+=1){
+        type = this.stylesList[i].type;
+        if(type === 'st' && this.stylesList[i].wi === 0){
+            continue;
+        }
+        renderer.save();
+        elems = this.stylesList[i].elements;
+        if(type === 'st'){
+            ctx.strokeStyle = this.stylesList[i].co;
+            ctx.lineWidth = this.stylesList[i].wi;
+            ctx.lineCap = this.stylesList[i].lc;
+            ctx.lineJoin = this.stylesList[i].lj;
+            ctx.miterLimit = this.stylesList[i].ml || 0;
+        }else{
+            ctx.fillStyle = this.stylesList[i].co;
+        }
+        renderer.ctxOpacity(this.stylesList[i].coOp);
+        if(type !== 'st'){
+            ctx.beginPath();
+        }
+        jLen = elems.length;
+        for(j=0;j<jLen;j+=1){
+            if(type === 'st'){
+                ctx.beginPath();
+                if(this.stylesList[i].da){
+                    ctx.setLineDash(this.stylesList[i].da);
+                    ctx.lineDashOffset = this.stylesList[i].do;
+                    this.globalData.isDashed = true;
+                }else if(this.globalData.isDashed){
+                    ctx.setLineDash(this.dashResetter);
+                    this.globalData.isDashed = false;
+                }
+            }
+            nodes = elems[j].trNodes;
+            kLen = nodes.length;
+
+            for(k=0;k<kLen;k+=1){
+                if(nodes[k].t == 'm'){
+                    ctx.moveTo(nodes[k].p[0],nodes[k].p[1]);
+                }else if(nodes[k].t == 'c'){
+                    ctx.bezierCurveTo(nodes[k].p1[0],nodes[k].p1[1],nodes[k].p2[0],nodes[k].p2[1],nodes[k].p3[0],nodes[k].p3[1]);
+                }else{
+                    ctx.closePath();
+                }
+            }
+            if(type === 'st'){
+                ctx.stroke();
+            }
+        }
+        if(type !== 'st'){
+            ctx.fill(this.stylesList[i].r);
+        }
+        renderer.restore();
+    }
+    renderer.restore();
+    if(this.firstFrame){
+        this.firstFrame = false;
+    }
+};
+CVShapeElement.prototype.renderPath = function(pathData,viewData,groupTransform){
+    var len, i, j,jLen;
+    var redraw = groupTransform.matMdf || viewData.sh.mdf || this.firstFrame;
+    if(redraw) {
+        var paths = viewData.sh.paths;
+        jLen = paths._length;
+        var pathStringTransformed = viewData.trNodes;
+        pathStringTransformed.length = 0;
+        for(j=0;j<jLen;j+=1){
+            var pathNodes = paths.shapes[j];
+            if(pathNodes && pathNodes.v){
+                len = pathNodes._length;
+                for (i = 1; i < len; i += 1) {
+                    if (i == 1) {
+                        pathStringTransformed.push({
+                            t: 'm',
+                            p: groupTransform.mat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
+                        });
+                    }
+                    pathStringTransformed.push({
+                        t: 'c',
+                        p1: groupTransform.mat.applyToPointArray(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1], 0),
+                        p2: groupTransform.mat.applyToPointArray(pathNodes.i[i][0], pathNodes.i[i][1], 0),
+                        p3: groupTransform.mat.applyToPointArray(pathNodes.v[i][0], pathNodes.v[i][1], 0)
+                    });
+                }
+                if (len == 1) {
+                    pathStringTransformed.push({
+                        t: 'm',
+                        p: groupTransform.mat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
+                    });
+                }
+                if (pathNodes.c && len) {
+                    pathStringTransformed.push({
+                        t: 'c',
+                        p1: groupTransform.mat.applyToPointArray(pathNodes.o[i - 1][0], pathNodes.o[i - 1][1], 0),
+                        p2: groupTransform.mat.applyToPointArray(pathNodes.i[0][0], pathNodes.i[0][1], 0),
+                        p3: groupTransform.mat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
+                    });
+                    pathStringTransformed.push({
+                        t: 'z'
+                    });
+                }
+                viewData.lStr = pathStringTransformed;
+            }
+
+        }
+
+        if (viewData.st) {
+            for (i = 0; i < 16; i += 1) {
+                viewData.tr[i] = groupTransform.mat.props[i];
+            }
+        }
+        viewData.trNodes = pathStringTransformed;
+
+    }
+};
+
+
+
+CVShapeElement.prototype.renderFill = function(styleData,viewData, groupTransform){
+    var styleElem = viewData.style;
+
+    if(viewData.c.mdf || this.firstFrame){
+        styleElem.co = 'rgb('+bm_floor(viewData.c.v[0])+','+bm_floor(viewData.c.v[1])+','+bm_floor(viewData.c.v[2])+')';
+    }
+    if(viewData.o.mdf || groupTransform.opMdf || this.firstFrame){
+        styleElem.coOp = viewData.o.v*groupTransform.opacity;
+    }
+};
+
+CVShapeElement.prototype.renderStroke = function(styleData,viewData, groupTransform){
+    var styleElem = viewData.style;
+    //TODO fix dashes
+    var d = viewData.d;
+    var dasharray,dashoffset;
+    if(d && (d.mdf  || this.firstFrame)){
+        styleElem.da = d.dasharray;
+        styleElem.do = d.dashoffset;
+    }
+    if(viewData.c.mdf || this.firstFrame){
+        styleElem.co = 'rgb('+bm_floor(viewData.c.v[0])+','+bm_floor(viewData.c.v[1])+','+bm_floor(viewData.c.v[2])+')';
+    }
+    if(viewData.o.mdf || groupTransform.opMdf || this.firstFrame){
+        styleElem.coOp = viewData.o.v*groupTransform.opacity;
+    }
+    if(viewData.w.mdf || this.firstFrame){
+        styleElem.wi = viewData.w.v;
+    }
+};
+
+
+CVShapeElement.prototype.destroy = function(){
+    this.shapesData = null;
+    this.globalData = null;
+    this.canvasContext = null;
+    this.stylesList.length = 0;
+    this.viewData.length = 0;
+    this._parent.destroy.call(this._parent);
+};
+
+
+function CVSolidElement(data, comp,globalData){
+    this._parent.constructor.call(this,data, comp,globalData);
+}
+createElement(CVBaseElement, CVSolidElement);
+
+CVSolidElement.prototype.renderFrame = function(parentMatrix){
+    if(this._parent.renderFrame.call(this, parentMatrix)===false){
+        return;
+    }
+    var ctx = this.canvasContext;
+    this.globalData.renderer.save();
+    this.globalData.renderer.ctxTransform(this.finalTransform.mat.props);
+    this.globalData.renderer.ctxOpacity(this.finalTransform.opacity);
+    ctx.fillStyle=this.data.sc;
+    ctx.fillRect(0,0,this.data.sw,this.data.sh);
+    this.globalData.renderer.restore(this.data.hasMask);
+    if(this.firstFrame){
+        this.firstFrame = false;
+    }
+};
+function CVTextElement(data, comp, globalData){
+    this.textSpans = [];
+    this.yOffset = 0;
+    this.fillColorAnim = false;
+    this.strokeColorAnim = false;
+    this.strokeWidthAnim = false;
+    this.stroke = false;
+    this.fill = false;
+    this.justifyOffset = 0;
+    this.currentRender = null;
+    this.renderType = 'canvas';
+    this.values = {
+        fill: 'rgba(0,0,0,0)',
+        stroke: 'rgba(0,0,0,0)',
+        sWidth: 0,
+        fValue: ''
+    }
+    this._parent.constructor.call(this,data,comp, globalData);
+}
+createElement(CVBaseElement, CVTextElement);
+
+CVTextElement.prototype.init = ITextElement.prototype.init;
+CVTextElement.prototype.getMeasures = ITextElement.prototype.getMeasures;
+CVTextElement.prototype.getMult = ITextElement.prototype.getMult;
+CVTextElement.prototype.prepareFrame = ITextElement.prototype.prepareFrame;
+
+CVTextElement.prototype.tHelper = document.createElement('canvas').getContext('2d');
+
+CVTextElement.prototype.createElements = function(){
+
+    this._parent.createElements.call(this);
+    //console.log('this.data: ',this.data);
+
+};
+
+CVTextElement.prototype.buildNewText = function(){
+    var documentData = this.currentTextDocumentData;
+    this.renderedLetters = Array.apply(null,{length:this.currentTextDocumentData.l ? this.currentTextDocumentData.l.length : 0});
+
+    var hasFill = false;
+    if(documentData.fc) {
+        hasFill = true;
+        this.values.fill = 'rgb(' + Math.round(documentData.fc[0]*255) + ',' + Math.round(documentData.fc[1]*255) + ',' + Math.round(documentData.fc[2]*255) + ')';
+    }else{
+        this.values.fill = 'rgba(0,0,0,0)';
+    }
+    this.fill = hasFill;
+    var hasStroke = false;
+    if(documentData.sc){
+        hasStroke = true;
+        this.values.stroke = 'rgb(' + Math.round(documentData.sc[0]*255) + ',' + Math.round(documentData.sc[1]*255) + ',' + Math.round(documentData.sc[2]*255) + ')';
+        this.values.sWidth = documentData.sw;
+    }
+    var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+    var i, len;
+    var letters = documentData.l;
+    var matrixHelper = this.mHelper;
+    this.stroke = hasStroke;
+    this.values.fValue = documentData.s + 'px '+ this.globalData.fontManager.getFontByName(documentData.f).fFamily;
+    len = documentData.t.length;
+    this.tHelper.font = this.values.fValue;
+    var charData, shapeData, k, kLen, shapes, j, jLen, pathNodes, commands, pathArr, singleShape = this.data.singleShape;
+    if (singleShape) {
+        var xPos = 0, yPos = 0, lineWidths = documentData.lineWidths, boxWidth = documentData.boxWidth, firstLine = true;
+    }
+    var cnt = 0;
+    for (i = 0;i < len ;i += 1) {
+        charData = this.globalData.fontManager.getCharData(documentData.t.charAt(i), fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+        var shapeData;
+        if(charData){
+            shapeData = charData.data;
+        } else {
+            shapeData = null;
+        }
+        matrixHelper.reset();
+        if(singleShape && letters[i].n) {
+            xPos = 0;
+            yPos += documentData.yOffset;
+            yPos += firstLine ? 1 : 0;
+            firstLine = false;
+        }
+
+        if(shapeData && shapeData.shapes){
+            shapes = shapeData.shapes[0].it;
+            jLen = shapes.length;
+            matrixHelper.scale(documentData.s/100,documentData.s/100);
+            if(singleShape){
+                if(documentData.ps){
+                    matrixHelper.translate(documentData.ps[0],documentData.ps[1] + documentData.ascent,0);
+                }
+                matrixHelper.translate(0,-documentData.ls,0);
+                switch(documentData.j){
+                    case 1:
+                        matrixHelper.translate(documentData.justifyOffset + (boxWidth - lineWidths[letters[i].line]),0,0);
+                        break;
+                    case 2:
+                        matrixHelper.translate(documentData.justifyOffset + (boxWidth - lineWidths[letters[i].line])/2,0,0);
+                        break;
+                }
+                matrixHelper.translate(xPos,yPos,0);
+            }
+            commands = new Array(jLen);
+            for(j=0;j<jLen;j+=1){
+                kLen = shapes[j].ks.k.i.length;
+                pathNodes = shapes[j].ks.k;
+                pathArr = [];
+                for(k=1;k<kLen;k+=1){
+                    if(k==1){
+                        pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0],pathNodes.v[0][1],0),matrixHelper.applyToY(pathNodes.v[0][0],pathNodes.v[0][1],0));
+                    }
+                    pathArr.push(matrixHelper.applyToX(pathNodes.o[k-1][0],pathNodes.o[k-1][1],0),matrixHelper.applyToY(pathNodes.o[k-1][0],pathNodes.o[k-1][1],0),matrixHelper.applyToX(pathNodes.i[k][0],pathNodes.i[k][1],0),matrixHelper.applyToY(pathNodes.i[k][0],pathNodes.i[k][1],0),matrixHelper.applyToX(pathNodes.v[k][0],pathNodes.v[k][1],0),matrixHelper.applyToY(pathNodes.v[k][0],pathNodes.v[k][1],0));
+                }
+                pathArr.push(matrixHelper.applyToX(pathNodes.o[k-1][0],pathNodes.o[k-1][1],0),matrixHelper.applyToY(pathNodes.o[k-1][0],pathNodes.o[k-1][1],0),matrixHelper.applyToX(pathNodes.i[0][0],pathNodes.i[0][1],0),matrixHelper.applyToY(pathNodes.i[0][0],pathNodes.i[0][1],0),matrixHelper.applyToX(pathNodes.v[0][0],pathNodes.v[0][1],0),matrixHelper.applyToY(pathNodes.v[0][0],pathNodes.v[0][1],0));
+                commands[j] = pathArr;
+            }
+        }else{
+            commands = [];
+        }
+        if(singleShape){
+            xPos += letters[i].l;
+        }
+        if(this.textSpans[cnt]){
+            this.textSpans[cnt].elem = commands;
+        } else {
+            this.textSpans[cnt] = {elem: commands};
+        }
+        cnt +=1;
+    }
+}
+
+CVTextElement.prototype.renderFrame = function(parentMatrix){
+    if(this._parent.renderFrame.call(this, parentMatrix)===false){
+        return;
+    }
+    var ctx = this.canvasContext;
+    var finalMat = this.finalTransform.mat.props;
+    this.globalData.renderer.save();
+    this.globalData.renderer.ctxTransform(finalMat);
+    this.globalData.renderer.ctxOpacity(this.finalTransform.opacity);
+    ctx.font = this.values.fValue;
+    ctx.lineCap = 'butt';
+    ctx.lineJoin = 'miter';
+    ctx.miterLimit = 4;
+
+    if(!this.data.singleShape){
+        this.getMeasures();
+    }
+
+    var  i,len, j, jLen, k, kLen;
+    var renderedLetters = this.renderedLetters;
+
+    var letters = this.currentTextDocumentData.l;
+
+    len = letters.length;
+    var renderedLetter;
+    var lastFill = null, lastStroke = null, lastStrokeW = null, commands, pathArr;
+    for(i=0;i<len;i+=1){
+        if(letters[i].n){
+            continue;
+        }
+        renderedLetter = renderedLetters[i];
+        if(renderedLetter){
+            this.globalData.renderer.save();
+            this.globalData.renderer.ctxTransform(renderedLetter.props);
+            this.globalData.renderer.ctxOpacity(renderedLetter.o);
+        }
+        if(this.fill){
+            if(renderedLetter && renderedLetter.fc){
+                if(lastFill !== renderedLetter.fc){
+                    lastFill = renderedLetter.fc;
+                    ctx.fillStyle = renderedLetter.fc;
+                }
+            }else if(lastFill !== this.values.fill){
+                lastFill = this.values.fill;
+                ctx.fillStyle = this.values.fill;
+            }
+            commands = this.textSpans[i].elem;
+            jLen = commands.length;
+            this.globalData.canvasContext.beginPath();
+            for(j=0;j<jLen;j+=1) {
+                pathArr = commands[j];
+                kLen = pathArr.length;
+                this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+                for (k = 2; k < kLen; k += 6) {
+                    this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+                }
+            }
+            this.globalData.canvasContext.closePath();
+            this.globalData.canvasContext.fill();
+            ///ctx.fillText(this.textSpans[i].val,0,0);
+        }
+        if(this.stroke){
+            if(renderedLetter && renderedLetter.sw){
+                if(lastStrokeW !== renderedLetter.sw){
+                    lastStrokeW = renderedLetter.sw;
+                    ctx.lineWidth = renderedLetter.sw;
+                }
+            }else if(lastStrokeW !== this.values.sWidth){
+                lastStrokeW = this.values.sWidth;
+                ctx.lineWidth = this.values.sWidth;
+            }
+            if(renderedLetter && renderedLetter.sc){
+                if(lastStroke !== renderedLetter.sc){
+                    lastStroke = renderedLetter.sc;
+                    ctx.strokeStyle = renderedLetter.sc;
+                }
+            }else if(lastStroke !== this.values.stroke){
+                lastStroke = this.values.stroke;
+                ctx.strokeStyle = this.values.stroke;
+            }
+            commands = this.textSpans[i].elem;
+            jLen = commands.length;
+            this.globalData.canvasContext.beginPath();
+            for(j=0;j<jLen;j+=1) {
+                pathArr = commands[j];
+                kLen = pathArr.length;
+                this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+                for (k = 2; k < kLen; k += 6) {
+                    this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+                }
+            }
+            this.globalData.canvasContext.closePath();
+            this.globalData.canvasContext.stroke();
+            ///ctx.strokeText(letters[i].val,0,0);
+        }
+        if(renderedLetter) {
+            this.globalData.renderer.restore();
+        }
+    }
+    /*if(this.data.hasMask){
+     this.globalData.renderer.restore(true);
+     }*/
+    this.globalData.renderer.restore(this.data.hasMask);
+    if(this.firstFrame){
+        this.firstFrame = false;
+    }
+};
+function HBaseElement(data,parentContainer,globalData,comp, placeholder){
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.matteElement = null;
+    this.parentContainer = parentContainer;
+    this.layerId = placeholder ? placeholder.layerId : 'ly_'+randomString(10);
+    this.placeholder = placeholder;
+    this.init();
+};
+
+createElement(BaseElement, HBaseElement);
+HBaseElement.prototype.checkBlendMode = function(){
+
+};
+HBaseElement.prototype.setBlendMode = BaseElement.prototype.setBlendMode;
+
+/*HBaseElement.prototype.appendNodeToParent = function(node) {
+    if(this.data.hd){
+        return;
+    }
+    if(this.placeholder){
+        var g = this.placeholder.phElement;
+        g.parentNode.insertBefore(node, g);
+        //g.parentNode.removeChild(g);
+    }else{
+        this.parentContainer.appendChild(node);
+    }
+};*/
+
+
+HBaseElement.prototype.getBaseElement = function(){
+    return this.baseElement;
+};
+
+HBaseElement.prototype.createElements = function(){
+    if(this.data.hasMask){
+        this.layerElement = document.createElementNS(svgNS,'svg');
+        styleDiv(this.layerElement);
+        //this.appendNodeToParent(this.layerElement);
+        this.baseElement = this.layerElement;
+        this.maskedElement = this.layerElement;
+    }else{
+        this.layerElement = this.parentContainer;
+    }
+    this.transformedElement = this.layerElement;
+    if(this.data.ln && (this.data.ty === 4 || this.data.ty === 0)){
+        if(this.layerElement === this.parentContainer){
+            this.layerElement = document.createElementNS(svgNS,'g');
+            //this.appendNodeToParent(this.layerElement);
+            this.baseElement = this.layerElement;
+        }
+        this.layerElement.setAttribute('id',this.data.ln);
+    }
+    this.setBlendMode();
+    if(this.layerElement !== this.parentContainer){
+        this.placeholder = null;
+    }
+    this.checkParenting();
+};
+
+HBaseElement.prototype.renderFrame = function(parentTransform){
+    if(this.data.ty === 3){
+        return false;
+    }
+
+    if(this.currentFrameNum === this.lastNum || !this.isVisible){
+        return this.isVisible;
+    }
+    this.lastNum = this.currentFrameNum;
+
+    this.finalTransform.opMdf = this.finalTransform.op.mdf;
+    this.finalTransform.matMdf = this.finalTransform.mProp.mdf;
+    this.finalTransform.opacity = this.finalTransform.op.v;
+    if(this.firstFrame){
+        this.finalTransform.opMdf = true;
+        this.finalTransform.matMdf = true;
+    }
+
+    var mat;
+    var finalMat = this.finalTransform.mat;
+
+    if(this.hierarchy){
+        var i, len = this.hierarchy.length;
+
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for(i=0;i<len;i+=1){
+            this.finalTransform.matMdf = this.hierarchy[i].finalTransform.mProp.mdf ? true : this.finalTransform.matMdf;
+            mat = this.hierarchy[i].finalTransform.mProp.v.props;
+            finalMat.transform(mat[0],mat[1],mat[2],mat[3],mat[4],mat[5],mat[6],mat[7],mat[8],mat[9],mat[10],mat[11],mat[12],mat[13],mat[14],mat[15]);
+        }
+    }else{
+        if(this.isVisible && this.finalTransform.matMdf){
+            if(!parentTransform){
+                finalMat.cloneFromProps(this.finalTransform.mProp.v.props);
+            }else{
+                mat = this.finalTransform.mProp.v.props;
+                finalMat.cloneFromProps(mat);
+            }
+        }
+    }
+    if(this.data.hasMask){
+        this.maskManager.renderFrame(finalMat);
+    }
+
+    if(parentTransform){
+        mat = parentTransform.mat.props;
+        finalMat.cloneFromProps(mat);
+        this.finalTransform.opacity *= parentTransform.opacity;
+        this.finalTransform.opMdf = parentTransform.opMdf ? true : this.finalTransform.opMdf;
+        this.finalTransform.matMdf = parentTransform.matMdf ? true : this.finalTransform.matMdf
+    }
+
+    if(this.finalTransform.matMdf){
+        this.transformedElement.style.transform = this.transformedElement.style.webkitTransform = finalMat.toCSS();
+        this.finalMat = finalMat;
+    }
+    if(this.finalTransform.opMdf){
+        this.transformedElement.style.opacity = this.finalTransform.opacity;
+    }
+    return this.isVisible;
+};
+
+HBaseElement.prototype.destroy = function(){
+    this.layerElement = null;
+    this.transformedElement = null;
+    this.parentContainer = null;
+    if(this.matteElement) {
+        this.matteElement = null;
+    }
+    if(this.maskManager) {
+        this.maskManager.destroy();
+        this.maskManager = null;
+    }
+};
+
+HBaseElement.prototype.getDomElement = function(){
+    return this.layerElement;
+};
+HBaseElement.prototype.addMasks = function(data){
+    this.maskManager = new MaskElement(data,this,this.globalData);
+};
+
+HBaseElement.prototype.hide = function(){
+};
+
+HBaseElement.prototype.setMatte = function(){
+
+}
+
+HBaseElement.prototype.buildElementParenting = HybridRenderer.prototype.buildElementParenting;
+function HSolidElement(data,parentContainer,globalData,comp, placeholder){
+    this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder);
+}
+createElement(HBaseElement, HSolidElement);
+
+HSolidElement.prototype.createElements = function(){
+    var parent = document.createElement('div');
+    styleDiv(parent);
+    var cont = document.createElementNS(svgNS,'svg');
+    styleDiv(cont);
+    cont.setAttribute('width',this.data.sw);
+    cont.setAttribute('height',this.data.sh);
+    parent.appendChild(cont);
+    this.layerElement = parent;
+    this.transformedElement = parent;
+    //this.appendNodeToParent(parent);
+    this.baseElement = parent;
+    this.innerElem = parent;
+    if(this.data.ln){
+        this.innerElem.setAttribute('id',this.data.ln);
+    }
+    if(this.data.bm !== 0){
+        this.setBlendMode();
+    }
+    var rect = document.createElementNS(svgNS,'rect');
+    rect.setAttribute('width',this.data.sw);
+    rect.setAttribute('height',this.data.sh);
+    rect.setAttribute('fill',this.data.sc);
+    cont.appendChild(rect);
+    if(this.data.hasMask){
+        this.maskedElement = rect;
+    }
+    this.checkParenting();
+};
+
+
+
+HSolidElement.prototype.hide = IImageElement.prototype.hide;
+HSolidElement.prototype.renderFrame = IImageElement.prototype.renderFrame;
+HSolidElement.prototype.destroy = IImageElement.prototype.destroy;
+function HCompElement(data,parentContainer,globalData,comp, placeholder){
+    this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder);
+    this.layers = data.layers;
+    this.supports3d = true;
+    this.completeLayers = false;
+    this.pendingElements = [];
+    this.elements = Array.apply(null,{length:this.layers.length});
+    if(this.data.tm){
+        this.tm = PropertyFactory.getProp(this,this.data.tm,0,globalData.frameRate,this.dynamicProperties);
+    }
+    if(this.data.hasMask) {
+        this.supports3d = false;
+    }
+    if(this.data.xt){
+        this.layerElement = document.createElement('div');
+    }
+    this.buildAllItems();
+
+}
+createElement(HBaseElement, HCompElement);
+
+HCompElement.prototype.createElements = function(){
+    var divElement = document.createElement('div');
+    styleDiv(divElement);
+    if(this.data.ln){
+        divElement.setAttribute('id',this.data.ln);
+    }
+    divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
+    if(this.data.hasMask){
+        var compSvg = document.createElementNS(svgNS,'svg');
+        styleDiv(compSvg);
+        compSvg.setAttribute('width',this.data.w);
+        compSvg.setAttribute('height',this.data.h);
+        var g = document.createElementNS(svgNS,'g');
+        compSvg.appendChild(g);
+        divElement.appendChild(compSvg);
+        this.maskedElement = g;
+        this.baseElement = divElement;
+        this.layerElement = g;
+        this.transformedElement = divElement;
+    }else{
+        this.layerElement = divElement;
+        this.baseElement = this.layerElement;
+        this.transformedElement = divElement;
+    }
+    //this.appendNodeToParent(this.layerElement);
+    this.checkParenting();
+};
+
+HCompElement.prototype.hide = ICompElement.prototype.hide;
+HCompElement.prototype.prepareFrame = ICompElement.prototype.prepareFrame;
+HCompElement.prototype.setElements = ICompElement.prototype.setElements;
+HCompElement.prototype.getElements = ICompElement.prototype.getElements;
+HCompElement.prototype.destroy = ICompElement.prototype.destroy;
+
+HCompElement.prototype.renderFrame = function(parentMatrix){
+    var renderParent = this._parent.renderFrame.call(this,parentMatrix);
+    var i,len = this.layers.length;
+    if(renderParent===false){
+        this.hide();
+        return;
+    }
+
+    this.hidden = false;
+
+    for( i = 0; i < len; i+=1 ){
+        if(this.completeLayers || this.elements[i]){
+            this.elements[i].renderFrame();
+        }
+    }
+    if(this.firstFrame){
+        this.firstFrame = false;
+    }
+};
+
+HCompElement.prototype.checkLayers = BaseRenderer.prototype.checkLayers;
+HCompElement.prototype.buildItem = HybridRenderer.prototype.buildItem;
+HCompElement.prototype.checkPendingElements = HybridRenderer.prototype.checkPendingElements;
+HCompElement.prototype.addPendingElement = HybridRenderer.prototype.addPendingElement;
+HCompElement.prototype.buildAllItems = BaseRenderer.prototype.buildAllItems;
+HCompElement.prototype.createItem = HybridRenderer.prototype.createItem;
+HCompElement.prototype.buildElementParenting = HybridRenderer.prototype.buildElementParenting;
+HCompElement.prototype.createImage = HybridRenderer.prototype.createImage;
+HCompElement.prototype.createComp = HybridRenderer.prototype.createComp;
+HCompElement.prototype.createSolid = HybridRenderer.prototype.createSolid;
+HCompElement.prototype.createShape = HybridRenderer.prototype.createShape;
+HCompElement.prototype.createText = HybridRenderer.prototype.createText;
+HCompElement.prototype.createBase = HybridRenderer.prototype.createBase;
+HCompElement.prototype.appendElementInPos = HybridRenderer.prototype.appendElementInPos;
+function HShapeElement(data,parentContainer,globalData,comp, placeholder){
+    this.shapes = [];
+    this.shapeModifiers = [];
+    this.shapesData = data.shapes;
+    this.stylesList = [];
+    this.viewData = [];
+    this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder);
+    this.addedTransforms = {
+        mdf: false,
+        mats: [this.finalTransform.mat]
+    };
+    this.currentBBox = {
+        x:999999,
+        y: -999999,
+        h: 0,
+        w: 0
+    };
+}
+createElement(HBaseElement, HShapeElement);
+var parent = HShapeElement.prototype._parent;
+extendPrototype(IShapeElement, HShapeElement);
+HShapeElement.prototype._parent = parent;
+
+HShapeElement.prototype.createElements = function(){
+    var parent = document.createElement('div');
+    styleDiv(parent);
+    var cont = document.createElementNS(svgNS,'svg');
+    styleDiv(cont);
+    var size = this.comp.data ? this.comp.data : this.globalData.compSize;
+    cont.setAttribute('width',size.w);
+    cont.setAttribute('height',size.h);
+    if(this.data.hasMask){
+        var g = document.createElementNS(svgNS,'g');
+        parent.appendChild(cont);
+        cont.appendChild(g);
+        this.maskedElement = g;
+        this.layerElement = g;
+        this.shapesContainer = g;
+    }else{
+        parent.appendChild(cont);
+        this.layerElement = cont;
+        this.shapesContainer = document.createElementNS(svgNS,'g');
+        this.layerElement.appendChild(this.shapesContainer);
+    }
+    if(!this.data.hd){
+        //this.parentContainer.appendChild(parent);
+        this.baseElement = parent;
+    }
+    this.innerElem = parent;
+    if(this.data.ln){
+        this.innerElem.setAttribute('id',this.data.ln);
+    }
+    this.searchShapes(this.shapesData,this.viewData,this.layerElement,this.dynamicProperties,0);
+    this.buildExpressionInterface();
+    this.layerElement = parent;
+    this.transformedElement = parent;
+    this.shapeCont = cont;
+    if(this.data.bm !== 0){
+        this.setBlendMode();
+    }
+    this.checkParenting();
+};
+
+HShapeElement.prototype.renderFrame = function(parentMatrix){
+    var renderParent = this._parent.renderFrame.call(this,parentMatrix);
+    if(renderParent===false){
+        this.hide();
+        return;
+    }
+    if(this.hidden){
+        this.layerElement.style.display = 'block';
+        this.hidden = false;
+    }
+    this.renderModifiers();
+    this.addedTransforms.mdf = this.finalTransform.matMdf;
+    this.addedTransforms.mats.length = 1;
+    this.addedTransforms.mats[0] = this.finalTransform.mat;
+    this.renderShape(null,null,true, null);
+
+    if(this.isVisible && (this.elemMdf || this.firstFrame)){
+        var boundingBox = this.shapeCont.getBBox();
+        var changed = false;
+        if(this.currentBBox.w !== boundingBox.width){
+            this.currentBBox.w = boundingBox.width;
+            this.shapeCont.setAttribute('width',boundingBox.width);
+            changed = true;
+        }
+        if(this.currentBBox.h !== boundingBox.height){
+            this.currentBBox.h = boundingBox.height;
+            this.shapeCont.setAttribute('height',boundingBox.height);
+            changed = true;
+        }
+        if(changed  || this.currentBBox.x !== boundingBox.x  || this.currentBBox.y !== boundingBox.y){
+            this.currentBBox.w = boundingBox.width;
+            this.currentBBox.h = boundingBox.height;
+            this.currentBBox.x = boundingBox.x;
+            this.currentBBox.y = boundingBox.y;
+
+            this.shapeCont.setAttribute('viewBox',this.currentBBox.x+' '+this.currentBBox.y+' '+this.currentBBox.w+' '+this.currentBBox.h);
+            this.shapeCont.style.transform = this.shapeCont.style.webkitTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+        }
+    }
+
+};
+function HTextElement(data,parentContainer,globalData,comp, placeholder){
+    this.textSpans = [];
+    this.textPaths = [];
+    this.currentBBox = {
+        x:999999,
+        y: -999999,
+        h: 0,
+        w: 0
+    }
+    this.renderType = 'svg';
+    this.isMasked = false;
+    this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder);
+
+}
+createElement(HBaseElement, HTextElement);
+
+HTextElement.prototype.init = ITextElement.prototype.init;
+HTextElement.prototype.getMeasures = ITextElement.prototype.getMeasures;
+HTextElement.prototype.createPathShape = ITextElement.prototype.createPathShape;
+HTextElement.prototype.prepareFrame = ITextElement.prototype.prepareFrame;
+
+HTextElement.prototype.createElements = function(){
+    this.isMasked = this.checkMasks();
+    var parent = document.createElement('div');
+    styleDiv(parent);
+    this.layerElement = parent;
+    this.transformedElement = parent;
+    if(this.isMasked){
+        this.renderType = 'svg';
+        var cont = document.createElementNS(svgNS,'svg');
+        styleDiv(cont);
+        this.cont = cont;
+        this.compW = this.comp.data.w;
+        this.compH = this.comp.data.h;
+        cont.setAttribute('width',this.compW);
+        cont.setAttribute('height',this.compH);
+        var g = document.createElementNS(svgNS,'g');
+        cont.appendChild(g);
+        parent.appendChild(cont);
+        this.maskedElement = g;
+        this.innerElem = g;
+    } else {
+        this.renderType = 'html';
+        this.innerElem = parent;
+    }
+    this.baseElement = parent;
+
+    this.checkParenting();
+
+};
+
+HTextElement.prototype.buildNewText = function(){
+    var documentData = this.currentTextDocumentData;
+    this.renderedLetters = Array.apply(null,{length:this.currentTextDocumentData.l ? this.currentTextDocumentData.l.length : 0});
+    if(documentData.fc) {
+        this.innerElem.style.color = this.innerElem.style.fill = 'rgb(' + Math.round(documentData.fc[0]*255) + ',' + Math.round(documentData.fc[1]*255) + ',' + Math.round(documentData.fc[2]*255) + ')';
+        ////this.innerElem.setAttribute('fill', 'rgb(' + documentData.fc[0] + ',' + documentData.fc[1] + ',' + documentData.fc[2] + ')');
+    }else{
+        this.innerElem.style.color = this.innerElem.style.fill = 'rgba(0,0,0,0)';
+        ////this.innerElem.setAttribute('fill', 'rgba(0,0,0,0)');
+    }
+    if(documentData.sc){
+        ////this.innerElem.setAttribute('stroke', 'rgb(' + documentData.sc[0] + ',' + documentData.sc[1] + ',' + documentData.sc[2] + ')');
+        this.innerElem.style.stroke = 'rgb(' + Math.round(documentData.sc[0]*255) + ',' + Math.round(documentData.sc[1]*255) + ',' + Math.round(documentData.sc[2]*255) + ')';
+        ////this.innerElem.setAttribute('stroke-width', documentData.sw);
+        this.innerElem.style.strokeWidth = documentData.sw+'px';
+    }
+    ////this.innerElem.setAttribute('font-size', documentData.s);
+    var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+    if(!this.globalData.fontManager.chars){
+        this.innerElem.style.fontSize = documentData.s+'px';
+        this.innerElem.style.lineHeight = documentData.s+'px';
+        if(fontData.fClass){
+            this.innerElem.className = fontData.fClass;
+        } else {
+            ////this.innerElem.setAttribute('font-family', fontData.fFamily);
+            this.innerElem.style.fontFamily = fontData.fFamily;
+            var fWeight = documentData.fWeight, fStyle = documentData.fStyle;
+            ////this.innerElem.setAttribute('font-style', fStyle);
+            this.innerElem.style.fontStyle = fStyle;
+            ////this.innerElem.setAttribute('font-weight', fWeight);
+            this.innerElem.style.fontWeight = fWeight;
+        }
+    }
+    var i, len;
+
+    var letters = documentData.l;
+    len = letters.length;
+    var tSpan,tParent,tCont;
+    var matrixHelper = this.mHelper;
+    var shapes, shapeStr = '';
+    var cnt = 0;
+    for (i = 0;i < len ;i += 1) {
+        if(this.globalData.fontManager.chars){
+            if(!this.textPaths[cnt]){
+                tSpan = document.createElementNS(svgNS,'path');
+                tSpan.setAttribute('stroke-linecap', 'butt');
+                tSpan.setAttribute('stroke-linejoin','round');
+                tSpan.setAttribute('stroke-miterlimit','4');
+            } else {
+                tSpan = this.textPaths[cnt];
+            }
+            if(!this.isMasked){
+                if(this.textSpans[cnt]){
+                    tParent = this.textSpans[cnt];
+                    tCont = tParent.children[0];
+                } else {
+
+                    tParent = document.createElement('div');
+                    tCont = document.createElementNS(svgNS,'svg');
+                    tCont.appendChild(tSpan);
+                    styleDiv(tParent);
+                }
+            }
+        }else{
+            if(!this.isMasked){
+                if(this.textSpans[cnt]){
+                    tParent = this.textSpans[cnt];
+                    tSpan = this.textPaths[cnt];
+                } else {
+                    tParent = document.createElement('span');
+                    styleDiv(tParent);
+                    tSpan = document.createElement('span');
+                    styleDiv(tSpan);
+                    tParent.appendChild(tSpan);
+                }
+            } else {
+                tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : document.createElementNS(svgNS,'text');
+            }
+        }
+        //tSpan.setAttribute('visibility', 'hidden');
+        if(this.globalData.fontManager.chars){
+            var charData = this.globalData.fontManager.getCharData(documentData.t.charAt(i), fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+            var shapeData;
+            if(charData){
+                shapeData = charData.data;
+            } else {
+                shapeData = null;
+            }
+            matrixHelper.reset();
+            if(shapeData && shapeData.shapes){
+                shapes = shapeData.shapes[0].it;
+                matrixHelper.scale(documentData.s/100,documentData.s/100);
+                shapeStr = this.createPathShape(matrixHelper,shapes);
+                tSpan.setAttribute('d',shapeStr);
+            }
+            if(!this.isMasked){
+                this.innerElem.appendChild(tParent);
+                if(shapeData && shapeData.shapes){
+                    document.body.appendChild(tCont);
+
+                    var boundingBox = tCont.getBBox();
+                    tCont.setAttribute('width',boundingBox.width);
+                    tCont.setAttribute('height',boundingBox.height);
+                    tCont.setAttribute('viewBox',boundingBox.x+' '+ boundingBox.y+' '+ boundingBox.width+' '+ boundingBox.height);
+                    tCont.style.transform = tCont.style.webkitTransform = 'translate(' + boundingBox.x + 'px,' + boundingBox.y + 'px)';
+
+                    letters[i].yOffset = boundingBox.y;
+                    tParent.appendChild(tCont);
+
+                } else{
+                    tCont.setAttribute('width',1);
+                    tCont.setAttribute('height',1);
+                }
+            }else{
+                this.innerElem.appendChild(tSpan);
+            }
+        }else{
+            tSpan.textContent = letters[i].val;
+            tSpan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space","preserve");
+            if(!this.isMasked){
+                this.innerElem.appendChild(tParent);
+                //
+                tSpan.style.transform = tSpan.style.webkitTransform = 'translate3d(0,'+ -documentData.s/1.2+'px,0)';
+            } else {
+                this.innerElem.appendChild(tSpan);
+            }
+        }
+        //
+        if(!this.isMasked){
+            this.textSpans[cnt] = tParent;
+        }else{
+            this.textSpans[cnt] = tSpan;
+        }
+        this.textSpans[cnt].style.display = 'block';
+        this.textPaths[cnt] = tSpan;
+        cnt += 1;
+    }
+    while(cnt < this.textSpans.length){
+        this.textSpans[cnt].style.display = 'none';
+        cnt += 1;
+    }
+}
+
+HTextElement.prototype.hide = SVGTextElement.prototype.hide;
+
+HTextElement.prototype.renderFrame = function(parentMatrix){
+
+    var renderParent = this._parent.renderFrame.call(this,parentMatrix);
+    if(renderParent===false){
+        this.hide();
+        return;
+    }
+    if(this.hidden){
+        this.hidden = false;
+        this.innerElem.style.display = 'block';
+        this.layerElement.style.display = 'block';
+    }
+
+    if(this.data.singleShape){
+        if(!this.firstFrame && !this.lettersChangedFlag){
+            return;
+        } else {
+            // Todo Benchmark if using this is better than getBBox
+             if(this.isMasked && this.finalTransform.matMdf){
+                 this.cont.setAttribute('viewBox',-this.finalTransform.mProp.p.v[0]+' '+ -this.finalTransform.mProp.p.v[1]+' '+this.compW+' '+this.compH);
+                this.cont.style.transform = this.cont.style.webkitTransform = 'translate(' + -this.finalTransform.mProp.p.v[0] + 'px,' + -this.finalTransform.mProp.p.v[1] + 'px)';
+             }
+        }
+    }
+
+    this.getMeasures();
+    if(!this.lettersChangedFlag){
+        return;
+    }
+    var  i,len;
+    var renderedLetters = this.renderedLetters;
+
+    var letters = this.currentTextDocumentData.l;
+
+    len = letters.length;
+    var renderedLetter;
+    for(i=0;i<len;i+=1){
+        if(letters[i].n){
+            continue;
+        }
+        renderedLetter = renderedLetters[i];
+        if(!this.isMasked){
+            this.textSpans[i].style.transform = this.textSpans[i].style.webkitTransform = renderedLetter.m;
+        }else{
+            this.textSpans[i].setAttribute('transform',renderedLetter.m);
+        }
+        ////this.textSpans[i].setAttribute('opacity',renderedLetter.o);
+        this.textSpans[i].style.opacity = renderedLetter.o;
+        if(renderedLetter.sw){
+            this.textPaths[i].setAttribute('stroke-width',renderedLetter.sw);
+        }
+        if(renderedLetter.sc){
+            this.textPaths[i].setAttribute('stroke',renderedLetter.sc);
+        }
+        if(renderedLetter.fc){
+            this.textPaths[i].setAttribute('fill',renderedLetter.fc);
+            this.textPaths[i].style.color = renderedLetter.fc;
+        }
+    }
+    if(this.isVisible && (this.elemMdf || this.firstFrame)){
+        if(this.innerElem.getBBox){
+            var boundingBox = this.innerElem.getBBox();
+
+            if(this.currentBBox.w !== boundingBox.width){
+                this.currentBBox.w = boundingBox.width;
+                this.cont.setAttribute('width',boundingBox.width);
+            }
+            if(this.currentBBox.h !== boundingBox.height){
+                this.currentBBox.h = boundingBox.height;
+                this.cont.setAttribute('height',boundingBox.height);
+            }
+            if(this.currentBBox.w !== boundingBox.width || this.currentBBox.h !== boundingBox.height  || this.currentBBox.x !== boundingBox.x  || this.currentBBox.y !== boundingBox.y){
+                this.currentBBox.w = boundingBox.width;
+                this.currentBBox.h = boundingBox.height;
+                this.currentBBox.x = boundingBox.x;
+                this.currentBBox.y = boundingBox.y;
+
+                this.cont.setAttribute('viewBox',this.currentBBox.x+' '+this.currentBBox.y+' '+this.currentBBox.w+' '+this.currentBBox.h);
+                this.cont.style.transform = this.cont.style.webkitTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+            }
+        }
+    }
+    if(this.firstFrame){
+        this.firstFrame = false;
+    }
+}
+
+
+HTextElement.prototype.destroy = SVGTextElement.prototype.destroy;
+function HImageElement(data,parentContainer,globalData,comp, placeholder){
+    this.assetData = globalData.getAssetData(data.refId);
+    this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder);
+}
+createElement(HBaseElement, HImageElement);
+
+HImageElement.prototype.createElements = function(){
+
+    var assetPath = this.globalData.getAssetsPath(this.assetData);
+    var img = new Image();
+
+    if(this.data.hasMask){
+        var parent = document.createElement('div');
+        styleDiv(parent);
+        var cont = document.createElementNS(svgNS,'svg');
+        styleDiv(cont);
+        cont.setAttribute('width',this.assetData.w);
+        cont.setAttribute('height',this.assetData.h);
+        parent.appendChild(cont);
+        this.imageElem = document.createElementNS(svgNS,'image');
+        this.imageElem.setAttribute('width',this.assetData.w+"px");
+        this.imageElem.setAttribute('height',this.assetData.h+"px");
+        this.imageElem.setAttributeNS('http://www.w3.org/1999/xlink','href',assetPath);
+        cont.appendChild(this.imageElem);
+        this.layerElement = parent;
+        this.transformedElement = parent;
+        this.baseElement = parent;
+        this.innerElem = parent;
+        this.maskedElement = this.imageElem;
+    } else {
+        styleDiv(img);
+        this.layerElement = img;
+        this.baseElement = img;
+        this.innerElem = img;
+        this.transformedElement = img;
+    }
+    img.src = assetPath;
+    if(this.data.ln){
+        this.innerElem.setAttribute('id',this.data.ln);
+    }
+    this.checkParenting();
+};
+
+HImageElement.prototype.hide = HSolidElement.prototype.hide;
+HImageElement.prototype.renderFrame = HSolidElement.prototype.renderFrame;
+HImageElement.prototype.destroy = HSolidElement.prototype.destroy;
+function HCameraElement(data,parentContainer,globalData,comp, placeholder){
+    this._parent.constructor.call(this,data,parentContainer,globalData,comp, placeholder);
+    this.pe = PropertyFactory.getProp(this,data.pe,0,0,this.dynamicProperties);
+    if(data.ks.p.s){
+        this.px = PropertyFactory.getProp(this,data.ks.p.x,1,0,this.dynamicProperties);
+        this.py = PropertyFactory.getProp(this,data.ks.p.y,1,0,this.dynamicProperties);
+        this.pz = PropertyFactory.getProp(this,data.ks.p.z,1,0,this.dynamicProperties);
+    }else{
+        this.p = PropertyFactory.getProp(this,data.ks.p,1,0,this.dynamicProperties);
+    }
+    if(data.ks.a){
+        this.a = PropertyFactory.getProp(this,data.ks.a,1,0,this.dynamicProperties);
+    }
+    if(data.ks.or.k.length && data.ks.or.k[0].to){
+        var i,len = data.ks.or.k.length;
+        for(i=0;i<len;i+=1){
+            data.ks.or.k[i].to = null;
+            data.ks.or.k[i].ti = null;
+        }
+    }
+    this.or = PropertyFactory.getProp(this,data.ks.or,1,degToRads,this.dynamicProperties);
+    this.or.sh = true;
+    this.rx = PropertyFactory.getProp(this,data.ks.rx,0,degToRads,this.dynamicProperties);
+    this.ry = PropertyFactory.getProp(this,data.ks.ry,0,degToRads,this.dynamicProperties);
+    this.rz = PropertyFactory.getProp(this,data.ks.rz,0,degToRads,this.dynamicProperties);
+    this.mat = new Matrix();
+}
+createElement(HBaseElement, HCameraElement);
+
+HCameraElement.prototype.setup = function() {
+    var i, len = this.comp.threeDElements.length, comp;
+    for(i=0;i<len;i+=1){
+        //[perspectiveElem,container]
+        comp = this.comp.threeDElements[i];
+        comp.perspectiveElem.style.perspective = comp.perspectiveElem.style.webkitPerspective = this.pe.v+'px';
+        comp.container.style.transformOrigin = comp.container.style.mozTransformOrigin = comp.container.style.webkitTransformOrigin = "0px 0px 0px";
+        comp.perspectiveElem.style.transform = comp.perspectiveElem.style.webkitTransform = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+    }
+};
+
+HCameraElement.prototype.createElements = function(){
+};
+
+HCameraElement.prototype.hide = function(){
+};
+
+HCameraElement.prototype.renderFrame = function(){
+    var mdf = this.firstFrame;
+    var i, len;
+    if(this.hierarchy){
+        len = this.hierarchy.length;
+        for(i=0;i<len;i+=1){
+            mdf = this.hierarchy[i].finalTransform.mProp.mdf ? true : mdf;
+        }
+    }
+    if(mdf || (this.p && this.p.mdf) || (this.px && (this.px.mdf || this.py.mdf || this.pz.mdf)) || this.rx.mdf || this.ry.mdf || this.rz.mdf || this.or.mdf || (this.a && this.a.mdf)) {
+        this.mat.reset();
+
+        if(this.p){
+            this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]);
+        }else{
+            this.mat.translate(-this.px.v,-this.py.v,this.pz.v);
+        }
+        if(this.a){
+            var diffVector = [this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]];
+            var mag = Math.sqrt(Math.pow(diffVector[0],2)+Math.pow(diffVector[1],2)+Math.pow(diffVector[2],2));
+            //var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
+            var lookDir = [diffVector[0]/mag,diffVector[1]/mag,diffVector[2]/mag];
+            var lookLengthOnXZ = Math.sqrt( lookDir[2]*lookDir[2] + lookDir[0]*lookDir[0] );
+            var m_rotationX = (Math.atan2( lookDir[1], lookLengthOnXZ ));
+            var m_rotationY = (Math.atan2( lookDir[0], -lookDir[2]));
+            this.mat.rotateY(m_rotationY).rotateX(-m_rotationX);
+
+        }
+        this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
+        this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
+        this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0);
+        this.mat.translate(0,0,this.pe.v);
+        if(this.hierarchy){
+            var mat;
+            len = this.hierarchy.length;
+            for(i=0;i<len;i+=1){
+                mat = this.hierarchy[i].finalTransform.mProp.iv.props;
+                this.mat.transform(mat[0],mat[1],mat[2],mat[3],mat[4],mat[5],mat[6],mat[7],mat[8],mat[9],mat[10],mat[11],-mat[12],-mat[13],mat[14],mat[15]);
+            }
+        }
+        len = this.comp.threeDElements.length;
+        var comp;
+        for(i=0;i<len;i+=1){
+            comp = this.comp.threeDElements[i];
+            comp.container.style.transform = comp.container.style.webkitTransform = this.mat.toCSS();
+        }
+    }
+    this.firstFrame = false;
+};
+
+HCameraElement.prototype.destroy = function(){
+};
+var Expressions = (function(){
+    var ob = {};
+    ob.initExpressions = initExpressions;
+
+
+    function initExpressions(animation){
+        animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
+        animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
+    }
+   return ob;
+}());
+
+expressionsPlugin = Expressions;
+
+(function addPropertyDecorator() {
+
+    function getStaticValueAtTime() {
+        return this.pv;
+    }
+
+    function getValueAtTime(frameNum, offsetTime) {
+        frameNum *= this.elem.globalData.frameRate;
+        var i = 0,len = this.keyframes.length- 1,dir= 1,flag = true;
+        var keyData, nextKeyData;
+        offsetTime = offsetTime === undefined ? this.offsetTime : 0;
+        //console.log(this.offsetTime);
+        var retVal = typeof this.pv === 'object' ? [this.pv.length] : 0;
+
+        while(flag){
+            keyData = this.keyframes[i];
+            nextKeyData = this.keyframes[i+1];
+            if(i == len-1 && frameNum >= nextKeyData.t - offsetTime){
+                if(keyData.h){
+                    keyData = nextKeyData;
+                }
+                break;
+            }
+            if((nextKeyData.t - offsetTime) > frameNum){
+                break;
+            }
+            if(i < len - 1){
+                i += dir;
+            }else{
+                flag = false;
+            }
+        }
+
+        var k, kLen,perc,jLen, j = 0, fnc;
+        if (keyData.to) {
+
+            if (!keyData.bezierData) {
+                bez.buildBezierData(keyData);
+            }
+            var bezierData = keyData.bezierData;
+            if (frameNum >= nextKeyData.t-offsetTime || frameNum < keyData.t-offsetTime) {
+                var ind = frameNum >= nextKeyData.t-offsetTime ? bezierData.points.length - 1 : 0;
+                kLen = bezierData.points[ind].point.length;
+                for(k = 0; k < kLen; k += 1){
+                    retVal[k] = bezierData.points[ind].point[k];
+                }
+            } else {
+                if (keyData.__fnct) {
+                    fnc = keyData.__fnct;
+                } else {
+                    //fnc = bez.getEasingCurve(keyData.o.x,keyData.o.y,keyData.i.x,keyData.i.y,keyData.n);
+                    fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+                    keyData.__fnct = fnc;
+                }
+                perc = fnc((frameNum - (keyData.t - offsetTime)) / ((nextKeyData.t - offsetTime) - (keyData.t - offsetTime)));
+                var distanceInLine = bezierData.segmentLength * perc;
+
+                var segmentPerc;
+                var addedLength = 0;
+                dir = 1;
+                flag = true;
+                jLen = bezierData.points.length;
+                while(flag) {
+                    addedLength += bezierData.points[j].partialLength*dir;
+                    if (distanceInLine === 0 || perc === 0 || j == bezierData.points.length - 1) {
+                        kLen = bezierData.points[j].point.length;
+                        for (k = 0; k < kLen; k += 1) {
+                            retVal[k] = bezierData.points[j].point[k];
+                        }
+                        break;
+                    } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j+1].partialLength){
+                        segmentPerc = (distanceInLine - addedLength) / (bezierData.points[j + 1].partialLength);
+                        kLen = bezierData.points[j].point.length;
+                        for (k = 0; k < kLen; k += 1) {
+                            retVal[k] = bezierData.points[j].point[k] + (bezierData.points[j+1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+                        }
+                        break;
+                    }
+                    if (j < jLen - 1 && dir == 1 || j > 0 && dir == -1) {
+                        j += dir;
+                    } else {
+                        flag = false;
+                    }
+                }
+            }
+        } else {
+            var outX,outY,inX,inY, isArray = false, keyValue;
+            len = keyData.s.length;
+            for(i=0;i<len;i+=1){
+                if(keyData.h !== 1){
+                    if(keyData.o.x instanceof Array){
+                        isArray = true;
+                        if(!keyData.__fnct){
+                            keyData.__fnct = [];
+                        }
+                        if(!keyData.__fnct[i]){
+                            outX = keyData.o.x[i] || keyData.o.x[0];
+                            outY = keyData.o.y[i] || keyData.o.y[0];
+                            inX = keyData.i.x[i] || keyData.i.x[0];
+                            inY = keyData.i.y[i] || keyData.i.y[0];
+                        }
+                    }else{
+                        isArray = false;
+                        if(!keyData.__fnct) {
+                            outX = keyData.o.x;
+                            outY = keyData.o.y;
+                            inX = keyData.i.x;
+                            inY = keyData.i.y;
+                        }
+                    }
+                    if(isArray){
+                        if(keyData.__fnct[i]){
+                            fnc = keyData.__fnct[i];
+                        }else{
+                            //fnc = bez.getEasingCurve(outX,outY,inX,inY);
+                            fnc = BezierFactory.getBezierEasing(outX,outY,inX,inY).get;
+                            keyData.__fnct[i] = fnc;
+                        }
+                    }else{
+                        if(keyData.__fnct){
+                            fnc = keyData.__fnct;
+                        }else{
+                            //fnc = bez.getEasingCurve(outX,outY,inX,inY);
+                            fnc = BezierFactory.getBezierEasing(outX,outY,inX,inY).get;
+                            keyData.__fnct = fnc;
+                        }
+                    }
+                    if(frameNum >= nextKeyData.t-offsetTime){
+                        perc = 1;
+                    }else if(frameNum < keyData.t-offsetTime){
+                        perc = 0;
+                    }else{
+                        perc = fnc((frameNum-(keyData.t-offsetTime))/((nextKeyData.t-offsetTime)-(keyData.t-offsetTime)));
+                    }
+                }
+                if(this.sh && keyData.h !== 1){
+                    var initP = keyData.s[i];
+                    var endP = keyData.e[i];
+                    if(initP-endP < -180){
+                        initP += 360;
+                    } else if(initP-endP > 180){
+                        initP -= 360;
+                    }
+                    keyValue = initP+(endP-initP)*perc;
+                } else {
+                    keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i]+(keyData.e[i]-keyData.s[i])*perc;
+                }
+                if(len === 1){
+                    retVal = keyValue;
+                }else{
+                    retVal[i] = keyValue;
+                }
+            }
+        }
+        return retVal;
+    }
+
+    function getVelocityAtTime(frameNum) {
+        if(this.vel !== undefined){
+            return this.vel;
+        }
+        var delta = -0.01;
+        //frameNum += this.elem.data.st;
+        var v1 = this.getValueAtTime(frameNum, 0);
+        var v2 = this.getValueAtTime(frameNum + delta, 0);
+        var velocity;
+        if(v1.length){
+            velocity = Array.apply(null,{length:v1.length});
+            var i;
+            for(i=0;i<v1.length;i+=1){
+                //removing frameRate
+                //if needed, don't add it here
+                //velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta);
+                velocity[i] = (v2[i] - v1[i])/delta;
+            }
+        } else {
+            velocity = (v2 - v1)/delta;
+        }
+        return velocity;
+    };
+
+    function setGroupProperty(propertyGroup){
+        this.propertyGroup = propertyGroup;
+    }
+
+    function searchExpressions(elem,data,prop){
+        if(data.x){
+            prop.k = true;
+            prop.x = true;
+            if(prop.getValue) {
+                prop.getPreValue = prop.getValue;
+            }
+            prop.getValue = ExpressionManager.initiateExpression.bind(prop)(elem,data,prop);
+        }
+    }
+
+    var TextExpressionSelectorProp = (function(){
+
+        function getValueProxy(index,total){
+            this.textIndex = index+1;
+            this.textTotal = total;
+            this.getValue();
+            return this.v;
+        }
+
+        return function TextExpressionSelectorProp(elem,data){
+            this.pv = 1;
+            this.comp = elem.comp;
+            this.elem = elem;
+            this.mult = .01;
+            this.type = 'textSelector';
+            this.textTotal = data.totalChars;
+            this.selectorValue = 100;
+            this.lastValue = [1,1,1];
+            searchExpressions.bind(this)(elem,data,this);
+            this.getMult = getValueProxy;
+            this.getVelocityAtTime = getVelocityAtTime;
+            if(this.kf){
+                this.getValueAtTime = getValueAtTime.bind(this);
+            } else {
+                this.getValueAtTime = getStaticValueAtTime.bind(this);
+            }
+            this.setGroupProperty = setGroupProperty;
+        }
+    }());
+
+
+    var propertyGetProp = PropertyFactory.getProp;
+    PropertyFactory.getProp = function(elem,data,type, mult, arr){
+        var prop = propertyGetProp(elem,data,type, mult, arr);
+        prop.getVelocityAtTime = getVelocityAtTime;
+        if(prop.kf){
+            prop.getValueAtTime = getValueAtTime.bind(prop);
+        } else {
+            prop.getValueAtTime = getStaticValueAtTime.bind(prop);
+        }
+        prop.setGroupProperty = setGroupProperty;
+        var isAdded = prop.k;
+        if(data.ix !== undefined){
+            Object.defineProperty(prop,'propertyIndex',{
+                get: function(){
+                    return data.ix;
+                }
+            })
+        }
+        searchExpressions(elem,data,prop);
+        if(!isAdded && prop.x){
+            arr.push(prop);
+        }
+
+        return prop;
+    }
+
+    var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
+    ShapePropertyFactory.getShapeProp = function(elem,data,type, arr, trims){
+        var prop = propertyGetShapeProp(elem,data,type, arr, trims);
+        prop.setGroupProperty = setGroupProperty;
+        if(prop.kf){
+            prop.getValueAtTime = getValueAtTime;
+        } else {
+            prop.getValueAtTime = getStaticValueAtTime;
+        }
+        var isAdded = prop.k;
+        if(data.ix !== undefined){
+            Object.defineProperty(prop,'propertyIndex',{
+                get: function(){
+                    return data.ix;
+                }
+            })
+        }
+        if(type === 3){
+            searchExpressions(elem,data.pt,prop);
+        } else if(type === 4){
+            searchExpressions(elem,data.ks,prop);
+        }
+        if(!isAdded && prop.x){
+            arr.push(prop);
+        }
+        return prop;
+    }
+
+    var propertyGetTextProp = PropertyFactory.getTextSelectorProp;
+    PropertyFactory.getTextSelectorProp = function(elem, data,arr){
+        if(data.t === 1){
+            return new TextExpressionSelectorProp(elem, data,arr);
+        } else {
+            return propertyGetTextProp(elem,data,arr);
+        }
+    }
+}());
+var ExpressionManager = (function(){
+    var ob = {};
+    var Math = BMMath;
+    var window = null;
+    var document = null;
+
+    function duplicatePropertyValue(value, mult){
+        mult = mult || 1;
+
+        if(typeof value === 'number'  || value instanceof Number){
+            return value*mult;
+        }else if(value.i){
+            return JSON.parse(JSON.stringify(value));
+        }else{
+            var arr = Array.apply(null,{length:value.length});
+            var i, len = value.length;
+            for(i=0;i<len;i+=1){
+                arr[i]=value[i]*mult;
+            }
+            return arr;
+        }
+    }
+
+    function shapesEqual(shape1, shape2) {
+        if(shape1._length !== shape2._length || shape1.c !== shape2.c){
+            return false;
+        }
+        var i, len = shape1._length;
+        for(i = 0; i < len; i += 1) {
+            if(shape1.v[i][0] !== shape2.v[i][0] || shape1.v[i][1] !== shape2.v[i][1]
+                || shape1.o[i][0] !== shape2.o[i][0] || shape1.o[i][1] !== shape2.o[i][1]
+                || shape1.i[i][0] !== shape2.i[i][0] || shape1.i[i][1] !== shape2.i[i][1]){
+                return false;
+            }
+        }
+        return true;
+    }
+
+    function $bm_neg(a){
+        var tOfA = typeof a;
+        if(tOfA === 'number' || tOfA === 'boolean'  || a instanceof Number ){
+            return -a;
+        }
+        if(a.constructor === Array){
+            var i, lenA = a.length;
+            var retArr = [];
+            for(i=0;i<lenA;i+=1){
+                retArr[i] = -a[i];
+            }
+            return retArr;
+        }
+    }
+
+    function sum(a,b) {
+        var tOfA = typeof a;
+        var tOfB = typeof b;
+        if(tOfA === 'string' || tOfB === 'string'){
+            return a + b;
+        }
+        if((tOfA === 'number' || tOfA === 'boolean' || tOfA === 'string' || a instanceof Number) && (tOfB === 'number' || tOfB === 'boolean' || tOfB === 'string'  || b instanceof Number)) {
+            return a + b;
+        }
+        if(a.constructor === Array && (tOfB === 'number' || tOfB === 'boolean' || tOfB === 'string' || b instanceof Number )){
+            a[0] = a[0] + b;
+            return a;
+        }
+        if((tOfA === 'number' || tOfA === 'boolean' || tOfA === 'string' || a instanceof Number ) && b.constructor === Array){
+            b[0] = a + b[0];
+            return b;
+        }
+        if(a.constructor === Array && b.constructor === Array){
+            var i = 0, lenA = a.length, lenB = b.length;
+            var retArr = [];
+            while(i<lenA || i < lenB){
+                if(typeof a[i] === 'number' && typeof b[i] === 'number'){
+                    retArr[i] = a[i] + b[i];
+                }else{
+                    retArr[i] = b[i] == undefined ? a[i] : a[i] || b[i];
+                }
+                i += 1;
+            }
+            return retArr;
+        }
+        return 0;
+    }
+    var add = sum;
+
+    function sub(a,b) {
+        var tOfA = typeof a;
+        var tOfB = typeof b;
+        if((tOfA === 'number' || tOfA === 'boolean' || tOfA === 'string' || a instanceof Number ) && (tOfB === 'number' || tOfB === 'boolean' || tOfB === 'string' || b instanceof Number )) {
+            return a - b;
+        }
+        if( a.constructor === Array && (tOfB === 'number' || tOfB === 'boolean' || tOfB === 'string' || b instanceof Number )){
+            a[0] = a[0] - b;
+            return a;
+        }
+        if((tOfA === 'number' || tOfA === 'boolean' || tOfA === 'string' || a instanceof Number ) &&  b.constructor === Array){
+            b[0] = a - b[0];
+            return b;
+        }
+        if(a.constructor === Array && b.constructor === Array){
+            var i = 0, lenA = a.length, lenB = b.length;
+            var retArr = [];
+            while(i<lenA || i < lenB){
+                if(typeof a[i] === 'number' && typeof b[i] === 'number'){
+                    retArr[i] = a[i] - b[i];
+                }else{
+                    retArr[i] = b[i] == undefined ? a[i] : a[i] || b[i];
+                }
+                i += 1;
+            }
+            return retArr;
+        }
+        return 0;
+    }
+
+    function mul(a,b) {
+        var tOfA = typeof a;
+        var tOfB = typeof b;
+        var arr;
+        if((tOfA === 'number' || tOfA === 'boolean' || tOfA === 'string' || a instanceof Number ) && (tOfB === 'number' || tOfB === 'boolean' || tOfB === 'string' || b instanceof Number )) {
+            return a * b;
+        }
+
+        var i, len;
+        if(a.constructor === Array && (tOfB === 'number' || tOfB === 'boolean' || tOfB === 'string' || b instanceof Number )){
+            len = a.length;
+            arr = Array.apply(null,{length:len});
+            for(i=0;i<len;i+=1){
+                arr[i] = a[i] * b;
+            }
+            return arr;
+        }
+        if((tOfA === 'number' || tOfA === 'boolean' || tOfA === 'string' || a instanceof Number ) && b.constructor === Array){
+            len = b.length;
+            arr = Array.apply(null,{length:len});
+            for(i=0;i<len;i+=1){
+                arr[i] = a * b[i];
+            }
+            return arr;
+        }
+        return 0;
+    }
+
+    function div(a,b) {
+        var tOfA = typeof a;
+        var tOfB = typeof b;
+        var arr;
+        if((tOfA === 'number' || tOfA === 'boolean' || tOfA === 'string' || a instanceof Number ) && (tOfB === 'number' || tOfB === 'boolean' || tOfB === 'string' || b instanceof Number )) {
+            return a / b;
+        }
+        var i, len;
+        if(a.constructor === Array && (tOfB === 'number' || tOfB === 'boolean' || tOfB === 'string' || b instanceof Number  )){
+            len = a.length;
+            arr = Array.apply(null,{length:len});
+            for(i=0;i<len;i+=1){
+                arr[i] = a[i] / b;
+            }
+            return arr;
+        }
+        if((tOfA === 'number' || tOfA === 'boolean' || tOfA === 'string' || a instanceof Number ) && b.constructor === Array){
+            len = b.length;
+            arr = Array.apply(null,{length:len});
+            for(i=0;i<len;i+=1){
+                arr[i] = a / b[i];
+            }
+            return arr;
+        }
+        return 0;
+    }
+
+    function clamp(num, min, max) {
+        if(min > max){
+            var mm = max;
+            max = min;
+            min = mm;
+        }
+        return Math.min(Math.max(num, min), max);
+    }
+
+    function radiansToDegrees(val) {
+        return val/degToRads;
+    }
+    var radians_to_degrees = radiansToDegrees;
+
+    function degreesToRadians(val) {
+        return val*degToRads;
+    }
+    var degrees_to_radians = radiansToDegrees;
+
+    var helperLengthArray = [0,0,0,0,0,0];
+
+    function length(arr1,arr2){
+        if(typeof arr1 === "number"){
+            arr2 = arr2 || 0;
+            return Math.abs(arr1 - arr2);
+        }
+        if(!arr2){
+            arr2 = helperLengthArray;
+        }
+        var i,len = Math.min(arr1.length,arr2.length);
+        var addedLength = 0;
+        for(i=0;i<len;i+=1){
+            addedLength += Math.pow(arr2[i]-arr1[i],2);
+        }
+        return Math.sqrt(addedLength);
+    }
+
+    function normalize(vec){
+        return div(vec, length(vec));
+    }
+
+    function rgbToHsl(val){
+        var r = val[0]; var g = val[1]; var b = val[2];
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2;
+
+        if(max == min){
+            h = s = 0; // achromatic
+        }else{
+            var d = max - min;
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+            switch(max){
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2; break;
+                case b: h = (r - g) / d + 4; break;
+            }
+            h /= 6;
+        }
+
+        return [h, s, l,val[3]];
+    }
+    function hslToRgb(val){
+        var h = val[0];
+        var s = val[1];
+        var l = val[2];
+
+        var r, g, b;
+
+        if(s == 0){
+            r = g = b = l; // achromatic
+        }else{
+            function hue2rgb(p, q, t){
+                if(t < 0) t += 1;
+                if(t > 1) t -= 1;
+                if(t < 1/6) return p + (q - p) * 6 * t;
+                if(t < 1/2) return q;
+                if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
+                return p;
+            }
+
+            var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+            var p = 2 * l - q;
+            r = hue2rgb(p, q, h + 1/3);
+            g = hue2rgb(p, q, h);
+            b = hue2rgb(p, q, h - 1/3);
+        }
+
+        return [r, g , b, val[3]];
+    }
+
+    function linear(t, tMin, tMax, value1, value2){
+        if(value1 === undefined || value2 === undefined){
+            return linear(t,0,1,tMin,tMax);
+        }
+        if(t <= tMin) {
+            return value1;
+        }else if(t >= tMax){
+            return value2;
+        }
+        var perc = tMax === tMin ? 0 : (t-tMin)/(tMax-tMin);
+        if(!value1.length){
+            return value1 + (value2-value1)*perc;
+        }
+        var i, len = value1.length;
+        var arr = Array.apply( null, { length: len } );
+        for(i=0;i<len;i+=1){
+            arr[i] = value1[i] + (value2[i]-value1[i])*perc;
+        }
+        return arr;
+    }
+    function random(min,max){
+        if(max === undefined){
+            if(min === undefined){
+                min = 0;
+                max = 1;
+            } else {
+                max = min;
+                min = undefined;
+            }
+        }
+        if(max.length){
+            var i, len = max.length;
+            if(!min){
+                min = Array.apply(null,{length:len});
+            }
+            var arr = Array.apply(null,{length:len});
+            var rnd = BMMath.random();
+            for(i=0;i<len;i+=1){
+                arr[i] = min[i] + rnd*(max[i]-min[i])
+            }
+            return arr;
+        }
+        if(min === undefined){
+            min = 0;
+        }
+        var rndm = BMMath.random();
+        return min + rndm*(max-min);
+    }
+
+    function initiateExpression(elem,data,property){
+        var val = data.x;
+        var needsVelocity = /velocity(?![\w\d])/.test(val);
+        var _needsRandom = val.indexOf('random') !== -1;
+        var elemType = elem.data.ty;
+        var transform,content,effect;
+        var thisComp = elem.comp;
+        var thisProperty = property;
+        elem.comp.frameDuration = 1/elem.comp.globalData.frameRate;
+        var inPoint = elem.data.ip/elem.comp.globalData.frameRate;
+        var outPoint = elem.data.op/elem.comp.globalData.frameRate;
+        var width = elem.data.sw ? elem.data.sw : 0;
+        var height = elem.data.sh ? elem.data.sh : 0;
+        var thisLayer,thisComp;
+        var fn = new Function();
+        //var fnStr = 'var fn = function(){'+val+';this.v = $bm_rt;}';
+        //eval(fnStr);
+        var fn = eval('[function(){' + val+';this.v = $bm_rt;}' + ']')[0];
+        var bindedFn = fn.bind(this);
+        var numKeys = property.kf ? data.k.length : 0;
+
+        var wiggle = function wiggle(freq,amp){
+            var i,j, len = this.pv.length ? this.pv.length : 1;
+            var addedAmps = Array.apply(null,{len:len});
+            for(j=0;j<len;j+=1){
+                addedAmps[j] = 0;
+            }
+            freq = 5;
+            var iterations = Math.floor(time*freq);
+            i = 0;
+            j = 0;
+            while(i<iterations){
+                //var rnd = BMMath.random();
+                for(j=0;j<len;j+=1){
+                    addedAmps[j] += -amp + amp*2*BMMath.random();
+                    //addedAmps[j] += -amp + amp*2*rnd;
+                }
+                i += 1;
+            }
+            //var rnd2 = BMMath.random();
+            var periods = time*freq;
+            var perc = periods - Math.floor(periods);
+            var arr = Array.apply({length:len});
+            if(len>1){
+                for(j=0;j<len;j+=1){
+                    arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*BMMath.random())*perc;
+                    //arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+                    //arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
+                }
+                return arr;
+            } else {
+                return this.pv + addedAmps[0] + (-amp + amp*2*BMMath.random())*perc;
+            }
+        }.bind(this);
+
+        var loopIn = function loopIn(type,duration, durationFlag) {
+            if(!this.k){
+                return this.pv;
+            }
+            var currentFrame = time*elem.comp.globalData.frameRate;
+            var keyframes = this.keyframes;
+            var firstKeyFrame = keyframes[0].t;
+            if(currentFrame>=firstKeyFrame){
+                return this.pv;
+            }else{
+                var cycleDuration, lastKeyFrame;
+                if(!durationFlag){
+                    if(!duration || duration > keyframes.length - 1){
+                        duration = keyframes.length - 1;
+                    }
+                    lastKeyFrame = keyframes[duration].t;
+                    cycleDuration = lastKeyFrame - firstKeyFrame;
+                } else {
+                    if(!duration){
+                        cycleDuration = Math.max(0,this.elem.data.op - firstKeyFrame);
+                    } else {
+                        cycleDuration = Math.abs(elem.comp.globalData.frameRate*duration);
+                    }
+                    lastKeyFrame = firstKeyFrame + cycleDuration;
+                }
+                var i, len, ret;
+                if(type === 'pingpong') {
+                    var iterations = Math.floor((firstKeyFrame - currentFrame)/cycleDuration);
+                    if(iterations % 2 === 0){
+                        return this.getValueAtTime(((firstKeyFrame - currentFrame)%cycleDuration +  firstKeyFrame) / this.comp.globalData.frameRate, 0);
+                    }
+                } else if(type === 'offset'){
+                    var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+                    var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+                    var current = this.getValueAtTime((cycleDuration - (firstKeyFrame - currentFrame)%cycleDuration +  firstKeyFrame) / this.comp.globalData.frameRate, 0);
+                    var repeats = Math.floor((firstKeyFrame - currentFrame)/cycleDuration)+1;
+                    if(this.pv.length){
+                        ret = new Array(initV.length);
+                        len = ret.length;
+                        for(i=0;i<len;i+=1){
+                            ret[i] = current[i]-(endV[i]-initV[i])*repeats;
+                        }
+                        return ret;
+                    }
+                    return current-(endV-initV)*repeats;
+                } else if(type === 'continue'){
+                    var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+                    var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
+                    if(this.pv.length){
+                        ret = new Array(firstValue.length);
+                        len = ret.length;
+                        for(i=0;i<len;i+=1){
+                            ret[i] = firstValue[i] + (firstValue[i]-nextFirstValue[i])*(firstKeyFrame - currentFrame)/0.001;
+                        }
+                        return ret;
+                    }
+                    return firstValue + (firstValue-nextFirstValue)*(firstKeyFrame - currentFrame)/0.001;
+                }
+                return this.getValueAtTime((cycleDuration - (firstKeyFrame - currentFrame) % cycleDuration +  firstKeyFrame) / this.comp.globalData.frameRate, 0);
+            }
+        }.bind(this);
+
+        var loopInDuration = function loopInDuration(type,duration){
+            return loopIn(type,duration,true);
+        }.bind(this);
+
+        var loopOut = function loopOut(type,duration,durationFlag){
+            if(!this.k || !this.keyframes){
+                return this.pv;
+            }
+            var currentFrame = time*elem.comp.globalData.frameRate;
+            var keyframes = this.keyframes;
+            var lastKeyFrame = keyframes[keyframes.length - 1].t;
+            if(currentFrame<=lastKeyFrame){
+                return this.pv;
+            }else{
+                var cycleDuration, firstKeyFrame;
+                if(!durationFlag){
+                    if(!duration || duration > keyframes.length - 1){
+                        duration = keyframes.length - 1;
+                    }
+                    firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
+                    cycleDuration = lastKeyFrame - firstKeyFrame;
+                } else {
+                    if(!duration){
+                        cycleDuration = Math.max(0,lastKeyFrame - this.elem.data.ip);
+                    } else {
+                        cycleDuration = Math.abs(lastKeyFrame - elem.comp.globalData.frameRate*duration);
+                    }
+                    firstKeyFrame = lastKeyFrame - cycleDuration;
+                }
+                var i, len, ret;
+                if(type === 'pingpong') {
+                    var iterations = Math.floor((currentFrame - firstKeyFrame)/cycleDuration);
+                    if(iterations % 2 !== 0){
+                        return this.getValueAtTime((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration +  firstKeyFrame) / this.comp.globalData.frameRate, 0);
+                    }
+                } else if(type === 'offset'){
+                    var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+                    var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+                    var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration +  firstKeyFrame) / this.comp.globalData.frameRate, 0);
+                    var repeats = Math.floor((currentFrame - firstKeyFrame)/cycleDuration);
+                    if(this.pv.length){
+                        ret = new Array(initV.length);
+                        len = ret.length;
+                        for(i=0;i<len;i+=1){
+                            ret[i] = (endV[i]-initV[i])*repeats + current[i];
+                        }
+                        return ret;
+                    }
+                    return (endV-initV)*repeats + current;
+                } else if(type === 'continue'){
+                    var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+                    var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
+                    if(this.pv.length){
+                        ret = new Array(lastValue.length);
+                        len = ret.length;
+                        for(i=0;i<len;i+=1){
+                            ret[i] = lastValue[i] + (lastValue[i]-nextLastValue[i])*((currentFrame - lastKeyFrame)/ this.comp.globalData.frameRate)/0.0005;
+                        }
+                        return ret;
+                    }
+                    return lastValue + (lastValue-nextLastValue)*(((currentFrame - lastKeyFrame))/0.001);
+                }
+                return this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration +  firstKeyFrame) / this.comp.globalData.frameRate, 0);
+            }
+        }.bind(this);
+        var loop_out = loopOut;
+
+        var loopOutDuration = function loopOutDuration(type,duration){
+            return loopOut(type,duration,true);
+        }.bind(this);
+
+        var valueAtTime = function valueAtTime(t) {
+            return this.getValueAtTime(t, 0);
+        }.bind(this);
+
+        var velocityAtTime = function velocityAtTime(t) {
+            return this.getVelocityAtTime(t);
+        }.bind(this);
+
+        var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
+
+        function lookAt(elem1,elem2){
+            var fVec = [elem2[0]-elem1[0],elem2[1]-elem1[1],elem2[2]-elem1[2]];
+            var pitch = Math.atan2(fVec[0],Math.sqrt(fVec[1]*fVec[1]+fVec[2]*fVec[2]))/degToRads;
+            var yaw = -Math.atan2(fVec[1],fVec[2])/degToRads;
+            return [yaw,pitch,0];
+        }
+
+        function easeOut(t, val1, val2){
+            return -(val2-val1) * t*(t-2) + val1;
+        }
+
+        function nearestKey(time){
+            var i, len = data.k.length,index,keyTime;
+            if(!data.k.length || typeof(data.k[0]) === 'number'){
+                index = 0;
+                keyTime = 0;
+            } else {
+                index = -1;
+                time *= elem.comp.globalData.frameRate;
+                if (time < data.k[0].t) {
+                    index = 1;
+                    keyTime = data.k[0].t;
+                } else {
+                    for(i=0;i<len-1;i+=1){
+                        if(time === data.k[i].t){
+                            index = i + 1;
+                            keyTime = data.k[i].t;
+                            break;
+                        }else if(time>data.k[i].t && time<data.k[i+1].t){
+                            if(time-data.k[i].t > data.k[i+1].t - time){
+                                index = i + 2;
+                                keyTime = data.k[i+1].t;
+                            } else {
+                                index = i + 1;
+                                keyTime = data.k[i].t;
+                            }
+                            break;
+                        }
+                    }
+                    if(index === -1){
+                        index = i + 1;
+                        keyTime = data.k[i].t;
+                    }
+                }
+                
+            }
+            var ob = {};
+            ob.index = index;
+            ob.time = keyTime/elem.comp.globalData.frameRate;
+            return ob;
+        }
+
+        function key(ind){
+            if(!data.k.length || typeof(data.k[0]) === 'number'){
+                return {time:0};
+            }
+            ind -= 1;
+            var ob = {
+                time: data.k[ind].t/elem.comp.globalData.frameRate
+            };
+            var arr;
+            if(ind === data.k.length - 1 && !data.k[ind].h){
+                arr = data.k[ind-1].e;
+            }else{
+                arr = data.k[ind].s;
+            }
+            var i, len = arr.length;
+            for(i=0;i<len;i+=1){
+                ob[i] = arr[i];
+            }
+            return ob;
+        }
+
+        function framesToTime(frames,fps){
+            if(!fps){
+                fps = elem.comp.globalData.frameRate;
+            }
+            return frames/fps;
+        }
+
+        function timeToFrames(t,fps){
+            if(!t){
+                t = time;
+            }
+            if(!fps){
+                fps = elem.comp.globalData.frameRate;
+            }
+            return t*fps;
+        }
+
+        var toworldMatrix = new Matrix();
+        function toWorld(arr){
+            toworldMatrix.reset();
+            elem.finalTransform.mProp.applyToMatrix(toworldMatrix);
+            if(elem.hierarchy && elem.hierarchy.length){
+                var i, len = elem.hierarchy.length;
+                for(i=0;i<len;i+=1){
+                    elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toworldMatrix);
+                }
+                return toworldMatrix.applyToPointArray(arr[0],arr[1],arr[2]||0);
+            }
+            return toworldMatrix.applyToPointArray(arr[0],arr[1],arr[2]||0);
+        }
+
+        var fromworldMatrix = new Matrix();
+        function fromWorld(arr){
+            fromworldMatrix.reset();
+            var pts = [];
+            pts.push(arr);
+            elem.finalTransform.mProp.applyToMatrix(fromworldMatrix);
+            if(elem.hierarchy && elem.hierarchy.length){
+                var i, len = elem.hierarchy.length;
+                for(i=0;i<len;i+=1){
+                    elem.hierarchy[i].finalTransform.mProp.applyToMatrix(fromworldMatrix);
+                }
+                return fromworldMatrix.inversePoints(pts)[0];
+            }
+            return fromworldMatrix.inversePoints(pts)[0];
+        }
+
+        function seedRandom(seed){
+            BMMath.seedrandom(randSeed + seed);
+        };
+
+        var time,velocity, value,textIndex,textTotal,selectorValue;
+        var index = elem.data.ind;
+        var hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+        var parent;
+        var randSeed = Math.floor(Math.random()*1000000);
+        function execute(){
+            if(_needsRandom){
+                seedRandom(randSeed);
+            }
+            if(this.frameExpressionId === elem.globalData.frameId && this.type !== 'textSelector'){
+                return;
+            }
+            if(this.lock){
+                this.v = duplicatePropertyValue(this.pv,this.mult);
+                return true;
+            }
+            if(this.type === 'textSelector'){
+                textIndex = this.textIndex;
+                textTotal = this.textTotal;
+                selectorValue = this.selectorValue;
+            }
+            if(!thisLayer){
+                thisLayer = elem.layerInterface;
+                thisComp = elem.comp.compInterface;
+            }
+            if(!transform){
+                transform = elem.layerInterface("ADBE Transform Group");
+            }
+            if(elemType === 4 && !content){
+                content = thisLayer("ADBE Root Vectors Group");
+            }
+            if(!effect){
+                effect = thisLayer(4);
+            }
+            hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+            if(hasParent && !parent){
+                parent = elem.hierarchy[0].layerInterface;
+            }
+            this.lock = true;
+            if(this.getPreValue){
+                this.getPreValue();
+            }
+            value = this.pv;
+            time = this.comp.renderedFrame/this.comp.globalData.frameRate;
+            if(needsVelocity){
+                velocity = velocityAtTime(time);
+            }
+            bindedFn();
+            this.frameExpressionId = elem.globalData.frameId;
+            var i,len;
+            if(this.mult){
+                if(typeof this.v === 'number' || this.v instanceof Number || typeof this.v === 'string'){
+                    this.v *= this.mult;
+                }else if(this.v.length === 1){
+                    this.v = this.v[0] * this.mult;
+                }else{
+                    len = this.v.length;
+                    if(value === this.v){
+                        this.v = len === 2 ? [value[0],value[1]] : [value[0],value[1],value[2]];
+                    }
+                    for(i = 0; i < len; i += 1){
+                        this.v[i] *= this.mult;
+                    }
+                }
+            }
+
+            if(this.v.length === 1){
+                this.v = this.v[0];
+            }
+            if(typeof this.v === 'number' || this.v instanceof Number || typeof this.v === 'string'){
+                if(this.lastValue !== this.v){
+                    this.lastValue = this.v;
+                    this.mdf = true;
+                }
+            }else if(this.v._length){
+                if(!shapesEqual(this.v,this.localShapeCollection.shapes[0])){
+                    this.mdf = true;
+                    this.localShapeCollection.releaseShapes();
+                    this.localShapeCollection.addShape(shape_pool.clone(this.v));
+                }
+            }else{
+                len = this.v.length;
+                for(i = 0; i < len; i += 1){
+                    if(this.v[i] !== this.lastValue[i]){
+                        this.lastValue[i] = this.v[i];
+                        this.mdf = true;
+                    }
+                }
+            }
+            this.lock = false;
+        }
+        return execute;
+    }
+
+    ob.initiateExpression = initiateExpression;
+    return ob;
+}());
+var ShapeExpressionInterface = (function(){
+    var ob = {
+        createShapeInterface:createShapeInterface,
+        createGroupInterface:createGroupInterface,
+        createTrimInterface:createTrimInterface,
+        createStrokeInterface:createStrokeInterface,
+        createTransformInterface:createTransformInterface,
+        createEllipseInterface:createEllipseInterface,
+        createStarInterface:createStarInterface,
+        createRectInterface:createRectInterface,
+        createRoundedInterface:createRoundedInterface,
+        createRepatearInterface:createRepatearInterface,
+        createPathInterface:createPathInterface,
+        createFillInterface:createFillInterface
+    };
+    function createShapeInterface(shapes,view,propertyGroup){
+        return shapeInterfaceFactory(shapes,view,propertyGroup);
+    }
+    function createGroupInterface(shapes,view,propertyGroup){
+        return groupInterfaceFactory(shapes,view,propertyGroup);
+    }
+    function createFillInterface(shape,view,propertyGroup){
+        return fillInterfaceFactory(shape,view,propertyGroup);
+    }
+    function createStrokeInterface(shape,view,propertyGroup){
+        return strokeInterfaceFactory(shape,view,propertyGroup);
+    }
+    function createTrimInterface(shape,view,propertyGroup){
+        return trimInterfaceFactory(shape,view,propertyGroup);
+    }
+    function createTransformInterface(shape,view,propertyGroup){
+        return transformInterfaceFactory(shape,view,propertyGroup);
+    }
+    function createEllipseInterface(shape,view,propertyGroup){
+        return ellipseInterfaceFactory(shape,view,propertyGroup);
+    }
+    function createStarInterface(shape,view,propertyGroup){
+        return starInterfaceFactory(shape,view,propertyGroup);
+    }
+    function createRectInterface(shape,view,propertyGroup){
+        return rectInterfaceFactory(shape,view,propertyGroup);
+    }
+    function createRoundedInterface(shape,view,propertyGroup){
+        return roundedInterfaceFactory(shape,view,propertyGroup);
+    }
+    function createRepatearInterface(shape,view,propertyGroup){
+        return repeaterInterfaceFactory(shape,view,propertyGroup);
+    }
+    function createPathInterface(shape,view,propertyGroup){
+        return pathInterfaceFactory(shape,view,propertyGroup);
+    }
+
+    function iterateElements(shapes,view, propertyGroup){
+        var arr = [];
+        var i, len = shapes ? shapes.length : 0;
+        for(i=0;i<len;i+=1){
+            if(shapes[i].ty == 'gr'){
+                arr.push(ShapeExpressionInterface.createGroupInterface(shapes[i],view[i],propertyGroup));
+            }else if(shapes[i].ty == 'fl'){
+                arr.push(ShapeExpressionInterface.createFillInterface(shapes[i],view[i],propertyGroup));
+            }else if(shapes[i].ty == 'st'){
+                arr.push(ShapeExpressionInterface.createStrokeInterface(shapes[i],view[i],propertyGroup));
+            }else if(shapes[i].ty == 'tm'){
+                arr.push(ShapeExpressionInterface.createTrimInterface(shapes[i],view[i],propertyGroup));
+            }else if(shapes[i].ty == 'tr'){
+                //arr.push(ShapeExpressionInterface.createTransformInterface(shapes[i],view[i],propertyGroup));
+            }else if(shapes[i].ty == 'el'){
+                arr.push(ShapeExpressionInterface.createEllipseInterface(shapes[i],view[i],propertyGroup));
+            }else if(shapes[i].ty == 'sr'){
+                arr.push(ShapeExpressionInterface.createStarInterface(shapes[i],view[i],propertyGroup));
+            } else if(shapes[i].ty == 'sh'){
+                arr.push(ShapeExpressionInterface.createPathInterface(shapes[i],view[i],propertyGroup));
+            } else if(shapes[i].ty == 'rc'){
+                arr.push(ShapeExpressionInterface.createRectInterface(shapes[i],view[i],propertyGroup));
+            } else if(shapes[i].ty == 'rd'){
+                arr.push(ShapeExpressionInterface.createRoundedInterface(shapes[i],view[i],propertyGroup));
+            } else if(shapes[i].ty == 'rp'){
+                arr.push(ShapeExpressionInterface.createRepatearInterface(shapes[i],view[i],propertyGroup));
+            } else{
+                //console.log(shapes[i].ty);
+            }
+        }
+        return arr;
+    }
+
+    var shapeInterfaceFactory = (function(){
+        return function(shapes,view,propertyGroup){
+            var interfaces;
+            function _interfaceFunction(value){
+                if(typeof value === 'number'){
+                    return interfaces[value-1];
+                } else {
+                    var i = 0, len = interfaces.length;
+                    while(i<len){
+                        if(interfaces[i]._name === value){
+                            return interfaces[i];
+                        }
+                        i+=1;
+                    }
+                }
+            }
+            _interfaceFunction.propertyGroup = propertyGroup;
+            interfaces = iterateElements(shapes, view, _interfaceFunction);
+            return _interfaceFunction;
+        }
+    }());
+
+    var contentsInterfaceFactory = (function(){
+       return function(shape,view, propertyGroup){
+           var interfaces;
+           var interfaceFunction = function _interfaceFunction(value){
+               var i = 0, len = interfaces.length;
+                while(i<len){
+                    if(interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value){
+                       return interfaces[i];
+                    }
+                    i+=1;
+                }
+                if(typeof value === 'number'){
+                   return interfaces[value-1];
+                }
+           };
+           interfaceFunction.propertyGroup = function(val){
+               if(val === 1){
+                   return interfaceFunction;
+               } else{
+                   return propertyGroup(val-1);
+               }
+           };
+           interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
+           interfaceFunction.numProperties = interfaces.length;
+           interfaceFunction.propertyIndex = shape.cix;
+
+           return interfaceFunction;
+       }
+    }());
+
+    var groupInterfaceFactory = (function(){
+        return function(shape,view, propertyGroup){
+            var interfaceFunction = function _interfaceFunction(value){
+                switch(value){
+                    case 'ADBE Vectors Group':
+                    case 'Contents':
+                    case 2:
+                        return interfaceFunction.content;
+                    case 'ADBE Vector Transform Group':
+                    case 3:
+                    default:
+                        return interfaceFunction.transform;
+                }
+                /*if(value === 'ADBE Vector Transform Group'){
+                    return interfaceFunction.transform;
+                    var i = 0, len = interfaces.length;
+                    while(i<len){
+                        if(interfaces[i].ty === 'tr'){
+                            return interfaces[i];
+                        }
+                        i+=1;
+                    }
+                    return null;
+                }
+                if(typeof value === 'number'){
+                    return interfaces[value-1];
+                } else {
+                    var i = 0, len = interfaces.length;
+                    while(i<len){
+                        if(interfaces[i]._name === value){
+                            return interfaces[i];
+                        }
+                        i+=1;
+                    }
+                }*/
+            }
+            interfaceFunction.propertyGroup = function(val){
+                if(val === 1){
+                    return interfaceFunction;
+                } else{
+                    return propertyGroup(val-1);
+                }
+            };
+            var content = contentsInterfaceFactory(shape,view,interfaceFunction.propertyGroup);
+            var transformInterface = ShapeExpressionInterface.createTransformInterface(shape.it[shape.it.length - 1],view.it[view.it.length - 1],interfaceFunction.propertyGroup);
+            interfaceFunction.content = content;
+            interfaceFunction.transform = transformInterface;
+            Object.defineProperty(interfaceFunction, '_name', {
+                get: function(){
+                    return shape.nm;
+                }
+            });
+            //interfaceFunction.content = interfaceFunction;
+            interfaceFunction.numProperties = shape.np;
+            interfaceFunction.propertyIndex = shape.ix;
+            interfaceFunction.nm = shape.nm;
+            interfaceFunction.mn = shape.mn;
+            return interfaceFunction;
+        }
+    }());
+
+    var fillInterfaceFactory = (function(){
+        return function(shape,view,propertyGroup){
+
+            function interfaceFunction(val){
+                if(val === 'Color' || val === 'color'){
+                    return interfaceFunction.color;
+                } else if(val === 'Opacity' || val === 'opacity'){
+                    return interfaceFunction.opacity;
+                }
+            }
+            Object.defineProperty(interfaceFunction, 'color', {
+                get: function(){
+                    return ExpressionValue(view.c, 1 / view.c.mult, 'color');
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'opacity', {
+                get: function(){
+                    return ExpressionValue(view.o, 100);
+                }
+            });
+            Object.defineProperty(interfaceFunction, '_name', { value: shape.nm });
+            Object.defineProperty(interfaceFunction, 'mn', { value: shape.mn });
+
+            view.c.setGroupProperty(propertyGroup);
+            view.o.setGroupProperty(propertyGroup);
+            return interfaceFunction;
+        }
+    }());
+
+    var strokeInterfaceFactory = (function(){
+        return function(shape,view,propertyGroup){
+            function _propertyGroup(val){
+                if(val === 1){
+                    return ob;
+                } else{
+                    return propertyGroup(val-1);
+                }
+            };
+            function _dashPropertyGroup(val){
+                if(val === 1){
+                    return dashOb;
+                } else{
+                    return _propertyGroup(val-1);
+                }
+            };
+            function addPropertyToDashOb(i) {
+                Object.defineProperty(dashOb, shape.d[i].nm, {
+                    get: function(){
+                        return ExpressionValue(view.d.dataProps[i].p)
+                    }
+                });
+            }
+            var i, len = shape.d ? shape.d.length : 0;
+            var dashOb = {}
+            for (i = 0; i < len; i += 1) {
+                addPropertyToDashOb(i);
+                view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
+            }
+
+            function interfaceFunction(val){
+                if(val === 'Color' || val === 'color'){
+                    return interfaceFunction.color;
+                } else if(val === 'Opacity' || val === 'opacity'){
+                    return interfaceFunction.opacity;
+                } else if(val === 'Stroke Width' || val === 'stroke width'){
+                    return interfaceFunction.strokeWidth;
+                }
+            }
+            Object.defineProperty(interfaceFunction, 'color', {
+                get: function(){
+                    return ExpressionValue(view.c, 1 / view.c.mult, 'color');
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'opacity', {
+                get: function(){
+                    return ExpressionValue(view.o, 100);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'strokeWidth', {
+                get: function(){
+                    return ExpressionValue(view.w);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'dash', {
+                get: function(){
+                    return dashOb;
+                }
+            });
+            Object.defineProperty(interfaceFunction, '_name', { value: shape.nm });
+            Object.defineProperty(interfaceFunction, 'mn', { value: shape.mn });
+
+            view.c.setGroupProperty(_propertyGroup);
+            view.o.setGroupProperty(_propertyGroup);
+            view.w.setGroupProperty(_propertyGroup);
+            return interfaceFunction;
+        }
+    }());
+
+    var trimInterfaceFactory = (function(){
+        return function(shape,view,propertyGroup){
+            function _propertyGroup(val){
+                if(val == 1){
+                    return interfaceFunction;
+                } else {
+                    return propertyGroup(--val);
+                }
+            }
+            interfaceFunction.propertyIndex = shape.ix;
+
+            view.s.setGroupProperty(_propertyGroup);
+            view.e.setGroupProperty(_propertyGroup);
+            view.o.setGroupProperty(_propertyGroup);
+
+            function interfaceFunction(val){
+                if(val === shape.e.ix || val === 'End' || val === 'end'){
+                    return interfaceFunction.end;
+                }
+                if(val === shape.s.ix){
+                    return interfaceFunction.start;
+                }
+                if(val === shape.o.ix){
+                    return interfaceFunction.offset;
+                }
+            }
+            interfaceFunction.propertyIndex = shape.ix;
+            Object.defineProperty(interfaceFunction, 'start', {
+                get: function(){
+                    return ExpressionValue(view.s, 1 / view.s.mult);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'end', {
+                get: function(){
+                    return ExpressionValue(view.e, 1 / view.e.mult);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'offset', {
+                get: function(){
+                    return ExpressionValue(view.o);
+                }
+            });
+            Object.defineProperty(interfaceFunction, '_name', {
+                get: function(){
+                    return shape.nm;
+                }
+            });
+            interfaceFunction.mn = shape.mn;
+            return interfaceFunction;
+        }
+    }());
+
+    var transformInterfaceFactory = (function(){
+        return function(shape,view,propertyGroup){
+            function _propertyGroup(val){
+                if(val == 1){
+                    return interfaceFunction;
+                } else {
+                    return propertyGroup(--val);
+                }
+            }
+            view.transform.mProps.o.setGroupProperty(_propertyGroup);
+            view.transform.mProps.p.setGroupProperty(_propertyGroup);
+            view.transform.mProps.a.setGroupProperty(_propertyGroup);
+            view.transform.mProps.s.setGroupProperty(_propertyGroup);
+            view.transform.mProps.r.setGroupProperty(_propertyGroup);
+            if(view.transform.mProps.sk){
+                view.transform.mProps.sk.setGroupProperty(_propertyGroup);
+                view.transform.mProps.sa.setGroupProperty(_propertyGroup);
+            }
+            view.transform.op.setGroupProperty(_propertyGroup);
+
+            function interfaceFunction(value){
+                if(shape.a.ix === value){
+                    return interfaceFunction.anchorPoint;
+                }
+                if(shape.o.ix === value){
+                    return interfaceFunction.opacity;
+                }
+                if(shape.p.ix === value){
+                    return interfaceFunction.position;
+                }
+                if(shape.r.ix === value){
+                    return interfaceFunction.rotation;
+                }
+                if(shape.s.ix === value){
+                    return interfaceFunction.scale;
+                }
+                if(shape.sk && shape.sk.ix === value){
+                    return interfaceFunction.skew;
+                }
+                if(shape.sa && shape.sa.ix === value){
+                    return interfaceFunction.skewAxis;
+                }
+                if(value === 'Opacity') {
+                    return interfaceFunction.opacity;
+                }
+                if(value === 'Position') {
+                    return interfaceFunction.position;
+                }
+                if(value === 'Anchor Point') {
+                    return interfaceFunction.anchorPoint;
+                }
+                if(value === 'Scale') {
+                    return interfaceFunction.scale;
+                }
+                if(value === 'Rotation' || value === 'ADBE Vector Rotation') {
+                    return interfaceFunction.rotation;
+                }
+                if(value === 'Skew') {
+                    return interfaceFunction.skew;
+                }
+                if(value === 'Skew Axis') {
+                    return interfaceFunction.skewAxis;
+                }
+
+            }
+            Object.defineProperty(interfaceFunction, 'opacity', {
+                get: function(){
+                    return ExpressionValue(view.transform.mProps.o, 1/view.transform.mProps.o.mult);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'position', {
+                get: function(){
+                    return ExpressionValue(view.transform.mProps.p);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'anchorPoint', {
+                get: function(){
+                    return ExpressionValue(view.transform.mProps.a);
+                }
+            });
+            var scaleArray = [];
+            Object.defineProperty(interfaceFunction, 'scale', {
+                get: function(){
+                    return ExpressionValue(view.transform.mProps.s, 1 / view.transform.mProps.s.mult);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'rotation', {
+                get: function(){
+                    return ExpressionValue(view.transform.mProps.r, 1 / view.transform.mProps.r.mult);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'skew', {
+                get: function(){
+                    return ExpressionValue(view.transform.mProps.sk);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'skewAxis', {
+                get: function(){
+                    return ExpressionValue(view.transform.mProps.sa);
+                }
+            });
+            Object.defineProperty(interfaceFunction, '_name', {
+                get: function(){
+                    return shape.nm;
+                }
+            });
+            interfaceFunction.ty = 'tr';
+            interfaceFunction.mn = shape.mn;
+            return interfaceFunction;
+        }
+    }());
+
+    var ellipseInterfaceFactory = (function(){
+        return function(shape,view,propertyGroup){
+            function _propertyGroup(val){
+                if(val == 1){
+                    return interfaceFunction;
+                } else {
+                    return propertyGroup(--val);
+                }
+            }
+            interfaceFunction.propertyIndex = shape.ix;
+            var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+            prop.s.setGroupProperty(_propertyGroup);
+            prop.p.setGroupProperty(_propertyGroup);
+            function interfaceFunction(value){
+                if(shape.p.ix === value){
+                    return interfaceFunction.position;
+                }
+                if(shape.s.ix === value){
+                    return interfaceFunction.size;
+                }
+            }
+            Object.defineProperty(interfaceFunction, 'size', {
+                get: function(){
+                    return ExpressionValue(prop.s);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'position', {
+                get: function(){
+                    return ExpressionValue(prop.p);
+                }
+            });
+            Object.defineProperty(interfaceFunction, '_name', {
+                get: function(){
+                    return shape.nm;
+                }
+            });
+            interfaceFunction.mn = shape.mn;
+            return interfaceFunction;
+        }
+    }());
+
+    var starInterfaceFactory = (function(){
+        return function(shape,view,propertyGroup){
+            function _propertyGroup(val){
+                if(val == 1){
+                    return interfaceFunction;
+                } else {
+                    return propertyGroup(--val);
+                }
+            }
+            var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+            interfaceFunction.propertyIndex = shape.ix;
+            prop.or.setGroupProperty(_propertyGroup);
+            prop.os.setGroupProperty(_propertyGroup);
+            prop.pt.setGroupProperty(_propertyGroup);
+            prop.p.setGroupProperty(_propertyGroup);
+            prop.r.setGroupProperty(_propertyGroup);
+            if(shape.ir){
+                prop.ir.setGroupProperty(_propertyGroup);
+                prop.is.setGroupProperty(_propertyGroup);
+            }
+
+            function interfaceFunction(value){
+                if(shape.p.ix === value){
+                    return interfaceFunction.position;
+                }
+                if(shape.r.ix === value){
+                    return interfaceFunction.rotation;
+                }
+                if(shape.pt.ix === value){
+                    return interfaceFunction.points;
+                }
+                if(shape.or.ix === value || 'ADBE Vector Star Outer Radius' === value){
+                    return interfaceFunction.outerRadius;
+                }
+                if(shape.os.ix === value){
+                    return interfaceFunction.outerRoundness;
+                }
+                if(shape.ir && (shape.ir.ix === value || 'ADBE Vector Star Inner Radius' === value)){
+                    return interfaceFunction.innerRadius;
+                }
+                if(shape.is && shape.is.ix === value){
+                    return interfaceFunction.innerRoundness;
+                }
+
+            }
+            Object.defineProperty(interfaceFunction, 'position', {
+                get: function(){
+                    return ExpressionValue(prop.p);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'rotation', {
+                get: function(){
+                    return ExpressionValue(prop.r, 1 / prop.r.mult);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'points', {
+                get: function(){
+                    return ExpressionValue(prop.pt);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'outerRadius', {
+                get: function(){
+                    return ExpressionValue(prop.or);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'outerRoundness', {
+                get: function(){
+                    return ExpressionValue(prop.os);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'innerRadius', {
+                get: function(){
+                    if(!prop.ir){
+                        return 0;
+                    }
+                    return ExpressionValue(prop.ir);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'innerRoundness', {
+                get: function(){
+                    if(!prop.is){
+                        return 0;
+                    }
+                    return ExpressionValue(prop.is, 1 / prop.is.mult);
+                }
+            });
+            Object.defineProperty(interfaceFunction, '_name', {
+                get: function(){
+                    return shape.nm;
+                }
+            });
+            interfaceFunction.mn = shape.mn;
+            return interfaceFunction;
+        }
+    }());
+
+    var rectInterfaceFactory = (function(){
+        return function(shape,view,propertyGroup){
+            function _propertyGroup(val){
+                if(val == 1){
+                    return interfaceFunction;
+                } else {
+                    return propertyGroup(--val);
+                }
+            }
+            var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+            interfaceFunction.propertyIndex = shape.ix;
+            prop.p.setGroupProperty(_propertyGroup);
+            prop.s.setGroupProperty(_propertyGroup);
+            prop.r.setGroupProperty(_propertyGroup);
+
+            function interfaceFunction(value){
+                if(shape.p.ix === value){
+                    return interfaceFunction.position;
+                }
+                if(shape.r.ix === value){
+                    return interfaceFunction.rotation;
+                }
+                if(shape.pt.ix === value){
+                    return interfaceFunction.points;
+                }
+                if(shape.or.ix === value || 'ADBE Vector Star Outer Radius' === value){
+                    return interfaceFunction.outerRadius;
+                }
+                if(shape.os.ix === value){
+                    return interfaceFunction.outerRoundness;
+                }
+                if(shape.ir && (shape.ir.ix === value || 'ADBE Vector Star Inner Radius' === value)){
+                    return interfaceFunction.innerRadius;
+                }
+                if(shape.is && shape.is.ix === value){
+                    return interfaceFunction.innerRoundness;
+                }
+
+            }
+            Object.defineProperty(interfaceFunction, 'position', {
+                get: function(){
+                    return ExpressionValue(prop.p);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'roundness', {
+                get: function(){
+                    return ExpressionValue(prop.r);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'size', {
+                get: function(){
+                    return ExpressionValue(prop.s);
+                }
+            });
+
+            Object.defineProperty(interfaceFunction, '_name', {
+                get: function(){
+                    return shape.nm;
+                }
+            });
+            interfaceFunction.mn = shape.mn;
+            return interfaceFunction;
+        }
+    }());
+
+    var roundedInterfaceFactory = (function(){
+        return function(shape,view,propertyGroup){
+            function _propertyGroup(val){
+                if(val == 1){
+                    return interfaceFunction;
+                } else {
+                    return propertyGroup(--val);
+                }
+            }
+            var prop = view;
+            interfaceFunction.propertyIndex = shape.ix;
+            prop.rd.setGroupProperty(_propertyGroup);
+
+            function interfaceFunction(value){
+                if(shape.r.ix === value || 'Round Corners 1' === value){
+                    return interfaceFunction.radius;
+                }
+
+            }
+            Object.defineProperty(interfaceFunction, 'radius', {
+                get: function(){
+                    return ExpressionValue(prop.rd);
+                }
+            });
+
+            Object.defineProperty(interfaceFunction, '_name', {
+                get: function(){
+                    return shape.nm;
+                }
+            });
+            interfaceFunction.mn = shape.mn;
+            return interfaceFunction;
+        }
+    }());
+
+    var repeaterInterfaceFactory = (function(){
+        return function(shape,view,propertyGroup){
+            function _propertyGroup(val){
+                if(val == 1){
+                    return interfaceFunction;
+                } else {
+                    return propertyGroup(--val);
+                }
+            }
+            var prop = view;
+            interfaceFunction.propertyIndex = shape.ix;
+            prop.c.setGroupProperty(_propertyGroup);
+            prop.o.setGroupProperty(_propertyGroup);
+
+            function interfaceFunction(value){
+                if(shape.c.ix === value || 'Copies' === value){
+                    return interfaceFunction.copies;
+                } else if(shape.o.ix === value || 'Offset' === value){
+                    return interfaceFunction.offset;
+                }
+
+            }
+            Object.defineProperty(interfaceFunction, 'copies', {
+                get: function(){
+                    return ExpressionValue(prop.c);
+                }
+            });
+
+            Object.defineProperty(interfaceFunction, 'offset', {
+                get: function(){
+                    return ExpressionValue(prop.o);
+                }
+            });
+
+            Object.defineProperty(interfaceFunction, '_name', {
+                get: function(){
+                    return shape.nm;
+                }
+            });
+            interfaceFunction.mn = shape.mn;
+            return interfaceFunction;
+        }
+    }());
+
+    var pathInterfaceFactory = (function(){
+        return function(shape,view,propertyGroup){
+            var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+            function _propertyGroup(val){
+                if(val == 1){
+                    return interfaceFunction;
+                } else {
+                    return propertyGroup(--val);
+                }
+            }
+            prop.setGroupProperty(_propertyGroup);
+
+            function interfaceFunction(val){
+                if(val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path'){
+                    return interfaceFunction.path;
+                }
+            }
+            Object.defineProperty(interfaceFunction, 'path', {
+                get: function(){
+                    if(prop.k){
+                        prop.getValue();
+                    }
+                    return prop.v;
+                    //return shape_pool.clone(prop.v);
+                }
+            });
+            Object.defineProperty(interfaceFunction, 'shape', {
+                get: function(){
+                    if(prop.k){
+                        prop.getValue();
+                    }
+                    return prop.v;
+                    //return shape_pool.clone(prop.v);
+                }
+            });
+            Object.defineProperty(interfaceFunction, '_name', { value: shape.nm });
+            Object.defineProperty(interfaceFunction, 'ix', { value: shape.ix });
+            Object.defineProperty(interfaceFunction, 'mn', { value: shape.mn });
+            return interfaceFunction;
+        }
+    }());
+
+
+    return ob;
+}())
+
+var TextExpressionInterface = (function(){
+	return function(elem){
+        function _thisLayerFunction(){
+        }
+        Object.defineProperty(_thisLayerFunction, "sourceText", {
+            get: function(){
+            	if(!elem.currentTextDocumentData.t) {
+            		return ''
+            	}
+                return elem.currentTextDocumentData.t;
+            }
+        });
+        return _thisLayerFunction;
+    }
+}())
+var LayerExpressionInterface = (function (){
+    function toWorld(arr){
+        var toWorldMat = new Matrix();
+        toWorldMat.reset();
+        this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
+        if(this._elem.hierarchy && this._elem.hierarchy.length){
+            var i, len = this._elem.hierarchy.length;
+            for(i=0;i<len;i+=1){
+                this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
+            }
+            return toWorldMat.applyToPointArray(arr[0],arr[1],arr[2]||0);
+        }
+        return toWorldMat.applyToPointArray(arr[0],arr[1],arr[2]||0);
+    }
+    function fromComp(arr){
+        var toWorldMat = new Matrix();
+        toWorldMat.reset();
+        this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
+        if(this._elem.hierarchy && this._elem.hierarchy.length){
+            var i, len = this._elem.hierarchy.length;
+            for(i=0;i<len;i+=1){
+                this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
+            }
+            return toWorldMat.inversePoint(arr);
+        }
+        return toWorldMat.inversePoint(arr);
+    }
+
+
+    return function(elem){
+
+        var transformInterface = TransformExpressionInterface(elem.transform);
+
+        function _registerMaskInterface(maskManager){
+            _thisLayerFunction.mask = maskManager.getMask.bind(maskManager);
+        }
+        function _registerEffectsInterface(effects){
+            _thisLayerFunction.effect = effects;
+        }
+
+        function _thisLayerFunction(name){
+            switch(name){
+                case "ADBE Root Vectors Group":
+                case "Contents":
+                case 2:
+                    return _thisLayerFunction.shapeInterface;
+                case 1:
+                case "Transform":
+                case "transform":
+                case "ADBE Transform Group":
+                    return transformInterface;
+                case 4:
+                case "ADBE Effect Parade":
+                    return _thisLayerFunction.effect;
+            }
+        }
+        _thisLayerFunction.toWorld = toWorld;
+        _thisLayerFunction.toComp = toWorld;
+        _thisLayerFunction.fromComp = fromComp;
+        _thisLayerFunction._elem = elem;
+        Object.defineProperty(_thisLayerFunction, 'hasParent', {
+            get: function(){
+                return !!elem.hierarchy;
+            }
+        });
+        Object.defineProperty(_thisLayerFunction, 'parent', {
+            get: function(){
+                return elem.hierarchy[0].layerInterface;
+            }
+        });
+        Object.defineProperty(_thisLayerFunction, "rotation", {
+            get: function(){
+                return transformInterface.rotation;
+            }
+        });
+        Object.defineProperty(_thisLayerFunction, "scale", {
+            get: function () {
+                return transformInterface.scale;
+            }
+        });
+
+        Object.defineProperty(_thisLayerFunction, "position", {
+            get: function () {
+                return transformInterface.position;
+            }
+        });
+
+        Object.defineProperty(_thisLayerFunction, "anchorPoint", {
+            get: function () {
+                return transformInterface.anchorPoint;
+            }
+        });
+
+        Object.defineProperty(_thisLayerFunction, "transform", {
+            get: function () {
+                return transformInterface;
+            }
+        });
+
+        Object.defineProperty(_thisLayerFunction, "width", {
+            get: function () {
+                if(elem.data.ty === 0) {
+                    return elem.data.w
+                }
+                return 100;
+            }
+        });
+
+        Object.defineProperty(_thisLayerFunction, "height", {
+            get: function () {
+                if(elem.data.ty === 0) {
+                    return elem.data.h
+                }
+                return 100;
+            }
+        });
+
+        Object.defineProperty(_thisLayerFunction, "source", {
+            get: function () {
+                return elem.data.refId;
+            }
+        });
+
+        Object.defineProperty(_thisLayerFunction, "_name", { value:elem.data.nm });
+        Object.defineProperty(_thisLayerFunction, "content", {
+            get: function(){
+                return _thisLayerFunction.shapeInterface;
+            }
+        });
+
+        Object.defineProperty(_thisLayerFunction, "active", {
+            get: function(){
+                return elem.isVisible;
+            }
+        });
+
+        Object.defineProperty(_thisLayerFunction, "text", {
+            get: function(){
+                return _thisLayerFunction.textInterface;
+            }
+        });
+
+        _thisLayerFunction.registerMaskInterface = _registerMaskInterface;
+        _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface;
+        return _thisLayerFunction;
+    }
+}());
+
+var CompExpressionInterface = (function (){
+    return function(comp){
+        function _thisLayerFunction(name){
+            var i=0, len = comp.layers.length;
+            while(i<len){
+                if(comp.layers[i].nm === name || comp.layers[i].ind === name){
+                    return comp.elements[i].layerInterface;
+                }
+                i += 1;
+            }
+            return {active:false}
+        }
+        Object.defineProperty(_thisLayerFunction, "_name", { value:comp.data.nm });
+        _thisLayerFunction.layer = _thisLayerFunction;
+        _thisLayerFunction.pixelAspect = 1;
+        _thisLayerFunction.height = comp.globalData.compSize.h;
+        _thisLayerFunction.width = comp.globalData.compSize.w;
+        _thisLayerFunction.pixelAspect = 1;
+        _thisLayerFunction.frameDuration = 1/comp.globalData.frameRate;
+        return _thisLayerFunction;
+    }
+}());
+var TransformExpressionInterface = (function (){
+    return function(transform){
+        function _thisFunction(name){
+            switch(name){
+                case "scale":
+                case "Scale":
+                case "ADBE Scale":
+                    return _thisFunction.scale;
+                case "rotation":
+                case "Rotation":
+                case "ADBE Rotation":
+                case "ADBE Rotate Z":
+                    return _thisFunction.rotation;
+                case "position":
+                case "Position":
+                case "ADBE Position":
+                    return transform.position;
+                case "anchorPoint":
+                case "AnchorPoint":
+                case "Anchor Point":
+                case "ADBE AnchorPoint":
+                    return _thisFunction.anchorPoint;
+                case "opacity":
+                case "Opacity":
+                    return _thisFunction.opacity;
+            }
+        }
+
+        Object.defineProperty(_thisFunction, "rotation", {
+            get: function(){
+                return transform.rotation;
+            }
+        });
+        Object.defineProperty(_thisFunction, "scale", {
+            get: function () {
+                return transform.scale;
+            }
+        });
+
+        Object.defineProperty(_thisFunction, "position", {
+            get: function () {
+                return transform.position;
+            }
+        });
+
+        Object.defineProperty(_thisFunction, "xPosition", {
+            get: function () {
+                return transform.xPosition;
+            }
+        });
+
+        Object.defineProperty(_thisFunction, "yPosition", {
+            get: function () {
+                return transform.yPosition;
+            }
+        });
+
+        Object.defineProperty(_thisFunction, "anchorPoint", {
+            get: function () {
+                return transform.anchorPoint;
+            }
+        });
+
+        Object.defineProperty(_thisFunction, "opacity", {
+            get: function () {
+                return transform.opacity;
+            }
+        });
+
+        Object.defineProperty(_thisFunction, "skew", {
+            get: function () {
+                return transform.skew;
+            }
+        });
+
+        Object.defineProperty(_thisFunction, "skewAxis", {
+            get: function () {
+                return transform.skewAxis;
+            }
+        });
+
+        return _thisFunction;
+    }
+}());
+var ProjectInterface = (function (){
+
+    function registerComposition(comp){
+        this.compositions.push(comp);
+    }
+
+    return function(){
+        function _thisProjectFunction(name){
+            var i = 0, len = this.compositions.length;
+            while(i<len){
+                if(this.compositions[i].data && this.compositions[i].data.nm === name){
+                    this.compositions[i].prepareFrame(this.currentFrame);
+                    return this.compositions[i].compInterface;
+                }
+                i+=1;
+            }
+        }
+
+        _thisProjectFunction.compositions = [];
+        _thisProjectFunction.currentFrame = 0;
+
+        _thisProjectFunction.registerComposition = registerComposition;
+
+
+
+        return _thisProjectFunction;
+    }
+}());
+var EffectsExpressionInterface = (function (){
+    var ob = {
+        createEffectsInterface: createEffectsInterface
+    };
+
+    function createEffectsInterface(elem, propertyGroup){
+        if(elem.effects){
+
+            var effectElements = [];
+            var effectsData = elem.data.ef;
+            var i, len = elem.effects.effectElements.length;
+            for(i=0;i<len;i+=1){
+                effectElements.push(createGroupInterface(effectsData[i],elem.effects.effectElements[i],propertyGroup,elem));
+            }
+
+            return function(name){
+                var effects = elem.data.ef, i = 0, len = effects.length;
+                while(i<len) {
+                    if(name === effects[i].nm || name === effects[i].mn || name === effects[i].ix){
+                        return effectElements[i];
+                    }
+                    i += 1;
+                }
+            }
+        }
+    }
+
+    function createGroupInterface(data,elements, propertyGroup, elem){
+        var effectElements = [];
+        var i, len = data.ef.length;
+        for(i=0;i<len;i+=1){
+            if(data.ef[i].ty === 5){
+                effectElements.push(createGroupInterface(data.ef[i],elements.effectElements[i],propertyGroup, elem));
+            } else {
+                effectElements.push(createValueInterface(elements.effectElements[i],data.ef[i].ty, elem));
+            }
+        }
+        var groupInterface = function(name){
+            var effects = data.ef, i = 0, len = effects.length;
+            while(i<len) {
+                if(name === effects[i].nm || name === effects[i].mn || name === effects[i].ix){
+                    if(effects[i].ty === 5){
+                        return effectElements[i];
+                    } else {
+                        return effectElements[i]();
+                    }
+                }
+                i += 1;
+            }
+            return effectElements[0]();
+        }
+        if(data.mn === 'ADBE Color Control'){
+            Object.defineProperty(groupInterface, 'color', {
+                get: function(){
+                    return effectElements[0]();
+                }
+            });
+        }
+        groupInterface.active = data.en !== 0;
+        return groupInterface
+    }
+
+    function createValueInterface(element, type, elem){
+        return function(){
+            if(type === 10){
+                return elem.comp.compInterface(element.p.v);
+            }
+            return ExpressionValue(element.p);
+        }
+    }
+
+    return ob;
+
+}());
+var ExpressionValue = (function() {
+	return function(elementProp, mult, type) {
+        var expressionValue, arrayValue;
+		if (elementProp.k) {
+            elementProp.getValue();
+        }
+        var i, len, arrValue;
+        if (type) {
+        	if(type === 'color') {
+        		len = 4;
+		        expressionValue = Array.apply(null, {length: len});
+		        arrValue = Array.apply(null, {length: len});
+		        for (i = 0; i < len; i += 1) {
+		            expressionValue[i] = arrValue[i] = (mult && i < 3) ? elementProp.v[i] * mult : 1;
+		        }
+	        	expressionValue.value = arrValue;
+        	}
+        } else if (typeof elementProp.v === 'number' || elementProp.v instanceof Number){
+            expressionValue = mult ? new Number(elementProp.v * mult) : new Number(elementProp.v);
+            expressionValue.value = mult ? elementProp.v * mult : elementProp.v;
+        } else {
+        	len = elementProp.v.length;
+	        expressionValue = Array.apply(null, {length: len});
+	        arrValue = Array.apply(null, {length: len});
+	        for (i = 0; i < len; i += 1) {
+	            expressionValue[i] = arrValue[i] = mult ? elementProp.v[i] * mult : elementProp.v[i];
+	        }
+	        expressionValue.value = arrValue;
+        }
+        
+        expressionValue.numKeys = elementProp.keyframes ? elementProp.keyframes.length : 0;
+        expressionValue.key = function(pos) {
+            if (!expressionValue.numKeys) {
+                return 0;
+            } else {
+                return elementProp.keyframes[pos-1].t;
+            }
+        };
+        expressionValue.valueAtTime = elementProp.getValueAtTime;
+        expressionValue.propertyGroup = elementProp.propertyGroup;
+        return expressionValue;
+	}
+}())
+function SliderEffect(data,elem, dynamicProperties){
+    this.p = PropertyFactory.getProp(elem,data.v,0,0,dynamicProperties);
+}
+function AngleEffect(data,elem, dynamicProperties){
+    this.p = PropertyFactory.getProp(elem,data.v,0,0,dynamicProperties);
+}
+function ColorEffect(data,elem, dynamicProperties){
+    this.p = PropertyFactory.getProp(elem,data.v,1,0,dynamicProperties);
+}
+function PointEffect(data,elem, dynamicProperties){
+    this.p = PropertyFactory.getProp(elem,data.v,1,0,dynamicProperties);
+}
+function LayerIndexEffect(data,elem, dynamicProperties){
+    this.p = PropertyFactory.getProp(elem,data.v,0,0,dynamicProperties);
+}
+function MaskIndexEffect(data,elem, dynamicProperties){
+    this.p = PropertyFactory.getProp(elem,data.v,0,0,dynamicProperties);
+}
+function CheckboxEffect(data,elem, dynamicProperties){
+    this.p = PropertyFactory.getProp(elem,data.v,0,0,dynamicProperties);
+}
+function NoValueEffect(){
+    this.p = {};
+}
+function EffectsManager(data,element,dynamicProperties){
+    var effects = data.ef;
+    this.effectElements = [];
+    var i,len = effects.length;
+    var effectItem;
+    for(i=0;i<len;i++) {
+        effectItem = new GroupEffect(effects[i],element,dynamicProperties);
+        this.effectElements.push(effectItem);
+    }
+}
+
+function GroupEffect(data,element,dynamicProperties){
+    this.dynamicProperties = [];
+    this.init(data,element,this.dynamicProperties);
+    if(this.dynamicProperties.length){
+        dynamicProperties.push(this);
+    }
+}
+
+GroupEffect.prototype.getValue = function(){
+    this.mdf = false;
+    var i, len = this.dynamicProperties.length;
+    for(i=0;i<len;i+=1){
+        this.dynamicProperties[i].getValue();
+        this.mdf = this.dynamicProperties[i].mdf ? true : this.mdf;
+    }
+};
+
+GroupEffect.prototype.init = function(data,element,dynamicProperties){
+    this.data = data;
+    this.mdf = false;
+    this.effectElements = [];
+    var i, len = this.data.ef.length;
+    var eff, effects = this.data.ef;
+    for(i=0;i<len;i+=1){
+        switch(effects[i].ty){
+            case 0:
+                eff = new SliderEffect(effects[i],element,dynamicProperties);
+                this.effectElements.push(eff);
+                break;
+            case 1:
+                eff = new AngleEffect(effects[i],element,dynamicProperties);
+                this.effectElements.push(eff);
+                break;
+            case 2:
+                eff = new ColorEffect(effects[i],element,dynamicProperties);
+                this.effectElements.push(eff);
+                break;
+            case 3:
+                eff = new PointEffect(effects[i],element,dynamicProperties);
+                this.effectElements.push(eff);
+                break;
+            case 4:
+            case 7:
+                eff = new CheckboxEffect(effects[i],element,dynamicProperties);
+                this.effectElements.push(eff);
+                break;
+            case 10:
+                eff = new LayerIndexEffect(effects[i],element,dynamicProperties);
+                this.effectElements.push(eff);
+                break;
+            case 11:
+                eff = new MaskIndexEffect(effects[i],element,dynamicProperties);
+                this.effectElements.push(eff);
+                break;
+            case 5:
+                eff = new EffectsManager(effects[i],element,dynamicProperties);
+                this.effectElements.push(eff);
+                break;
+            case 6:
+                eff = new NoValueEffect(effects[i],element,dynamicProperties);
+                this.effectElements.push(eff);
+                break;
+        }
+    }
+};var bodymovinjs = {}; function play(animation){ animationManager.play(animation); } function pause(animation){ animationManager.pause(animation); } function togglePause(animation){ animationManager.togglePause(animation); } function setSpeed(value,animation){ animationManager.setSpeed(value, animation); } function setDirection(value,animation){ animationManager.setDirection(value, animation); } function stop(animation){ animationManager.stop(animation); } function moveFrame(value){ animationManager.moveFrame(value); } function searchAnimations(){ if(standalone === true){ animationManager.searchAnimations(animationData,standalone, renderer); }else{ animationManager.searchAnimations(); } } function registerAnimation(elem){ return animationManager.registerAnimation(elem); } function resize(){ animationManager.resize(); } function start(){ animationManager.start(); } function goToAndStop(val,isFrame, animation){ animationManager.goToAndStop(val,isFrame, animation); } function setSubframeRendering(flag){ subframeEnabled = flag; } function loadAnimation(params){ if(standalone === true){ params.animationData = JSON.parse(animationData); } return animationManager.loadAnimation(params); } function destroy(animation){ return animationManager.destroy(animation); } function setQuality(value){ if(typeof value === 'string'){ switch(value){ case 'high': defaultCurveSegments = 200; break; case 'medium': defaultCurveSegments = 50; break; case 'low': defaultCurveSegments = 10; break; } }else if(!isNaN(value) && value > 1){ defaultCurveSegments = value; } if(defaultCurveSegments >= 50){ roundValues(false); }else{ roundValues(true); } } function installPlugin(type,plugin){ if(type==='expressions'){ expressionsPlugin = plugin; } } function getFactory(name){ switch(name){ case "propertyFactory": return PropertyFactory;case "shapePropertyFactory": return ShapePropertyFactory; case "matrix": return Matrix; } } bodymovinjs.play = play; bodymovinjs.pause = pause; bodymovinjs.togglePause = togglePause; bodymovinjs.setSpeed = setSpeed; bodymovinjs.setDirection = setDirection; bodymovinjs.stop = stop; bodymovinjs.moveFrame = moveFrame; bodymovinjs.searchAnimations = searchAnimations; bodymovinjs.registerAnimation = registerAnimation; bodymovinjs.loadAnimation = loadAnimation; bodymovinjs.setSubframeRendering = setSubframeRendering; bodymovinjs.resize = resize; bodymovinjs.start = start; bodymovinjs.goToAndStop = goToAndStop; bodymovinjs.destroy = destroy; bodymovinjs.setQuality = setQuality; bodymovinjs.installPlugin = installPlugin; bodymovinjs.__getFactory = getFactory; bodymovinjs.version = '4.6.10'; function checkReady(){ if (document.readyState === "complete") { clearInterval(readyStateCheckInterval); searchAnimations(); } } function getQueryVariable(variable) { var vars = queryString.split('&'); for (var i = 0; i < vars.length; i++) { var pair = vars[i].split('='); if (decodeURIComponent(pair[0]) == variable) { return decodeURIComponent(pair[1]); } } } var standalone = '__[STANDALONE]__'; var animationData = '__[ANIMATIONDATA]__'; var renderer = ''; if(standalone) { var scripts = document.getElementsByTagName('script'); var index = scripts.length - 1; var myScript = scripts[index] || { src: '' }; var queryString = myScript.src.replace(/^[^\?]+\??/,''); renderer = getQueryVariable('renderer'); } var readyStateCheckInterval = setInterval(checkReady, 100); return bodymovinjs; }));  
\ No newline at end of file
diff --git a/player/index.html b/player/index.html
index e934bb2..882bcef 100644
--- a/player/index.html
+++ b/player/index.html
@@ -12,11 +12,10 @@
         }
 
         #lottie{
-            background-color:#333;
+            background-color:#000;
             width:100%;
             height:100%;
             display:block;
-            overflow: hidden;
             transform: translate3d(0,0,0);
             margin: auto;
             /*display:none;*/
@@ -67,6 +66,7 @@
     <script src="js/3rd_party/transformation-matrix.js"></script>
     <script src="js/3rd_party/seedrandom.js"></script>
     <script src="js/3rd_party/BezierEaser.js"></script>
+    <script src="js/3rd_party/PIXI_4_4_3.js"></script>
     <script src="js/utils/animationFramePolyFill.js"></script>
     <script src="js/utils/functionExtensions.js"></script>
     <script src="js/utils/bez.js"></script>
@@ -102,6 +102,7 @@
     <script src="js/utils/pooling/bezier_length_pool.js"></script>
     <script src="js/renderers/BaseRenderer.js"></script>
     <script src="js/renderers/SVGRenderer.js"></script>
+    <script src="js/renderers/PIXIRenderer.js" data-light-skip="true"></script>
     <script src="js/renderers/CanvasRenderer.js" data-light-skip="true"></script>
     <script src="js/renderers/HybridRenderer.js" data-light-skip="true"></script>
     <script src="js/mask.js"></script>
@@ -120,6 +121,7 @@
     <script src="js/elements/helpers/shapes/SVGGradientStrokeStyleData.js"></script>
     <script src="js/elements/helpers/shapes/ShapeGroupData.js"></script>
     <script src="js/elements/helpers/shapes/SVGElementsRenderer.js"></script>
+    <script src="js/elements/helpers/shapes/PIXIElementsRenderer.js"></script>
     <script src="js/elements/helpers/shapes/CVShapeData.js" data-light-skip="true"></script>
     <script src="js/elements/BaseElement.js"></script>
     <script src="js/elements/NullElement.js"></script>
@@ -157,6 +159,14 @@
     <script src="js/elements/htmlElements/HImageElement.js" data-light-skip="true"></script>
     <script src="js/elements/htmlElements/HCameraElement.js" data-light-skip="true"></script>
     <script src="js/elements/htmlElements/HEffects.js" data-light-skip="true"></script>
+    <script src="js/elements/pixiElements/PIXIBaseElement.js" data-light-skip="true"></script>
+    <script src="js/elements/pixiElements/PIXIImageElement.js" data-light-skip="true"></script>
+    <script src="js/elements/pixiElements/PIXISolidElement.js" data-light-skip="true"></script>
+    <script src="js/elements/pixiElements/PIXIShapeElement.js" data-light-skip="true"></script>
+    <script src="js/elements/pixiElements/PIXICompElement.js" data-light-skip="true"></script>
+    <script src="js/elements/pixiElements/PIXIMask.js" data-light-skip="true"></script>
+    <script src="js/elements/pixiElements/PIXIEffects.js"></script>
+    <script src="js/elements/pixiElements/effects/PIXIGaussianBlurEffect.js"></script>
     <script src="js/animation/AnimationManager.js"></script>
     <script src="js/animation/AnimationItem.js"></script>
     <!-- Expressions -->
@@ -186,15 +196,22 @@
 <body>
 <div id="lottie"></div>
 
+<script id="shader" type="shader">
+
+void main(){
+   gl_FragColor = vec4(1.0,1.0,1.0,1.0);
+}
+</script>
+
 <script>
     var anim;
     var elem = document.getElementById('lottie');
     //elem.style.display = 'none';
     var animData = {
         container: elem,
-        renderer: 'canvas',
-        loop: false,
-        autoplay: false,
+        renderer: 'pixi',
+        loop: true,
+        autoplay: true,
         rendererSettings: {
             progressiveLoad:false,
             imagePreserveAspectRatio: 'xMidYMid meet'
@@ -202,9 +219,7 @@
         path: 'exports/bm/data.json'
     };
     anim = lottie.loadAnimation(animData);
-    anim.addEventListener('DOMLoaded', function() {
-        anim.playSegments([30,0], true);
-    })
+    anim.setSubframe(false);
 
 </script>
 </body>
diff --git a/player/js/3rd_party/PIXI.js b/player/js/3rd_party/PIXI.js
new file mode 100644
index 0000000..13df1de
--- /dev/null
+++ b/player/js/3rd_party/PIXI.js
@@ -0,0 +1,31257 @@
+/*!
+ * pixi.js - v4.0.3
+ * Compiled Thu Sep 29 2016 12:09:34 GMT-0400 (EDT)
+ *
+ * pixi.js is licensed under the MIT License.
+ * http://www.opensource.org/licenses/mit-license
+ */
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.PIXI = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+    /**
+     * Bit twiddling hacks for JavaScript.
+     *
+     * Author: Mikola Lysenko
+     *
+     * Ported from Stanford bit twiddling hack library:
+     *    http://graphics.stanford.edu/~seander/bithacks.html
+     */
+
+    "use strict"; "use restrict";
+
+//Number of bits in an integer
+    var INT_BITS = 32;
+
+//Constants
+    exports.INT_BITS  = INT_BITS;
+    exports.INT_MAX   =  0x7fffffff;
+    exports.INT_MIN   = -1<<(INT_BITS-1);
+
+//Returns -1, 0, +1 depending on sign of x
+    exports.sign = function(v) {
+        return (v > 0) - (v < 0);
+    }
+
+//Computes absolute value of integer
+    exports.abs = function(v) {
+        var mask = v >> (INT_BITS-1);
+        return (v ^ mask) - mask;
+    }
+
+//Computes minimum of integers x and y
+    exports.min = function(x, y) {
+        return y ^ ((x ^ y) & -(x < y));
+    }
+
+//Computes maximum of integers x and y
+    exports.max = function(x, y) {
+        return x ^ ((x ^ y) & -(x < y));
+    }
+
+//Checks if a number is a power of two
+    exports.isPow2 = function(v) {
+        return !(v & (v-1)) && (!!v);
+    }
+
+//Computes log base 2 of v
+    exports.log2 = function(v) {
+        var r, shift;
+        r =     (v > 0xFFFF) << 4; v >>>= r;
+        shift = (v > 0xFF  ) << 3; v >>>= shift; r |= shift;
+        shift = (v > 0xF   ) << 2; v >>>= shift; r |= shift;
+        shift = (v > 0x3   ) << 1; v >>>= shift; r |= shift;
+        return r | (v >> 1);
+    }
+
+//Computes log base 10 of v
+    exports.log10 = function(v) {
+        return  (v >= 1000000000) ? 9 : (v >= 100000000) ? 8 : (v >= 10000000) ? 7 :
+            (v >= 1000000) ? 6 : (v >= 100000) ? 5 : (v >= 10000) ? 4 :
+                (v >= 1000) ? 3 : (v >= 100) ? 2 : (v >= 10) ? 1 : 0;
+    }
+
+//Counts number of bits
+    exports.popCount = function(v) {
+        v = v - ((v >>> 1) & 0x55555555);
+        v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);
+        return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24;
+    }
+
+//Counts number of trailing zeros
+    function countTrailingZeros(v) {
+        var c = 32;
+        v &= -v;
+        if (v) c--;
+        if (v & 0x0000FFFF) c -= 16;
+        if (v & 0x00FF00FF) c -= 8;
+        if (v & 0x0F0F0F0F) c -= 4;
+        if (v & 0x33333333) c -= 2;
+        if (v & 0x55555555) c -= 1;
+        return c;
+    }
+    exports.countTrailingZeros = countTrailingZeros;
+
+//Rounds to next power of 2
+    exports.nextPow2 = function(v) {
+        v += v === 0;
+        --v;
+        v |= v >>> 1;
+        v |= v >>> 2;
+        v |= v >>> 4;
+        v |= v >>> 8;
+        v |= v >>> 16;
+        return v + 1;
+    }
+
+//Rounds down to previous power of 2
+    exports.prevPow2 = function(v) {
+        v |= v >>> 1;
+        v |= v >>> 2;
+        v |= v >>> 4;
+        v |= v >>> 8;
+        v |= v >>> 16;
+        return v - (v>>>1);
+    }
+
+//Computes parity of word
+    exports.parity = function(v) {
+        v ^= v >>> 16;
+        v ^= v >>> 8;
+        v ^= v >>> 4;
+        v &= 0xf;
+        return (0x6996 >>> v) & 1;
+    }
+
+    var REVERSE_TABLE = new Array(256);
+
+    (function(tab) {
+        for(var i=0; i<256; ++i) {
+            var v = i, r = i, s = 7;
+            for (v >>>= 1; v; v >>>= 1) {
+                r <<= 1;
+                r |= v & 1;
+                --s;
+            }
+            tab[i] = (r << s) & 0xff;
+        }
+    })(REVERSE_TABLE);
+
+//Reverse bits in a 32 bit word
+    exports.reverse = function(v) {
+        return  (REVERSE_TABLE[ v         & 0xff] << 24) |
+            (REVERSE_TABLE[(v >>> 8)  & 0xff] << 16) |
+            (REVERSE_TABLE[(v >>> 16) & 0xff] << 8)  |
+            REVERSE_TABLE[(v >>> 24) & 0xff];
+    }
+
+//Interleave bits of 2 coordinates with 16 bits.  Useful for fast quadtree codes
+    exports.interleave2 = function(x, y) {
+        x &= 0xFFFF;
+        x = (x | (x << 8)) & 0x00FF00FF;
+        x = (x | (x << 4)) & 0x0F0F0F0F;
+        x = (x | (x << 2)) & 0x33333333;
+        x = (x | (x << 1)) & 0x55555555;
+
+        y &= 0xFFFF;
+        y = (y | (y << 8)) & 0x00FF00FF;
+        y = (y | (y << 4)) & 0x0F0F0F0F;
+        y = (y | (y << 2)) & 0x33333333;
+        y = (y | (y << 1)) & 0x55555555;
+
+        return x | (y << 1);
+    }
+
+//Extracts the nth interleaved component
+    exports.deinterleave2 = function(v, n) {
+        v = (v >>> n) & 0x55555555;
+        v = (v | (v >>> 1))  & 0x33333333;
+        v = (v | (v >>> 2))  & 0x0F0F0F0F;
+        v = (v | (v >>> 4))  & 0x00FF00FF;
+        v = (v | (v >>> 16)) & 0x000FFFF;
+        return (v << 16) >> 16;
+    }
+
+
+//Interleave bits of 3 coordinates, each with 10 bits.  Useful for fast octree codes
+    exports.interleave3 = function(x, y, z) {
+        x &= 0x3FF;
+        x  = (x | (x<<16)) & 4278190335;
+        x  = (x | (x<<8))  & 251719695;
+        x  = (x | (x<<4))  & 3272356035;
+        x  = (x | (x<<2))  & 1227133513;
+
+        y &= 0x3FF;
+        y  = (y | (y<<16)) & 4278190335;
+        y  = (y | (y<<8))  & 251719695;
+        y  = (y | (y<<4))  & 3272356035;
+        y  = (y | (y<<2))  & 1227133513;
+        x |= (y << 1);
+
+        z &= 0x3FF;
+        z  = (z | (z<<16)) & 4278190335;
+        z  = (z | (z<<8))  & 251719695;
+        z  = (z | (z<<4))  & 3272356035;
+        z  = (z | (z<<2))  & 1227133513;
+
+        return x | (z << 2);
+    }
+
+//Extracts nth interleaved component of a 3-tuple
+    exports.deinterleave3 = function(v, n) {
+        v = (v >>> n)       & 1227133513;
+        v = (v | (v>>>2))   & 3272356035;
+        v = (v | (v>>>4))   & 251719695;
+        v = (v | (v>>>8))   & 4278190335;
+        v = (v | (v>>>16))  & 0x3FF;
+        return (v<<22)>>22;
+    }
+
+//Computes next combination in colexicographic order (this is mistakenly called nextPermutation on the bit twiddling hacks page)
+    exports.nextCombination = function(v) {
+        var t = v | (v - 1);
+        return (t + 1) | (((~t & -~t) - 1) >>> (countTrailingZeros(v) + 1));
+    }
+
+
+},{}],2:[function(require,module,exports){
+    'use strict';
+
+    module.exports = earcut;
+
+    function earcut(data, holeIndices, dim) {
+
+        dim = dim || 2;
+
+        var hasHoles = holeIndices && holeIndices.length,
+            outerLen = hasHoles ? holeIndices[0] * dim : data.length,
+            outerNode = linkedList(data, 0, outerLen, dim, true),
+            triangles = [];
+
+        if (!outerNode) return triangles;
+
+        var minX, minY, maxX, maxY, x, y, size;
+
+        if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
+
+        // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
+        if (data.length > 80 * dim) {
+            minX = maxX = data[0];
+            minY = maxY = data[1];
+
+            for (var i = dim; i < outerLen; i += dim) {
+                x = data[i];
+                y = data[i + 1];
+                if (x < minX) minX = x;
+                if (y < minY) minY = y;
+                if (x > maxX) maxX = x;
+                if (y > maxY) maxY = y;
+            }
+
+            // minX, minY and size are later used to transform coords into integers for z-order calculation
+            size = Math.max(maxX - minX, maxY - minY);
+        }
+
+        earcutLinked(outerNode, triangles, dim, minX, minY, size);
+
+        return triangles;
+    }
+
+// create a circular doubly linked list from polygon points in the specified winding order
+    function linkedList(data, start, end, dim, clockwise) {
+        var i, last;
+
+        if (clockwise === (signedArea(data, start, end, dim) > 0)) {
+            for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
+        } else {
+            for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
+        }
+
+        if (last && equals(last, last.next)) {
+            removeNode(last);
+            last = last.next;
+        }
+
+        return last;
+    }
+
+// eliminate colinear or duplicate points
+    function filterPoints(start, end) {
+        if (!start) return start;
+        if (!end) end = start;
+
+        var p = start,
+            again;
+        do {
+            again = false;
+
+            if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
+                removeNode(p);
+                p = end = p.prev;
+                if (p === p.next) return null;
+                again = true;
+
+            } else {
+                p = p.next;
+            }
+        } while (again || p !== end);
+
+        return end;
+    }
+
+// main ear slicing loop which triangulates a polygon (given as a linked list)
+    function earcutLinked(ear, triangles, dim, minX, minY, size, pass) {
+        if (!ear) return;
+
+        // interlink polygon nodes in z-order
+        if (!pass && size) indexCurve(ear, minX, minY, size);
+
+        var stop = ear,
+            prev, next;
+
+        // iterate through ears, slicing them one by one
+        while (ear.prev !== ear.next) {
+            prev = ear.prev;
+            next = ear.next;
+
+            if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {
+                // cut off the triangle
+                triangles.push(prev.i / dim);
+                triangles.push(ear.i / dim);
+                triangles.push(next.i / dim);
+
+                removeNode(ear);
+
+                // skipping the next vertice leads to less sliver triangles
+                ear = next.next;
+                stop = next.next;
+
+                continue;
+            }
+
+            ear = next;
+
+            // if we looped through the whole remaining polygon and can't find any more ears
+            if (ear === stop) {
+                // try filtering points and slicing again
+                if (!pass) {
+                    earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);
+
+                    // if this didn't work, try curing all small self-intersections locally
+                } else if (pass === 1) {
+                    ear = cureLocalIntersections(ear, triangles, dim);
+                    earcutLinked(ear, triangles, dim, minX, minY, size, 2);
+
+                    // as a last resort, try splitting the remaining polygon into two
+                } else if (pass === 2) {
+                    splitEarcut(ear, triangles, dim, minX, minY, size);
+                }
+
+                break;
+            }
+        }
+    }
+
+// check whether a polygon node forms a valid ear with adjacent nodes
+    function isEar(ear) {
+        var a = ear.prev,
+            b = ear,
+            c = ear.next;
+
+        if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
+
+        // now make sure we don't have other points inside the potential ear
+        var p = ear.next.next;
+
+        while (p !== ear.prev) {
+            if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
+                area(p.prev, p, p.next) >= 0) return false;
+            p = p.next;
+        }
+
+        return true;
+    }
+
+    function isEarHashed(ear, minX, minY, size) {
+        var a = ear.prev,
+            b = ear,
+            c = ear.next;
+
+        if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
+
+        // triangle bbox; min & max are calculated like this for speed
+        var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),
+            minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),
+            maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),
+            maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);
+
+        // z-order range for the current triangle bbox;
+        var minZ = zOrder(minTX, minTY, minX, minY, size),
+            maxZ = zOrder(maxTX, maxTY, minX, minY, size);
+
+        // first look for points inside the triangle in increasing z-order
+        var p = ear.nextZ;
+
+        while (p && p.z <= maxZ) {
+            if (p !== ear.prev && p !== ear.next &&
+                pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
+                area(p.prev, p, p.next) >= 0) return false;
+            p = p.nextZ;
+        }
+
+        // then look for points in decreasing z-order
+        p = ear.prevZ;
+
+        while (p && p.z >= minZ) {
+            if (p !== ear.prev && p !== ear.next &&
+                pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
+                area(p.prev, p, p.next) >= 0) return false;
+            p = p.prevZ;
+        }
+
+        return true;
+    }
+
+// go through all polygon nodes and cure small local self-intersections
+    function cureLocalIntersections(start, triangles, dim) {
+        var p = start;
+        do {
+            var a = p.prev,
+                b = p.next.next;
+
+            if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
+
+                triangles.push(a.i / dim);
+                triangles.push(p.i / dim);
+                triangles.push(b.i / dim);
+
+                // remove two nodes involved
+                removeNode(p);
+                removeNode(p.next);
+
+                p = start = b;
+            }
+            p = p.next;
+        } while (p !== start);
+
+        return p;
+    }
+
+// try splitting polygon into two and triangulate them independently
+    function splitEarcut(start, triangles, dim, minX, minY, size) {
+        // look for a valid diagonal that divides the polygon into two
+        var a = start;
+        do {
+            var b = a.next.next;
+            while (b !== a.prev) {
+                if (a.i !== b.i && isValidDiagonal(a, b)) {
+                    // split the polygon in two by the diagonal
+                    var c = splitPolygon(a, b);
+
+                    // filter colinear points around the cuts
+                    a = filterPoints(a, a.next);
+                    c = filterPoints(c, c.next);
+
+                    // run earcut on each half
+                    earcutLinked(a, triangles, dim, minX, minY, size);
+                    earcutLinked(c, triangles, dim, minX, minY, size);
+                    return;
+                }
+                b = b.next;
+            }
+            a = a.next;
+        } while (a !== start);
+    }
+
+// link every hole into the outer loop, producing a single-ring polygon without holes
+    function eliminateHoles(data, holeIndices, outerNode, dim) {
+        var queue = [],
+            i, len, start, end, list;
+
+        for (i = 0, len = holeIndices.length; i < len; i++) {
+            start = holeIndices[i] * dim;
+            end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
+            list = linkedList(data, start, end, dim, false);
+            if (list === list.next) list.steiner = true;
+            queue.push(getLeftmost(list));
+        }
+
+        queue.sort(compareX);
+
+        // process holes from left to right
+        for (i = 0; i < queue.length; i++) {
+            eliminateHole(queue[i], outerNode);
+            outerNode = filterPoints(outerNode, outerNode.next);
+        }
+
+        return outerNode;
+    }
+
+    function compareX(a, b) {
+        return a.x - b.x;
+    }
+
+// find a bridge between vertices that connects hole with an outer ring and and link it
+    function eliminateHole(hole, outerNode) {
+        outerNode = findHoleBridge(hole, outerNode);
+        if (outerNode) {
+            var b = splitPolygon(outerNode, hole);
+            filterPoints(b, b.next);
+        }
+    }
+
+// David Eberly's algorithm for finding a bridge between hole and outer polygon
+    function findHoleBridge(hole, outerNode) {
+        var p = outerNode,
+            hx = hole.x,
+            hy = hole.y,
+            qx = -Infinity,
+            m;
+
+        // find a segment intersected by a ray from the hole's leftmost point to the left;
+        // segment's endpoint with lesser x will be potential connection point
+        do {
+            if (hy <= p.y && hy >= p.next.y) {
+                var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
+                if (x <= hx && x > qx) {
+                    qx = x;
+                    if (x === hx) {
+                        if (hy === p.y) return p;
+                        if (hy === p.next.y) return p.next;
+                    }
+                    m = p.x < p.next.x ? p : p.next;
+                }
+            }
+            p = p.next;
+        } while (p !== outerNode);
+
+        if (!m) return null;
+
+        if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint
+
+        // look for points inside the triangle of hole point, segment intersection and endpoint;
+        // if there are no points found, we have a valid connection;
+        // otherwise choose the point of the minimum angle with the ray as connection point
+
+        var stop = m,
+            mx = m.x,
+            my = m.y,
+            tanMin = Infinity,
+            tan;
+
+        p = m.next;
+
+        while (p !== stop) {
+            if (hx >= p.x && p.x >= mx &&
+                pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
+
+                tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
+
+                if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) {
+                    m = p;
+                    tanMin = tan;
+                }
+            }
+
+            p = p.next;
+        }
+
+        return m;
+    }
+
+// interlink polygon nodes in z-order
+    function indexCurve(start, minX, minY, size) {
+        var p = start;
+        do {
+            if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);
+            p.prevZ = p.prev;
+            p.nextZ = p.next;
+            p = p.next;
+        } while (p !== start);
+
+        p.prevZ.nextZ = null;
+        p.prevZ = null;
+
+        sortLinked(p);
+    }
+
+// Simon Tatham's linked list merge sort algorithm
+// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
+    function sortLinked(list) {
+        var i, p, q, e, tail, numMerges, pSize, qSize,
+            inSize = 1;
+
+        do {
+            p = list;
+            list = null;
+            tail = null;
+            numMerges = 0;
+
+            while (p) {
+                numMerges++;
+                q = p;
+                pSize = 0;
+                for (i = 0; i < inSize; i++) {
+                    pSize++;
+                    q = q.nextZ;
+                    if (!q) break;
+                }
+
+                qSize = inSize;
+
+                while (pSize > 0 || (qSize > 0 && q)) {
+
+                    if (pSize === 0) {
+                        e = q;
+                        q = q.nextZ;
+                        qSize--;
+                    } else if (qSize === 0 || !q) {
+                        e = p;
+                        p = p.nextZ;
+                        pSize--;
+                    } else if (p.z <= q.z) {
+                        e = p;
+                        p = p.nextZ;
+                        pSize--;
+                    } else {
+                        e = q;
+                        q = q.nextZ;
+                        qSize--;
+                    }
+
+                    if (tail) tail.nextZ = e;
+                    else list = e;
+
+                    e.prevZ = tail;
+                    tail = e;
+                }
+
+                p = q;
+            }
+
+            tail.nextZ = null;
+            inSize *= 2;
+
+        } while (numMerges > 1);
+
+        return list;
+    }
+
+// z-order of a point given coords and size of the data bounding box
+    function zOrder(x, y, minX, minY, size) {
+        // coords are transformed into non-negative 15-bit integer range
+        x = 32767 * (x - minX) / size;
+        y = 32767 * (y - minY) / size;
+
+        x = (x | (x << 8)) & 0x00FF00FF;
+        x = (x | (x << 4)) & 0x0F0F0F0F;
+        x = (x | (x << 2)) & 0x33333333;
+        x = (x | (x << 1)) & 0x55555555;
+
+        y = (y | (y << 8)) & 0x00FF00FF;
+        y = (y | (y << 4)) & 0x0F0F0F0F;
+        y = (y | (y << 2)) & 0x33333333;
+        y = (y | (y << 1)) & 0x55555555;
+
+        return x | (y << 1);
+    }
+
+// find the leftmost node of a polygon ring
+    function getLeftmost(start) {
+        var p = start,
+            leftmost = start;
+        do {
+            if (p.x < leftmost.x) leftmost = p;
+            p = p.next;
+        } while (p !== start);
+
+        return leftmost;
+    }
+
+// check if a point lies within a convex triangle
+    function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
+        return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&
+            (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&
+            (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
+    }
+
+// check if a diagonal between two polygon nodes is valid (lies in polygon interior)
+    function isValidDiagonal(a, b) {
+        return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) &&
+            locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);
+    }
+
+// signed area of a triangle
+    function area(p, q, r) {
+        return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
+    }
+
+// check if two points are equal
+    function equals(p1, p2) {
+        return p1.x === p2.x && p1.y === p2.y;
+    }
+
+// check if two segments intersect
+    function intersects(p1, q1, p2, q2) {
+        if ((equals(p1, q1) && equals(p2, q2)) ||
+            (equals(p1, q2) && equals(p2, q1))) return true;
+        return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 &&
+            area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;
+    }
+
+// check if a polygon diagonal intersects any polygon segments
+    function intersectsPolygon(a, b) {
+        var p = a;
+        do {
+            if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
+                intersects(p, p.next, a, b)) return true;
+            p = p.next;
+        } while (p !== a);
+
+        return false;
+    }
+
+// check if a polygon diagonal is locally inside the polygon
+    function locallyInside(a, b) {
+        return area(a.prev, a, a.next) < 0 ?
+        area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :
+        area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
+    }
+
+// check if the middle point of a polygon diagonal is inside the polygon
+    function middleInside(a, b) {
+        var p = a,
+            inside = false,
+            px = (a.x + b.x) / 2,
+            py = (a.y + b.y) / 2;
+        do {
+            if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))
+                inside = !inside;
+            p = p.next;
+        } while (p !== a);
+
+        return inside;
+    }
+
+// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
+// if one belongs to the outer ring and another to a hole, it merges it into a single ring
+    function splitPolygon(a, b) {
+        var a2 = new Node(a.i, a.x, a.y),
+            b2 = new Node(b.i, b.x, b.y),
+            an = a.next,
+            bp = b.prev;
+
+        a.next = b;
+        b.prev = a;
+
+        a2.next = an;
+        an.prev = a2;
+
+        b2.next = a2;
+        a2.prev = b2;
+
+        bp.next = b2;
+        b2.prev = bp;
+
+        return b2;
+    }
+
+// create a node and optionally link it with previous one (in a circular doubly linked list)
+    function insertNode(i, x, y, last) {
+        var p = new Node(i, x, y);
+
+        if (!last) {
+            p.prev = p;
+            p.next = p;
+
+        } else {
+            p.next = last.next;
+            p.prev = last;
+            last.next.prev = p;
+            last.next = p;
+        }
+        return p;
+    }
+
+    function removeNode(p) {
+        p.next.prev = p.prev;
+        p.prev.next = p.next;
+
+        if (p.prevZ) p.prevZ.nextZ = p.nextZ;
+        if (p.nextZ) p.nextZ.prevZ = p.prevZ;
+    }
+
+    function Node(i, x, y) {
+        // vertice index in coordinates array
+        this.i = i;
+
+        // vertex coordinates
+        this.x = x;
+        this.y = y;
+
+        // previous and next vertice nodes in a polygon ring
+        this.prev = null;
+        this.next = null;
+
+        // z-order curve value
+        this.z = null;
+
+        // previous and next nodes in z-order
+        this.prevZ = null;
+        this.nextZ = null;
+
+        // indicates whether this is a steiner point
+        this.steiner = false;
+    }
+
+// return a percentage difference between the polygon area and its triangulation area;
+// used to verify correctness of triangulation
+    earcut.deviation = function (data, holeIndices, dim, triangles) {
+        var hasHoles = holeIndices && holeIndices.length;
+        var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
+
+        var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
+        if (hasHoles) {
+            for (var i = 0, len = holeIndices.length; i < len; i++) {
+                var start = holeIndices[i] * dim;
+                var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
+                polygonArea -= Math.abs(signedArea(data, start, end, dim));
+            }
+        }
+
+        var trianglesArea = 0;
+        for (i = 0; i < triangles.length; i += 3) {
+            var a = triangles[i] * dim;
+            var b = triangles[i + 1] * dim;
+            var c = triangles[i + 2] * dim;
+            trianglesArea += Math.abs(
+                (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -
+                (data[a] - data[b]) * (data[c + 1] - data[a + 1]));
+        }
+
+        return polygonArea === 0 && trianglesArea === 0 ? 0 :
+            Math.abs((trianglesArea - polygonArea) / polygonArea);
+    };
+
+    function signedArea(data, start, end, dim) {
+        var sum = 0;
+        for (var i = start, j = end - dim; i < end; i += dim) {
+            sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
+            j = i;
+        }
+        return sum;
+    }
+
+// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts
+    earcut.flatten = function (data) {
+        var dim = data[0][0].length,
+            result = {vertices: [], holes: [], dimensions: dim},
+            holeIndex = 0;
+
+        for (var i = 0; i < data.length; i++) {
+            for (var j = 0; j < data[i].length; j++) {
+                for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);
+            }
+            if (i > 0) {
+                holeIndex += data[i - 1].length;
+                result.holes.push(holeIndex);
+            }
+        }
+        return result;
+    };
+
+},{}],3:[function(require,module,exports){
+    'use strict';
+
+    var has = Object.prototype.hasOwnProperty;
+
+//
+// We store our EE objects in a plain object whose properties are event names.
+// If `Object.create(null)` is not supported we prefix the event names with a
+// `~` to make sure that the built-in object properties are not overridden or
+// used as an attack vector.
+// We also assume that `Object.create(null)` is available when the event name
+// is an ES6 Symbol.
+//
+    var prefix = typeof Object.create !== 'function' ? '~' : false;
+
+    /**
+     * Representation of a single EventEmitter function.
+     *
+     * @param {Function} fn Event handler to be called.
+     * @param {Mixed} context Context for function execution.
+     * @param {Boolean} [once=false] Only emit once
+     * @api private
+     */
+    function EE(fn, context, once) {
+        this.fn = fn;
+        this.context = context;
+        this.once = once || false;
+    }
+
+    /**
+     * Minimal EventEmitter interface that is molded against the Node.js
+     * EventEmitter interface.
+     *
+     * @constructor
+     * @api public
+     */
+    function EventEmitter() { /* Nothing to set */ }
+
+    /**
+     * Hold the assigned EventEmitters by name.
+     *
+     * @type {Object}
+     * @private
+     */
+    EventEmitter.prototype._events = undefined;
+
+    /**
+     * Return an array listing the events for which the emitter has registered
+     * listeners.
+     *
+     * @returns {Array}
+     * @api public
+     */
+    EventEmitter.prototype.eventNames = function eventNames() {
+        var events = this._events
+            , names = []
+            , name;
+
+        if (!events) return names;
+
+        for (name in 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 a list of assigned event listeners.
+     *
+     * @param {String} event The events that should be listed.
+     * @param {Boolean} exists We only need to know if there are listeners.
+     * @returns {Array|Boolean}
+     * @api public
+     */
+    EventEmitter.prototype.listeners = function listeners(event, exists) {
+        var evt = prefix ? prefix + event : event
+            , available = this._events && this._events[evt];
+
+        if (exists) return !!available;
+        if (!available) return [];
+        if (available.fn) return [available.fn];
+
+        for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {
+            ee[i] = available[i].fn;
+        }
+
+        return ee;
+    };
+
+    /**
+     * Emit an event to all registered event listeners.
+     *
+     * @param {String} event The name of the event.
+     * @returns {Boolean} Indication if we've emitted an event.
+     * @api public
+     */
+    EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
+        var evt = prefix ? prefix + event : event;
+
+        if (!this._events || !this._events[evt]) return false;
+
+        var listeners = this._events[evt]
+            , len = arguments.length
+            , args
+            , i;
+
+        if ('function' === typeof 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;
+                    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;
+    };
+
+    /**
+     * Register a new EventListener for the given event.
+     *
+     * @param {String} event Name of the event.
+     * @param {Function} fn Callback function.
+     * @param {Mixed} [context=this] The context of the function.
+     * @api public
+     */
+    EventEmitter.prototype.on = function on(event, fn, context) {
+        var listener = new EE(fn, context || this)
+            , evt = prefix ? prefix + event : event;
+
+        if (!this._events) this._events = prefix ? {} : Object.create(null);
+        if (!this._events[evt]) this._events[evt] = listener;
+        else {
+            if (!this._events[evt].fn) this._events[evt].push(listener);
+            else this._events[evt] = [
+                this._events[evt], listener
+            ];
+        }
+
+        return this;
+    };
+
+    /**
+     * Add an EventListener that's only called once.
+     *
+     * @param {String} event Name of the event.
+     * @param {Function} fn Callback function.
+     * @param {Mixed} [context=this] The context of the function.
+     * @api public
+     */
+    EventEmitter.prototype.once = function once(event, fn, context) {
+        var listener = new EE(fn, context || this, true)
+            , evt = prefix ? prefix + event : event;
+
+        if (!this._events) this._events = prefix ? {} : Object.create(null);
+        if (!this._events[evt]) this._events[evt] = listener;
+        else {
+            if (!this._events[evt].fn) this._events[evt].push(listener);
+            else this._events[evt] = [
+                this._events[evt], listener
+            ];
+        }
+
+        return this;
+    };
+
+    /**
+     * Remove event listeners.
+     *
+     * @param {String} event The event we want to remove.
+     * @param {Function} fn The listener that we need to find.
+     * @param {Mixed} context Only remove listeners matching this context.
+     * @param {Boolean} once Only remove once listeners.
+     * @api public
+     */
+    EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
+        var evt = prefix ? prefix + event : event;
+
+        if (!this._events || !this._events[evt]) return this;
+
+        var listeners = this._events[evt]
+            , events = [];
+
+        if (fn) {
+            if (listeners.fn) {
+                if (
+                    listeners.fn !== fn
+                    || (once && !listeners.once)
+                    || (context && listeners.context !== context)
+                ) {
+                    events.push(listeners);
+                }
+            } else {
+                for (var i = 0, 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 {
+            delete this._events[evt];
+        }
+
+        return this;
+    };
+
+    /**
+     * Remove all listeners or only the listeners for the specified event.
+     *
+     * @param {String} event The event want to remove all listeners for.
+     * @api public
+     */
+    EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
+        if (!this._events) return this;
+
+        if (event) delete this._events[prefix ? prefix + event : event];
+        else this._events = prefix ? {} : Object.create(null);
+
+        return this;
+    };
+
+//
+// Alias methods names because people roll like that.
+//
+    EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
+    EventEmitter.prototype.addListener = EventEmitter.prototype.on;
+
+//
+// This function doesn't apply anymore.
+//
+    EventEmitter.prototype.setMaxListeners = function setMaxListeners() {
+        return this;
+    };
+
+//
+// Expose the prefix.
+//
+    EventEmitter.prefixed = prefix;
+
+//
+// Expose the module.
+//
+    if ('undefined' !== typeof module) {
+        module.exports = EventEmitter;
+    }
+
+},{}],4:[function(require,module,exports){
+    /**
+     * isMobile.js v0.4.0
+     *
+     * A simple library to detect Apple phones and tablets,
+     * Android phones and tablets, other mobile devices (like blackberry, mini-opera and windows phone),
+     * and any kind of seven inch device, via user agent sniffing.
+     *
+     * @author: Kai Mallea (kmallea@gmail.com)
+     *
+     * @license: http://creativecommons.org/publicdomain/zero/1.0/
+     */
+    (function (global) {
+
+        var apple_phone         = /iPhone/i,
+            apple_ipod          = /iPod/i,
+            apple_tablet        = /iPad/i,
+            android_phone       = /(?=.*\bAndroid\b)(?=.*\bMobile\b)/i, // Match 'Android' AND 'Mobile'
+            android_tablet      = /Android/i,
+            amazon_phone        = /(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i,
+            amazon_tablet       = /(?=.*\bAndroid\b)(?=.*\b(?:KFOT|KFTT|KFJWI|KFJWA|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFSAWI|KFSAWA)\b)/i,
+            windows_phone       = /IEMobile/i,
+            windows_tablet      = /(?=.*\bWindows\b)(?=.*\bARM\b)/i, // Match 'Windows' AND 'ARM'
+            other_blackberry    = /BlackBerry/i,
+            other_blackberry_10 = /BB10/i,
+            other_opera         = /Opera Mini/i,
+            other_chrome        = /(CriOS|Chrome)(?=.*\bMobile\b)/i,
+            other_firefox       = /(?=.*\bFirefox\b)(?=.*\bMobile\b)/i, // Match 'Firefox' AND 'Mobile'
+            seven_inch = new RegExp(
+                '(?:' +         // Non-capturing group
+
+                'Nexus 7' +     // Nexus 7
+
+                '|' +           // OR
+
+                'BNTV250' +     // B&N Nook Tablet 7 inch
+
+                '|' +           // OR
+
+                'Kindle Fire' + // Kindle Fire
+
+                '|' +           // OR
+
+                'Silk' +        // Kindle Fire, Silk Accelerated
+
+                '|' +           // OR
+
+                'GT-P1000' +    // Galaxy Tab 7 inch
+
+                ')',            // End non-capturing group
+
+                'i');           // Case-insensitive matching
+
+        var match = function(regex, userAgent) {
+            return regex.test(userAgent);
+        };
+
+        var IsMobileClass = function(userAgent) {
+            var ua = userAgent || navigator.userAgent;
+
+            // Facebook mobile app's integrated browser adds a bunch of strings that
+            // match everything. Strip it out if it exists.
+            var tmp = ua.split('[FBAN');
+            if (typeof tmp[1] !== 'undefined') {
+                ua = tmp[0];
+            }
+
+            // Twitter mobile app's integrated browser on iPad adds a "Twitter for
+            // iPhone" string. Same probable happens on other tablet platforms.
+            // This will confuse detection so strip it out if it exists.
+            tmp = ua.split('Twitter');
+            if (typeof tmp[1] !== 'undefined') {
+                ua = tmp[0];
+            }
+
+            this.apple = {
+                phone:  match(apple_phone, ua),
+                ipod:   match(apple_ipod, ua),
+                tablet: !match(apple_phone, ua) && match(apple_tablet, ua),
+                device: match(apple_phone, ua) || match(apple_ipod, ua) || match(apple_tablet, ua)
+            };
+            this.amazon = {
+                phone:  match(amazon_phone, ua),
+                tablet: !match(amazon_phone, ua) && match(amazon_tablet, ua),
+                device: match(amazon_phone, ua) || match(amazon_tablet, ua)
+            };
+            this.android = {
+                phone:  match(amazon_phone, ua) || match(android_phone, ua),
+                tablet: !match(amazon_phone, ua) && !match(android_phone, ua) && (match(amazon_tablet, ua) || match(android_tablet, ua)),
+                device: match(amazon_phone, ua) || match(amazon_tablet, ua) || match(android_phone, ua) || match(android_tablet, ua)
+            };
+            this.windows = {
+                phone:  match(windows_phone, ua),
+                tablet: match(windows_tablet, ua),
+                device: match(windows_phone, ua) || match(windows_tablet, ua)
+            };
+            this.other = {
+                blackberry:   match(other_blackberry, ua),
+                blackberry10: match(other_blackberry_10, ua),
+                opera:        match(other_opera, ua),
+                firefox:      match(other_firefox, ua),
+                chrome:       match(other_chrome, ua),
+                device:       match(other_blackberry, ua) || match(other_blackberry_10, ua) || match(other_opera, ua) || match(other_firefox, ua) || match(other_chrome, ua)
+            };
+            this.seven_inch = match(seven_inch, ua);
+            this.any = this.apple.device || this.android.device || this.windows.device || this.other.device || this.seven_inch;
+
+            // excludes 'other' devices and ipods, targeting touchscreen phones
+            this.phone = this.apple.phone || this.android.phone || this.windows.phone;
+
+            // excludes 7 inch devices, classifying as phone or tablet is left to the user
+            this.tablet = this.apple.tablet || this.android.tablet || this.windows.tablet;
+
+            if (typeof window === 'undefined') {
+                return this;
+            }
+        };
+
+        var instantiate = function() {
+            var IM = new IsMobileClass();
+            IM.Class = IsMobileClass;
+            return IM;
+        };
+
+        if (typeof module !== 'undefined' && module.exports && typeof window === 'undefined') {
+            //node
+            module.exports = IsMobileClass;
+        } else if (typeof module !== 'undefined' && module.exports && typeof window !== 'undefined') {
+            //browserify
+            module.exports = instantiate();
+        } else if (typeof define === 'function' && define.amd) {
+            //AMD
+            define('isMobile', [], global.isMobile = instantiate());
+        } else {
+            global.isMobile = instantiate();
+        }
+
+    })(this);
+
+},{}],5:[function(require,module,exports){
+    'use strict';
+    /* eslint-disable no-unused-vars */
+    var hasOwnProperty = Object.prototype.hasOwnProperty;
+    var propIsEnumerable = Object.prototype.propertyIsEnumerable;
+
+    function toObject(val) {
+        if (val === null || val === undefined) {
+            throw new TypeError('Object.assign cannot be called with null or undefined');
+        }
+
+        return Object(val);
+    }
+
+    function shouldUseNative() {
+        try {
+            if (!Object.assign) {
+                return false;
+            }
+
+            // Detect buggy property enumeration order in older V8 versions.
+
+            // https://bugs.chromium.org/p/v8/issues/detail?id=4118
+            var test1 = new String('abc');  // eslint-disable-line
+            test1[5] = 'de';
+            if (Object.getOwnPropertyNames(test1)[0] === '5') {
+                return false;
+            }
+
+            // https://bugs.chromium.org/p/v8/issues/detail?id=3056
+            var test2 = {};
+            for (var i = 0; i < 10; i++) {
+                test2['_' + String.fromCharCode(i)] = i;
+            }
+            var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
+                return test2[n];
+            });
+            if (order2.join('') !== '0123456789') {
+                return false;
+            }
+
+            // https://bugs.chromium.org/p/v8/issues/detail?id=3056
+            var test3 = {};
+            'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
+                test3[letter] = letter;
+            });
+            if (Object.keys(Object.assign({}, test3)).join('') !==
+                'abcdefghijklmnopqrst') {
+                return false;
+            }
+
+            return true;
+        } catch (e) {
+            // We don't expect any of the above to throw, but better to be safe.
+            return false;
+        }
+    }
+
+    module.exports = shouldUseNative() ? Object.assign : function (target, source) {
+        var from;
+        var to = toObject(target);
+        var symbols;
+
+        for (var s = 1; s < arguments.length; s++) {
+            from = Object(arguments[s]);
+
+            for (var key in from) {
+                if (hasOwnProperty.call(from, key)) {
+                    to[key] = from[key];
+                }
+            }
+
+            if (Object.getOwnPropertySymbols) {
+                symbols = Object.getOwnPropertySymbols(from);
+                for (var i = 0; i < symbols.length; i++) {
+                    if (propIsEnumerable.call(from, symbols[i])) {
+                        to[symbols[i]] = from[symbols[i]];
+                    }
+                }
+            }
+        }
+
+        return to;
+    };
+
+},{}],6:[function(require,module,exports){
+    var EMPTY_ARRAY_BUFFER = new ArrayBuffer(0);
+
+    /**
+     * Helper class to create a webGL buffer
+     *
+     * @class
+     * @memberof pixi.gl
+     * @param gl {WebGLRenderingContext} The current WebGL rendering context
+     * @param type {gl.ARRAY_BUFFER | gl.ELEMENT_ARRAY_BUFFER} @mat
+     * @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
+     * @param drawType {gl.STATIC_DRAW|gl.DYNAMIC_DRAW|gl.STREAM_DRAW}
+     */
+    var Buffer = function(gl, type, data, drawType)
+    {
+
+        /**
+         * The current WebGL rendering context
+         *
+         * @member {WebGLRenderingContext}
+         */
+        this.gl = gl;
+
+        /**
+         * The WebGL buffer, created upon instantiation
+         *
+         * @member {WebGLBuffer}
+         */
+        this.buffer = gl.createBuffer();
+
+        /**
+         * The type of the buffer
+         *
+         * @member {gl.ARRAY_BUFFER|gl.ELEMENT_ARRAY_BUFFER}
+         */
+        this.type = type || gl.ARRAY_BUFFER;
+
+        /**
+         * The draw type of the buffer
+         *
+         * @member {gl.STATIC_DRAW|gl.DYNAMIC_DRAW|gl.STREAM_DRAW}
+         */
+        this.drawType = drawType || gl.STATIC_DRAW;
+
+        /**
+         * The data in the buffer, as a typed array
+         *
+         * @member {ArrayBuffer| SharedArrayBuffer|ArrayBufferView}
+         */
+        this.data = EMPTY_ARRAY_BUFFER;
+
+        if(data)
+        {
+            this.upload(data);
+        }
+    };
+
+    /**
+     * Uploads the buffer to the GPU
+     * @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data to upload
+     * @param offset {Number} if only a subset of the data should be uploaded, this is the amount of data to subtract
+     * @param dontBind {Boolean} whether to bind the buffer before uploading it
+     */
+    Buffer.prototype.upload = function(data, offset, dontBind)
+    {
+        // todo - needed?
+        if(!dontBind) this.bind();
+
+        var gl = this.gl;
+
+        data = data || this.data;
+        offset = offset || 0;
+
+        if(this.data.byteLength >= data.byteLength)
+        {
+            gl.bufferSubData(this.type, offset, data);
+        }
+        else
+        {
+            gl.bufferData(this.type, data, this.drawType);
+        }
+
+        this.data = data;
+    };
+    /**
+     * Binds the buffer
+     *
+     */
+    Buffer.prototype.bind = function()
+    {
+        var gl = this.gl;
+        gl.bindBuffer(this.type, this.buffer);
+    };
+
+    Buffer.createVertexBuffer = function(gl, data, drawType)
+    {
+        return new Buffer(gl, gl.ARRAY_BUFFER, data, drawType);
+    };
+
+    Buffer.createIndexBuffer = function(gl, data, drawType)
+    {
+        return new Buffer(gl, gl.ELEMENT_ARRAY_BUFFER, data, drawType);
+    };
+
+    Buffer.create = function(gl, type, data, drawType)
+    {
+        return new Buffer(gl, type, drawType);
+    };
+
+    /**
+     * Destroys the buffer
+     *
+     */
+    Buffer.prototype.destroy = function(){
+        this.gl.deleteBuffer(this.buffer);
+    };
+
+    module.exports = Buffer;
+
+},{}],7:[function(require,module,exports){
+
+    var Texture = require('./GLTexture');
+
+    /**
+     * Helper class to create a webGL Framebuffer
+     *
+     * @class
+     * @memberof pixi.gl
+     * @param gl {WebGLRenderingContext} The current WebGL rendering context
+     * @param width {Number} the width of the drawing area of the frame buffer
+     * @param height {Number} the height of the drawing area of the frame buffer
+     */
+    var Framebuffer = function(gl, width, height)
+    {
+        /**
+         * The current WebGL rendering context
+         *
+         * @member {WebGLRenderingContext}
+         */
+        this.gl = gl;
+
+        /**
+         * The frame buffer
+         *
+         * @member {WebGLFramebuffer}
+         */
+        this.framebuffer = gl.createFramebuffer();
+
+        /**
+         * The stencil buffer
+         *
+         * @member {WebGLRenderbuffer}
+         */
+        this.stencil = null;
+
+        /**
+         * The stencil buffer
+         *
+         * @member {GLTexture}
+         */
+        this.texture = null;
+
+        /**
+         * The width of the drawing area of the buffer
+         *
+         * @member {Number}
+         */
+        this.width = width || 100;
+        /**
+         * The height of the drawing area of the buffer
+         *
+         * @member {Number}
+         */
+        this.height = height || 100;
+    };
+
+    /**
+     * Adds a texture to the frame buffer
+     * @param texture {GLTexture}
+     */
+    Framebuffer.prototype.enableTexture = function(texture)
+    {
+        var gl = this.gl;
+
+        this.texture = texture || new Texture(gl);
+
+        this.texture.bind();
+
+        //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,  this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+        this.bind();
+
+        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
+    };
+
+    /**
+     * Initialises the stencil buffer
+     */
+    Framebuffer.prototype.enableStencil = function()
+    {
+        if(this.stencil)return;
+
+        var gl = this.gl;
+
+        this.stencil = gl.createRenderbuffer();
+
+        gl.bindRenderbuffer(gl.RENDERBUFFER, this.stencil);
+
+        // TODO.. this is depth AND stencil?
+        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.stencil);
+        gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL,  this.width  , this.height );
+    };
+
+    /**
+     * Erases the drawing area and fills it with a colour
+     * @param  r {Number} the red value of the clearing colour
+     * @param  g {Number} the green value of the clearing colour
+     * @param  b {Number} the blue value of the clearing colour
+     * @param  a {Number} the alpha value of the clearing colour
+     */
+    Framebuffer.prototype.clear = function( r, g, b, a )
+    {
+        this.bind();
+
+        var gl = this.gl;
+
+        gl.clearColor(r, g, b, a);
+        gl.clear(gl.COLOR_BUFFER_BIT);
+    };
+
+    /**
+     * Binds the frame buffer to the WebGL context
+     */
+    Framebuffer.prototype.bind = function()
+    {
+        var gl = this.gl;
+
+        if(this.texture)
+        {
+            this.texture.unbind();
+        }
+
+        gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer );
+    };
+
+    /**
+     * Unbinds the frame buffer to the WebGL context
+     */
+    Framebuffer.prototype.unbind = function()
+    {
+        var gl = this.gl;
+        gl.bindFramebuffer(gl.FRAMEBUFFER, null );
+    };
+    /**
+     * Resizes the drawing area of the buffer to the given width and height
+     * @param  width  {Number} the new width
+     * @param  height {Number} the new height
+     */
+    Framebuffer.prototype.resize = function(width, height)
+    {
+        var gl = this.gl;
+
+        this.width = width;
+        this.height = height;
+
+        if ( this.texture )
+        {
+            this.texture.uploadData(null, width, height);
+        }
+
+        if ( this.stencil )
+        {
+            // update the stencil buffer width and height
+            gl.bindRenderbuffer(gl.RENDERBUFFER, this.stencil);
+            gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
+        }
+    };
+
+    /**
+     * Destroys this buffer
+     */
+    Framebuffer.prototype.destroy = function()
+    {
+        var gl = this.gl;
+
+        //TODO
+        if(this.texture)
+        {
+            this.texture.destroy();
+        }
+
+        gl.deleteFramebuffer(this.framebuffer);
+
+        this.gl = null;
+
+        this.stencil = null;
+        this.texture = null;
+    };
+
+    /**
+     * Creates a frame buffer with a texture containing the given data
+     * @static
+     * @param gl {WebGLRenderingContext} The current WebGL rendering context
+     * @param width {Number} the width of the drawing area of the frame buffer
+     * @param height {Number} the height of the drawing area of the frame buffer
+     * @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
+     */
+    Framebuffer.createRGBA = function(gl, width, height/*, data*/)
+    {
+        var texture = Texture.fromData(gl, null, width, height);
+        texture.enableNearestScaling();
+        texture.enableWrapClamp();
+
+        //now create the framebuffer object and attach the texture to it.
+        var fbo = new Framebuffer(gl, width, height);
+        fbo.enableTexture(texture);
+
+        fbo.unbind();
+
+        return fbo;
+    };
+
+    /**
+     * Creates a frame buffer with a texture containing the given data
+     * @static
+     * @param gl {WebGLRenderingContext} The current WebGL rendering context
+     * @param width {Number} the width of the drawing area of the frame buffer
+     * @param height {Number} the height of the drawing area of the frame buffer
+     * @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
+     */
+    Framebuffer.createFloat32 = function(gl, width, height, data)
+    {
+        // create a new texture..
+        var texture = new Texture.fromData(gl, data, width, height);
+        texture.enableNearestScaling();
+        texture.enableWrapClamp();
+
+        //now create the framebuffer object and attach the texture to it.
+        var fbo = new Framebuffer(gl, width, height);
+        fbo.enableTexture(texture);
+
+        fbo.unbind();
+
+        return fbo;
+    };
+
+    module.exports = Framebuffer;
+
+},{"./GLTexture":9}],8:[function(require,module,exports){
+
+    var compileProgram = require('./shader/compileProgram'),
+        extractAttributes = require('./shader/extractAttributes'),
+        extractUniforms = require('./shader/extractUniforms'),
+        generateUniformAccessObject = require('./shader/generateUniformAccessObject');
+
+    /**
+     * Helper class to create a webGL Shader
+     *
+     * @class
+     * @memberof pixi.gl
+     * @param gl {WebGLRenderingContext}
+     * @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
+     * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.
+     */
+    var Shader = function(gl, vertexSrc, fragmentSrc)
+    {
+        /**
+         * The current WebGL rendering context
+         *
+         * @member {WebGLRenderingContext}
+         */
+        this.gl = gl;
+
+        /**
+         * The shader program
+         *
+         * @member {WebGLProgram}
+         */
+            // First compile the program..
+        this.program = compileProgram(gl, vertexSrc, fragmentSrc);
+
+
+        /**
+         * The attributes of the shader as an object containing the following properties
+         * {
+	 * 	type,
+	 * 	size,
+	 * 	location,
+	 * 	pointer
+	 * }
+         * @member {Object}
+         */
+            // next extract the attributes
+        this.attributes = extractAttributes(gl, this.program);
+
+        var uniformData = extractUniforms(gl, this.program);
+
+        /**
+         * The uniforms of the shader as an object containing the following properties
+         * {
+	 * 	gl,
+	 * 	data
+	 * }
+         * @member {Object}
+         */
+        this.uniforms = generateUniformAccessObject( gl, uniformData );
+    };
+    /**
+     * Uses this shader
+     */
+    Shader.prototype.bind = function()
+    {
+        this.gl.useProgram(this.program);
+    };
+
+    /**
+     * Destroys this shader
+     * TODO
+     */
+    Shader.prototype.destroy = function()
+    {
+        // var gl = this.gl;
+    };
+
+    module.exports = Shader;
+
+},{"./shader/compileProgram":14,"./shader/extractAttributes":16,"./shader/extractUniforms":17,"./shader/generateUniformAccessObject":18}],9:[function(require,module,exports){
+
+    /**
+     * Helper class to create a WebGL Texture
+     *
+     * @class
+     * @memberof pixi.gl
+     * @param gl {WebGLRenderingContext} The current WebGL context
+     * @param width {number} the width of the texture
+     * @param height {number} the height of the texture
+     * @param format {number} the pixel format of the texture. defaults to gl.RGBA
+     * @param type {number} the gl type of the texture. defaults to gl.UNSIGNED_BYTE
+     */
+    var Texture = function(gl, width, height, format, type)
+    {
+        /**
+         * The current WebGL rendering context
+         *
+         * @member {WebGLRenderingContext}
+         */
+        this.gl = gl;
+
+
+        /**
+         * The WebGL texture
+         *
+         * @member {WebGLTexture}
+         */
+        this.texture = gl.createTexture();
+
+        /**
+         * If mipmapping was used for this texture, enable and disable with enableMipmap()
+         *
+         * @member {Boolean}
+         */
+            // some settings..
+        this.mipmap = false;
+
+
+        /**
+         * Set to true to enable pre-multiplied alpha
+         *
+         * @member {Boolean}
+         */
+        this.premultiplyAlpha = false;
+
+        /**
+         * The width of texture
+         *
+         * @member {Number}
+         */
+        this.width = width || 0;
+        /**
+         * The height of texture
+         *
+         * @member {Number}
+         */
+        this.height = height || 0;
+
+        /**
+         * The pixel format of the texture. defaults to gl.RGBA
+         *
+         * @member {Number}
+         */
+        this.format = format || gl.RGBA;
+
+        /**
+         * The gl type of the texture. defaults to gl.UNSIGNED_BYTE
+         *
+         * @member {Number}
+         */
+        this.type = type || gl.UNSIGNED_BYTE;
+
+
+    };
+
+    /**
+     * Uploads this texture to the GPU
+     * @param source {HTMLImageElement|ImageData|HTMLVideoElement} the source image of the texture
+     */
+    Texture.prototype.upload = function(source)
+    {
+        this.bind();
+
+        var gl = this.gl;
+
+        // if the source is a video, we need to use the videoWidth / videoHeight properties as width / height will be incorrect.
+        this.width = source.videoWidth || source.width;
+        this.height = source.videoHeight || source.height;
+
+        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);
+        gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, this.type, source);
+    };
+
+    var FLOATING_POINT_AVAILABLE = false;
+
+    /**
+     * Use a data source and uploads this texture to the GPU
+     * @param data {TypedArray} the data to upload to the texture
+     * @param width {number} the new width of the texture
+     * @param height {number} the new height of the texture
+     */
+    Texture.prototype.uploadData = function(data, width, height)
+    {
+        this.bind();
+
+        var gl = this.gl;
+
+        this.width = width || this.width;
+        this.height = height || this.height;
+
+        if(data instanceof Float32Array)
+        {
+            if(!FLOATING_POINT_AVAILABLE)
+            {
+                var ext = gl.getExtension("OES_texture_float");
+
+                if(ext)
+                {
+                    FLOATING_POINT_AVAILABLE = true;
+                }
+                else
+                {
+                    throw new Error('floating point textures not available');
+                }
+            }
+
+            this.type = gl.FLOAT;
+        }
+        else
+        {
+            // TODO support for other types
+            this.type = gl.UNSIGNED_BYTE;
+        }
+
+
+
+        // what type of data?
+        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);
+        gl.texImage2D(gl.TEXTURE_2D, 0, this.format,  this.width, this.height, 0, this.format, this.type, data || null);
+
+    };
+
+    /**
+     * Binds the texture
+     * @param  location
+     */
+    Texture.prototype.bind = function(location)
+    {
+        var gl = this.gl;
+
+        if(location !== undefined)
+        {
+            gl.activeTexture(gl.TEXTURE0 + location);
+        }
+
+        gl.bindTexture(gl.TEXTURE_2D, this.texture);
+    };
+
+    /**
+     * Unbinds the texture
+     */
+    Texture.prototype.unbind = function()
+    {
+        var gl = this.gl;
+        gl.bindTexture(gl.TEXTURE_2D, null);
+    };
+
+    /**
+     * @param linear {Boolean} if we want to use linear filtering or nearest neighbour interpolation
+     */
+    Texture.prototype.minFilter = function( linear )
+    {
+        var gl = this.gl;
+
+        this.bind();
+
+        if(this.mipmap)
+        {
+            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linear ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST);
+        }
+        else
+        {
+            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linear ? gl.LINEAR : gl.NEAREST);
+        }
+    };
+
+    /**
+     * @param linear {Boolean} if we want to use linear filtering or nearest neighbour interpolation
+     */
+    Texture.prototype.magFilter = function( linear )
+    {
+        var gl = this.gl;
+
+        this.bind();
+
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, linear ? gl.LINEAR : gl.NEAREST);
+    };
+
+    /**
+     * Enables mipmapping
+     */
+    Texture.prototype.enableMipmap = function()
+    {
+        var gl = this.gl;
+
+        this.bind();
+
+        this.mipmap = true;
+
+        gl.generateMipmap(gl.TEXTURE_2D);
+    };
+
+    /**
+     * Enables linear filtering
+     */
+    Texture.prototype.enableLinearScaling = function()
+    {
+        this.minFilter(true);
+        this.magFilter(true);
+    };
+
+    /**
+     * Enables nearest neighbour interpolation
+     */
+    Texture.prototype.enableNearestScaling = function()
+    {
+        this.minFilter(false);
+        this.magFilter(false);
+    };
+
+    /**
+     * Enables clamping on the texture so WebGL will not repeat it
+     */
+    Texture.prototype.enableWrapClamp = function()
+    {
+        var gl = this.gl;
+
+        this.bind();
+
+        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);
+    };
+
+    /**
+     * Enable tiling on the texture
+     */
+    Texture.prototype.enableWrapRepeat = function()
+    {
+        var gl = this.gl;
+
+        this.bind();
+
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+    };
+
+    Texture.prototype.enableWrapMirrorRepeat = function()
+    {
+        var gl = this.gl;
+
+        this.bind();
+
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT);
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);
+    };
+
+
+    /**
+     * Destroys this texture
+     */
+    Texture.prototype.destroy = function()
+    {
+        var gl = this.gl;
+        //TODO
+        gl.deleteTexture(this.texture);
+    };
+
+    /**
+     * @static
+     * @param gl {WebGLRenderingContext} The current WebGL context
+     * @param source {HTMLImageElement|ImageData} the source image of the texture
+     * @param premultiplyAlpha {Boolean} If we want to use pre-multiplied alpha
+     */
+    Texture.fromSource = function(gl, source, premultiplyAlpha)
+    {
+        var texture = new Texture(gl);
+        texture.premultiplyAlpha = premultiplyAlpha || false;
+        texture.upload(source);
+
+        return texture;
+    };
+
+    /**
+     * @static
+     * @param gl {WebGLRenderingContext} The current WebGL context
+     * @param data {TypedArray} the data to upload to the texture
+     * @param width {number} the new width of the texture
+     * @param height {number} the new height of the texture
+     */
+    Texture.fromData = function(gl, data, width, height)
+    {
+        //console.log(data, width, height);
+        var texture = new Texture(gl);
+        texture.uploadData(data, width, height);
+
+        return texture;
+    };
+
+
+    module.exports = Texture;
+
+},{}],10:[function(require,module,exports){
+
+// state object//
+    var setVertexAttribArrays = require( './setVertexAttribArrays' );
+
+    /**
+     * Helper class to work with WebGL VertexArrayObjects (vaos)
+     * Only works if WebGL extensions are enabled (they usually are)
+     *
+     * @class
+     * @memberof pixi.gl
+     * @param gl {WebGLRenderingContext} The current WebGL rendering context
+     */
+    function VertexArrayObject(gl, state)
+    {
+        this.nativeVaoExtension = null;
+
+        if(!VertexArrayObject.FORCE_NATIVE)
+        {
+            this.nativeVaoExtension = gl.getExtension('OES_vertex_array_object') ||
+            gl.getExtension('MOZ_OES_vertex_array_object') ||
+            gl.getExtension('WEBKIT_OES_vertex_array_object');
+        }
+
+        this.nativeState = state;
+
+        if(this.nativeVaoExtension)
+        {
+            this.nativeVao = this.nativeVaoExtension.createVertexArrayOES();
+
+            var maxAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
+
+            // VAO - overwrite the state..
+            this.nativeState = {
+                tempAttribState: new Array(maxAttribs),
+                attribState: new Array(maxAttribs)
+            };
+        }
+
+        /**
+         * The current WebGL rendering context
+         *
+         * @member {WebGLRenderingContext}
+         */
+        this.gl = gl;
+
+        /**
+         * An array of attributes
+         *
+         * @member {Array}
+         */
+        this.attributes = [];
+
+        /**
+         * @member {Array}
+         */
+        this.indexBuffer = null;
+
+        /**
+         * A boolean flag
+         *
+         * @member {Boolean}
+         */
+        this.dirty = false;
+    }
+
+    VertexArrayObject.prototype.constructor = VertexArrayObject;
+    module.exports = VertexArrayObject;
+
+    /**
+     * Some devices behave a bit funny when using the newer extensions (im looking at you ipad 2!)
+     * If you find on older devices that things have gone a bit weird then set this to true.
+     */
+    /**
+     * Lets the VAO know if you should use the WebGL extension or the native methods.
+     * Some devices behave a bit funny when using the newer extensions (im looking at you ipad 2!)
+     * If you find on older devices that things have gone a bit weird then set this to true.
+     * @static
+     * @property {Boolean} FORCE_NATIVE
+     */
+    VertexArrayObject.FORCE_NATIVE = false;
+
+    /**
+     * Binds the buffer
+     */
+    VertexArrayObject.prototype.bind = function()
+    {
+        if(this.nativeVao)
+        {
+            this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao);
+
+            if(this.dirty)
+            {
+                this.dirty = false;
+                this.activate();
+            }
+        }
+        else
+        {
+
+            this.activate();
+        }
+
+        return this;
+    };
+
+    /**
+     * Unbinds the buffer
+     */
+    VertexArrayObject.prototype.unbind = function()
+    {
+        if(this.nativeVao)
+        {
+            this.nativeVaoExtension.bindVertexArrayOES(null);
+        }
+
+        return this;
+    };
+
+    /**
+     * Uses this vao
+     */
+    VertexArrayObject.prototype.activate = function()
+    {
+
+        var gl = this.gl;
+        var lastBuffer = null;
+
+        for (var i = 0; i < this.attributes.length; i++)
+        {
+            var attrib = this.attributes[i];
+
+            if(lastBuffer !== attrib.buffer)
+            {
+                attrib.buffer.bind();
+                lastBuffer = attrib.buffer;
+            }
+
+            //attrib.attribute.pointer(attrib.type, attrib.normalized, attrib.stride, attrib.start);
+            gl.vertexAttribPointer(attrib.attribute.location,
+                attrib.attribute.size, attrib.type || gl.FLOAT,
+                attrib.normalized || false,
+                attrib.stride || 0,
+                attrib.start || 0);
+
+
+        }
+
+        setVertexAttribArrays(gl, this.attributes, this.nativeState);
+
+        this.indexBuffer.bind();
+
+        return this;
+    };
+
+    /**
+     *
+     * @param buffer     {WebGLBuffer}
+     * @param attribute  {*}
+     * @param type       {String}
+     * @param normalized {Boolean}
+     * @param stride     {Number}
+     * @param start      {Number}
+     */
+    VertexArrayObject.prototype.addAttribute = function(buffer, attribute, type, normalized, stride, start)
+    {
+        this.attributes.push({
+            buffer:     buffer,
+            attribute:  attribute,
+
+            location:   attribute.location,
+            type:       type || this.gl.FLOAT,
+            normalized: normalized || false,
+            stride:     stride || 0,
+            start:      start || 0
+        });
+
+        this.dirty = true;
+
+        return this;
+    };
+
+    /**
+     *
+     * @param buffer   {WebGLBuffer}
+     * @param options  {Object}
+     */
+    VertexArrayObject.prototype.addIndex = function(buffer/*, options*/)
+    {
+        this.indexBuffer = buffer;
+
+        this.dirty = true;
+
+        return this;
+    };
+
+    /**
+     * Unbinds this vao and disables it
+     */
+    VertexArrayObject.prototype.clear = function()
+    {
+        // var gl = this.gl;
+
+        // TODO - should this function unbind after clear?
+        // for now, no but lets see what happens in the real world!
+        if(this.nativeVao)
+        {
+            this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao);
+        }
+
+        this.attributes.length = 0;
+        this.indexBuffer = null;
+
+        return this;
+    };
+
+    /**
+     * @param type  {Number}
+     * @param size  {Number}
+     * @param start {Number}
+     */
+    VertexArrayObject.prototype.draw = function(type, size, start)
+    {
+        var gl = this.gl;
+        gl.drawElements(type, size, gl.UNSIGNED_SHORT, start || 0);
+
+        return this;
+    };
+
+    /**
+     * Destroy this vao
+     */
+    VertexArrayObject.prototype.destroy = function()
+    {
+        // lose references
+        this.gl = null;
+        this.indexBuffer = null;
+        this.attributes = null;
+        this.nativeState = null;
+
+        if(this.nativeVao)
+        {
+            this.nativeVaoExtension.deleteVertexArrayOES(this.nativeVao);
+        }
+
+        this.nativeVaoExtension = null;
+        this.nativeVao = null;
+    };
+
+},{"./setVertexAttribArrays":13}],11:[function(require,module,exports){
+
+    /**
+     * Helper class to create a webGL Context
+     *
+     * @class
+     * @memberof pixi.gl
+     * @param canvas {HTMLCanvasElement} the canvas element that we will get the context from
+     * @param options {Object} An options object that gets passed in to the canvas element containing the context attributes,
+     *                         see https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext for the options available
+     * @return {WebGLRenderingContext} the WebGL context
+     */
+    var createContext = function(canvas, options)
+    {
+        var gl = canvas.getContext('webgl', options) ||
+            canvas.getContext('experimental-webgl', options);
+
+        if (!gl)
+        {
+            // fail, not able to get a context
+            throw new Error('This browser does not support webGL. Try using the canvas renderer');
+        }
+
+        return gl;
+    };
+
+    module.exports = createContext;
+
+},{}],12:[function(require,module,exports){
+    var gl = {
+        createContext:          require('./createContext'),
+        setVertexAttribArrays:  require('./setVertexAttribArrays'),
+        GLBuffer:               require('./GLBuffer'),
+        GLFramebuffer:          require('./GLFramebuffer'),
+        GLShader:               require('./GLShader'),
+        GLTexture:              require('./GLTexture'),
+        VertexArrayObject:      require('./VertexArrayObject'),
+        shader:                 require('./shader')
+    };
+
+// Export for Node-compatible environments
+    if (typeof module !== 'undefined' && module.exports)
+    {
+        // Export the module
+        module.exports = gl;
+    }
+
+// Add to the browser window pixi.gl
+    if (typeof window !== 'undefined')
+    {
+        // add the window object
+        window.pixi = { gl: gl };
+    }
+},{"./GLBuffer":6,"./GLFramebuffer":7,"./GLShader":8,"./GLTexture":9,"./VertexArrayObject":10,"./createContext":11,"./setVertexAttribArrays":13,"./shader":19}],13:[function(require,module,exports){
+// var GL_MAP = {};
+
+    /**
+     * @param gl {WebGLRenderingContext} The current WebGL context
+     * @param attribs {*}
+     * @param state {*}
+     */
+    var setVertexAttribArrays = function (gl, attribs, state)
+    {
+        var i;
+        if(state)
+        {
+            var tempAttribState = state.tempAttribState,
+                attribState = state.attribState;
+
+            for (i = 0; i < tempAttribState.length; i++)
+            {
+                tempAttribState[i] = false;
+            }
+
+            // set the new attribs
+            for (i = 0; i < attribs.length; i++)
+            {
+                tempAttribState[attribs[i].attribute.location] = true;
+            }
+
+            for (i = 0; i < attribState.length; i++)
+            {
+                if (attribState[i] !== tempAttribState[i])
+                {
+                    attribState[i] = tempAttribState[i];
+
+                    if (state.attribState[i])
+                    {
+                        gl.enableVertexAttribArray(i);
+                    }
+                    else
+                    {
+                        gl.disableVertexAttribArray(i);
+                    }
+                }
+            }
+
+        }
+        else
+        {
+            for (i = 0; i < attribs.length; i++)
+            {
+                var attrib = attribs[i];
+                gl.enableVertexAttribArray(attrib.attribute.location);
+            }
+        }
+    };
+
+    module.exports = setVertexAttribArrays;
+
+},{}],14:[function(require,module,exports){
+
+    /**
+     * @class
+     * @memberof pixi.gl.shader
+     * @param gl {WebGLRenderingContext} The current WebGL context {WebGLProgram}
+     * @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
+     * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.
+     * @return {WebGLProgram} the shader program
+     */
+    var compileProgram = function(gl, vertexSrc, fragmentSrc)
+    {
+        var glVertShader = compileShader(gl, gl.VERTEX_SHADER, vertexSrc);
+        var glFragShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSrc);
+
+        var program = gl.createProgram();
+
+        gl.attachShader(program, glVertShader);
+        gl.attachShader(program, glFragShader);
+        gl.linkProgram(program);
+
+        // if linking fails, then log and cleanup
+        if (!gl.getProgramParameter(program, gl.LINK_STATUS))
+        {
+            console.error('Pixi.js Error: Could not initialize shader.');
+            console.error('gl.VALIDATE_STATUS', gl.getProgramParameter(program, gl.VALIDATE_STATUS));
+            console.error('gl.getError()', gl.getError());
+
+            // if there is a program info log, log it
+            if (gl.getProgramInfoLog(program) !== '')
+            {
+                console.warn('Pixi.js Warning: gl.getProgramInfoLog()', gl.getProgramInfoLog(program));
+            }
+
+            gl.deleteProgram(program);
+            program = null;
+        }
+
+        // clean up some shaders
+        gl.deleteShader(glVertShader);
+        gl.deleteShader(glFragShader);
+
+        return program;
+    };
+
+    /**
+     * @private
+     * @param gl {WebGLRenderingContext} The current WebGL context {WebGLProgram}
+     * @param type {Number} the type, can be either VERTEX_SHADER or FRAGMENT_SHADER
+     * @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
+     * @return {WebGLShader} the shader
+     */
+    var compileShader = function (gl, type, src)
+    {
+        var shader = gl.createShader(type);
+
+        gl.shaderSource(shader, src);
+        gl.compileShader(shader);
+
+        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
+        {
+            console.log(gl.getShaderInfoLog(shader));
+            return null;
+        }
+
+        return shader;
+    };
+
+    module.exports = compileProgram;
+
+},{}],15:[function(require,module,exports){
+    /**
+     * @class
+     * @memberof pixi.gl.shader
+     * @param type {String} Type of value
+     * @param size {Number}
+     */
+    var defaultValue = function(type, size)
+    {
+        switch (type)
+        {
+            case 'float':
+                return 0;
+
+            case 'vec2':
+                return new Float32Array(2 * size);
+
+            case 'vec3':
+                return new Float32Array(3 * size);
+
+            case 'vec4':
+                return new Float32Array(4 * size);
+
+            case 'int':
+            case 'sampler2D':
+                return 0;
+
+            case 'ivec2':
+                return new Int32Array(2 * size);
+
+            case 'ivec3':
+                return new Int32Array(3 * size);
+
+            case 'ivec4':
+                return new Int32Array(4 * size);
+
+            case 'bool':
+                return false;
+
+            case 'bvec2':
+
+                return booleanArray( 2 * size);
+
+            case 'bvec3':
+                return booleanArray(3 * size);
+
+            case 'bvec4':
+                return booleanArray(4 * size);
+
+            case 'mat2':
+                return new Float32Array([1, 0,
+                    0, 1]);
+
+            case 'mat3':
+                return new Float32Array([1, 0, 0,
+                    0, 1, 0,
+                    0, 0, 1]);
+
+            case 'mat4':
+                return new Float32Array([1, 0, 0, 0,
+                    0, 1, 0, 0,
+                    0, 0, 1, 0,
+                    0, 0, 0, 1]);
+        }
+    };
+
+    var booleanArray = function(size)
+    {
+        var array = new Array(size);
+
+        for (var i = 0; i < array.length; i++)
+        {
+            array[i] = false;
+        }
+
+        return array;
+    };
+
+    module.exports = defaultValue;
+
+},{}],16:[function(require,module,exports){
+
+    var mapType = require('./mapType');
+    var mapSize = require('./mapSize');
+
+    /**
+     * Extracts the attributes
+     * @class
+     * @memberof pixi.gl.shader
+     * @param gl {WebGLRenderingContext} The current WebGL rendering context
+     * @param program {WebGLProgram} The shader program to get the attributes from
+     * @return attributes {Object}
+     */
+    var extractAttributes = function(gl, program)
+    {
+        var attributes = {};
+
+        var totalAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
+
+        for (var i = 0; i < totalAttributes; i++)
+        {
+            var attribData = gl.getActiveAttrib(program, i);
+            var type = mapType(gl, attribData.type);
+
+            attributes[attribData.name] = {
+                type:type,
+                size:mapSize(type),
+                location:gl.getAttribLocation(program, attribData.name),
+                //TODO - make an attribute object
+                pointer: pointer
+            };
+        }
+
+        return attributes;
+    };
+
+    var pointer = function(type, normalized, stride, start){
+        // console.log(this.location)
+        gl.vertexAttribPointer(this.location,this.size, type || gl.FLOAT, normalized || false, stride || 0, start || 0);
+    };
+
+    module.exports = extractAttributes;
+
+},{"./mapSize":20,"./mapType":21}],17:[function(require,module,exports){
+    var mapType = require('./mapType');
+    var defaultValue = require('./defaultValue');
+
+    /**
+     * Extracts the uniforms
+     * @class
+     * @memberof pixi.gl.shader
+     * @param gl {WebGLRenderingContext} The current WebGL rendering context
+     * @param program {WebGLProgram} The shader program to get the uniforms from
+     * @return uniforms {Object}
+     */
+    var extractUniforms = function(gl, program)
+    {
+        var uniforms = {};
+
+        var totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
+
+        for (var i = 0; i < totalUniforms; i++)
+        {
+            var uniformData = gl.getActiveUniform(program, i);
+            var name = uniformData.name.replace(/\[.*?\]/, "");
+            var type = mapType(gl, uniformData.type );
+
+            uniforms[name] = {
+                type:type,
+                size:uniformData.size,
+                location:gl.getUniformLocation(program, name),
+                value:defaultValue(type, uniformData.size)
+            };
+        }
+
+        return uniforms;
+    };
+
+    module.exports = extractUniforms;
+
+},{"./defaultValue":15,"./mapType":21}],18:[function(require,module,exports){
+    /**
+     * Extracts the attributes
+     * @class
+     * @memberof pixi.gl.shader
+     * @param gl {WebGLRenderingContext} The current WebGL rendering context
+     * @param uniforms {Array} @mat ?
+     * @return attributes {Object}
+     */
+    var generateUniformAccessObject = function(gl, uniformData)
+    {
+        // this is the object we will be sending back.
+        // an object hierachy will be created for structs
+        var uniforms = {data:{}};
+
+        uniforms.gl = gl;
+
+        var uniformKeys= Object.keys(uniformData);
+
+        for (var i = 0; i < uniformKeys.length; i++)
+        {
+            var fullName = uniformKeys[i];
+
+            var nameTokens = fullName.split('.');
+            var name = nameTokens[nameTokens.length - 1];
+
+            var uniformGroup = getUniformGroup(nameTokens, uniforms);
+
+            var uniform =  uniformData[fullName];
+            uniformGroup.data[name] = uniform;
+
+            uniformGroup.gl = gl;
+
+            Object.defineProperty(uniformGroup, name, {
+                get: generateGetter(name),
+                set: generateSetter(name, uniform)
+            });
+        }
+
+        return uniforms;
+    };
+
+    var generateGetter = function(name)
+    {
+        var template = getterTemplate.replace('%%', name);
+        return new Function(template); // jshint ignore:line
+    };
+
+    var generateSetter = function(name, uniform)
+    {
+        var template = setterTemplate.replace(/%%/g, name);
+        var setTemplate;
+
+        if(uniform.size === 1)
+        {
+            setTemplate = GLSL_TO_SINGLE_SETTERS[uniform.type];
+        }
+        else
+        {
+            setTemplate = GLSL_TO_ARRAY_SETTERS[uniform.type];
+        }
+
+        if(setTemplate)
+        {
+            template += "\nthis.gl." + setTemplate + ";";
+        }
+
+        return new Function('value', template); // jshint ignore:line
+    };
+
+    var getUniformGroup = function(nameTokens, uniform)
+    {
+        var cur = uniform;
+
+        for (var i = 0; i < nameTokens.length - 1; i++)
+        {
+            var o = cur[nameTokens[i]] || {data:{}};
+            cur[nameTokens[i]] = o;
+            cur = o;
+        }
+
+        return cur;
+    };
+
+    var getterTemplate = [
+        'return this.data.%%.value;',
+    ].join('\n');
+
+    var setterTemplate = [
+        'this.data.%%.value = value;',
+        'var location = this.data.%%.location;'
+    ].join('\n');
+
+
+    var GLSL_TO_SINGLE_SETTERS = {
+
+        'float':    'uniform1f(location, value)',
+
+        'vec2':     'uniform2f(location, value[0], value[1])',
+        'vec3':     'uniform3f(location, value[0], value[1], value[2])',
+        'vec4':     'uniform4f(location, value[0], value[1], value[2], value[3])',
+
+        'int':      'uniform1i(location, value)',
+        'ivec2':    'uniform2i(location, value[0], value[1])',
+        'ivec3':    'uniform3i(location, value[0], value[1], value[2])',
+        'ivec4':    'uniform4i(location, value[0], value[1], value[2], value[3])',
+
+        'bool':     'uniform1i(location, value)',
+        'bvec2':    'uniform2i(location, value[0], value[1])',
+        'bvec3':    'uniform3i(location, value[0], value[1], value[2])',
+        'bvec4':    'uniform4i(location, value[0], value[1], value[2], value[3])',
+
+        'mat2':     'uniformMatrix2fv(location, false, value)',
+        'mat3':     'uniformMatrix3fv(location, false, value)',
+        'mat4':     'uniformMatrix4fv(location, false, value)',
+
+        'sampler2D':'uniform1i(location, value)'
+    };
+
+    var GLSL_TO_ARRAY_SETTERS = {
+
+        'float':    'uniform1fv(location, value)',
+
+        'vec2':     'uniform2fv(location, value)',
+        'vec3':     'uniform3fv(location, value)',
+        'vec4':     'uniform4fv(location, value)',
+
+        'int':      'uniform1iv(location, value)',
+        'ivec2':    'uniform2iv(location, value)',
+        'ivec3':    'uniform3iv(location, value)',
+        'ivec4':    'uniform4iv(location, value)',
+
+        'bool':     'uniform1iv(location, value)',
+        'bvec2':    'uniform2iv(location, value)',
+        'bvec3':    'uniform3iv(location, value)',
+        'bvec4':    'uniform4iv(location, value)',
+
+        'sampler2D':'uniform1iv(location, value)'
+    };
+
+    module.exports = generateUniformAccessObject;
+
+},{}],19:[function(require,module,exports){
+    module.exports = {
+        compileProgram: require('./compileProgram'),
+        defaultValue: require('./defaultValue'),
+        extractAttributes: require('./extractAttributes'),
+        extractUniforms: require('./extractUniforms'),
+        generateUniformAccessObject: require('./generateUniformAccessObject'),
+        mapSize: require('./mapSize'),
+        mapType: require('./mapType')
+    };
+},{"./compileProgram":14,"./defaultValue":15,"./extractAttributes":16,"./extractUniforms":17,"./generateUniformAccessObject":18,"./mapSize":20,"./mapType":21}],20:[function(require,module,exports){
+    /**
+     * @class
+     * @memberof pixi.gl.shader
+     * @param type {String}
+     * @return {Number}
+     */
+    var mapSize = function(type)
+    {
+        return GLSL_TO_SIZE[type];
+    };
+
+
+    var GLSL_TO_SIZE = {
+        'float':    1,
+        'vec2':     2,
+        'vec3':     3,
+        'vec4':     4,
+
+        'int':      1,
+        'ivec2':    2,
+        'ivec3':    3,
+        'ivec4':    4,
+
+        'bool':     1,
+        'bvec2':    2,
+        'bvec3':    3,
+        'bvec4':    4,
+
+        'mat2':     4,
+        'mat3':     9,
+        'mat4':     16,
+
+        'sampler2D':  1
+    };
+
+    module.exports = mapSize;
+
+},{}],21:[function(require,module,exports){
+
+
+    var mapSize = function(gl, type)
+    {
+        if(!GL_TABLE)
+        {
+            var typeNames = Object.keys(GL_TO_GLSL_TYPES);
+
+            GL_TABLE = {};
+
+            for(var i = 0; i < typeNames.length; ++i)
+            {
+                var tn = typeNames[i];
+                GL_TABLE[ gl[tn] ] = GL_TO_GLSL_TYPES[tn];
+            }
+        }
+
+        return GL_TABLE[type];
+    };
+
+    var GL_TABLE = null;
+
+    var GL_TO_GLSL_TYPES = {
+        'FLOAT':       'float',
+        'FLOAT_VEC2':  'vec2',
+        'FLOAT_VEC3':  'vec3',
+        'FLOAT_VEC4':  'vec4',
+
+        'INT':         'int',
+        'INT_VEC2':    'ivec2',
+        'INT_VEC3':    'ivec3',
+        'INT_VEC4':    'ivec4',
+
+        'BOOL':        'bool',
+        'BOOL_VEC2':   'bvec2',
+        'BOOL_VEC3':   'bvec3',
+        'BOOL_VEC4':   'bvec4',
+
+        'FLOAT_MAT2':  'mat2',
+        'FLOAT_MAT3':  'mat3',
+        'FLOAT_MAT4':  'mat4',
+
+        'SAMPLER_2D':  'sampler2D'
+    };
+
+    module.exports = mapSize;
+
+},{}],22:[function(require,module,exports){
+    (function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// resolves . and .. elements in a path array with directory names there
+// must be no slashes, empty elements, or device names (c:\) in the array
+// (so also no leading and trailing slashes - it does not distinguish
+// relative and absolute paths)
+        function normalizeArray(parts, allowAboveRoot) {
+            // if the path tries to go above the root, `up` ends up > 0
+            var up = 0;
+            for (var i = parts.length - 1; i >= 0; i--) {
+                var last = parts[i];
+                if (last === '.') {
+                    parts.splice(i, 1);
+                } else if (last === '..') {
+                    parts.splice(i, 1);
+                    up++;
+                } else if (up) {
+                    parts.splice(i, 1);
+                    up--;
+                }
+            }
+
+            // if the path is allowed to go above the root, restore leading ..s
+            if (allowAboveRoot) {
+                for (; up--; up) {
+                    parts.unshift('..');
+                }
+            }
+
+            return parts;
+        }
+
+// Split a filename into [root, dir, basename, ext], unix version
+// 'root' is just a slash, or nothing.
+        var splitPathRe =
+            /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+        var splitPath = function(filename) {
+            return splitPathRe.exec(filename).slice(1);
+        };
+
+// path.resolve([from ...], to)
+// posix version
+        exports.resolve = function() {
+            var resolvedPath = '',
+                resolvedAbsolute = false;
+
+            for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+                var path = (i >= 0) ? arguments[i] : process.cwd();
+
+                // Skip empty and invalid entries
+                if (typeof path !== 'string') {
+                    throw new TypeError('Arguments to path.resolve must be strings');
+                } else if (!path) {
+                    continue;
+                }
+
+                resolvedPath = path + '/' + resolvedPath;
+                resolvedAbsolute = path.charAt(0) === '/';
+            }
+
+            // At this point the path should be resolved to a full absolute path, but
+            // handle relative paths to be safe (might happen when process.cwd() fails)
+
+            // Normalize the path
+            resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
+                return !!p;
+            }), !resolvedAbsolute).join('/');
+
+            return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+        };
+
+// path.normalize(path)
+// posix version
+        exports.normalize = function(path) {
+            var isAbsolute = exports.isAbsolute(path),
+                trailingSlash = substr(path, -1) === '/';
+
+            // Normalize the path
+            path = normalizeArray(filter(path.split('/'), function(p) {
+                return !!p;
+            }), !isAbsolute).join('/');
+
+            if (!path && !isAbsolute) {
+                path = '.';
+            }
+            if (path && trailingSlash) {
+                path += '/';
+            }
+
+            return (isAbsolute ? '/' : '') + path;
+        };
+
+// posix version
+        exports.isAbsolute = function(path) {
+            return path.charAt(0) === '/';
+        };
+
+// posix version
+        exports.join = function() {
+            var paths = Array.prototype.slice.call(arguments, 0);
+            return exports.normalize(filter(paths, function(p, index) {
+                if (typeof p !== 'string') {
+                    throw new TypeError('Arguments to path.join must be strings');
+                }
+                return p;
+            }).join('/'));
+        };
+
+
+// path.relative(from, to)
+// posix version
+        exports.relative = function(from, to) {
+            from = exports.resolve(from).substr(1);
+            to = exports.resolve(to).substr(1);
+
+            function trim(arr) {
+                var start = 0;
+                for (; start < arr.length; start++) {
+                    if (arr[start] !== '') break;
+                }
+
+                var end = arr.length - 1;
+                for (; end >= 0; end--) {
+                    if (arr[end] !== '') break;
+                }
+
+                if (start > end) return [];
+                return arr.slice(start, end - start + 1);
+            }
+
+            var fromParts = trim(from.split('/'));
+            var toParts = trim(to.split('/'));
+
+            var length = Math.min(fromParts.length, toParts.length);
+            var samePartsLength = length;
+            for (var i = 0; i < length; i++) {
+                if (fromParts[i] !== toParts[i]) {
+                    samePartsLength = i;
+                    break;
+                }
+            }
+
+            var outputParts = [];
+            for (var i = samePartsLength; i < fromParts.length; i++) {
+                outputParts.push('..');
+            }
+
+            outputParts = outputParts.concat(toParts.slice(samePartsLength));
+
+            return outputParts.join('/');
+        };
+
+        exports.sep = '/';
+        exports.delimiter = ':';
+
+        exports.dirname = function(path) {
+            var result = splitPath(path),
+                root = result[0],
+                dir = result[1];
+
+            if (!root && !dir) {
+                // No dirname whatsoever
+                return '.';
+            }
+
+            if (dir) {
+                // It has a dirname, strip trailing slash
+                dir = dir.substr(0, dir.length - 1);
+            }
+
+            return root + dir;
+        };
+
+
+        exports.basename = function(path, ext) {
+            var f = splitPath(path)[2];
+            // TODO: make this comparison case-insensitive on windows?
+            if (ext && f.substr(-1 * ext.length) === ext) {
+                f = f.substr(0, f.length - ext.length);
+            }
+            return f;
+        };
+
+
+        exports.extname = function(path) {
+            return splitPath(path)[3];
+        };
+
+        function filter (xs, f) {
+            if (xs.filter) return xs.filter(f);
+            var res = [];
+            for (var i = 0; i < xs.length; i++) {
+                if (f(xs[i], i, xs)) res.push(xs[i]);
+            }
+            return res;
+        }
+
+// String.prototype.substr - negative index don't work in IE8
+        var substr = 'ab'.substr(-1) === 'b'
+                ? function (str, start, len) { return str.substr(start, len) }
+                : function (str, start, len) {
+                if (start < 0) start = str.length + start;
+                return str.substr(start, len);
+            }
+            ;
+
+    }).call(this,require('_process'))
+
+},{"_process":23}],23:[function(require,module,exports){
+// shim for using process in browser
+    var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things.  But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals.  It's inside a
+// function because try/catches deoptimize in certain engines.
+
+    var cachedSetTimeout;
+    var cachedClearTimeout;
+
+    function defaultSetTimout() {
+        throw new Error('setTimeout has not been defined');
+    }
+    function defaultClearTimeout () {
+        throw new Error('clearTimeout has not been defined');
+    }
+    (function () {
+        try {
+            if (typeof setTimeout === 'function') {
+                cachedSetTimeout = setTimeout;
+            } else {
+                cachedSetTimeout = defaultSetTimout;
+            }
+        } catch (e) {
+            cachedSetTimeout = defaultSetTimout;
+        }
+        try {
+            if (typeof clearTimeout === 'function') {
+                cachedClearTimeout = clearTimeout;
+            } else {
+                cachedClearTimeout = defaultClearTimeout;
+            }
+        } catch (e) {
+            cachedClearTimeout = defaultClearTimeout;
+        }
+    } ())
+    function runTimeout(fun) {
+        if (cachedSetTimeout === setTimeout) {
+            //normal enviroments in sane situations
+            return setTimeout(fun, 0);
+        }
+        // if setTimeout wasn't available but was latter defined
+        if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+            cachedSetTimeout = setTimeout;
+            return setTimeout(fun, 0);
+        }
+        try {
+            // when when somebody has screwed with setTimeout but no I.E. maddness
+            return cachedSetTimeout(fun, 0);
+        } catch(e){
+            try {
+                // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+                return cachedSetTimeout.call(null, fun, 0);
+            } catch(e){
+                // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+                return cachedSetTimeout.call(this, fun, 0);
+            }
+        }
+
+
+    }
+    function runClearTimeout(marker) {
+        if (cachedClearTimeout === clearTimeout) {
+            //normal enviroments in sane situations
+            return clearTimeout(marker);
+        }
+        // if clearTimeout wasn't available but was latter defined
+        if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+            cachedClearTimeout = clearTimeout;
+            return clearTimeout(marker);
+        }
+        try {
+            // when when somebody has screwed with setTimeout but no I.E. maddness
+            return cachedClearTimeout(marker);
+        } catch (e){
+            try {
+                // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
+                return cachedClearTimeout.call(null, marker);
+            } catch (e){
+                // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+                // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+                return cachedClearTimeout.call(this, marker);
+            }
+        }
+
+
+
+    }
+    var queue = [];
+    var draining = false;
+    var currentQueue;
+    var queueIndex = -1;
+
+    function cleanUpNextTick() {
+        if (!draining || !currentQueue) {
+            return;
+        }
+        draining = false;
+        if (currentQueue.length) {
+            queue = currentQueue.concat(queue);
+        } else {
+            queueIndex = -1;
+        }
+        if (queue.length) {
+            drainQueue();
+        }
+    }
+
+    function drainQueue() {
+        if (draining) {
+            return;
+        }
+        var timeout = runTimeout(cleanUpNextTick);
+        draining = true;
+
+        var len = queue.length;
+        while(len) {
+            currentQueue = queue;
+            queue = [];
+            while (++queueIndex < len) {
+                if (currentQueue) {
+                    currentQueue[queueIndex].run();
+                }
+            }
+            queueIndex = -1;
+            len = queue.length;
+        }
+        currentQueue = null;
+        draining = false;
+        runClearTimeout(timeout);
+    }
+
+    process.nextTick = function (fun) {
+        var args = new Array(arguments.length - 1);
+        if (arguments.length > 1) {
+            for (var i = 1; i < arguments.length; i++) {
+                args[i - 1] = arguments[i];
+            }
+        }
+        queue.push(new Item(fun, args));
+        if (queue.length === 1 && !draining) {
+            runTimeout(drainQueue);
+        }
+    };
+
+// v8 likes predictible objects
+    function Item(fun, array) {
+        this.fun = fun;
+        this.array = array;
+    }
+    Item.prototype.run = function () {
+        this.fun.apply(null, this.array);
+    };
+    process.title = 'browser';
+    process.browser = true;
+    process.env = {};
+    process.argv = [];
+    process.version = ''; // empty string to avoid regexp issues
+    process.versions = {};
+
+    function noop() {}
+
+    process.on = noop;
+    process.addListener = noop;
+    process.once = noop;
+    process.off = noop;
+    process.removeListener = noop;
+    process.removeAllListeners = noop;
+    process.emit = noop;
+
+    process.binding = function (name) {
+        throw new Error('process.binding is not supported');
+    };
+
+    process.cwd = function () { return '/' };
+    process.chdir = function (dir) {
+        throw new Error('process.chdir is not supported');
+    };
+    process.umask = function() { return 0; };
+
+},{}],24:[function(require,module,exports){
+    (function (global){
+        /*! https://mths.be/punycode v1.4.1 by @mathias */
+        ;(function(root) {
+
+            /** Detect free variables */
+            var freeExports = typeof exports == 'object' && exports &&
+                !exports.nodeType && exports;
+            var freeModule = typeof module == 'object' && module &&
+                !module.nodeType && module;
+            var freeGlobal = typeof global == 'object' && global;
+            if (
+                freeGlobal.global === freeGlobal ||
+                freeGlobal.window === freeGlobal ||
+                freeGlobal.self === freeGlobal
+            ) {
+                root = freeGlobal;
+            }
+
+            /**
+             * The `punycode` object.
+             * @name punycode
+             * @type Object
+             */
+            var punycode,
+
+                /** Highest positive signed 32-bit float value */
+                maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
+
+                /** Bootstring parameters */
+                base = 36,
+                tMin = 1,
+                tMax = 26,
+                skew = 38,
+                damp = 700,
+                initialBias = 72,
+                initialN = 128, // 0x80
+                delimiter = '-', // '\x2D'
+
+                /** Regular expressions */
+                regexPunycode = /^xn--/,
+                regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
+                regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
+
+                /** Error messages */
+                errors = {
+                    'overflow': 'Overflow: input needs wider integers to process',
+                    'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
+                    'invalid-input': 'Invalid input'
+                },
+
+                /** Convenience shortcuts */
+                baseMinusTMin = base - tMin,
+                floor = Math.floor,
+                stringFromCharCode = String.fromCharCode,
+
+                /** Temporary variable */
+                key;
+
+            /*--------------------------------------------------------------------------*/
+
+            /**
+             * A generic error utility function.
+             * @private
+             * @param {String} type The error type.
+             * @returns {Error} Throws a `RangeError` with the applicable error message.
+             */
+            function error(type) {
+                throw new RangeError(errors[type]);
+            }
+
+            /**
+             * A generic `Array#map` utility function.
+             * @private
+             * @param {Array} array The array to iterate over.
+             * @param {Function} callback The function that gets called for every array
+             * item.
+             * @returns {Array} A new array of values returned by the callback function.
+             */
+            function map(array, fn) {
+                var length = array.length;
+                var result = [];
+                while (length--) {
+                    result[length] = fn(array[length]);
+                }
+                return result;
+            }
+
+            /**
+             * A simple `Array#map`-like wrapper to work with domain name strings or email
+             * addresses.
+             * @private
+             * @param {String} domain The domain name or email address.
+             * @param {Function} callback The function that gets called for every
+             * character.
+             * @returns {Array} A new string of characters returned by the callback
+             * function.
+             */
+            function mapDomain(string, fn) {
+                var parts = string.split('@');
+                var result = '';
+                if (parts.length > 1) {
+                    // In email addresses, only the domain name should be punycoded. Leave
+                    // the local part (i.e. everything up to `@`) intact.
+                    result = parts[0] + '@';
+                    string = parts[1];
+                }
+                // Avoid `split(regex)` for IE8 compatibility. See #17.
+                string = string.replace(regexSeparators, '\x2E');
+                var labels = string.split('.');
+                var encoded = map(labels, fn).join('.');
+                return result + encoded;
+            }
+
+            /**
+             * Creates an array containing the numeric code points of each Unicode
+             * character in the string. While JavaScript uses UCS-2 internally,
+             * this function will convert a pair of surrogate halves (each of which
+             * UCS-2 exposes as separate characters) into a single code point,
+             * matching UTF-16.
+             * @see `punycode.ucs2.encode`
+             * @see <https://mathiasbynens.be/notes/javascript-encoding>
+             * @memberOf punycode.ucs2
+             * @name decode
+             * @param {String} string The Unicode input string (UCS-2).
+             * @returns {Array} The new array of code points.
+             */
+            function ucs2decode(string) {
+                var output = [],
+                    counter = 0,
+                    length = string.length,
+                    value,
+                    extra;
+                while (counter < length) {
+                    value = string.charCodeAt(counter++);
+                    if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
+                        // high surrogate, and there is a next character
+                        extra = string.charCodeAt(counter++);
+                        if ((extra & 0xFC00) == 0xDC00) { // low surrogate
+                            output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
+                        } else {
+                            // unmatched surrogate; only append this code unit, in case the next
+                            // code unit is the high surrogate of a surrogate pair
+                            output.push(value);
+                            counter--;
+                        }
+                    } else {
+                        output.push(value);
+                    }
+                }
+                return output;
+            }
+
+            /**
+             * Creates a string based on an array of numeric code points.
+             * @see `punycode.ucs2.decode`
+             * @memberOf punycode.ucs2
+             * @name encode
+             * @param {Array} codePoints The array of numeric code points.
+             * @returns {String} The new Unicode string (UCS-2).
+             */
+            function ucs2encode(array) {
+                return map(array, function(value) {
+                    var output = '';
+                    if (value > 0xFFFF) {
+                        value -= 0x10000;
+                        output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
+                        value = 0xDC00 | value & 0x3FF;
+                    }
+                    output += stringFromCharCode(value);
+                    return output;
+                }).join('');
+            }
+
+            /**
+             * Converts a basic code point into a digit/integer.
+             * @see `digitToBasic()`
+             * @private
+             * @param {Number} codePoint The basic numeric code point value.
+             * @returns {Number} The numeric value of a basic code point (for use in
+             * representing integers) in the range `0` to `base - 1`, or `base` if
+             * the code point does not represent a value.
+             */
+            function basicToDigit(codePoint) {
+                if (codePoint - 48 < 10) {
+                    return codePoint - 22;
+                }
+                if (codePoint - 65 < 26) {
+                    return codePoint - 65;
+                }
+                if (codePoint - 97 < 26) {
+                    return codePoint - 97;
+                }
+                return base;
+            }
+
+            /**
+             * Converts a digit/integer into a basic code point.
+             * @see `basicToDigit()`
+             * @private
+             * @param {Number} digit The numeric value of a basic code point.
+             * @returns {Number} The basic code point whose value (when used for
+             * representing integers) is `digit`, which needs to be in the range
+             * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
+             * used; else, the lowercase form is used. The behavior is undefined
+             * if `flag` is non-zero and `digit` has no uppercase form.
+             */
+            function digitToBasic(digit, flag) {
+                //  0..25 map to ASCII a..z or A..Z
+                // 26..35 map to ASCII 0..9
+                return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
+            }
+
+            /**
+             * Bias adaptation function as per section 3.4 of RFC 3492.
+             * https://tools.ietf.org/html/rfc3492#section-3.4
+             * @private
+             */
+            function adapt(delta, numPoints, firstTime) {
+                var k = 0;
+                delta = firstTime ? floor(delta / damp) : delta >> 1;
+                delta += floor(delta / numPoints);
+                for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
+                    delta = floor(delta / baseMinusTMin);
+                }
+                return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
+            }
+
+            /**
+             * Converts a Punycode string of ASCII-only symbols to a string of Unicode
+             * symbols.
+             * @memberOf punycode
+             * @param {String} input The Punycode string of ASCII-only symbols.
+             * @returns {String} The resulting string of Unicode symbols.
+             */
+            function decode(input) {
+                // Don't use UCS-2
+                var output = [],
+                    inputLength = input.length,
+                    out,
+                    i = 0,
+                    n = initialN,
+                    bias = initialBias,
+                    basic,
+                    j,
+                    index,
+                    oldi,
+                    w,
+                    k,
+                    digit,
+                    t,
+                    /** Cached calculation results */
+                    baseMinusT;
+
+                // Handle the basic code points: let `basic` be the number of input code
+                // points before the last delimiter, or `0` if there is none, then copy
+                // the first basic code points to the output.
+
+                basic = input.lastIndexOf(delimiter);
+                if (basic < 0) {
+                    basic = 0;
+                }
+
+                for (j = 0; j < basic; ++j) {
+                    // if it's not a basic code point
+                    if (input.charCodeAt(j) >= 0x80) {
+                        error('not-basic');
+                    }
+                    output.push(input.charCodeAt(j));
+                }
+
+                // Main decoding loop: start just after the last delimiter if any basic code
+                // points were copied; start at the beginning otherwise.
+
+                for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
+
+                    // `index` is the index of the next character to be consumed.
+                    // Decode a generalized variable-length integer into `delta`,
+                    // which gets added to `i`. The overflow checking is easier
+                    // if we increase `i` as we go, then subtract off its starting
+                    // value at the end to obtain `delta`.
+                    for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
+
+                        if (index >= inputLength) {
+                            error('invalid-input');
+                        }
+
+                        digit = basicToDigit(input.charCodeAt(index++));
+
+                        if (digit >= base || digit > floor((maxInt - i) / w)) {
+                            error('overflow');
+                        }
+
+                        i += digit * w;
+                        t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+
+                        if (digit < t) {
+                            break;
+                        }
+
+                        baseMinusT = base - t;
+                        if (w > floor(maxInt / baseMinusT)) {
+                            error('overflow');
+                        }
+
+                        w *= baseMinusT;
+
+                    }
+
+                    out = output.length + 1;
+                    bias = adapt(i - oldi, out, oldi == 0);
+
+                    // `i` was supposed to wrap around from `out` to `0`,
+                    // incrementing `n` each time, so we'll fix that now:
+                    if (floor(i / out) > maxInt - n) {
+                        error('overflow');
+                    }
+
+                    n += floor(i / out);
+                    i %= out;
+
+                    // Insert `n` at position `i` of the output
+                    output.splice(i++, 0, n);
+
+                }
+
+                return ucs2encode(output);
+            }
+
+            /**
+             * Converts a string of Unicode symbols (e.g. a domain name label) to a
+             * Punycode string of ASCII-only symbols.
+             * @memberOf punycode
+             * @param {String} input The string of Unicode symbols.
+             * @returns {String} The resulting Punycode string of ASCII-only symbols.
+             */
+            function encode(input) {
+                var n,
+                    delta,
+                    handledCPCount,
+                    basicLength,
+                    bias,
+                    j,
+                    m,
+                    q,
+                    k,
+                    t,
+                    currentValue,
+                    output = [],
+                    /** `inputLength` will hold the number of code points in `input`. */
+                    inputLength,
+                    /** Cached calculation results */
+                    handledCPCountPlusOne,
+                    baseMinusT,
+                    qMinusT;
+
+                // Convert the input in UCS-2 to Unicode
+                input = ucs2decode(input);
+
+                // Cache the length
+                inputLength = input.length;
+
+                // Initialize the state
+                n = initialN;
+                delta = 0;
+                bias = initialBias;
+
+                // Handle the basic code points
+                for (j = 0; j < inputLength; ++j) {
+                    currentValue = input[j];
+                    if (currentValue < 0x80) {
+                        output.push(stringFromCharCode(currentValue));
+                    }
+                }
+
+                handledCPCount = basicLength = output.length;
+
+                // `handledCPCount` is the number of code points that have been handled;
+                // `basicLength` is the number of basic code points.
+
+                // Finish the basic string - if it is not empty - with a delimiter
+                if (basicLength) {
+                    output.push(delimiter);
+                }
+
+                // Main encoding loop:
+                while (handledCPCount < inputLength) {
+
+                    // All non-basic code points < n have been handled already. Find the next
+                    // larger one:
+                    for (m = maxInt, j = 0; j < inputLength; ++j) {
+                        currentValue = input[j];
+                        if (currentValue >= n && currentValue < m) {
+                            m = currentValue;
+                        }
+                    }
+
+                    // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
+                    // but guard against overflow
+                    handledCPCountPlusOne = handledCPCount + 1;
+                    if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
+                        error('overflow');
+                    }
+
+                    delta += (m - n) * handledCPCountPlusOne;
+                    n = m;
+
+                    for (j = 0; j < inputLength; ++j) {
+                        currentValue = input[j];
+
+                        if (currentValue < n && ++delta > maxInt) {
+                            error('overflow');
+                        }
+
+                        if (currentValue == n) {
+                            // Represent delta as a generalized variable-length integer
+                            for (q = delta, k = base; /* no condition */; k += base) {
+                                t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+                                if (q < t) {
+                                    break;
+                                }
+                                qMinusT = q - t;
+                                baseMinusT = base - t;
+                                output.push(
+                                    stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
+                                );
+                                q = floor(qMinusT / baseMinusT);
+                            }
+
+                            output.push(stringFromCharCode(digitToBasic(q, 0)));
+                            bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
+                            delta = 0;
+                            ++handledCPCount;
+                        }
+                    }
+
+                    ++delta;
+                    ++n;
+
+                }
+                return output.join('');
+            }
+
+            /**
+             * Converts a Punycode string representing a domain name or an email address
+             * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
+             * it doesn't matter if you call it on a string that has already been
+             * converted to Unicode.
+             * @memberOf punycode
+             * @param {String} input The Punycoded domain name or email address to
+             * convert to Unicode.
+             * @returns {String} The Unicode representation of the given Punycode
+             * string.
+             */
+            function toUnicode(input) {
+                return mapDomain(input, function(string) {
+                    return regexPunycode.test(string)
+                        ? decode(string.slice(4).toLowerCase())
+                        : string;
+                });
+            }
+
+            /**
+             * Converts a Unicode string representing a domain name or an email address to
+             * Punycode. Only the non-ASCII parts of the domain name will be converted,
+             * i.e. it doesn't matter if you call it with a domain that's already in
+             * ASCII.
+             * @memberOf punycode
+             * @param {String} input The domain name or email address to convert, as a
+             * Unicode string.
+             * @returns {String} The Punycode representation of the given domain name or
+             * email address.
+             */
+            function toASCII(input) {
+                return mapDomain(input, function(string) {
+                    return regexNonASCII.test(string)
+                        ? 'xn--' + encode(string)
+                        : string;
+                });
+            }
+
+            /*--------------------------------------------------------------------------*/
+
+            /** Define the public API */
+            punycode = {
+                /**
+                 * A string representing the current Punycode.js version number.
+                 * @memberOf punycode
+                 * @type String
+                 */
+                'version': '1.4.1',
+                /**
+                 * An object of methods to convert from JavaScript's internal character
+                 * representation (UCS-2) to Unicode code points, and back.
+                 * @see <https://mathiasbynens.be/notes/javascript-encoding>
+                 * @memberOf punycode
+                 * @type Object
+                 */
+                'ucs2': {
+                    'decode': ucs2decode,
+                    'encode': ucs2encode
+                },
+                'decode': decode,
+                'encode': encode,
+                'toASCII': toASCII,
+                'toUnicode': toUnicode
+            };
+
+            /** Expose `punycode` */
+            // Some AMD build optimizers, like r.js, check for specific condition patterns
+            // like the following:
+            if (
+                typeof define == 'function' &&
+                typeof define.amd == 'object' &&
+                define.amd
+            ) {
+                define('punycode', function() {
+                    return punycode;
+                });
+            } else if (freeExports && freeModule) {
+                if (module.exports == freeExports) {
+                    // in Node.js, io.js, or RingoJS v0.8.0+
+                    freeModule.exports = punycode;
+                } else {
+                    // in Narwhal or RingoJS v0.7.0-
+                    for (key in punycode) {
+                        punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
+                    }
+                }
+            } else {
+                // in Rhino or a web browser
+                root.punycode = punycode;
+            }
+
+        }(this));
+
+    }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{}],25:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+    'use strict';
+
+// If obj.hasOwnProperty has been overridden, then calling
+// obj.hasOwnProperty(prop) will break.
+// See: https://github.com/joyent/node/issues/1707
+    function hasOwnProperty(obj, prop) {
+        return Object.prototype.hasOwnProperty.call(obj, prop);
+    }
+
+    module.exports = function(qs, sep, eq, options) {
+        sep = sep || '&';
+        eq = eq || '=';
+        var obj = {};
+
+        if (typeof qs !== 'string' || qs.length === 0) {
+            return obj;
+        }
+
+        var regexp = /\+/g;
+        qs = qs.split(sep);
+
+        var maxKeys = 1000;
+        if (options && typeof options.maxKeys === 'number') {
+            maxKeys = options.maxKeys;
+        }
+
+        var len = qs.length;
+        // maxKeys <= 0 means that we should not limit keys count
+        if (maxKeys > 0 && len > maxKeys) {
+            len = maxKeys;
+        }
+
+        for (var i = 0; i < len; ++i) {
+            var x = qs[i].replace(regexp, '%20'),
+                idx = x.indexOf(eq),
+                kstr, vstr, k, v;
+
+            if (idx >= 0) {
+                kstr = x.substr(0, idx);
+                vstr = x.substr(idx + 1);
+            } else {
+                kstr = x;
+                vstr = '';
+            }
+
+            k = decodeURIComponent(kstr);
+            v = decodeURIComponent(vstr);
+
+            if (!hasOwnProperty(obj, k)) {
+                obj[k] = v;
+            } else if (isArray(obj[k])) {
+                obj[k].push(v);
+            } else {
+                obj[k] = [obj[k], v];
+            }
+        }
+
+        return obj;
+    };
+
+    var isArray = Array.isArray || function (xs) {
+            return Object.prototype.toString.call(xs) === '[object Array]';
+        };
+
+},{}],26:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+    'use strict';
+
+    var stringifyPrimitive = function(v) {
+        switch (typeof v) {
+            case 'string':
+                return v;
+
+            case 'boolean':
+                return v ? 'true' : 'false';
+
+            case 'number':
+                return isFinite(v) ? v : '';
+
+            default:
+                return '';
+        }
+    };
+
+    module.exports = function(obj, sep, eq, name) {
+        sep = sep || '&';
+        eq = eq || '=';
+        if (obj === null) {
+            obj = undefined;
+        }
+
+        if (typeof obj === 'object') {
+            return map(objectKeys(obj), function(k) {
+                var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
+                if (isArray(obj[k])) {
+                    return map(obj[k], function(v) {
+                        return ks + encodeURIComponent(stringifyPrimitive(v));
+                    }).join(sep);
+                } else {
+                    return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
+                }
+            }).join(sep);
+
+        }
+
+        if (!name) return '';
+        return encodeURIComponent(stringifyPrimitive(name)) + eq +
+            encodeURIComponent(stringifyPrimitive(obj));
+    };
+
+    var isArray = Array.isArray || function (xs) {
+            return Object.prototype.toString.call(xs) === '[object Array]';
+        };
+
+    function map (xs, f) {
+        if (xs.map) return xs.map(f);
+        var res = [];
+        for (var i = 0; i < xs.length; i++) {
+            res.push(f(xs[i], i));
+        }
+        return res;
+    }
+
+    var objectKeys = Object.keys || function (obj) {
+            var res = [];
+            for (var key in obj) {
+                if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
+            }
+            return res;
+        };
+
+},{}],27:[function(require,module,exports){
+    'use strict';
+
+    exports.decode = exports.parse = require('./decode');
+    exports.encode = exports.stringify = require('./encode');
+
+},{"./decode":25,"./encode":26}],28:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+    'use strict';
+
+    var punycode = require('punycode');
+    var util = require('./util');
+
+    exports.parse = urlParse;
+    exports.resolve = urlResolve;
+    exports.resolveObject = urlResolveObject;
+    exports.format = urlFormat;
+
+    exports.Url = Url;
+
+    function Url() {
+        this.protocol = null;
+        this.slashes = null;
+        this.auth = null;
+        this.host = null;
+        this.port = null;
+        this.hostname = null;
+        this.hash = null;
+        this.search = null;
+        this.query = null;
+        this.pathname = null;
+        this.path = null;
+        this.href = null;
+    }
+
+// Reference: RFC 3986, RFC 1808, RFC 2396
+
+// define these here so at least they only have to be
+// compiled once on the first module load.
+    var protocolPattern = /^([a-z0-9.+-]+:)/i,
+        portPattern = /:[0-9]*$/,
+
+    // Special case for a simple path URL
+        simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
+
+    // RFC 2396: characters reserved for delimiting URLs.
+    // We actually just auto-escape these.
+        delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
+
+    // RFC 2396: characters not allowed for various reasons.
+        unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
+
+    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
+        autoEscape = ['\''].concat(unwise),
+    // Characters that are never ever allowed in a hostname.
+    // Note that any invalid chars are also handled, but these
+    // are the ones that are *expected* to be seen, so we fast-path
+    // them.
+        nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
+        hostEndingChars = ['/', '?', '#'],
+        hostnameMaxLen = 255,
+        hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
+        hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
+    // protocols that can allow "unsafe" and "unwise" chars.
+        unsafeProtocol = {
+            'javascript': true,
+            'javascript:': true
+        },
+    // protocols that never have a hostname.
+        hostlessProtocol = {
+            'javascript': true,
+            'javascript:': true
+        },
+    // protocols that always contain a // bit.
+        slashedProtocol = {
+            'http': true,
+            'https': true,
+            'ftp': true,
+            'gopher': true,
+            'file': true,
+            'http:': true,
+            'https:': true,
+            'ftp:': true,
+            'gopher:': true,
+            'file:': true
+        },
+        querystring = require('querystring');
+
+    function urlParse(url, parseQueryString, slashesDenoteHost) {
+        if (url && util.isObject(url) && url instanceof Url) return url;
+
+        var u = new Url;
+        u.parse(url, parseQueryString, slashesDenoteHost);
+        return u;
+    }
+
+    Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
+        if (!util.isString(url)) {
+            throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
+        }
+
+        // Copy chrome, IE, opera backslash-handling behavior.
+        // Back slashes before the query string get converted to forward slashes
+        // See: https://code.google.com/p/chromium/issues/detail?id=25916
+        var queryIndex = url.indexOf('?'),
+            splitter =
+                (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',
+            uSplit = url.split(splitter),
+            slashRegex = /\\/g;
+        uSplit[0] = uSplit[0].replace(slashRegex, '/');
+        url = uSplit.join(splitter);
+
+        var rest = url;
+
+        // trim before proceeding.
+        // This is to support parse stuff like "  http://foo.com  \n"
+        rest = rest.trim();
+
+        if (!slashesDenoteHost && url.split('#').length === 1) {
+            // Try fast path regexp
+            var simplePath = simplePathPattern.exec(rest);
+            if (simplePath) {
+                this.path = rest;
+                this.href = rest;
+                this.pathname = simplePath[1];
+                if (simplePath[2]) {
+                    this.search = simplePath[2];
+                    if (parseQueryString) {
+                        this.query = querystring.parse(this.search.substr(1));
+                    } else {
+                        this.query = this.search.substr(1);
+                    }
+                } else if (parseQueryString) {
+                    this.search = '';
+                    this.query = {};
+                }
+                return this;
+            }
+        }
+
+        var proto = protocolPattern.exec(rest);
+        if (proto) {
+            proto = proto[0];
+            var lowerProto = proto.toLowerCase();
+            this.protocol = lowerProto;
+            rest = rest.substr(proto.length);
+        }
+
+        // figure out if it's got a host
+        // user@server is *always* interpreted as a hostname, and url
+        // resolution will treat //foo/bar as host=foo,path=bar because that's
+        // how the browser resolves relative URLs.
+        if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
+            var slashes = rest.substr(0, 2) === '//';
+            if (slashes && !(proto && hostlessProtocol[proto])) {
+                rest = rest.substr(2);
+                this.slashes = true;
+            }
+        }
+
+        if (!hostlessProtocol[proto] &&
+            (slashes || (proto && !slashedProtocol[proto]))) {
+
+            // there's a hostname.
+            // the first instance of /, ?, ;, or # ends the host.
+            //
+            // If there is an @ in the hostname, then non-host chars *are* allowed
+            // to the left of the last @ sign, unless some host-ending character
+            // comes *before* the @-sign.
+            // URLs are obnoxious.
+            //
+            // ex:
+            // http://a@b@c/ => user:a@b host:c
+            // http://a@b?@c => user:a host:c path:/?@c
+
+            // v0.12 TODO(isaacs): This is not quite how Chrome does things.
+            // Review our test case against browsers more comprehensively.
+
+            // find the first instance of any hostEndingChars
+            var hostEnd = -1;
+            for (var i = 0; i < hostEndingChars.length; i++) {
+                var hec = rest.indexOf(hostEndingChars[i]);
+                if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
+                    hostEnd = hec;
+            }
+
+            // at this point, either we have an explicit point where the
+            // auth portion cannot go past, or the last @ char is the decider.
+            var auth, atSign;
+            if (hostEnd === -1) {
+                // atSign can be anywhere.
+                atSign = rest.lastIndexOf('@');
+            } else {
+                // atSign must be in auth portion.
+                // http://a@b/c@d => host:b auth:a path:/c@d
+                atSign = rest.lastIndexOf('@', hostEnd);
+            }
+
+            // Now we have a portion which is definitely the auth.
+            // Pull that off.
+            if (atSign !== -1) {
+                auth = rest.slice(0, atSign);
+                rest = rest.slice(atSign + 1);
+                this.auth = decodeURIComponent(auth);
+            }
+
+            // the host is the remaining to the left of the first non-host char
+            hostEnd = -1;
+            for (var i = 0; i < nonHostChars.length; i++) {
+                var hec = rest.indexOf(nonHostChars[i]);
+                if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
+                    hostEnd = hec;
+            }
+            // if we still have not hit it, then the entire thing is a host.
+            if (hostEnd === -1)
+                hostEnd = rest.length;
+
+            this.host = rest.slice(0, hostEnd);
+            rest = rest.slice(hostEnd);
+
+            // pull out port.
+            this.parseHost();
+
+            // we've indicated that there is a hostname,
+            // so even if it's empty, it has to be present.
+            this.hostname = this.hostname || '';
+
+            // if hostname begins with [ and ends with ]
+            // assume that it's an IPv6 address.
+            var ipv6Hostname = this.hostname[0] === '[' &&
+                this.hostname[this.hostname.length - 1] === ']';
+
+            // validate a little.
+            if (!ipv6Hostname) {
+                var hostparts = this.hostname.split(/\./);
+                for (var i = 0, l = hostparts.length; i < l; i++) {
+                    var part = hostparts[i];
+                    if (!part) continue;
+                    if (!part.match(hostnamePartPattern)) {
+                        var newpart = '';
+                        for (var j = 0, k = part.length; j < k; j++) {
+                            if (part.charCodeAt(j) > 127) {
+                                // we replace non-ASCII char with a temporary placeholder
+                                // we need this to make sure size of hostname is not
+                                // broken by replacing non-ASCII by nothing
+                                newpart += 'x';
+                            } else {
+                                newpart += part[j];
+                            }
+                        }
+                        // we test again with ASCII char only
+                        if (!newpart.match(hostnamePartPattern)) {
+                            var validParts = hostparts.slice(0, i);
+                            var notHost = hostparts.slice(i + 1);
+                            var bit = part.match(hostnamePartStart);
+                            if (bit) {
+                                validParts.push(bit[1]);
+                                notHost.unshift(bit[2]);
+                            }
+                            if (notHost.length) {
+                                rest = '/' + notHost.join('.') + rest;
+                            }
+                            this.hostname = validParts.join('.');
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (this.hostname.length > hostnameMaxLen) {
+                this.hostname = '';
+            } else {
+                // hostnames are always lower case.
+                this.hostname = this.hostname.toLowerCase();
+            }
+
+            if (!ipv6Hostname) {
+                // IDNA Support: Returns a punycoded representation of "domain".
+                // It only converts parts of the domain name that
+                // have non-ASCII characters, i.e. it doesn't matter if
+                // you call it with a domain that already is ASCII-only.
+                this.hostname = punycode.toASCII(this.hostname);
+            }
+
+            var p = this.port ? ':' + this.port : '';
+            var h = this.hostname || '';
+            this.host = h + p;
+            this.href += this.host;
+
+            // strip [ and ] from the hostname
+            // the host field still retains them, though
+            if (ipv6Hostname) {
+                this.hostname = this.hostname.substr(1, this.hostname.length - 2);
+                if (rest[0] !== '/') {
+                    rest = '/' + rest;
+                }
+            }
+        }
+
+        // now rest is set to the post-host stuff.
+        // chop off any delim chars.
+        if (!unsafeProtocol[lowerProto]) {
+
+            // First, make 100% sure that any "autoEscape" chars get
+            // escaped, even if encodeURIComponent doesn't think they
+            // need to be.
+            for (var i = 0, l = autoEscape.length; i < l; i++) {
+                var ae = autoEscape[i];
+                if (rest.indexOf(ae) === -1)
+                    continue;
+                var esc = encodeURIComponent(ae);
+                if (esc === ae) {
+                    esc = escape(ae);
+                }
+                rest = rest.split(ae).join(esc);
+            }
+        }
+
+
+        // chop off from the tail first.
+        var hash = rest.indexOf('#');
+        if (hash !== -1) {
+            // got a fragment string.
+            this.hash = rest.substr(hash);
+            rest = rest.slice(0, hash);
+        }
+        var qm = rest.indexOf('?');
+        if (qm !== -1) {
+            this.search = rest.substr(qm);
+            this.query = rest.substr(qm + 1);
+            if (parseQueryString) {
+                this.query = querystring.parse(this.query);
+            }
+            rest = rest.slice(0, qm);
+        } else if (parseQueryString) {
+            // no query string, but parseQueryString still requested
+            this.search = '';
+            this.query = {};
+        }
+        if (rest) this.pathname = rest;
+        if (slashedProtocol[lowerProto] &&
+            this.hostname && !this.pathname) {
+            this.pathname = '/';
+        }
+
+        //to support http.request
+        if (this.pathname || this.search) {
+            var p = this.pathname || '';
+            var s = this.search || '';
+            this.path = p + s;
+        }
+
+        // finally, reconstruct the href based on what has been validated.
+        this.href = this.format();
+        return this;
+    };
+
+// format a parsed object into a url string
+    function urlFormat(obj) {
+        // ensure it's an object, and not a string url.
+        // If it's an obj, this is a no-op.
+        // this way, you can call url_format() on strings
+        // to clean up potentially wonky urls.
+        if (util.isString(obj)) obj = urlParse(obj);
+        if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
+        return obj.format();
+    }
+
+    Url.prototype.format = function() {
+        var auth = this.auth || '';
+        if (auth) {
+            auth = encodeURIComponent(auth);
+            auth = auth.replace(/%3A/i, ':');
+            auth += '@';
+        }
+
+        var protocol = this.protocol || '',
+            pathname = this.pathname || '',
+            hash = this.hash || '',
+            host = false,
+            query = '';
+
+        if (this.host) {
+            host = auth + this.host;
+        } else if (this.hostname) {
+            host = auth + (this.hostname.indexOf(':') === -1 ?
+                this.hostname :
+            '[' + this.hostname + ']');
+            if (this.port) {
+                host += ':' + this.port;
+            }
+        }
+
+        if (this.query &&
+            util.isObject(this.query) &&
+            Object.keys(this.query).length) {
+            query = querystring.stringify(this.query);
+        }
+
+        var search = this.search || (query && ('?' + query)) || '';
+
+        if (protocol && protocol.substr(-1) !== ':') protocol += ':';
+
+        // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
+        // unless they had them to begin with.
+        if (this.slashes ||
+            (!protocol || slashedProtocol[protocol]) && host !== false) {
+            host = '//' + (host || '');
+            if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
+        } else if (!host) {
+            host = '';
+        }
+
+        if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
+        if (search && search.charAt(0) !== '?') search = '?' + search;
+
+        pathname = pathname.replace(/[?#]/g, function(match) {
+            return encodeURIComponent(match);
+        });
+        search = search.replace('#', '%23');
+
+        return protocol + host + pathname + search + hash;
+    };
+
+    function urlResolve(source, relative) {
+        return urlParse(source, false, true).resolve(relative);
+    }
+
+    Url.prototype.resolve = function(relative) {
+        return this.resolveObject(urlParse(relative, false, true)).format();
+    };
+
+    function urlResolveObject(source, relative) {
+        if (!source) return relative;
+        return urlParse(source, false, true).resolveObject(relative);
+    }
+
+    Url.prototype.resolveObject = function(relative) {
+        if (util.isString(relative)) {
+            var rel = new Url();
+            rel.parse(relative, false, true);
+            relative = rel;
+        }
+
+        var result = new Url();
+        var tkeys = Object.keys(this);
+        for (var tk = 0; tk < tkeys.length; tk++) {
+            var tkey = tkeys[tk];
+            result[tkey] = this[tkey];
+        }
+
+        // hash is always overridden, no matter what.
+        // even href="" will remove it.
+        result.hash = relative.hash;
+
+        // if the relative url is empty, then there's nothing left to do here.
+        if (relative.href === '') {
+            result.href = result.format();
+            return result;
+        }
+
+        // hrefs like //foo/bar always cut to the protocol.
+        if (relative.slashes && !relative.protocol) {
+            // take everything except the protocol from relative
+            var rkeys = Object.keys(relative);
+            for (var rk = 0; rk < rkeys.length; rk++) {
+                var rkey = rkeys[rk];
+                if (rkey !== 'protocol')
+                    result[rkey] = relative[rkey];
+            }
+
+            //urlParse appends trailing / to urls like http://www.example.com
+            if (slashedProtocol[result.protocol] &&
+                result.hostname && !result.pathname) {
+                result.path = result.pathname = '/';
+            }
+
+            result.href = result.format();
+            return result;
+        }
+
+        if (relative.protocol && relative.protocol !== result.protocol) {
+            // if it's a known url protocol, then changing
+            // the protocol does weird things
+            // first, if it's not file:, then we MUST have a host,
+            // and if there was a path
+            // to begin with, then we MUST have a path.
+            // if it is file:, then the host is dropped,
+            // because that's known to be hostless.
+            // anything else is assumed to be absolute.
+            if (!slashedProtocol[relative.protocol]) {
+                var keys = Object.keys(relative);
+                for (var v = 0; v < keys.length; v++) {
+                    var k = keys[v];
+                    result[k] = relative[k];
+                }
+                result.href = result.format();
+                return result;
+            }
+
+            result.protocol = relative.protocol;
+            if (!relative.host && !hostlessProtocol[relative.protocol]) {
+                var relPath = (relative.pathname || '').split('/');
+                while (relPath.length && !(relative.host = relPath.shift()));
+                if (!relative.host) relative.host = '';
+                if (!relative.hostname) relative.hostname = '';
+                if (relPath[0] !== '') relPath.unshift('');
+                if (relPath.length < 2) relPath.unshift('');
+                result.pathname = relPath.join('/');
+            } else {
+                result.pathname = relative.pathname;
+            }
+            result.search = relative.search;
+            result.query = relative.query;
+            result.host = relative.host || '';
+            result.auth = relative.auth;
+            result.hostname = relative.hostname || relative.host;
+            result.port = relative.port;
+            // to support http.request
+            if (result.pathname || result.search) {
+                var p = result.pathname || '';
+                var s = result.search || '';
+                result.path = p + s;
+            }
+            result.slashes = result.slashes || relative.slashes;
+            result.href = result.format();
+            return result;
+        }
+
+        var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
+            isRelAbs = (
+            relative.host ||
+            relative.pathname && relative.pathname.charAt(0) === '/'
+            ),
+            mustEndAbs = (isRelAbs || isSourceAbs ||
+            (result.host && relative.pathname)),
+            removeAllDots = mustEndAbs,
+            srcPath = result.pathname && result.pathname.split('/') || [],
+            relPath = relative.pathname && relative.pathname.split('/') || [],
+            psychotic = result.protocol && !slashedProtocol[result.protocol];
+
+        // if the url is a non-slashed url, then relative
+        // links like ../.. should be able
+        // to crawl up to the hostname, as well.  This is strange.
+        // result.protocol has already been set by now.
+        // Later on, put the first path part into the host field.
+        if (psychotic) {
+            result.hostname = '';
+            result.port = null;
+            if (result.host) {
+                if (srcPath[0] === '') srcPath[0] = result.host;
+                else srcPath.unshift(result.host);
+            }
+            result.host = '';
+            if (relative.protocol) {
+                relative.hostname = null;
+                relative.port = null;
+                if (relative.host) {
+                    if (relPath[0] === '') relPath[0] = relative.host;
+                    else relPath.unshift(relative.host);
+                }
+                relative.host = null;
+            }
+            mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
+        }
+
+        if (isRelAbs) {
+            // it's absolute.
+            result.host = (relative.host || relative.host === '') ?
+                relative.host : result.host;
+            result.hostname = (relative.hostname || relative.hostname === '') ?
+                relative.hostname : result.hostname;
+            result.search = relative.search;
+            result.query = relative.query;
+            srcPath = relPath;
+            // fall through to the dot-handling below.
+        } else if (relPath.length) {
+            // it's relative
+            // throw away the existing file, and take the new path instead.
+            if (!srcPath) srcPath = [];
+            srcPath.pop();
+            srcPath = srcPath.concat(relPath);
+            result.search = relative.search;
+            result.query = relative.query;
+        } else if (!util.isNullOrUndefined(relative.search)) {
+            // just pull out the search.
+            // like href='?foo'.
+            // Put this after the other two cases because it simplifies the booleans
+            if (psychotic) {
+                result.hostname = result.host = srcPath.shift();
+                //occationaly the auth can get stuck only in host
+                //this especially happens in cases like
+                //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
+                var authInHost = result.host && result.host.indexOf('@') > 0 ?
+                    result.host.split('@') : false;
+                if (authInHost) {
+                    result.auth = authInHost.shift();
+                    result.host = result.hostname = authInHost.shift();
+                }
+            }
+            result.search = relative.search;
+            result.query = relative.query;
+            //to support http.request
+            if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
+                result.path = (result.pathname ? result.pathname : '') +
+                (result.search ? result.search : '');
+            }
+            result.href = result.format();
+            return result;
+        }
+
+        if (!srcPath.length) {
+            // no path at all.  easy.
+            // we've already handled the other stuff above.
+            result.pathname = null;
+            //to support http.request
+            if (result.search) {
+                result.path = '/' + result.search;
+            } else {
+                result.path = null;
+            }
+            result.href = result.format();
+            return result;
+        }
+
+        // if a url ENDs in . or .., then it must get a trailing slash.
+        // however, if it ends in anything else non-slashy,
+        // then it must NOT get a trailing slash.
+        var last = srcPath.slice(-1)[0];
+        var hasTrailingSlash = (
+        (result.host || relative.host || srcPath.length > 1) &&
+        (last === '.' || last === '..') || last === '');
+
+        // strip single dots, resolve double dots to parent dir
+        // if the path tries to go above the root, `up` ends up > 0
+        var up = 0;
+        for (var i = srcPath.length; i >= 0; i--) {
+            last = srcPath[i];
+            if (last === '.') {
+                srcPath.splice(i, 1);
+            } else if (last === '..') {
+                srcPath.splice(i, 1);
+                up++;
+            } else if (up) {
+                srcPath.splice(i, 1);
+                up--;
+            }
+        }
+
+        // if the path is allowed to go above the root, restore leading ..s
+        if (!mustEndAbs && !removeAllDots) {
+            for (; up--; up) {
+                srcPath.unshift('..');
+            }
+        }
+
+        if (mustEndAbs && srcPath[0] !== '' &&
+            (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
+            srcPath.unshift('');
+        }
+
+        if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
+            srcPath.push('');
+        }
+
+        var isAbsolute = srcPath[0] === '' ||
+            (srcPath[0] && srcPath[0].charAt(0) === '/');
+
+        // put the host back
+        if (psychotic) {
+            result.hostname = result.host = isAbsolute ? '' :
+                srcPath.length ? srcPath.shift() : '';
+            //occationaly the auth can get stuck only in host
+            //this especially happens in cases like
+            //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
+            var authInHost = result.host && result.host.indexOf('@') > 0 ?
+                result.host.split('@') : false;
+            if (authInHost) {
+                result.auth = authInHost.shift();
+                result.host = result.hostname = authInHost.shift();
+            }
+        }
+
+        mustEndAbs = mustEndAbs || (result.host && srcPath.length);
+
+        if (mustEndAbs && !isAbsolute) {
+            srcPath.unshift('');
+        }
+
+        if (!srcPath.length) {
+            result.pathname = null;
+            result.path = null;
+        } else {
+            result.pathname = srcPath.join('/');
+        }
+
+        //to support request.http
+        if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
+            result.path = (result.pathname ? result.pathname : '') +
+            (result.search ? result.search : '');
+        }
+        result.auth = relative.auth || result.auth;
+        result.slashes = result.slashes || relative.slashes;
+        result.href = result.format();
+        return result;
+    };
+
+    Url.prototype.parseHost = function() {
+        var host = this.host;
+        var port = portPattern.exec(host);
+        if (port) {
+            port = port[0];
+            if (port !== ':') {
+                this.port = port.substr(1);
+            }
+            host = host.substr(0, host.length - port.length);
+        }
+        if (host) this.hostname = host;
+    };
+
+},{"./util":29,"punycode":24,"querystring":27}],29:[function(require,module,exports){
+    'use strict';
+
+    module.exports = {
+        isString: function(arg) {
+            return typeof(arg) === 'string';
+        },
+        isObject: function(arg) {
+            return typeof(arg) === 'object' && arg !== null;
+        },
+        isNull: function(arg) {
+            return arg === null;
+        },
+        isNullOrUndefined: function(arg) {
+            return arg == null;
+        }
+    };
+
+},{}],30:[function(require,module,exports){
+    '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
+     * @api 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 {Mixed} context The context to invoke the listener with.
+     * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
+     * @constructor
+     * @api private
+     */
+    function EE(fn, context, once) {
+        this.fn = fn;
+        this.context = context;
+        this.once = once || false;
+    }
+
+    /**
+     * Minimal `EventEmitter` interface that is molded against the Node.js
+     * `EventEmitter` interface.
+     *
+     * @constructor
+     * @api 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}
+     * @api 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.
+     * @param {Boolean} exists Only check if there are listeners.
+     * @returns {Array|Boolean}
+     * @api public
+     */
+    EventEmitter.prototype.listeners = function listeners(event, exists) {
+        var evt = prefix ? prefix + event : event
+            , available = this._events[evt];
+
+        if (exists) return !!available;
+        if (!available) return [];
+        if (available.fn) return [available.fn];
+
+        for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {
+            ee[i] = available[i].fn;
+        }
+
+        return ee;
+    };
+
+    /**
+     * 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`.
+     * @api 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 {Mixed} [context=this] The context to invoke the listener with.
+     * @returns {EventEmitter} `this`.
+     * @api public
+     */
+    EventEmitter.prototype.on = function on(event, fn, context) {
+        var listener = new EE(fn, context || this)
+            , evt = prefix ? prefix + event : event;
+
+        if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;
+        else if (!this._events[evt].fn) this._events[evt].push(listener);
+        else this._events[evt] = [this._events[evt], listener];
+
+        return this;
+    };
+
+    /**
+     * Add a one-time listener for a given event.
+     *
+     * @param {String|Symbol} event The event name.
+     * @param {Function} fn The listener function.
+     * @param {Mixed} [context=this] The context to invoke the listener with.
+     * @returns {EventEmitter} `this`.
+     * @api public
+     */
+    EventEmitter.prototype.once = function once(event, fn, context) {
+        var listener = new EE(fn, context || this, true)
+            , evt = prefix ? prefix + event : event;
+
+        if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;
+        else if (!this._events[evt].fn) this._events[evt].push(listener);
+        else this._events[evt] = [this._events[evt], listener];
+
+        return this;
+    };
+
+    /**
+     * 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 {Mixed} context Only remove the listeners that have this context.
+     * @param {Boolean} once Only remove one-time listeners.
+     * @returns {EventEmitter} `this`.
+     * @api public
+     */
+    EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
+        var evt = prefix ? prefix + event : event;
+
+        if (!this._events[evt]) return this;
+        if (!fn) {
+            if (--this._eventsCount === 0) this._events = new Events();
+            else delete this._events[evt];
+            return this;
+        }
+
+        var listeners = this._events[evt];
+
+        if (listeners.fn) {
+            if (
+                listeners.fn === fn
+                && (!once || listeners.once)
+                && (!context || listeners.context === context)
+            ) {
+                if (--this._eventsCount === 0) this._events = new Events();
+                else delete this._events[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 if (--this._eventsCount === 0) this._events = new Events();
+            else delete this._events[evt];
+        }
+
+        return this;
+    };
+
+    /**
+     * Remove all listeners, or those of the specified event.
+     *
+     * @param {String|Symbol} [event] The event name.
+     * @returns {EventEmitter} `this`.
+     * @api public
+     */
+    EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
+        var evt;
+
+        if (event) {
+            evt = prefix ? prefix + event : event;
+            if (this._events[evt]) {
+                if (--this._eventsCount === 0) this._events = new Events();
+                else delete this._events[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;
+
+//
+// This function doesn't apply anymore.
+//
+    EventEmitter.prototype.setMaxListeners = function setMaxListeners() {
+        return this;
+    };
+
+//
+// Expose the prefix.
+//
+    EventEmitter.prefixed = prefix;
+
+//
+// Allow `EventEmitter` to be imported as module namespace.
+//
+    EventEmitter.EventEmitter = EventEmitter;
+
+//
+// Expose the module.
+//
+    if ('undefined' !== typeof module) {
+        module.exports = EventEmitter;
+    }
+
+},{}],31:[function(require,module,exports){
+    'use strict'
+
+    module.exports = function parseURI (str, opts) {
+        opts = opts || {}
+
+        var o = {
+            key: ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'],
+            q: {
+                name: 'queryKey',
+                parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+            },
+            parser: {
+                strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+                loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+            }
+        }
+
+        var m = o.parser[opts.strictMode ? 'strict' : 'loose'].exec(str)
+        var uri = {}
+        var i = 14
+
+        while (i--) uri[o.key[i]] = m[i] || ''
+
+        uri[o.q.name] = {}
+        uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+            if ($1) uri[o.q.name][$1] = $2
+        })
+
+        return uri
+    }
+
+},{}],32:[function(require,module,exports){
+    'use strict';
+
+    var parseUri        = require('parse-uri');
+    var async           = require('./async');
+    var Resource        = require('./Resource');
+    var EventEmitter    = require('eventemitter3');
+
+// some constants
+    var DEFAULT_CONCURRENCY = 10;
+    var MAX_PROGRESS = 100;
+
+    /**
+     * Manages the state and loading of multiple resources to load.
+     *
+     * @class
+     * @param {string} [baseUrl=''] - The base url for all resources loaded by this loader.
+     * @param {number} [concurrency=10] - The number of resources to load concurrently.
+     */
+    function Loader(baseUrl, concurrency) {
+        EventEmitter.call(this);
+
+        concurrency = concurrency || DEFAULT_CONCURRENCY;
+
+        /**
+         * The base url for all resources loaded by this loader.
+         *
+         * @member {string}
+         */
+        this.baseUrl = baseUrl || '';
+
+        /**
+         * The progress percent of the loader going through the queue.
+         *
+         * @member {number}
+         */
+        this.progress = 0;
+
+        /**
+         * Loading state of the loader, true if it is currently loading resources.
+         *
+         * @member {boolean}
+         */
+        this.loading = false;
+
+        /**
+         * The percentage of total progress that a single resource represents.
+         *
+         * @member {number}
+         */
+        this._progressChunk = 0;
+
+        /**
+         * The middleware to run before loading each resource.
+         *
+         * @member {function[]}
+         */
+        this._beforeMiddleware = [];
+
+        /**
+         * The middleware to run after loading each resource.
+         *
+         * @member {function[]}
+         */
+        this._afterMiddleware = [];
+
+        /**
+         * The `_loadResource` function bound with this object context.
+         *
+         * @private
+         * @member {function}
+         */
+        this._boundLoadResource = this._loadResource.bind(this);
+
+        /**
+         * The resource buffer that fills until `load` is called to start loading resources.
+         *
+         * @private
+         * @member {Resource[]}
+         */
+        this._buffer = [];
+
+        /**
+         * Used to track load completion.
+         *
+         * @private
+         * @member {number}
+         */
+        this._numToLoad = 0;
+
+        /**
+         * The resources waiting to be loaded.
+         *
+         * @private
+         * @member {Resource[]}
+         */
+        this._queue = async.queue(this._boundLoadResource, concurrency);
+
+        /**
+         * All the resources for this loader keyed by name.
+         *
+         * @member {object<string, Resource>}
+         */
+        this.resources = {};
+
+        /**
+         * Emitted once per loaded or errored resource.
+         *
+         * @event progress
+         * @memberof Loader#
+         */
+
+        /**
+         * Emitted once per errored resource.
+         *
+         * @event error
+         * @memberof Loader#
+         */
+
+        /**
+         * Emitted once per loaded resource.
+         *
+         * @event load
+         * @memberof Loader#
+         */
+
+        /**
+         * Emitted when the loader begins to process the queue.
+         *
+         * @event start
+         * @memberof Loader#
+         */
+
+        /**
+         * Emitted when the queued resources all load.
+         *
+         * @event complete
+         * @memberof Loader#
+         */
+    }
+
+    Loader.prototype = Object.create(EventEmitter.prototype);
+    Loader.prototype.constructor = Loader;
+    module.exports = Loader;
+
+    /**
+     * Adds a resource (or multiple resources) to the loader queue.
+     *
+     * This function can take a wide variety of different parameters. The only thing that is always
+     * required the url to load. All the following will work:
+     *
+     * ```js
+     * loader
+     *     // normal param syntax
+     *     .add('key', 'http://...', function () {})
+     *     .add('http://...', function () {})
+     *     .add('http://...')
+     *
+     *     // object syntax
+     *     .add({
+ *         name: 'key2',
+ *         url: 'http://...'
+ *     }, function () {})
+     *     .add({
+ *         url: 'http://...'
+ *     }, function () {})
+     *     .add({
+ *         name: 'key3',
+ *         url: 'http://...'
+ *         onComplete: function () {}
+ *     })
+     *     .add({
+ *         url: 'https://...',
+ *         onComplete: function () {},
+ *         crossOrigin: true
+ *     })
+     *
+     *     // you can also pass an array of objects or urls or both
+     *     .add([
+     *         { name: 'key4', url: 'http://...', onComplete: function () {} },
+     *         { url: 'http://...', onComplete: function () {} },
+     *         'http://...'
+     *     ])
+     *
+     *     // and you can use both params and options
+     *     .add('key', 'http://...', { crossOrigin: true }, function () {})
+     *     .add('http://...', { crossOrigin: true }, function () {});
+     * ```
+     *
+     * @alias enqueue
+     * @param {string} [name] - The name of the resource to load, if not passed the url is used.
+     * @param {string} [url] - The url for this resource, relative to the baseUrl of this loader.
+     * @param {object} [options] - The options for the load.
+     * @param {boolean} [options.crossOrigin] - Is this request cross-origin? Default is to determine automatically.
+     * @param {Resource.XHR_LOAD_TYPE} [options.loadType=Resource.LOAD_TYPE.XHR] - How should this resource be loaded?
+     * @param {Resource.XHR_RESPONSE_TYPE} [options.xhrType=Resource.XHR_RESPONSE_TYPE.DEFAULT] - How should the data being
+     *      loaded be interpreted when using XHR?
+     * @param {function} [cb] - Function to call when this specific resource completes loading.
+     * @return {Loader} Returns itself.
+     */
+    Loader.prototype.add = Loader.prototype.enqueue = function (name, url, options, cb) {
+        // special case of an array of objects or urls
+        if (Array.isArray(name)) {
+            for (var i = 0; i < name.length; ++i) {
+                this.add(name[i]);
+            }
+
+            return this;
+        }
+
+        // if an object is passed instead of params
+        if (typeof name === 'object') {
+            cb = url || name.callback || name.onComplete;
+            options = name;
+            url = name.url;
+            name = name.name || name.key || name.url;
+        }
+
+        // case where no name is passed shift all args over by one.
+        if (typeof url !== 'string') {
+            cb = options;
+            options = url;
+            url = name;
+        }
+
+        // now that we shifted make sure we have a proper url.
+        if (typeof url !== 'string') {
+            throw new Error('No url passed to add resource to loader.');
+        }
+
+        // options are optional so people might pass a function and no options
+        if (typeof options === 'function') {
+            cb = options;
+            options = null;
+        }
+
+        // check if resource already exists.
+        if (this.resources[name]) {
+            throw new Error('Resource with name "' + name + '" already exists.');
+        }
+
+        // add base url if this isn't an absolute url
+        url = this._prepareUrl(url);
+
+        // create the store the resource
+        this.resources[name] = new Resource(name, url, options);
+
+        if (typeof cb === 'function') {
+            this.resources[name].once('afterMiddleware', cb);
+        }
+
+        this._numToLoad++;
+
+        // if already loading add it to the worker queue
+        if (this._queue.started) {
+            this._queue.push(this.resources[name]);
+            this._progressChunk = (MAX_PROGRESS - this.progress) / (this._queue.length() + this._queue.running());
+        }
+        // otherwise buffer it to be added to the queue later
+        else {
+            this._buffer.push(this.resources[name]);
+            this._progressChunk = MAX_PROGRESS / this._buffer.length;
+        }
+
+        return this;
+    };
+
+    /**
+     * Sets up a middleware function that will run *before* the
+     * resource is loaded.
+     *
+     * @alias pre
+     * @method before
+     * @param {function} fn - The middleware function to register.
+     * @return {Loader} Returns itself.
+     */
+    Loader.prototype.before = Loader.prototype.pre = function (fn) {
+        this._beforeMiddleware.push(fn);
+
+        return this;
+    };
+
+    /**
+     * Sets up a middleware function that will run *after* the
+     * resource is loaded.
+     *
+     * @alias use
+     * @method after
+     * @param {function} fn - The middleware function to register.
+     * @return {Loader} Returns itself.
+     */
+    Loader.prototype.after = Loader.prototype.use = function (fn) {
+        this._afterMiddleware.push(fn);
+
+        return this;
+    };
+
+    /**
+     * Resets the queue of the loader to prepare for a new load.
+     *
+     * @return {Loader} Returns itself.
+     */
+    Loader.prototype.reset = function () {
+        // this.baseUrl = baseUrl || '';
+
+        this.progress = 0;
+
+        this.loading = false;
+
+        this._progressChunk = 0;
+
+        // this._beforeMiddleware.length = 0;
+        // this._afterMiddleware.length = 0;
+
+        this._buffer.length = 0;
+
+        this._numToLoad = 0;
+
+        this._queue.kill();
+        this._queue.started = false;
+
+        // abort all resource loads
+        for (var k in this.resources) {
+            var res = this.resources[k];
+
+            res.off('complete', this._onLoad, this);
+
+            if (res.isLoading) {
+                res.abort();
+            }
+        }
+
+        this.resources = {};
+
+        return this;
+    };
+
+    /**
+     * Starts loading the queued resources.
+     *
+     * @fires start
+     * @param {function} [cb] - Optional callback that will be bound to the `complete` event.
+     * @return {Loader} Returns itself.
+     */
+    Loader.prototype.load = function (cb) {
+        // register complete callback if they pass one
+        if (typeof cb === 'function') {
+            this.once('complete', cb);
+        }
+
+        // if the queue has already started we are done here
+        if (this._queue.started) {
+            return this;
+        }
+
+        // notify of start
+        this.emit('start', this);
+
+        // update loading state
+        this.loading = true;
+
+        // start the internal queue
+        for (var i = 0; i < this._buffer.length; ++i) {
+            this._queue.push(this._buffer[i]);
+        }
+
+        // empty the buffer
+        this._buffer.length = 0;
+
+        return this;
+    };
+
+    /**
+     * Prepares a url for usage based on the configuration of this object
+     *
+     * @private
+     * @param {string} url - The url to prepare.
+     * @return {string} The prepared url.
+     */
+    Loader.prototype._prepareUrl = function (url) {
+        var parsedUrl = parseUri(url, { strictMode: true });
+
+        // absolute url, just use it as is.
+        if (parsedUrl.protocol || !parsedUrl.path || parsedUrl.path.indexOf('//') === 0) {
+            return url;
+        }
+
+        // if baseUrl doesn't end in slash and url doesn't start with slash, then add a slash inbetween
+        if (this.baseUrl.length
+            && this.baseUrl.lastIndexOf('/') !== this.baseUrl.length - 1
+            && url.charAt(0) !== '/'
+        ) {
+            return this.baseUrl + '/' + url;
+        }
+
+        return this.baseUrl + url;
+    };
+
+    /**
+     * Loads a single resource.
+     *
+     * @private
+     * @param {Resource} resource - The resource to load.
+     * @param {function} dequeue - The function to call when we need to dequeue this item.
+     */
+    Loader.prototype._loadResource = function (resource, dequeue) {
+        var self = this;
+
+        resource._dequeue = dequeue;
+
+        // run before middleware
+        async.eachSeries(
+            this._beforeMiddleware,
+            function (fn, next) {
+                fn.call(self, resource, function () {
+                    // if the before middleware marks the resource as complete,
+                    // break and don't process any more before middleware
+                    next(resource.isComplete ? {} : null);
+                });
+            },
+            function () {
+                // resource.on('progress', self.emit.bind(self, 'progress'));
+
+                if (resource.isComplete) {
+                    self._onLoad(resource);
+                }
+                else {
+                    resource.once('complete', self._onLoad, self);
+                    resource.load();
+                }
+            }
+        );
+    };
+
+    /**
+     * Called once each resource has loaded.
+     *
+     * @fires complete
+     * @private
+     */
+    Loader.prototype._onComplete = function () {
+        this.loading = false;
+
+        this.emit('complete', this, this.resources);
+    };
+
+    /**
+     * Called each time a resources is loaded.
+     *
+     * @fires progress
+     * @fires error
+     * @fires load
+     * @private
+     * @param {Resource} resource - The resource that was loaded
+     */
+    Loader.prototype._onLoad = function (resource) {
+        var self = this;
+
+        // run middleware, this *must* happen before dequeue so sub-assets get added properly
+        async.eachSeries(
+            this._afterMiddleware,
+            function (fn, next) {
+                fn.call(self, resource, next);
+            },
+            function () {
+                resource.emit('afterMiddleware', resource);
+
+                self._numToLoad--;
+
+                self.progress += self._progressChunk;
+                self.emit('progress', self, resource);
+
+                if (resource.error) {
+                    self.emit('error', resource.error, self, resource);
+                }
+                else {
+                    self.emit('load', self, resource);
+                }
+
+                // do completion check
+                if (self._numToLoad === 0) {
+                    self.progress = 100;
+                    self._onComplete();
+                }
+            }
+        );
+
+        // remove this resource from the async queue
+        resource._dequeue();
+    };
+
+    Loader.LOAD_TYPE = Resource.LOAD_TYPE;
+    Loader.XHR_RESPONSE_TYPE = Resource.XHR_RESPONSE_TYPE;
+
+},{"./Resource":33,"./async":34,"eventemitter3":30,"parse-uri":31}],33:[function(require,module,exports){
+    'use strict';
+
+    var EventEmitter    = require('eventemitter3');
+    var parseUri        = require('parse-uri');
+
+// tests is CORS is supported in XHR, if not we need to use XDR
+    var useXdr = !!(window.XDomainRequest && !('withCredentials' in (new XMLHttpRequest())));
+    var tempAnchor = null;
+
+// some status constants
+    var STATUS_NONE = 0;
+    var STATUS_OK = 200;
+    var STATUS_EMPTY = 204;
+
+    /**
+     * Manages the state and loading of a single resource represented by
+     * a single URL.
+     *
+     * @class
+     * @param {string} name - The name of the resource to load.
+     * @param {string|string[]} url - The url for this resource, for audio/video loads you can pass an array of sources.
+     * @param {object} [options] - The options for the load.
+     * @param {string|boolean} [options.crossOrigin] - Is this request cross-origin? Default is to determine automatically.
+     * @param {Resource.LOAD_TYPE} [options.loadType=Resource.LOAD_TYPE.XHR] - How should this resource be loaded?
+     * @param {Resource.XHR_RESPONSE_TYPE} [options.xhrType=Resource.XHR_RESPONSE_TYPE.DEFAULT] - How should the data being
+     *      loaded be interpreted when using XHR?
+     * @param {object} [options.metadata] - Extra info for middleware.
+     */
+    function Resource(name, url, options) {
+        EventEmitter.call(this);
+
+        options = options || {};
+
+        if (typeof name !== 'string' || typeof url !== 'string') {
+            throw new Error('Both name and url are required for constructing a resource.');
+        }
+
+        /**
+         * The name of this resource.
+         *
+         * @member {string}
+         * @readonly
+         */
+        this.name = name;
+
+        /**
+         * The url used to load this resource.
+         *
+         * @member {string}
+         * @readonly
+         */
+        this.url = url;
+
+        /**
+         * Stores whether or not this url is a data url.
+         *
+         * @member {boolean}
+         * @readonly
+         */
+        this.isDataUrl = this.url.indexOf('data:') === 0;
+
+        /**
+         * The data that was loaded by the resource.
+         *
+         * @member {any}
+         */
+        this.data = null;
+
+        /**
+         * Is this request cross-origin? If unset, determined automatically.
+         *
+         * @member {string}
+         */
+        this.crossOrigin = options.crossOrigin === true ? 'anonymous' : options.crossOrigin;
+
+        /**
+         * The method of loading to use for this resource.
+         *
+         * @member {Resource.LOAD_TYPE}
+         */
+        this.loadType = options.loadType || this._determineLoadType();
+
+        /**
+         * The type used to load the resource via XHR. If unset, determined automatically.
+         *
+         * @member {string}
+         */
+        this.xhrType = options.xhrType;
+
+        /**
+         * Extra info for middleware, and controlling specifics about how the resource loads.
+         *
+         * Note that if you pass in a `loadElement`, the Resource class takes ownership of it.
+         * Meaning it will modify it as it sees fit.
+         *
+         * @member {object}
+         * @property {HTMLImageElement|HTMLAudioElement|HTMLVideoElement} [loadElement=null] - The
+         *  element to use for loading, instead of creating one.
+         * @property {boolean} [skipSource=false] - Skips adding source(s) to the load element. This
+         *  is useful if you want to pass in a `loadElement` that you already added load sources
+         *  to.
+         */
+        this.metadata = options.metadata || {};
+
+        /**
+         * The error that occurred while loading (if any).
+         *
+         * @member {Error}
+         * @readonly
+         */
+        this.error = null;
+
+        /**
+         * The XHR object that was used to load this resource. This is only set
+         * when `loadType` is `Resource.LOAD_TYPE.XHR`.
+         *
+         * @member {XMLHttpRequest}
+         */
+        this.xhr = null;
+
+        /**
+         * Describes if this resource was loaded as json. Only valid after the resource
+         * has completely loaded.
+         *
+         * @member {boolean}
+         */
+        this.isJson = false;
+
+        /**
+         * Describes if this resource was loaded as xml. Only valid after the resource
+         * has completely loaded.
+         *
+         * @member {boolean}
+         */
+        this.isXml = false;
+
+        /**
+         * Describes if this resource was loaded as an image tag. Only valid after the resource
+         * has completely loaded.
+         *
+         * @member {boolean}
+         */
+        this.isImage = false;
+
+        /**
+         * Describes if this resource was loaded as an audio tag. Only valid after the resource
+         * has completely loaded.
+         *
+         * @member {boolean}
+         */
+        this.isAudio = false;
+
+        /**
+         * Describes if this resource was loaded as a video tag. Only valid after the resource
+         * has completely loaded.
+         *
+         * @member {boolean}
+         */
+        this.isVideo = false;
+
+        /**
+         * Describes if this resource has finished loading. Is true when the resource has completely
+         * loaded.
+         *
+         * @member {boolean}
+         */
+        this.isComplete = false;
+
+        /**
+         * Describes if this resource is currently loading. Is true when the resource starts loading,
+         * and is false again when complete.
+         *
+         * @member {boolean}
+         */
+        this.isLoading = false;
+
+        /**
+         * The `dequeue` method that will be used a storage place for the async queue dequeue method
+         * used privately by the loader.
+         *
+         * @private
+         * @member {function}
+         */
+        this._dequeue = null;
+
+        /**
+         * The `complete` function bound to this resource's context.
+         *
+         * @private
+         * @member {function}
+         */
+        this._boundComplete = this.complete.bind(this);
+
+        /**
+         * The `_onError` function bound to this resource's context.
+         *
+         * @private
+         * @member {function}
+         */
+        this._boundOnError = this._onError.bind(this);
+
+        /**
+         * The `_onProgress` function bound to this resource's context.
+         *
+         * @private
+         * @member {function}
+         */
+        this._boundOnProgress = this._onProgress.bind(this);
+
+        // xhr callbacks
+        this._boundXhrOnError = this._xhrOnError.bind(this);
+        this._boundXhrOnAbort = this._xhrOnAbort.bind(this);
+        this._boundXhrOnLoad = this._xhrOnLoad.bind(this);
+        this._boundXdrOnTimeout = this._xdrOnTimeout.bind(this);
+
+        /**
+         * Emitted when the resource beings to load.
+         *
+         * @event start
+         * @memberof Resource#
+         */
+
+        /**
+         * Emitted each time progress of this resource load updates.
+         * Not all resources types and loader systems can support this event
+         * so sometimes it may not be available. If the resource
+         * is being loaded on a modern browser, using XHR, and the remote server
+         * properly sets Content-Length headers, then this will be available.
+         *
+         * @event progress
+         * @memberof Resource#
+         */
+
+        /**
+         * Emitted once this resource has loaded, if there was an error it will
+         * be in the `error` property.
+         *
+         * @event complete
+         * @memberof Resource#
+         */
+    }
+
+    Resource.prototype = Object.create(EventEmitter.prototype);
+    Resource.prototype.constructor = Resource;
+    module.exports = Resource;
+
+    /**
+     * Marks the resource as complete.
+     *
+     * @fires complete
+     */
+    Resource.prototype.complete = function () {
+        // TODO: Clean this up in a wrapper or something...gross....
+        if (this.data && this.data.removeEventListener) {
+            this.data.removeEventListener('error', this._boundOnError, false);
+            this.data.removeEventListener('load', this._boundComplete, false);
+            this.data.removeEventListener('progress', this._boundOnProgress, false);
+            this.data.removeEventListener('canplaythrough', this._boundComplete, false);
+        }
+
+        if (this.xhr) {
+            if (this.xhr.removeEventListener) {
+                this.xhr.removeEventListener('error', this._boundXhrOnError, false);
+                this.xhr.removeEventListener('abort', this._boundXhrOnAbort, false);
+                this.xhr.removeEventListener('progress', this._boundOnProgress, false);
+                this.xhr.removeEventListener('load', this._boundXhrOnLoad, false);
+            }
+            else {
+                this.xhr.onerror = null;
+                this.xhr.ontimeout = null;
+                this.xhr.onprogress = null;
+                this.xhr.onload = null;
+            }
+        }
+
+        if (this.isComplete) {
+            throw new Error('Complete called again for an already completed resource.');
+        }
+
+        this.isComplete = true;
+        this.isLoading = false;
+
+        this.emit('complete', this);
+    };
+
+    /**
+     * Aborts the loading of this resource, with an optional message.
+     *
+     * @param {string} message - The message to use for the error
+     */
+    Resource.prototype.abort = function (message) {
+        // abort can be called multiple times, ignore subsequent calls.
+        if (this.error) {
+            return;
+        }
+
+        // store error
+        this.error = new Error(message);
+
+        // abort the actual loading
+        if (this.xhr) {
+            this.xhr.abort();
+        }
+        else if (this.xdr) {
+            this.xdr.abort();
+        }
+        else if (this.data) {
+            // single source
+            if (typeof this.data.src !== 'undefined') {
+                this.data.src = '';
+            }
+            // multi-source
+            else {
+                while (this.data.firstChild) {
+                    this.data.removeChild(this.data.firstChild);
+                }
+            }
+        }
+
+        // done now.
+        this.complete();
+    };
+
+    /**
+     * Kicks off loading of this resource. This method is asynchronous.
+     *
+     * @fires start
+     * @param {function} [cb] - Optional callback to call once the resource is loaded.
+     */
+    Resource.prototype.load = function (cb) {
+        if (this.isLoading) {
+            return;
+        }
+
+        if (this.isComplete) {
+            if (cb) {
+                var self = this;
+
+                setTimeout(function () {
+                    cb(self);
+                }, 1);
+            }
+
+            return;
+        }
+        else if (cb) {
+            this.once('complete', cb);
+        }
+
+        this.isLoading = true;
+
+        this.emit('start', this);
+
+        // if unset, determine the value
+        if (this.crossOrigin === false || typeof this.crossOrigin !== 'string') {
+            this.crossOrigin = this._determineCrossOrigin(this.url);
+        }
+
+        switch (this.loadType) {
+            case Resource.LOAD_TYPE.IMAGE:
+                this._loadElement('image');
+                break;
+
+            case Resource.LOAD_TYPE.AUDIO:
+                this._loadSourceElement('audio');
+                break;
+
+            case Resource.LOAD_TYPE.VIDEO:
+                this._loadSourceElement('video');
+                break;
+
+            case Resource.LOAD_TYPE.XHR:
+            /* falls through */
+            default:
+                if (useXdr && this.crossOrigin) {
+                    this._loadXdr();
+                }
+                else {
+                    this._loadXhr();
+                }
+                break;
+        }
+    };
+
+    /**
+     * Loads this resources using an element that has a single source,
+     * like an HTMLImageElement.
+     *
+     * @private
+     * @param {string} type - The type of element to use.
+     */
+    Resource.prototype._loadElement = function (type) {
+        if (this.metadata.loadElement) {
+            this.data = this.metadata.loadElement;
+        }
+        else if (type === 'image' && typeof window.Image !== 'undefined') {
+            this.data = new Image();
+        }
+        else {
+            this.data = document.createElement(type);
+        }
+
+        if (this.crossOrigin) {
+            this.data.crossOrigin = this.crossOrigin;
+        }
+
+        if (!this.metadata.skipSource) {
+            this.data.src = this.url;
+        }
+
+        var typeName = 'is' + type[0].toUpperCase() + type.substring(1);
+
+        if (this[typeName] === false) {
+            this[typeName] = true;
+        }
+
+        this.data.addEventListener('error', this._boundOnError, false);
+        this.data.addEventListener('load', this._boundComplete, false);
+        this.data.addEventListener('progress', this._boundOnProgress, false);
+    };
+
+    /**
+     * Loads this resources using an element that has multiple sources,
+     * like an HTMLAudioElement or HTMLVideoElement.
+     *
+     * @private
+     * @param {string} type - The type of element to use.
+     */
+    Resource.prototype._loadSourceElement = function (type) {
+        if (this.metadata.loadElement) {
+            this.data = this.metadata.loadElement;
+        }
+        else if (type === 'audio' && typeof window.Audio !== 'undefined') {
+            this.data = new Audio();
+        }
+        else {
+            this.data = document.createElement(type);
+        }
+
+        if (this.data === null) {
+            this.abort('Unsupported element ' + type);
+
+            return;
+        }
+
+        if (!this.metadata.skipSource) {
+            // support for CocoonJS Canvas+ runtime, lacks document.createElement('source')
+            if (navigator.isCocoonJS) {
+                this.data.src = Array.isArray(this.url) ? this.url[0] : this.url;
+            }
+            else if (Array.isArray(this.url)) {
+                for (var i = 0; i < this.url.length; ++i) {
+                    this.data.appendChild(this._createSource(type, this.url[i]));
+                }
+            }
+            else {
+                this.data.appendChild(this._createSource(type, this.url));
+            }
+        }
+
+        this['is' + type[0].toUpperCase() + type.substring(1)] = true;
+
+        this.data.addEventListener('error', this._boundOnError, false);
+        this.data.addEventListener('load', this._boundComplete, false);
+        this.data.addEventListener('progress', this._boundOnProgress, false);
+        this.data.addEventListener('canplaythrough', this._boundComplete, false);
+
+        this.data.load();
+    };
+
+    /**
+     * Loads this resources using an XMLHttpRequest.
+     *
+     * @private
+     */
+    Resource.prototype._loadXhr = function () {
+        // if unset, determine the value
+        if (typeof this.xhrType !== 'string') {
+            this.xhrType = this._determineXhrType();
+        }
+
+        var xhr = this.xhr = new XMLHttpRequest();
+
+        // set the request type and url
+        xhr.open('GET', this.url, true);
+
+        // load json as text and parse it ourselves. We do this because some browsers
+        // *cough* safari *cough* can't deal with it.
+        if (this.xhrType === Resource.XHR_RESPONSE_TYPE.JSON || this.xhrType === Resource.XHR_RESPONSE_TYPE.DOCUMENT) {
+            xhr.responseType = Resource.XHR_RESPONSE_TYPE.TEXT;
+        }
+        else {
+            xhr.responseType = this.xhrType;
+        }
+
+        xhr.addEventListener('error', this._boundXhrOnError, false);
+        xhr.addEventListener('abort', this._boundXhrOnAbort, false);
+        xhr.addEventListener('progress', this._boundOnProgress, false);
+        xhr.addEventListener('load', this._boundXhrOnLoad, false);
+
+        xhr.send();
+    };
+
+    /**
+     * Loads this resources using an XDomainRequest. This is here because we need to support IE9 (gross).
+     *
+     * @private
+     */
+    Resource.prototype._loadXdr = function () {
+        // if unset, determine the value
+        if (typeof this.xhrType !== 'string') {
+            this.xhrType = this._determineXhrType();
+        }
+
+        var xdr = this.xhr = new XDomainRequest();
+
+        // XDomainRequest has a few quirks. Occasionally it will abort requests
+        // A way to avoid this is to make sure ALL callbacks are set even if not used
+        // More info here: http://stackoverflow.com/questions/15786966/xdomainrequest-aborts-post-on-ie-9
+        xdr.timeout = 5000;
+
+        xdr.onerror = this._boundXhrOnError;
+        xdr.ontimeout = this._boundXdrOnTimeout;
+        xdr.onprogress = this._boundOnProgress;
+        xdr.onload = this._boundXhrOnLoad;
+
+        xdr.open('GET', this.url, true);
+
+        // Note: The xdr.send() call is wrapped in a timeout to prevent an
+        // issue with the interface where some requests are lost if multiple
+        // XDomainRequests are being sent at the same time.
+        // Some info here: https://github.com/photonstorm/phaser/issues/1248
+        setTimeout(function () {
+            xdr.send();
+        }, 0);
+    };
+
+    /**
+     * Creates a source used in loading via an element.
+     *
+     * @private
+     * @param {string} type - The element type (video or audio).
+     * @param {string} url - The source URL to load from.
+     * @param {string} [mime] - The mime type of the video
+     * @return {HTMLSourceElement} The source element.
+     */
+    Resource.prototype._createSource = function (type, url, mime) {
+        if (!mime) {
+            mime = type + '/' + url.substr(url.lastIndexOf('.') + 1);
+        }
+
+        var source = document.createElement('source');
+
+        source.src = url;
+        source.type = mime;
+
+        return source;
+    };
+
+    /**
+     * Called if a load errors out.
+     *
+     * @param {Event} event - The error event from the element that emits it.
+     * @private
+     */
+    Resource.prototype._onError = function (event) {
+        this.abort('Failed to load element using ' + event.target.nodeName);
+    };
+
+    /**
+     * Called if a load progress event fires for xhr/xdr.
+     *
+     * @fires progress
+     * @private
+     * @param {XMLHttpRequestProgressEvent|Event} event - Progress event.
+     */
+    Resource.prototype._onProgress = function (event) {
+        if (event && event.lengthComputable) {
+            this.emit('progress', this, event.loaded / event.total);
+        }
+    };
+
+    /**
+     * Called if an error event fires for xhr/xdr.
+     *
+     * @private
+     * @param {XMLHttpRequestErrorEvent|Event} event - Error event.
+     */
+    Resource.prototype._xhrOnError = function () {
+        var xhr = this.xhr;
+
+        this.abort(reqType(xhr) + ' Request failed. Status: ' + xhr.status + ', text: "' + xhr.statusText + '"');
+    };
+
+    /**
+     * Called if an abort event fires for xhr.
+     *
+     * @private
+     * @param {XMLHttpRequestAbortEvent} event - Abort Event
+     */
+    Resource.prototype._xhrOnAbort = function () {
+        this.abort(reqType(this.xhr) + ' Request was aborted by the user.');
+    };
+
+    /**
+     * Called if a timeout event fires for xdr.
+     *
+     * @private
+     * @param {Event} event - Timeout event.
+     */
+    Resource.prototype._xdrOnTimeout = function () {
+        this.abort(reqType(this.xhr) + ' Request timed out.');
+    };
+
+    /**
+     * Called when data successfully loads from an xhr/xdr request.
+     *
+     * @private
+     * @param {XMLHttpRequestLoadEvent|Event} event - Load event
+     */
+    Resource.prototype._xhrOnLoad = function () {
+        var xhr = this.xhr;
+        var status = typeof xhr.status === 'undefined' ? xhr.status : STATUS_OK; // XDR has no `.status`, assume 200.
+
+        // status can be 0 when using the file:// protocol, also check if a response was found
+        if (status === STATUS_OK || status === STATUS_EMPTY || (status === STATUS_NONE && xhr.responseText.length > 0)) {
+            // if text, just return it
+            if (this.xhrType === Resource.XHR_RESPONSE_TYPE.TEXT) {
+                this.data = xhr.responseText;
+            }
+            // if json, parse into json object
+            else if (this.xhrType === Resource.XHR_RESPONSE_TYPE.JSON) {
+                try {
+                    this.data = JSON.parse(xhr.responseText);
+                    this.isJson = true;
+                }
+                catch (e) {
+                    this.abort('Error trying to parse loaded json:', e);
+
+                    return;
+                }
+            }
+            // if xml, parse into an xml document or div element
+            else if (this.xhrType === Resource.XHR_RESPONSE_TYPE.DOCUMENT) {
+                try {
+                    if (window.DOMParser) {
+                        var domparser = new DOMParser();
+
+                        this.data = domparser.parseFromString(xhr.responseText, 'text/xml');
+                    }
+                    else {
+                        var div = document.createElement('div');
+
+                        div.innerHTML = xhr.responseText;
+                        this.data = div;
+                    }
+                    this.isXml = true;
+                }
+                catch (e) {
+                    this.abort('Error trying to parse loaded xml:', e);
+
+                    return;
+                }
+            }
+            // other types just return the response
+            else {
+                this.data = xhr.response || xhr.responseText;
+            }
+        }
+        else {
+            this.abort('[' + xhr.status + ']' + xhr.statusText + ':' + xhr.responseURL);
+
+            return;
+        }
+
+        this.complete();
+    };
+
+    /**
+     * Sets the `crossOrigin` property for this resource based on if the url
+     * for this resource is cross-origin. If crossOrigin was manually set, this
+     * function does nothing.
+     *
+     * @private
+     * @param {string} url - The url to test.
+     * @param {object} [loc=window.location] - The location object to test against.
+     * @return {string} The crossOrigin value to use (or empty string for none).
+     */
+    Resource.prototype._determineCrossOrigin = function (url, loc) {
+        // data: and javascript: urls are considered same-origin
+        if (url.indexOf('data:') === 0) {
+            return '';
+        }
+
+        // default is window.location
+        loc = loc || window.location;
+
+        if (!tempAnchor) {
+            tempAnchor = document.createElement('a');
+        }
+
+        // let the browser determine the full href for the url of this resource and then
+        // parse with the node url lib, we can't use the properties of the anchor element
+        // because they don't work in IE9 :(
+        tempAnchor.href = url;
+        url = parseUri(tempAnchor.href, { strictMode: true });
+
+        var samePort = (!url.port && loc.port === '') || (url.port === loc.port);
+        var protocol = url.protocol ? url.protocol + ':' : '';
+
+        // if cross origin
+        if (url.host !== loc.hostname || !samePort || protocol !== loc.protocol) {
+            return 'anonymous';
+        }
+
+        return '';
+    };
+
+    /**
+     * Determines the responseType of an XHR request based on the extension of the
+     * resource being loaded.
+     *
+     * @private
+     * @return {Resource.XHR_RESPONSE_TYPE} The responseType to use.
+     */
+    Resource.prototype._determineXhrType = function () {
+        return Resource._xhrTypeMap[this._getExtension()] || Resource.XHR_RESPONSE_TYPE.TEXT;
+    };
+
+    Resource.prototype._determineLoadType = function () {
+        return Resource._loadTypeMap[this._getExtension()] || Resource.LOAD_TYPE.XHR;
+    };
+
+    Resource.prototype._getExtension = function () {
+        var url = this.url;
+        var ext = '';
+
+        if (this.isDataUrl) {
+            var slashIndex = url.indexOf('/');
+
+            ext = url.substring(slashIndex + 1, url.indexOf(';', slashIndex));
+        }
+        else {
+            var queryStart = url.indexOf('?');
+
+            if (queryStart !== -1) {
+                url = url.substring(0, queryStart);
+            }
+
+            ext = url.substring(url.lastIndexOf('.') + 1);
+        }
+
+        return ext.toLowerCase();
+    };
+
+    /**
+     * Determines the mime type of an XHR request based on the responseType of
+     * resource being loaded.
+     *
+     * @private
+     * @param {Resource.XHR_RESPONSE_TYPE} type - The type to get a mime type for.
+     * @return {string} The mime type to use.
+     */
+    Resource.prototype._getMimeFromXhrType = function (type) {
+        switch (type) {
+            case Resource.XHR_RESPONSE_TYPE.BUFFER:
+                return 'application/octet-binary';
+
+            case Resource.XHR_RESPONSE_TYPE.BLOB:
+                return 'application/blob';
+
+            case Resource.XHR_RESPONSE_TYPE.DOCUMENT:
+                return 'application/xml';
+
+            case Resource.XHR_RESPONSE_TYPE.JSON:
+                return 'application/json';
+
+            case Resource.XHR_RESPONSE_TYPE.DEFAULT:
+            case Resource.XHR_RESPONSE_TYPE.TEXT:
+            /* falls through */
+            default:
+                return 'text/plain';
+
+        }
+    };
+
+    /**
+     * Quick helper to get string xhr type.
+     *
+     * @ignore
+     * @param {XMLHttpRequest|XDomainRequest} xhr - The request to check.
+     * @return {string} The type.
+     */
+    function reqType(xhr) {
+        return xhr.toString().replace('object ', '');
+    }
+
+    /**
+     * The types of loading a resource can use.
+     *
+     * @static
+     * @readonly
+     * @enum {number}
+     */
+    Resource.LOAD_TYPE = {
+        /** Uses XMLHttpRequest to load the resource. */
+        XHR:    1,
+        /** Uses an `Image` object to load the resource. */
+        IMAGE:  2,
+        /** Uses an `Audio` object to load the resource. */
+        AUDIO:  3,
+        /** Uses a `Video` object to load the resource. */
+        VIDEO:  4
+    };
+
+    /**
+     * The XHR ready states, used internally.
+     *
+     * @static
+     * @readonly
+     * @enum {string}
+     */
+    Resource.XHR_RESPONSE_TYPE = {
+        /** defaults to text */
+        DEFAULT:    'text',
+        /** ArrayBuffer */
+        BUFFER:     'arraybuffer',
+        /** Blob */
+        BLOB:       'blob',
+        /** Document */
+        DOCUMENT:   'document',
+        /** Object */
+        JSON:       'json',
+        /** String */
+        TEXT:       'text'
+    };
+
+    Resource._loadTypeMap = {
+        gif:      Resource.LOAD_TYPE.IMAGE,
+        png:      Resource.LOAD_TYPE.IMAGE,
+        bmp:      Resource.LOAD_TYPE.IMAGE,
+        jpg:      Resource.LOAD_TYPE.IMAGE,
+        jpeg:     Resource.LOAD_TYPE.IMAGE,
+        tif:      Resource.LOAD_TYPE.IMAGE,
+        tiff:     Resource.LOAD_TYPE.IMAGE,
+        webp:     Resource.LOAD_TYPE.IMAGE,
+        tga:      Resource.LOAD_TYPE.IMAGE,
+        'svg+xml':  Resource.LOAD_TYPE.IMAGE
+    };
+
+    Resource._xhrTypeMap = {
+        // xml
+        xhtml:    Resource.XHR_RESPONSE_TYPE.DOCUMENT,
+        html:     Resource.XHR_RESPONSE_TYPE.DOCUMENT,
+        htm:      Resource.XHR_RESPONSE_TYPE.DOCUMENT,
+        xml:      Resource.XHR_RESPONSE_TYPE.DOCUMENT,
+        tmx:      Resource.XHR_RESPONSE_TYPE.DOCUMENT,
+        tsx:      Resource.XHR_RESPONSE_TYPE.DOCUMENT,
+        svg:      Resource.XHR_RESPONSE_TYPE.DOCUMENT,
+
+        // images
+        gif:      Resource.XHR_RESPONSE_TYPE.BLOB,
+        png:      Resource.XHR_RESPONSE_TYPE.BLOB,
+        bmp:      Resource.XHR_RESPONSE_TYPE.BLOB,
+        jpg:      Resource.XHR_RESPONSE_TYPE.BLOB,
+        jpeg:     Resource.XHR_RESPONSE_TYPE.BLOB,
+        tif:      Resource.XHR_RESPONSE_TYPE.BLOB,
+        tiff:     Resource.XHR_RESPONSE_TYPE.BLOB,
+        webp:     Resource.XHR_RESPONSE_TYPE.BLOB,
+        tga:      Resource.XHR_RESPONSE_TYPE.BLOB,
+
+        // json
+        json:     Resource.XHR_RESPONSE_TYPE.JSON,
+
+        // text
+        text:     Resource.XHR_RESPONSE_TYPE.TEXT,
+        txt:      Resource.XHR_RESPONSE_TYPE.TEXT
+    };
+
+    /**
+     * Sets the load type to be used for a specific extension.
+     *
+     * @static
+     * @param {string} extname - The extension to set the type for, e.g. "png" or "fnt"
+     * @param {Resource.LOAD_TYPE} loadType - The load type to set it to.
+     */
+    Resource.setExtensionLoadType = function (extname, loadType) {
+        setExtMap(Resource._loadTypeMap, extname, loadType);
+    };
+
+    /**
+     * Sets the load type to be used for a specific extension.
+     *
+     * @static
+     * @param {string} extname - The extension to set the type for, e.g. "png" or "fnt"
+     * @param {Resource.XHR_RESPONSE_TYPE} xhrType - The xhr type to set it to.
+     */
+    Resource.setExtensionXhrType = function (extname, xhrType) {
+        setExtMap(Resource._xhrTypeMap, extname, xhrType);
+    };
+
+    function setExtMap(map, extname, val) {
+        if (extname && extname.indexOf('.') === 0) {
+            extname = extname.substring(1);
+        }
+
+        if (!extname) {
+            return;
+        }
+
+        map[extname] = val;
+    }
+
+},{"eventemitter3":30,"parse-uri":31}],34:[function(require,module,exports){
+    'use strict';
+
+    /**
+     * Smaller version of the async library constructs.
+     *
+     */
+
+    module.exports = {
+        eachSeries: asyncEachSeries,
+        queue: asyncQueue
+    };
+
+    function _noop() { /* empty */ }
+
+    /**
+     * Iterates an array in series.
+     *
+     * @param {*[]} array - Array to iterate.
+     * @param {function} iterator - Function to call for each element.
+     * @param {function} callback - Function to call when done, or on error.
+     */
+    function asyncEachSeries(array, iterator, callback) {
+        var i = 0;
+        var len = array.length;
+
+        (function next(err) {
+            if (err || i === len) {
+                if (callback) {
+                    callback(err);
+                }
+
+                return;
+            }
+
+            iterator(array[i++], next);
+        })();
+    }
+
+    /**
+     * Ensures a function is only called once.
+     *
+     * @param {function} fn - The function to wrap.
+     * @return {function} The wrapping function.
+     */
+    function onlyOnce(fn) {
+        return function onceWrapper() {
+            if (fn === null) {
+                throw new Error('Callback was already called.');
+            }
+
+            var callFn = fn;
+
+            fn = null;
+            callFn.apply(this, arguments);
+        };
+    }
+
+    /**
+     * Async queue implementation,
+     *
+     * @param {function} worker - The worker function to call for each task.
+     * @param {number} concurrency - How many workers to run in parrallel.
+     * @return {*} The async queue object.
+     */
+    function asyncQueue(worker, concurrency) {
+        if (concurrency == null) { // eslint-disable-line no-eq-null,eqeqeq
+            concurrency = 1;
+        }
+        else if (concurrency === 0) {
+            throw new Error('Concurrency must not be zero');
+        }
+
+        var workers = 0;
+        var q = {
+            _tasks: [],
+            concurrency: concurrency,
+            saturated: _noop,
+            unsaturated: _noop,
+            buffer: concurrency / 4,
+            empty: _noop,
+            drain: _noop,
+            error: _noop,
+            started: false,
+            paused: false,
+            push: function (data, callback) {
+                _insert(data, false, callback);
+            },
+            kill: function () {
+                q.drain = _noop;
+                q._tasks = [];
+            },
+            unshift: function (data, callback) {
+                _insert(data, true, callback);
+            },
+            process: function () {
+                while (!q.paused && workers < q.concurrency && q._tasks.length) {
+                    var task = q._tasks.shift();
+
+                    if (q._tasks.length === 0) {
+                        q.empty();
+                    }
+
+                    workers += 1;
+
+                    if (workers === q.concurrency) {
+                        q.saturated();
+                    }
+
+                    worker(task.data, onlyOnce(_next(task)));
+                }
+            },
+            length: function () {
+                return q._tasks.length;
+            },
+            running: function () {
+                return workers;
+            },
+            idle: function () {
+                return q._tasks.length + workers === 0;
+            },
+            pause: function () {
+                if (q.paused === true) {
+                    return;
+                }
+
+                q.paused = true;
+            },
+            resume: function () {
+                if (q.paused === false) {
+                    return;
+                }
+
+                q.paused = false;
+
+                // Need to call q.process once per concurrent
+                // worker to preserve full concurrency after pause
+                for (var w = 1; w <= q.concurrency; w++) {
+                    q.process();
+                }
+            }
+        };
+
+        function _insert(data, insertAtFront, callback) {
+            if (callback != null && typeof callback !== 'function') { // eslint-disable-line no-eq-null,eqeqeq
+                throw new Error('task callback must be a function');
+            }
+
+            q.started = true;
+
+            if (data == null && q.idle()) { // eslint-disable-line no-eq-null,eqeqeq
+                // call drain immediately if there are no tasks
+                setTimeout(function () {
+                    q.drain();
+                }, 1);
+
+                return;
+            }
+
+            var item = {
+                data: data,
+                callback: typeof callback === 'function' ? callback : _noop
+            };
+
+            if (insertAtFront) {
+                q._tasks.unshift(item);
+            }
+            else {
+                q._tasks.push(item);
+            }
+
+            setTimeout(function () {
+                q.process();
+            }, 1);
+        }
+
+        function _next(task) {
+            return function () {
+                workers -= 1;
+
+                task.callback.apply(task, arguments);
+
+                if (arguments[0] != null) { // eslint-disable-line no-eq-null,eqeqeq
+                    q.error(arguments[0], task.data);
+                }
+
+                if (workers <= (q.concurrency - q.buffer)) {
+                    q.unsaturated();
+                }
+
+                if (q.idle()) {
+                    q.drain();
+                }
+
+                q.process();
+            };
+        }
+
+        return q;
+    }
+
+},{}],35:[function(require,module,exports){
+    /* eslint no-magic-numbers: 0 */
+    'use strict';
+
+    module.exports = {
+        // private property
+        _keyStr: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
+
+        encodeBinary: function (input) {
+            var output = '';
+            var bytebuffer;
+            var encodedCharIndexes = new Array(4);
+            var inx = 0;
+            var jnx = 0;
+            var paddingBytes = 0;
+
+            while (inx < input.length) {
+                // Fill byte buffer array
+                bytebuffer = new Array(3);
+
+                for (jnx = 0; jnx < bytebuffer.length; jnx++) {
+                    if (inx < input.length) {
+                        // throw away high-order byte, as documented at:
+                        // https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data
+                        bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff;
+                    }
+                    else {
+                        bytebuffer[jnx] = 0;
+                    }
+                }
+
+                // Get each encoded character, 6 bits at a time
+                // index 1: first 6 bits
+                encodedCharIndexes[0] = bytebuffer[0] >> 2;
+                // index 2: second 6 bits (2 least significant bits from input byte 1 + 4 most significant bits from byte 2)
+                encodedCharIndexes[1] = ((bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4);
+                // index 3: third 6 bits (4 least significant bits from input byte 2 + 2 most significant bits from byte 3)
+                encodedCharIndexes[2] = ((bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6);
+                // index 3: forth 6 bits (6 least significant bits from input byte 3)
+                encodedCharIndexes[3] = bytebuffer[2] & 0x3f;
+
+                // Determine whether padding happened, and adjust accordingly
+                paddingBytes = inx - (input.length - 1);
+                switch (paddingBytes) {
+                    case 2:
+                        // Set last 2 characters to padding char
+                        encodedCharIndexes[3] = 64;
+                        encodedCharIndexes[2] = 64;
+                        break;
+
+                    case 1:
+                        // Set last character to padding char
+                        encodedCharIndexes[3] = 64;
+                        break;
+
+                    default:
+                        break; // No padding - proceed
+                }
+
+                // Now we will grab each appropriate character out of our keystring
+                // based on our index array and append it to the output string
+                for (jnx = 0; jnx < encodedCharIndexes.length; jnx++) {
+                    output += this._keyStr.charAt(encodedCharIndexes[jnx]);
+                }
+            }
+
+            return output;
+        }
+    };
+
+},{}],36:[function(require,module,exports){
+    /* eslint global-require: 0 */
+    'use strict';
+
+    module.exports = require('./Loader');
+    module.exports.Resource = require('./Resource');
+    module.exports.middleware = {
+        caching: {
+            memory: require('./middlewares/caching/memory')
+        },
+        parsing: {
+            blob: require('./middlewares/parsing/blob')
+        }
+    };
+
+    module.exports.async = require('./async');
+
+},{"./Loader":32,"./Resource":33,"./async":34,"./middlewares/caching/memory":37,"./middlewares/parsing/blob":38}],37:[function(require,module,exports){
+    'use strict';
+
+// a simple in-memory cache for resources
+    var cache = {};
+
+    module.exports = function () {
+        return function (resource, next) {
+            // if cached, then set data and complete the resource
+            if (cache[resource.url]) {
+                resource.data = cache[resource.url];
+                resource.complete(); // marks resource load complete and stops processing before middlewares
+            }
+            // if not cached, wait for complete and store it in the cache.
+            else {
+                resource.once('complete', function () {
+                    cache[this.url] = this.data;
+                });
+            }
+
+            next();
+        };
+    };
+
+},{}],38:[function(require,module,exports){
+    'use strict';
+
+    var Resource = require('../../Resource');
+    var b64 = require('../../b64');
+
+    var Url = window.URL || window.webkitURL;
+
+// a middleware for transforming XHR loaded Blobs into more useful objects
+
+    module.exports = function () {
+        return function (resource, next) {
+            if (!resource.data) {
+                next();
+
+                return;
+            }
+
+            // if this was an XHR load of a blob
+            if (resource.xhr && resource.xhrType === Resource.XHR_RESPONSE_TYPE.BLOB) {
+                // if there is no blob support we probably got a binary string back
+                if (!window.Blob || typeof resource.data === 'string') {
+                    var type = resource.xhr.getResponseHeader('content-type');
+
+                    // this is an image, convert the binary string into a data url
+                    if (type && type.indexOf('image') === 0) {
+                        resource.data = new Image();
+                        resource.data.src = 'data:' + type + ';base64,' + b64.encodeBinary(resource.xhr.responseText);
+
+                        resource.isImage = true;
+
+                        // wait until the image loads and then callback
+                        resource.data.onload = function () {
+                            resource.data.onload = null;
+
+                            next();
+                        };
+
+                        // next will be called on load
+                        return;
+                    }
+                }
+                // if content type says this is an image, then we should transform the blob into an Image object
+                else if (resource.data.type.indexOf('image') === 0) {
+                    var src = Url.createObjectURL(resource.data);
+
+                    resource.blob = resource.data;
+                    resource.data = new Image();
+                    resource.data.src = src;
+
+                    resource.isImage = true;
+
+                    // cleanup the no longer used blob after the image loads
+                    resource.data.onload = function () {
+                        Url.revokeObjectURL(src);
+                        resource.data.onload = null;
+
+                        next();
+                    };
+
+                    // next will be called on load.
+                    return;
+                }
+            }
+
+            next();
+        };
+    };
+
+},{"../../Resource":33,"../../b64":35}],39:[function(require,module,exports){
+    var core = require('../core');
+    var  Device = require('ismobilejs');
+
+// add some extra variables to the container..
+    Object.assign(
+        core.DisplayObject.prototype,
+        require('./accessibleTarget')
+    );
+
+
+    /**
+     * The Accessibility manager reacreates the ability to tab and and have content read by screen readers. This is very important as it can possibly help people with disabilities access pixi content.
+     * Much like interaction any DisplayObject can be made accessible. This manager will map the events as if the mouse was being used, minimizing the efferot required to implement.
+     *
+     * @class
+     * @memberof PIXI
+     * @param renderer {PIXI.CanvasRenderer|PIXI.WebGLRenderer} A reference to the current renderer
+     */
+    function AccessibilityManager(renderer)
+    {
+        if((Device.tablet || Device.phone) && !navigator.isCocoonJS)
+        {
+            this.createTouchHook();
+        }
+
+        // first we create a div that will sit over the pixi element. This is where the div overlays will go.
+        var div = document.createElement('div');
+
+        div.style.width = 100 + 'px';
+        div.style.height = 100 + 'px';
+        div.style.position = 'absolute';
+        div.style.top = 0;
+        div.style.left = 0;
+        //
+        div.style.zIndex = 2;
+
+        /**
+         * This is the dom element that will sit over the pixi element. This is where the div overlays will go.
+         *
+         * @type {HTMLElement}
+         * @private
+         */
+        this.div = div;
+
+        /**
+         * A simple pool for storing divs.
+         *
+         * @type {*}
+         * @private
+         */
+        this.pool = [];
+
+        /**
+         * This is a tick used to check if an object is no longer being rendered.
+         *
+         * @type {Number}
+         * @private
+         */
+        this.renderId = 0;
+
+        /**
+         * Setting this to true will visually show the divs
+         *
+         * @type {boolean}
+         */
+        this.debug = false;
+
+        /**
+         * The renderer this accessibility manager works for.
+         *
+         * @member {PIXI.SystemRenderer}
+         */
+        this.renderer = renderer;
+
+        /**
+         * The array of currently active accessible items.
+         *
+         * @member {Array<*>}
+         * @private
+         */
+        this.children = [];
+
+        /**
+         * pre-bind the functions
+         *
+         * @private
+         */
+        this._onKeyDown = this._onKeyDown.bind(this);
+        this._onMouseMove = this._onMouseMove.bind(this);
+
+        /**
+         * stores the state of the manager. If there are no accessible objects or the mouse is moving the will be false.
+         *
+         * @member {Array<*>}
+         * @private
+         */
+        this.isActive = false;
+        this.isMobileAccessabillity = false;
+
+        // let listen for tab.. once pressed we can fire up and show the accessibility layer
+        window.addEventListener('keydown', this._onKeyDown, false);
+    }
+
+
+    AccessibilityManager.prototype.constructor = AccessibilityManager;
+    module.exports = AccessibilityManager;
+
+    AccessibilityManager.prototype.createTouchHook = function()
+    {
+        var hookDiv = document.createElement('button');
+        hookDiv.style.width = 1 + 'px';
+        hookDiv.style.height = 1 + 'px';
+        hookDiv.style.position = 'absolute';
+        hookDiv.style.top = -1000+'px';
+        hookDiv.style.left = -1000+'px';
+        hookDiv.style.zIndex = 2;
+        hookDiv.style.backgroundColor = '#FF0000';
+        hookDiv.title = 'HOOK DIV';
+
+        hookDiv.addEventListener('focus', function(){
+
+            this.isMobileAccessabillity = true;
+            this.activate();
+            document.body.removeChild(hookDiv);
+
+        }.bind(this));
+
+        document.body.appendChild(hookDiv);
+
+    };
+
+    /**
+     * Activating will cause the Accessibility layer to be shown. This is called when a user preses the tab key
+     * @private
+     */
+    AccessibilityManager.prototype.activate = function()
+    {
+        if(this.isActive )
+        {
+            return;
+        }
+
+        this.isActive = true;
+
+        window.document.addEventListener('mousemove', this._onMouseMove, true);
+        window.removeEventListener('keydown', this._onKeyDown, false);
+
+        this.renderer.on('postrender', this.update, this);
+
+        if(this.renderer.view.parentNode)
+        {
+            this.renderer.view.parentNode.appendChild(this.div);
+        }
+    };
+
+    /**
+     * Deactivating will cause the Accessibility layer to be hidden. This is called when a user moves the mouse
+     * @private
+     */
+    AccessibilityManager.prototype.deactivate = function()
+    {
+
+        if(!this.isActive || this.isMobileAccessabillity)
+        {
+            return;
+        }
+
+        this.isActive = false;
+
+        window.document.removeEventListener('mousemove', this._onMouseMove);
+        window.addEventListener('keydown', this._onKeyDown, false);
+
+        this.renderer.off('postrender', this.update);
+
+        if(this.div.parentNode)
+        {
+            this.div.parentNode.removeChild(this.div);
+        }
+
+    };
+
+    /**
+     * This recursive function will run throught he scene graph and add any new accessible objects to the DOM layer.
+     * @param displayObject {PIXI.Container} the DisplayObject to check.
+     * @private
+     */
+    AccessibilityManager.prototype.updateAccessibleObjects = function(displayObject)
+    {
+        if(!displayObject.visible)
+        {
+            return;
+        }
+
+        if(displayObject.accessible && displayObject.interactive)
+        {
+            if(!displayObject._accessibleActive)
+            {
+                this.addChild(displayObject);
+            }
+
+            displayObject.renderId = this.renderId;
+        }
+
+        var children = displayObject.children;
+
+        for (var i = children.length - 1; i >= 0; i--) {
+
+            this.updateAccessibleObjects(children[i]);
+        }
+    };
+
+
+    /**
+     * Before each render this function will ensure that all divs are mapped correctly to their DisplayObjects
+     * @private
+     */
+    AccessibilityManager.prototype.update = function()
+    {
+        if(!this.renderer.renderingToScreen) {
+            return;
+        }
+
+        // update children...
+        this.updateAccessibleObjects(this.renderer._lastObjectRendered);
+
+        var rect = this.renderer.view.getBoundingClientRect();
+        var sx = rect.width  / this.renderer.width;
+        var sy = rect.height / this.renderer.height;
+
+        var div = this.div;
+
+        div.style.left = rect.left + 'px';
+        div.style.top = rect.top + 'px';
+        div.style.width = this.renderer.width + 'px';
+        div.style.height = this.renderer.height + 'px';
+
+        for (var i = 0; i < this.children.length; i++)
+        {
+
+            var child = this.children[i];
+
+            if(child.renderId !== this.renderId)
+            {
+                child._accessibleActive = false;
+
+                core.utils.removeItems(this.children, i, 1);
+                this.div.removeChild( child._accessibleDiv );
+                this.pool.push(child._accessibleDiv);
+                child._accessibleDiv = null;
+
+                i--;
+
+                if(this.children.length === 0)
+                {
+                    this.deactivate();
+                }
+            }
+            else
+            {
+                // map div to display..
+                div = child._accessibleDiv;
+                var hitArea = child.hitArea;
+                var wt = child.worldTransform;
+
+                if(child.hitArea)
+                {
+                    div.style.left = ((wt.tx + (hitArea.x * wt.a)) * sx) + 'px';
+                    div.style.top =  ((wt.ty + (hitArea.y * wt.d)) * sy) +  'px';
+
+                    div.style.width = (hitArea.width * wt.a * sx) + 'px';
+                    div.style.height = (hitArea.height * wt.d * sy) + 'px';
+
+                }
+                else
+                {
+                    hitArea = child.getBounds();
+
+                    this.capHitArea(hitArea);
+
+                    div.style.left = (hitArea.x * sx) + 'px';
+                    div.style.top =  (hitArea.y * sy) +  'px';
+
+                    div.style.width = (hitArea.width * sx) + 'px';
+                    div.style.height = (hitArea.height * sy) + 'px';
+                }
+            }
+        }
+
+        // increment the render id..
+        this.renderId++;
+    };
+
+    AccessibilityManager.prototype.capHitArea = function (hitArea)
+    {
+        if (hitArea.x < 0)
+        {
+            hitArea.width += hitArea.x;
+            hitArea.x = 0;
+        }
+
+        if (hitArea.y < 0)
+        {
+            hitArea.height += hitArea.y;
+            hitArea.y = 0;
+        }
+
+        if ( hitArea.x + hitArea.width > this.renderer.width )
+        {
+            hitArea.width = this.renderer.width - hitArea.x;
+        }
+
+        if ( hitArea.y + hitArea.height > this.renderer.height )
+        {
+            hitArea.height = this.renderer.height - hitArea.y;
+        }
+    };
+
+
+    /**
+     * Adds a DisplayObject to the accessibility manager
+     * @private
+     */
+    AccessibilityManager.prototype.addChild = function(displayObject)
+    {
+//	this.activate();
+
+        var div = this.pool.pop();
+
+        if(!div)
+        {
+            div = document.createElement('button');
+
+            div.style.width = 100 + 'px';
+            div.style.height = 100 + 'px';
+            div.style.backgroundColor = this.debug ? 'rgba(255,0,0,0.5)' : 'transparent';
+            div.style.position = 'absolute';
+            div.style.zIndex = 2;
+            div.style.borderStyle = 'none';
+
+
+            div.addEventListener('click', this._onClick.bind(this));
+            div.addEventListener('focus', this._onFocus.bind(this));
+            div.addEventListener('focusout', this._onFocusOut.bind(this));
+        }
+
+
+        if(displayObject.accessibleTitle)
+        {
+            div.title = displayObject.accessibleTitle;
+        }
+        else if (!displayObject.accessibleTitle && !displayObject.accessibleHint)
+        {
+            div.title = 'displayObject ' + this.tabIndex;
+        }
+
+        if(displayObject.accessibleHint)
+        {
+            div.setAttribute('aria-label', displayObject.accessibleHint);
+        }
+
+
+        //
+
+        displayObject._accessibleActive = true;
+        displayObject._accessibleDiv = div;
+        div.displayObject = displayObject;
+
+
+        this.children.push(displayObject);
+        this.div.appendChild( displayObject._accessibleDiv );
+        displayObject._accessibleDiv.tabIndex = displayObject.tabIndex;
+    };
+
+
+    /**
+     * Maps the div button press to pixi's InteractionManager (click)
+     * @private
+     */
+    AccessibilityManager.prototype._onClick = function(e)
+    {
+        var interactionManager = this.renderer.plugins.interaction;
+        interactionManager.dispatchEvent(e.target.displayObject, 'click', interactionManager.eventData);
+    };
+
+    /**
+     * Maps the div focus events to pixis InteractionManager (mouseover)
+     * @private
+     */
+    AccessibilityManager.prototype._onFocus = function(e)
+    {
+        var interactionManager = this.renderer.plugins.interaction;
+        interactionManager.dispatchEvent(e.target.displayObject, 'mouseover', interactionManager.eventData);
+    };
+
+    /**
+     * Maps the div focus events to pixis InteractionManager (mouseout)
+     * @private
+     */
+    AccessibilityManager.prototype._onFocusOut = function(e)
+    {
+        var interactionManager = this.renderer.plugins.interaction;
+        interactionManager.dispatchEvent(e.target.displayObject, 'mouseout', interactionManager.eventData);
+    };
+
+    /**
+     * Is called when a key is pressed
+     *
+     * @private
+     */
+    AccessibilityManager.prototype._onKeyDown = function(e)
+    {
+        if(e.keyCode !== 9)
+        {
+            return;
+        }
+
+        this.activate();
+    };
+
+    /**
+     * Is called when the mouse moves across the renderer element
+     *
+     * @private
+     */
+    AccessibilityManager.prototype._onMouseMove = function()
+    {
+        this.deactivate();
+    };
+
+
+    /**
+     * Destroys the accessibility manager
+     *
+     */
+    AccessibilityManager.prototype.destroy = function ()
+    {
+        this.div = null;
+
+        for (var i = 0; i < this.children.length; i++)
+        {
+            this.children[i].div = null;
+        }
+
+
+        window.document.removeEventListener('mousemove', this._onMouseMove);
+        window.removeEventListener('keydown', this._onKeyDown);
+
+        this.pool = null;
+        this.children = null;
+        this.renderer = null;
+
+    };
+
+    core.WebGLRenderer.registerPlugin('accessibility', AccessibilityManager);
+    core.CanvasRenderer.registerPlugin('accessibility', AccessibilityManager);
+
+},{"../core":62,"./accessibleTarget":40,"ismobilejs":4}],40:[function(require,module,exports){
+    /**
+     * Default property values of accessible objects
+     * used by {@link PIXI.accessibility.AccessibilityManager}.
+     *
+     * @mixin
+     * @memberof PIXI
+     * @example
+     *      function MyObject() {}
+     *
+     *      Object.assign(
+     *          MyObject.prototype,
+     *          PIXI.accessibility.accessibleTarget
+     *      );
+     */
+    var accessibleTarget = {
+
+        /**
+         *  Flag for if the object is accessible. If true AccessibilityManager will overlay a
+         *   shadow div with attributes set
+         *
+         * @member {boolean}
+         */
+        accessible:false,
+
+        /**
+         * Sets the title attribute of the shadow div
+         * If accessibleTitle AND accessibleHint has not been this will default to 'displayObject [tabIndex]'
+         *
+         * @member {string}
+         */
+        accessibleTitle:null,
+
+        /**
+         * Sets the aria-label attribute of the shadow div
+         *
+         * @member {string}
+         */
+        accessibleHint:null,
+
+        /**
+         * @todo Needs docs.
+         */
+        tabIndex:0,
+
+        /**
+         * @todo Needs docs.
+         */
+        _accessibleActive:false,
+
+        /**
+         * @todo Needs docs.
+         */
+        _accessibleDiv:false
+
+    };
+
+    module.exports = accessibleTarget;
+
+},{}],41:[function(require,module,exports){
+    /**
+     * @file        Main export of the PIXI accessibility library
+     * @author      Mat Groves <mat@goodboydigital.com>
+     * @copyright   2013-2015 GoodBoyDigital
+     * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}
+     */
+
+    /**
+     * @namespace PIXI.AccessibilityManager
+     */
+    module.exports = {
+        accessibleTarget:     require('./accessibleTarget'),
+        AccessibilityManager: require('./AccessibilityManager')
+    };
+
+},{"./AccessibilityManager":39,"./accessibleTarget":40}],42:[function(require,module,exports){
+    var GLShader = require('pixi-gl-core').GLShader;
+    var Const = require('./const');
+
+    function checkPrecision(src) {
+        if (src instanceof Array) {
+            if (src[0].substring(0,9) !== 'precision') {
+                var copy = src.slice(0);
+                copy.unshift('precision ' + Const.PRECISION.DEFAULT + ' float;');
+                return copy;
+            }
+        } else {
+            if (src.substring(0,9) !== 'precision') {
+                return 'precision ' + Const.PRECISION.DEFAULT + ' float;\n' + src;
+            }
+        }
+        return src;
+    }
+
+    /**
+     * Wrapper class, webGL Shader for Pixi.
+     * Adds precision string if vertexSrc or fragmentSrc have no mention of it.
+     *
+     * @class
+     * @memberof PIXI
+     * @param gl {WebGLRenderingContext} The current WebGL rendering context
+     * @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
+     * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.
+     * @param attributeLocations {Object} An attribute location map that lets you manually set the attribute locations.
+     */
+    var Shader = function(gl, vertexSrc, fragmentSrc, attributeLocations) {
+        GLShader.call(this, gl, checkPrecision(vertexSrc), checkPrecision(fragmentSrc), attributeLocations);
+    };
+
+    Shader.prototype = Object.create(GLShader.prototype);
+    Shader.prototype.constructor = Shader;
+    module.exports = Shader;
+
+},{"./const":43,"pixi-gl-core":12}],43:[function(require,module,exports){
+
+    /**
+     * Constant values used in pixi
+     *
+     * @lends PIXI
+     */
+    var CONST = {
+        /**
+         * String of the current PIXI version.
+         *
+         * @static
+         * @constant
+         * @type {string}
+         */
+        VERSION: '4.0.3',
+
+        /**
+         * Two Pi.
+         *
+         * @static
+         * @constant
+         * @type {number}
+         */
+        PI_2: Math.PI * 2,
+
+        /**
+         * Conversion factor for converting radians to degrees.
+         *
+         * @static
+         * @constant
+         * @type {number}
+         */
+        RAD_TO_DEG: 180 / Math.PI,
+
+        /**
+         * Conversion factor for converting degrees to radians.
+         *
+         * @static
+         * @constant
+         * @type {number}
+         */
+        DEG_TO_RAD: Math.PI / 180,
+
+        /**
+         * Target frames per millisecond.
+         *
+         * @static
+         * @constant
+         * @type {number}
+         * @default 0.06
+         */
+        TARGET_FPMS: 0.06,
+
+        /**
+         * Constant to identify the Renderer Type.
+         *
+         * @static
+         * @constant
+         * @type {object}
+         * @property {number} UNKNOWN - Unknown render type.
+         * @property {number} WEBGL - WebGL render type.
+         * @property {number} CANVAS - Canvas render type.
+         */
+        RENDERER_TYPE: {
+            UNKNOWN:    0,
+            WEBGL:      1,
+            CANVAS:     2
+        },
+
+        /**
+         * Various blend modes supported by PIXI.
+         *
+         * IMPORTANT - The WebGL renderer only supports the NORMAL, ADD, MULTIPLY and SCREEN blend modes.
+         * Anything else will silently act like NORMAL.
+         *
+         * @static
+         * @constant
+         * @type {object}
+         * @property {number} NORMAL
+         * @property {number} ADD
+         * @property {number} MULTIPLY
+         * @property {number} SCREEN
+         * @property {number} OVERLAY
+         * @property {number} DARKEN
+         * @property {number} LIGHTEN
+         * @property {number} COLOR_DODGE
+         * @property {number} COLOR_BURN
+         * @property {number} HARD_LIGHT
+         * @property {number} SOFT_LIGHT
+         * @property {number} DIFFERENCE
+         * @property {number} EXCLUSION
+         * @property {number} HUE
+         * @property {number} SATURATION
+         * @property {number} COLOR
+         * @property {number} LUMINOSITY
+         */
+        BLEND_MODES: {
+            NORMAL:         0,
+            ADD:            1,
+            MULTIPLY:       2,
+            SCREEN:         3,
+            OVERLAY:        4,
+            DARKEN:         5,
+            LIGHTEN:        6,
+            COLOR_DODGE:    7,
+            COLOR_BURN:     8,
+            HARD_LIGHT:     9,
+            SOFT_LIGHT:     10,
+            DIFFERENCE:     11,
+            EXCLUSION:      12,
+            HUE:            13,
+            SATURATION:     14,
+            COLOR:          15,
+            LUMINOSITY:     16
+        },
+
+        /**
+         * Various webgl draw modes. These can be used to specify which GL drawMode to use
+         * under certain situations and renderers.
+         *
+         * @static
+         * @constant
+         * @type {object}
+         * @property {number} POINTS
+         * @property {number} LINES
+         * @property {number} LINE_LOOP
+         * @property {number} LINE_STRIP
+         * @property {number} TRIANGLES
+         * @property {number} TRIANGLE_STRIP
+         * @property {number} TRIANGLE_FAN
+         */
+        DRAW_MODES: {
+            POINTS:         0,
+            LINES:          1,
+            LINE_LOOP:      2,
+            LINE_STRIP:     3,
+            TRIANGLES:      4,
+            TRIANGLE_STRIP: 5,
+            TRIANGLE_FAN:   6
+        },
+
+        /**
+         * The scale modes that are supported by pixi.
+         *
+         * The DEFAULT scale mode affects the default scaling mode of future operations.
+         * It can be re-assigned to either LINEAR or NEAREST, depending upon suitability.
+         *
+         * @static
+         * @constant
+         * @type {object}
+         * @property {number} DEFAULT=LINEAR
+         * @property {number} LINEAR Smooth scaling
+         * @property {number} NEAREST Pixelating scaling
+         */
+        SCALE_MODES: {
+            DEFAULT:    0,
+            LINEAR:     0,
+            NEAREST:    1
+        },
+
+        /**
+         * The wrap modes that are supported by pixi.
+         *
+         * The DEFAULT wrap mode affects the default wraping mode of future operations.
+         * It can be re-assigned to either CLAMP or REPEAT, depending upon suitability.
+         * If the texture is non power of two then clamp will be used regardless as webGL can only use REPEAT if the texture is po2.
+         * This property only affects WebGL.
+         *
+         * @static
+         * @constant
+         * @type {object}
+         * @property {number} DEFAULT=CLAMP
+         * @property {number} CLAMP - The textures uvs are clamped
+         * @property {number} REPEAT - The texture uvs tile and repeat
+         * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring
+         */
+        WRAP_MODES: {
+            DEFAULT:        0,
+            CLAMP:          0,
+            REPEAT:         1,
+            MIRRORED_REPEAT:2
+        },
+
+        /**
+         * The gc modes that are supported by pixi.
+         *
+         * The DEFAULT Garbage Collection mode for pixi textures is MANUAL
+         * If set to DEFAULT, the renderer will occasianally check textures usage. If they are not used for a specified period of time they will be removed from the GPU.
+         * They will of corse be uploaded again when they are required. This is a silent behind the scenes process that should ensure that the GPU does not  get filled up.
+         * Handy for mobile devices!
+         * This property only affects WebGL.
+         *
+         * @static
+         * @constant
+         * @type {object}
+         * @property {number} DEFAULT=MANUAL
+         * @property {number} AUTO - Garbage collection will happen periodically automatically
+         * @property {number} MANUAL - Garbage collection will need to be called manually
+         */
+        GC_MODES: {
+            DEFAULT:        0,
+            AUTO:           0,
+            MANUAL:         1,
+        },
+
+        /**
+         * If set to true WebGL will attempt make textures mimpaped by default.
+         * Mipmapping will only succeed if the base texture uploaded has power of two dimensions.
+         *
+         * @static
+         * @constant
+         * @type {boolean}
+         */
+        MIPMAP_TEXTURES: true,
+
+        /**
+         * The prefix that denotes a URL is for a retina asset.
+         *
+         * @static
+         * @constant
+         * @type {RegExp|string}
+         * @example `@2x`
+         */
+        RETINA_PREFIX: /@(.+)x/,
+
+        /**
+         * Default resolution / device pixel ratio of the renderer.
+         *
+         * @static
+         * @constant
+         * @type {number}
+         */
+        RESOLUTION: 1,
+
+        /**
+         * Default filter resolution.
+         *
+         * @static
+         * @constant
+         * @type {number}
+         */
+        FILTER_RESOLUTION:1,
+
+        /**
+         * The default render options if none are supplied to {@link PIXI.WebGLRenderer}
+         * or {@link PIXI.CanvasRenderer}.
+         *
+         * @static
+         * @constant
+         * @type {object}
+         * @property {HTMLCanvasElement} view=null
+         * @property {number} resolution=1
+         * @property {boolean} antialias=false
+         * @property {boolean} forceFXAA=false
+         * @property {boolean} autoResize=false
+         * @property {boolean} transparent=false
+         * @property {number} backgroundColor=0x000000
+         * @property {boolean} clearBeforeRender=true
+         * @property {boolean} preserveDrawingBuffer=false
+         * @property {boolean} roundPixels=false
+         */
+        DEFAULT_RENDER_OPTIONS: {
+            view: null,
+            resolution: 1,
+            antialias: false,
+            forceFXAA: false,
+            autoResize: false,
+            transparent: false,
+            backgroundColor: 0x000000,
+            clearBeforeRender: true,
+            preserveDrawingBuffer: false,
+            roundPixels: false
+        },
+
+        /**
+         * Constants that identify shapes, mainly to prevent `instanceof` calls.
+         *
+         * @static
+         * @constant
+         * @type {object}
+         * @property {number} POLY
+         * @property {number} RECT
+         * @property {number} CIRC
+         * @property {number} ELIP
+         * @property {number} RREC
+         */
+        SHAPES: {
+            POLY: 0,
+            RECT: 1,
+            CIRC: 2,
+            ELIP: 3,
+            RREC: 4
+        },
+
+        /**
+         * Constants that specify float precision in shaders.
+         *
+         * @static
+         * @constant
+         * @type {object}
+         * @property {number} DEFAULT='mediump'
+         * @property {number} LOW='lowp'
+         * @property {number} MEDIUM='mediump'
+         * @property {number} HIGH='highp'
+         */
+        PRECISION: {
+            DEFAULT: 'mediump',
+            LOW: 'lowp',
+            MEDIUM: 'mediump',
+            HIGH: 'highp'
+        },
+
+        /**
+         * Constants that specify the transform type.
+         *
+         * @static
+         * @constant
+         * @type {object}
+         * @property {number} DEFAULT=STATIC
+         * @property {number} STATIC
+         * @property {number} DYNAMIC
+         */
+        TRANSFORM_MODE:{
+            DEFAULT:    0,
+            STATIC:     0,
+            DYNAMIC:    1
+        },
+
+        /**
+         * Constants that define the type of gradient on text.
+         *
+         * @static
+         * @constant
+         * @type {object}
+         * @property {number} LINEAR_VERTICAL
+         * @property {number} LINEAR_HORIZONTAL
+         */
+        TEXT_GRADIENT: {
+            LINEAR_VERTICAL: 0,
+            LINEAR_HORIZONTAL: 1
+        },
+
+        // TODO: maybe change to SPRITE.BATCH_SIZE: 2000
+        // TODO: maybe add PARTICLE.BATCH_SIZE: 15000
+
+        /**
+         * The default sprite batch size.
+         *
+         * The default aims to balance desktop and mobile devices.
+         *
+         * @static
+         * @constant
+         * @type {number}
+         * @default 4096
+         */
+        SPRITE_BATCH_SIZE: 4096,
+
+        /**
+         * The maximum textures that this device supports.
+         *
+         * @static
+         * @constant
+         * @type {number}
+         */
+        SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32)
+    };
+
+    module.exports = CONST;
+
+},{"./utils/maxRecommendedTextures":117}],44:[function(require,module,exports){
+    var math = require('../math'),
+        Rectangle = math.Rectangle;
+
+    /**
+     * 'Builder' pattern for bounds rectangles
+     * Axis-Aligned Bounding Box
+     * It is not a shape! Its mutable thing, no 'EMPTY' or that kind of problems
+     *
+     * @class
+     * @memberof PIXI
+     */
+    function Bounds()
+    {
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.minX = Infinity;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.minY = Infinity;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.maxX = -Infinity;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.maxY = -Infinity;
+
+        this.rect = null;
+    }
+
+    Bounds.prototype.constructor = Bounds;
+    module.exports = Bounds;
+
+    Bounds.prototype.isEmpty = function()
+    {
+        return this.minX > this.maxX || this.minY > this.maxY;
+    };
+
+    Bounds.prototype.clear = function()
+    {
+        this.updateID++;
+
+        this.minX = Infinity;
+        this.minY = Infinity;
+        this.maxX = -Infinity;
+        this.maxY = -Infinity;
+    };
+
+    /**
+     * Can return Rectangle.EMPTY constant, either construct new rectangle, either use your rectangle
+     * It is not guaranteed that it will return tempRect
+     * @param tempRect {PIXI.Rectangle} temporary object will be used if AABB is not empty
+     * @returns {PIXI.Rectangle}
+     */
+    Bounds.prototype.getRectangle = function(rect)
+    {
+        if (this.minX > this.maxX || this.minY > this.maxY) {
+            return Rectangle.EMPTY;
+        }
+
+        rect = rect || new Rectangle(0, 0, 1, 1);
+
+        rect.x = this.minX;
+        rect.y = this.minY;
+        rect.width = this.maxX - this.minX;
+        rect.height = this.maxY - this.minY;
+
+        return rect;
+    };
+
+    /**
+     * This function should be inlined when its possible
+     * @param point {PIXI.Point}
+     */
+    Bounds.prototype.addPoint = function (point)
+    {
+        this.minX = Math.min(this.minX, point.x);
+        this.maxX = Math.max(this.maxX, point.x);
+        this.minY = Math.min(this.minY, point.y);
+        this.maxY = Math.max(this.maxY, point.y);
+    };
+
+    /**
+     * Adds a quad, not transformed
+     * @param vertices {Float32Array}
+     * @returns {PIXI.Bounds}
+     */
+    Bounds.prototype.addQuad = function(vertices)
+    {
+        var minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY;
+
+        var x = vertices[0];
+        var y = vertices[1];
+        minX = x < minX ? x : minX;
+        minY = y < minY ? y : minY;
+        maxX = x > maxX ? x : maxX;
+        maxY = y > maxY ? y : maxY;
+
+        x = vertices[2];
+        y = vertices[3];
+        minX = x < minX ? x : minX;
+        minY = y < minY ? y : minY;
+        maxX = x > maxX ? x : maxX;
+        maxY = y > maxY ? y : maxY;
+
+        x = vertices[4];
+        y = vertices[5];
+        minX = x < minX ? x : minX;
+        minY = y < minY ? y : minY;
+        maxX = x > maxX ? x : maxX;
+        maxY = y > maxY ? y : maxY;
+
+        x = vertices[6];
+        y = vertices[7];
+        minX = x < minX ? x : minX;
+        minY = y < minY ? y : minY;
+        maxX = x > maxX ? x : maxX;
+        maxY = y > maxY ? y : maxY;
+
+        this.minX = minX;
+        this.minY = minY;
+        this.maxX = maxX;
+        this.maxY = maxY;
+    };
+
+    /**
+     * Adds sprite frame, transformed
+     * @param transform {PIXI.TransformBase}
+     * @param x0 {number}
+     * @param y0 {number}
+     * @param x1 {number}
+     * @param y1 {number}
+     */
+    Bounds.prototype.addFrame = function(transform, x0, y0, x1, y1)
+    {
+        var matrix = transform.worldTransform;
+        var a = matrix.a, b = matrix.b, c = matrix.c, d = matrix.d, tx = matrix.tx, ty = matrix.ty;
+        var minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY;
+
+        var x = a * x0 + c * y0 + tx;
+        var y = b * x0 + d * y0 + ty;
+        minX = x < minX ? x : minX;
+        minY = y < minY ? y : minY;
+        maxX = x > maxX ? x : maxX;
+        maxY = y > maxY ? y : maxY;
+
+        x = a * x1 + c * y0 + tx;
+        y = b * x1 + d * y0 + ty;
+        minX = x < minX ? x : minX;
+        minY = y < minY ? y : minY;
+        maxX = x > maxX ? x : maxX;
+        maxY = y > maxY ? y : maxY;
+
+        x = a * x0 + c * y1 + tx;
+        y = b * x0 + d * y1 + ty;
+        minX = x < minX ? x : minX;
+        minY = y < minY ? y : minY;
+        maxX = x > maxX ? x : maxX;
+        maxY = y > maxY ? y : maxY;
+
+        x = a * x1 + c * y1 + tx;
+        y = b * x1 + d * y1 + ty;
+        minX = x < minX ? x : minX;
+        minY = y < minY ? y : minY;
+        maxX = x > maxX ? x : maxX;
+        maxY = y > maxY ? y : maxY;
+
+        this.minX = minX;
+        this.minY = minY;
+        this.maxX = maxX;
+        this.maxY = maxY;
+    };
+
+    /**
+     * add an array of vertices
+     * @param transform {PIXI.TransformBase}
+     * @param vertices {Float32Array}
+     * @param beginOffset {number}
+     * @param endOffset {number}
+     */
+    Bounds.prototype.addVertices = function(transform, vertices, beginOffset, endOffset)
+    {
+        var matrix = transform.worldTransform;
+        var a = matrix.a, b = matrix.b, c = matrix.c, d = matrix.d, tx = matrix.tx, ty = matrix.ty;
+        var minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY;
+
+        for (var i = beginOffset; i < endOffset; i += 2)
+        {
+            var rawX = vertices[i], rawY = vertices[i + 1];
+            var x = (a * rawX) + (c * rawY) + tx;
+            var y = (d * rawY) + (b * rawX) + ty;
+
+            minX = x < minX ? x : minX;
+            minY = y < minY ? y : minY;
+            maxX = x > maxX ? x : maxX;
+            maxY = y > maxY ? y : maxY;
+        }
+
+        this.minX = minX;
+        this.minY = minY;
+        this.maxX = maxX;
+        this.maxY = maxY;
+    };
+
+    Bounds.prototype.addBounds = function(bounds)
+    {
+        var minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY;
+
+        this.minX = bounds.minX < minX ? bounds.minX : minX;
+        this.minY = bounds.minY < minY ? bounds.minY : minY;
+        this.maxX = bounds.maxX > maxX ? bounds.maxX : maxX;
+        this.maxY = bounds.maxY > maxY ? bounds.maxY : maxY;
+    };
+
+},{"../math":67}],45:[function(require,module,exports){
+    var utils = require('../utils'),
+        DisplayObject = require('./DisplayObject');
+
+    /**
+     * A Container represents a collection of display objects.
+     * It is the base class of all display objects that act as a container for other objects.
+     *
+     *```js
+     * var container = new PIXI.Container();
+     * container.addChild(sprite);
+     * ```
+     * @class
+     * @extends PIXI.DisplayObject
+     * @memberof PIXI
+     */
+    function Container()
+    {
+        DisplayObject.call(this);
+
+        /**
+         * The array of children of this container.
+         *
+         * @member {PIXI.DisplayObject[]}
+         * @readonly
+         */
+        this.children = [];
+    }
+
+// constructor
+    Container.prototype = Object.create(DisplayObject.prototype);
+    Container.prototype.constructor = Container;
+    module.exports = Container;
+
+    Object.defineProperties(Container.prototype, {
+        /**
+         * The width of the Container, setting this will actually modify the scale to achieve the value set
+         *
+         * @member {number}
+         * @memberof PIXI.Container#
+         */
+        width: {
+            get: function ()
+            {
+                return this.scale.x * this.getLocalBounds().width;
+            },
+            set: function (value)
+            {
+
+                var width = this.getLocalBounds().width;
+
+                if (width !== 0)
+                {
+                    this.scale.x = value / width;
+                }
+                else
+                {
+                    this.scale.x = 1;
+                }
+
+
+                this._width = value;
+            }
+        },
+
+        /**
+         * The height of the Container, setting this will actually modify the scale to achieve the value set
+         *
+         * @member {number}
+         * @memberof PIXI.Container#
+         */
+        height: {
+            get: function ()
+            {
+                return  this.scale.y * this.getLocalBounds().height;
+            },
+            set: function (value)
+            {
+
+                var height = this.getLocalBounds().height;
+
+                if (height !== 0)
+                {
+                    this.scale.y = value / height ;
+                }
+                else
+                {
+                    this.scale.y = 1;
+                }
+
+                this._height = value;
+            }
+        }
+    });
+
+    /**
+     * Overridable method that can be used by Container subclasses whenever the children array is modified
+     *
+     * @private
+     */
+    Container.prototype.onChildrenChange = function () {};
+
+    /**
+     * Adds a child or multiple children to the container.
+     *
+     * Multple items can be added like so: `myContainer.addChild(thinkOne, thingTwo, thingThree)`
+     * @param child {...PIXI.DisplayObject} The DisplayObject(s) to add to the container
+     * @return {PIXI.DisplayObject} The first child that was added.
+     */
+    Container.prototype.addChild = function (child)
+    {
+        var argumentsLength = arguments.length;
+
+        // if there is only one argument we can bypass looping through the them
+        if(argumentsLength > 1)
+        {
+            // loop through the arguments property and add all children
+            // use it the right way (.length and [i]) so that this function can still be optimised by JS runtimes
+            for (var i = 0; i < argumentsLength; i++)
+            {
+                this.addChild( arguments[i] );
+            }
+        }
+        else
+        {
+            // if the child has a parent then lets remove it as Pixi objects can only exist in one place
+            if (child.parent)
+            {
+                child.parent.removeChild(child);
+            }
+
+            child.parent = this;
+
+            // ensure a transform will be recalculated..
+            this.transform._parentID = -1;
+
+            this.children.push(child);
+
+            // TODO - lets either do all callbacks or all events.. not both!
+            this.onChildrenChange(this.children.length-1);
+            child.emit('added', this);
+        }
+
+        return child;
+    };
+
+    /**
+     * Adds a child to the container at a specified index. If the index is out of bounds an error will be thrown
+     *
+     * @param child {PIXI.DisplayObject} The child to add
+     * @param index {number} The index to place the child in
+     * @return {PIXI.DisplayObject} The child that was added.
+     */
+    Container.prototype.addChildAt = function (child, index)
+    {
+        if (index >= 0 && index <= this.children.length)
+        {
+            if (child.parent)
+            {
+                child.parent.removeChild(child);
+            }
+
+            child.parent = this;
+
+            this.children.splice(index, 0, child);
+
+            // TODO - lets either do all callbacks or all events.. not both!
+            this.onChildrenChange(index);
+            child.emit('added', this);
+
+            return child;
+        }
+        else
+        {
+            throw new Error(child + 'addChildAt: The index '+ index +' supplied is out of bounds ' + this.children.length);
+        }
+    };
+
+    /**
+     * Swaps the position of 2 Display Objects within this container.
+     *
+     * @param child {PIXI.DisplayObject} First display object to swap
+     * @param child2 {PIXI.DisplayObject} Second display object to swap
+     */
+    Container.prototype.swapChildren = function (child, child2)
+    {
+        if (child === child2)
+        {
+            return;
+        }
+
+        var index1 = this.getChildIndex(child);
+        var index2 = this.getChildIndex(child2);
+
+        if (index1 < 0 || index2 < 0)
+        {
+            throw new Error('swapChildren: Both the supplied DisplayObjects must be children of the caller.');
+        }
+
+        this.children[index1] = child2;
+        this.children[index2] = child;
+        this.onChildrenChange(index1 < index2 ? index1 : index2);
+    };
+
+    /**
+     * Returns the index position of a child DisplayObject instance
+     *
+     * @param child {PIXI.DisplayObject} The DisplayObject instance to identify
+     * @return {number} The index position of the child display object to identify
+     */
+    Container.prototype.getChildIndex = function (child)
+    {
+        var index = this.children.indexOf(child);
+
+        if (index === -1)
+        {
+            throw new Error('The supplied DisplayObject must be a child of the caller');
+        }
+
+        return index;
+    };
+
+    /**
+     * Changes the position of an existing child in the display object container
+     *
+     * @param child {PIXI.DisplayObject} The child DisplayObject instance for which you want to change the index number
+     * @param index {number} The resulting index number for the child display object
+     */
+    Container.prototype.setChildIndex = function (child, index)
+    {
+        if (index < 0 || index >= this.children.length)
+        {
+            throw new Error('The supplied index is out of bounds');
+        }
+
+        var currentIndex = this.getChildIndex(child);
+
+        utils.removeItems(this.children, currentIndex, 1); // remove from old position
+        this.children.splice(index, 0, child); //add at new position
+        this.onChildrenChange(index);
+    };
+
+    /**
+     * Returns the child at the specified index
+     *
+     * @param index {number} The index to get the child at
+     * @return {PIXI.DisplayObject} The child at the given index, if any.
+     */
+    Container.prototype.getChildAt = function (index)
+    {
+        if (index < 0 || index >= this.children.length)
+        {
+            throw new Error('getChildAt: Supplied index ' + index + ' does not exist in the child list, or the supplied DisplayObject is not a child of the caller');
+        }
+
+        return this.children[index];
+    };
+
+    /**
+     * Removes a child from the container.
+     *
+     * @param child {PIXI.DisplayObject} The DisplayObject to remove
+     * @return {PIXI.DisplayObject} The child that was removed.
+     */
+    Container.prototype.removeChild = function (child)
+    {
+        var argumentsLength = arguments.length;
+
+        // if there is only one argument we can bypass looping through the them
+        if(argumentsLength > 1)
+        {
+            // loop through the arguments property and add all children
+            // use it the right way (.length and [i]) so that this function can still be optimised by JS runtimes
+            for (var i = 0; i < argumentsLength; i++)
+            {
+                this.removeChild( arguments[i] );
+            }
+        }
+        else
+        {
+            var index = this.children.indexOf(child);
+
+            if (index === -1)
+            {
+                return;
+            }
+
+            child.parent = null;
+            utils.removeItems(this.children, index, 1);
+
+            // TODO - lets either do all callbacks or all events.. not both!
+            this.onChildrenChange(index);
+            child.emit('removed', this);
+        }
+
+        return child;
+    };
+
+    /**
+     * Removes a child from the specified index position.
+     *
+     * @param index {number} The index to get the child from
+     * @return {PIXI.DisplayObject} The child that was removed.
+     */
+    Container.prototype.removeChildAt = function (index)
+    {
+        var child = this.getChildAt(index);
+
+        child.parent = null;
+        utils.removeItems(this.children, index, 1);
+
+        // TODO - lets either do all callbacks or all events.. not both!
+        this.onChildrenChange(index);
+        child.emit('removed', this);
+
+        return child;
+    };
+
+    /**
+     * Removes all children from this container that are within the begin and end indexes.
+     *
+     * @param [beginIndex=0] {number} The beginning position.
+     * @param [endIndex=this.children.length] {number} The ending position. Default value is size of the container.
+     */
+    Container.prototype.removeChildren = function (beginIndex, endIndex)
+    {
+        var begin = beginIndex || 0;
+        var end = typeof endIndex === 'number' ? endIndex : this.children.length;
+        var range = end - begin;
+        var removed, i;
+
+        if (range > 0 && range <= end)
+        {
+            removed = this.children.splice(begin, range);
+
+            for (i = 0; i < removed.length; ++i)
+            {
+                removed[i].parent = null;
+            }
+
+            this.onChildrenChange(beginIndex);
+
+            for (i = 0; i < removed.length; ++i)
+            {
+                removed[i].emit('removed', this);
+            }
+
+            return removed;
+        }
+        else if (range === 0 && this.children.length === 0)
+        {
+            return [];
+        }
+        else
+        {
+            throw new RangeError('removeChildren: numeric values are outside the acceptable range.');
+        }
+    };
+
+    /*
+     * Updates the transform on all children of this container for rendering
+     *
+     * @private
+     */
+    Container.prototype.updateTransform = function ()
+    {
+        this._boundsID++;
+
+        if (!this.visible)
+        {
+            return;
+        }
+
+        this.transform.updateTransform(this.parent.transform);
+
+        //TODO: check render flags, how to process stuff here
+        this.worldAlpha = this.alpha * this.parent.worldAlpha;
+
+        for (var i = 0, j = this.children.length; i < j; ++i)
+        {
+            this.children[i].updateTransform();
+        }
+    };
+
+// performance increase to avoid using call.. (10x faster)
+    Container.prototype.containerUpdateTransform = Container.prototype.updateTransform;
+
+
+    Container.prototype.calculateBounds = function ()
+    {
+        this._bounds.clear();
+
+        if(!this.visible)
+        {
+            return;
+        }
+
+        this._calculateBounds();
+
+        for (var i = 0; i < this.children.length; i++)
+        {
+            var child = this.children[i];
+
+            child.calculateBounds();
+
+            this._bounds.addBounds(child._bounds);
+        }
+
+        this._boundsID = this._lastBoundsID;
+    };
+
+    Container.prototype._calculateBounds = function ()
+    {
+        //FILL IN//
+    };
+
+    /**
+     * Renders the object using the WebGL renderer
+     *
+     * @param renderer {PIXI.WebGLRenderer} The renderer
+     */
+    Container.prototype.renderWebGL = function (renderer)
+    {
+
+        // if the object is not visible or the alpha is 0 then no need to render this element
+        if (!this.visible || this.worldAlpha <= 0 || !this.renderable)
+        {
+
+            return;
+        }
+
+
+        // do a quick check to see if this element has a mask or a filter.
+        if (this._mask || this._filters)
+        {
+            this.renderAdvancedWebGL(renderer);
+        }
+        else
+        {
+            this._renderWebGL(renderer);
+
+            // simple render children!
+            for (var i = 0, j = this.children.length; i < j; ++i)
+            {
+                this.children[i].renderWebGL(renderer);
+            }
+        }
+    };
+
+    Container.prototype.renderAdvancedWebGL = function (renderer)
+    {
+        renderer.currentRenderer.flush();
+
+        var filters = this._filters;
+        var mask = this._mask;
+        var i, j;
+
+        // push filter first as we need to ensure the stencil buffer is correct for any masking
+        if ( filters )
+        {
+            if(!this._enabledFilters)
+            {
+                this._enabledFilters = [];
+            }
+
+            this._enabledFilters.length = 0;
+
+            for (i = 0; i < filters.length; i++)
+            {
+                if(filters[i].enabled)
+                {
+                    this._enabledFilters.push( filters[i] );
+                }
+            }
+
+            if( this._enabledFilters.length )
+            {
+                renderer.filterManager.pushFilter(this, this._enabledFilters);
+            }
+        }
+
+        if ( mask )
+        {
+            renderer.maskManager.pushMask(this, this._mask);
+        }
+
+        renderer.currentRenderer.start();
+
+        // add this object to the batch, only rendered if it has a texture.
+        this._renderWebGL(renderer);
+
+        // now loop through the children and make sure they get rendered
+        for (i = 0, j = this.children.length; i < j; i++)
+        {
+            this.children[i].renderWebGL(renderer);
+        }
+
+        renderer.currentRenderer.flush();
+
+        if ( mask )
+        {
+            renderer.maskManager.popMask(this, this._mask);
+        }
+
+        if ( filters && this._enabledFilters && this._enabledFilters.length )
+        {
+            renderer.filterManager.popFilter();
+        }
+
+        renderer.currentRenderer.start();
+    };
+
+    /**
+     * To be overridden by the subclass
+     *
+     * @param renderer {PIXI.WebGLRenderer} The renderer
+     * @private
+     */
+    Container.prototype._renderWebGL = function (renderer) // jshint unused:false
+    {
+        // this is where content itself gets rendered...
+    };
+
+    /**
+     * To be overridden by the subclass
+     *
+     * @param renderer {PIXI.CanvasRenderer} The renderer
+     * @private
+     */
+    Container.prototype._renderCanvas = function (renderer) // jshint unused:false
+    {
+        // this is where content itself gets rendered...
+    };
+
+
+    /**
+     * Renders the object using the Canvas renderer
+     *
+     * @param renderer {PIXI.CanvasRenderer} The renderer
+     */
+    Container.prototype.renderCanvas = function (renderer)
+    {
+        // if not visible or the alpha is 0 then no need to render this
+        if (!this.visible || this.alpha <= 0 || !this.renderable)
+        {
+            return;
+        }
+
+        if (this._mask)
+        {
+            renderer.maskManager.pushMask(this._mask);
+        }
+
+        this._renderCanvas(renderer);
+        for (var i = 0, j = this.children.length; i < j; ++i)
+        {
+            this.children[i].renderCanvas(renderer);
+        }
+
+        if (this._mask)
+        {
+            renderer.maskManager.popMask(renderer);
+        }
+    };
+
+    /**
+     * Removes all internal references and listeners as well as removes children from the display list.
+     * Do not use a Container after calling `destroy`.
+     * @param [options] {object|boolean} Options parameter. A boolean will act as if all options have been set to that value
+     * @param [options.children=false] {boolean} if set to true, all the children will have their destroy
+     *      method called as well. 'options' will be passed on to those calls.
+     */
+    Container.prototype.destroy = function (options)
+    {
+        DisplayObject.prototype.destroy.call(this);
+
+        var destroyChildren = typeof options === 'boolean' ? options : options && options.children;
+
+        var oldChildren = this.children;
+        this.children = null;
+
+        if (destroyChildren)
+        {
+            for (var i = oldChildren.length - 1; i >= 0; i--)
+            {
+                var child = oldChildren[i];
+                child.parent = null;
+                child.destroy(options);
+            }
+        }
+    };
+
+},{"../utils":116,"./DisplayObject":46}],46:[function(require,module,exports){
+    var EventEmitter = require('eventemitter3'),
+        CONST = require('../const'),
+        TransformStatic = require('./TransformStatic'),
+        Transform = require('./Transform'),
+        Bounds = require('./Bounds'),
+        math = require('../math'),
+        _tempDisplayObjectParent = new DisplayObject();
+
+    /**
+     * The base class for all objects that are rendered on the screen.
+     * This is an abstract class and should not be used on its own rather it should be extended.
+     *
+     * @class
+     * @extends EventEmitter
+     * @mixes PIXI.interaction.interactiveTarget
+     * @memberof PIXI
+     */
+    function DisplayObject()
+    {
+        EventEmitter.call(this);
+
+        var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform;
+
+        //TODO: need to create Transform from factory
+        /**
+         * World transform and local transform of this object.
+         * This will be reworked in v4.1, please do not use it yet unless you know what are you doing!
+         *
+         * @member {PIXI.TransformBase}
+         */
+        this.transform =  new TransformClass();
+
+        /**
+         * The opacity of the object.
+         *
+         * @member {number}
+         */
+        this.alpha = 1;
+
+        /**
+         * The visibility of the object. If false the object will not be drawn, and
+         * the updateTransform function will not be called.
+         *
+         * @member {boolean}
+         */
+        this.visible = true;
+
+        /**
+         * Can this object be rendered, if false the object will not be drawn but the updateTransform
+         * methods will still be called.
+         *
+         * @member {boolean}
+         */
+        this.renderable = true;
+
+        /**
+         * The display object container that contains this display object.
+         *
+         * @member {PIXI.Container}
+         * @readonly
+         */
+        this.parent = null;
+
+        /**
+         * The multiplied alpha of the displayObject
+         *
+         * @member {number}
+         * @readonly
+         */
+        this.worldAlpha = 1;
+
+        /**
+         * The area the filter is applied to. This is used as more of an optimisation
+         * rather than figuring out the dimensions of the displayObject each frame you can set this rectangle
+         *
+         * Also works as an interaction mask
+         *
+         * @member {PIXI.Rectangle}
+         */
+        this.filterArea = null;
+
+        this._filters = null;
+        this._enabledFilters = null;
+
+        /**
+         * The bounds object, this is used to calculate and store the bounds of the displayObject
+         *
+         * @member {PIXI.Rectangle}
+         * @private
+         */
+        this._bounds = new Bounds();
+        this._boundsID = 0;
+        this._lastBoundsID = -1;
+        this._boundsRect = null;
+        this._localBoundsRect = null;
+
+        /**
+         * The original, cached mask of the object
+         *
+         * @member {PIXI.Rectangle}
+         * @private
+         */
+        this._mask = null;
+
+
+    }
+
+// constructor
+    DisplayObject.prototype = Object.create(EventEmitter.prototype);
+    DisplayObject.prototype.constructor = DisplayObject;
+    module.exports = DisplayObject;
+
+
+    Object.defineProperties(DisplayObject.prototype, {
+        /**
+         * The position of the displayObject on the x axis relative to the local coordinates of the parent.
+         * An alias to position.x
+         *
+         * @member {number}
+         * @memberof PIXI.DisplayObject#
+         */
+        x: {
+            get: function ()
+            {
+                return this.position.x;
+            },
+            set: function (value)
+            {
+                this.transform.position.x = value;
+            }
+        },
+
+        /**
+         * The position of the displayObject on the y axis relative to the local coordinates of the parent.
+         * An alias to position.y
+         *
+         * @member {number}
+         * @memberof PIXI.DisplayObject#
+         */
+        y: {
+            get: function ()
+            {
+                return this.position.y;
+            },
+            set: function (value)
+            {
+                this.transform.position.y = value;
+            }
+        },
+
+        /**
+         * Current transform of the object based on world (parent) factors
+         *
+         * @member {PIXI.Matrix}
+         * @memberof PIXI.DisplayObject#
+         * @readonly
+         */
+        worldTransform: {
+            get: function ()
+            {
+                return this.transform.worldTransform;
+            }
+        },
+
+        /**
+         * Current transform of the object based on local factors: position, scale, other stuff
+         *
+         * @member {PIXI.Matrix}
+         * @memberof PIXI.DisplayObject#
+         * @readonly
+         */
+        localTransform: {
+            get: function ()
+            {
+                return this.transform.localTransform;
+            }
+        },
+
+        /**
+         * The coordinate of the object relative to the local coordinates of the parent.
+         * Assignment by value since pixi-v4.
+         *
+         * @member {PIXI.Point|PIXI.ObservablePoint}
+         * @memberof PIXI.DisplayObject#
+         */
+        position: {
+            get: function()
+            {
+                return this.transform.position;
+            },
+            set: function(value) {
+                this.transform.position.copy(value);
+            }
+        },
+
+        /**
+         * The scale factor of the object.
+         * Assignment by value since pixi-v4.
+         *
+         * @member {PIXI.Point|PIXI.ObservablePoint}
+         * @memberof PIXI.DisplayObject#
+         */
+        scale: {
+            get: function() {
+                return this.transform.scale;
+            },
+            set: function(value) {
+                this.transform.scale.copy(value);
+            }
+        },
+
+        /**
+         * The pivot point of the displayObject that it rotates around
+         * Assignment by value since pixi-v4.
+         *
+         * @member {PIXI.Point|PIXI.ObservablePoint}
+         * @memberof PIXI.DisplayObject#
+         */
+        pivot: {
+            get: function() {
+                return this.transform.pivot;
+            },
+            set: function(value) {
+                this.transform.pivot.copy(value);
+            }
+        },
+
+        /**
+         * The skew factor for the object in radians.
+         * Assignment by value since pixi-v4.
+         *
+         * @member {PIXI.ObservablePoint}
+         * @memberof PIXI.DisplayObject#
+         */
+        skew: {
+            get: function() {
+                return this.transform.skew;
+            },
+            set: function(value) {
+                this.transform.skew.copy(value);
+            }
+        },
+
+        /**
+         * The rotation of the object in radians.
+         *
+         * @member {number}
+         * @memberof PIXI.DisplayObject#
+         */
+        rotation: {
+            get: function ()
+            {
+                return this.transform.rotation;
+            },
+            set: function (value)
+            {
+                this.transform.rotation = value;
+            }
+        },
+
+        /**
+         * Indicates if the sprite is globally visible.
+         *
+         * @member {boolean}
+         * @memberof PIXI.DisplayObject#
+         * @readonly
+         */
+        worldVisible: {
+            get: function ()
+            {
+                var item = this;
+
+                do {
+                    if (!item.visible)
+                    {
+                        return false;
+                    }
+
+                    item = item.parent;
+                } while (item);
+
+                return true;
+            }
+        },
+
+        /**
+         * Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it.
+         * In PIXI a regular mask must be a PIXI.Graphics or a PIXI.Sprite object. This allows for much faster masking in canvas as it utilises shape clipping.
+         * To remove a mask, set this property to null.
+         *
+         * @todo For the moment, PIXI.CanvasRenderer doesn't support PIXI.Sprite as mask.
+         *
+         * @member {PIXI.Graphics|PIXI.Sprite}
+         * @memberof PIXI.DisplayObject#
+         */
+        mask: {
+            get: function ()
+            {
+                return this._mask;
+            },
+            set: function (value)
+            {
+                if (this._mask)
+                {
+                    this._mask.renderable = true;
+                }
+
+                this._mask = value;
+
+                if (this._mask)
+                {
+                    this._mask.renderable = false;
+                }
+            }
+        },
+
+        /**
+         * Sets the filters for the displayObject.
+         * * IMPORTANT: This is a webGL only feature and will be ignored by the canvas renderer.
+         * To remove filters simply set this property to 'null'
+         *
+         * @member {PIXI.AbstractFilter[]}
+         * @memberof PIXI.DisplayObject#
+         */
+        filters: {
+            get: function ()
+            {
+                return this._filters && this._filters.slice();
+            },
+            set: function (value)
+            {
+                this._filters = value && value.slice();
+            }
+        }
+
+    });
+
+    /*
+     * Updates the object transform for rendering
+     *
+     * TODO - Optimization pass!
+     */
+    DisplayObject.prototype.updateTransform = function ()
+    {
+        this.transform.updateTransform(this.parent.transform);
+        // multiply the alphas..
+        this.worldAlpha = this.alpha * this.parent.worldAlpha;
+
+        this._bounds.updateID++;
+    };
+
+// performance increase to avoid using call.. (10x faster)
+    DisplayObject.prototype.displayObjectUpdateTransform = DisplayObject.prototype.updateTransform;
+
+    /**
+     * recursively updates transform of all objects from the root to this one
+     * internal function for toLocal()
+     */
+    DisplayObject.prototype._recursivePostUpdateTransform = function()
+    {
+        if (this.parent)
+        {
+            this.parent._recursivePostUpdateTransform();
+            this.transform.updateTransform(this.parent.transform);
+        }
+        else
+        {
+            this.transform.updateTransform(_tempDisplayObjectParent.transform);
+        }
+    };
+
+    /**
+     *
+     *
+     * Retrieves the bounds of the displayObject as a rectangle object.
+     * @param skipUpdate {boolean} setting to true will stop the transforms of the scene graph from being updated. This means the calculation returned MAY be out of date BUT will give you a nice performance boost
+     * @param rect {PIXI.Rectangle} Optional rectangle to store the result of the bounds calculation
+     * @return {PIXI.Rectangle} the rectangular bounding area
+     */
+    DisplayObject.prototype.getBounds = function (skipUpdate, rect)
+    {
+        if(!skipUpdate)
+        {
+            if(!this.parent)
+            {
+                this.parent = _tempDisplayObjectParent;
+                this.parent.transform._worldID++;
+                this.updateTransform();
+                this.parent = null;
+            }
+            else
+            {
+                this._recursivePostUpdateTransform();
+                this.updateTransform();
+            }
+        }
+
+        if(this._boundsID !== this._lastBoundsID)
+        {
+            this.calculateBounds();
+        }
+
+        if(!rect)
+        {
+            if(!this._boundsRect)
+            {
+                this._boundsRect = new math.Rectangle();
+            }
+
+            rect = this._boundsRect;
+        }
+
+        return this._bounds.getRectangle(rect);
+    };
+
+    /**
+     * Retrieves the local bounds of the displayObject as a rectangle object
+     * @param rect {PIXI.Rectangle} Optional rectangle to store the result of the bounds calculation
+     * @return {PIXI.Rectangle} the rectangular bounding area
+     */
+    DisplayObject.prototype.getLocalBounds = function (rect)
+    {
+        var transformRef = this.transform;
+        var parentRef = this.parent;
+
+        this.parent = null;
+        this.transform = _tempDisplayObjectParent.transform;
+
+        if(!rect)
+        {
+            if(!this._localBoundsRect)
+            {
+                this._localBoundsRect = new math.Rectangle();
+            }
+
+            rect = this._localBoundsRect;
+        }
+
+        var bounds = this.getBounds(false, rect);
+
+        this.parent = parentRef;
+        this.transform = transformRef;
+
+        return bounds;
+    };
+
+    /**
+     * Calculates the global position of the display object
+     *
+     * @param position {PIXI.Point} The world origin to calculate from
+     * @return {PIXI.Point} A point object representing the position of this object
+     */
+    DisplayObject.prototype.toGlobal = function (position, point, skipUpdate)
+    {
+        if(!skipUpdate)
+        {
+            this._recursivePostUpdateTransform();
+
+            // this parent check is for just in case the item is a root object.
+            // If it is we need to give it a temporary parent so that displayObjectUpdateTransform works correctly
+            // this is mainly to avoid a parent check in the main loop. Every little helps for performance :)
+            if(!this.parent)
+            {
+                this.parent = _tempDisplayObjectParent;
+                this.displayObjectUpdateTransform();
+                this.parent = null;
+            }
+            else
+            {
+                this.displayObjectUpdateTransform();
+            }
+        }
+
+        // don't need to update the lot
+        return this.worldTransform.apply(position, point);
+    };
+
+    /**
+     * Calculates the local position of the display object relative to another point
+     *
+     * @param position {PIXI.Point} The world origin to calculate from
+     * @param [from] {PIXI.DisplayObject} The DisplayObject to calculate the global position from
+     * @param [point] {PIXI.Point} A Point object in which to store the value, optional (otherwise will create a new Point)
+     * @return {PIXI.Point} A point object representing the position of this object
+     */
+    DisplayObject.prototype.toLocal = function (position, from, point, skipUpdate)
+    {
+        if (from)
+        {
+            position = from.toGlobal(position, point, skipUpdate);
+        }
+
+        if(! skipUpdate)
+        {
+            this._recursivePostUpdateTransform();
+
+            // this parent check is for just in case the item is a root object.
+            // If it is we need to give it a temporary parent so that displayObjectUpdateTransform works correctly
+            // this is mainly to avoid a parent check in the main loop. Every little helps for performance :)
+            if(!this.parent)
+            {
+                this.parent = _tempDisplayObjectParent;
+                this.displayObjectUpdateTransform();
+                this.parent = null;
+            }
+            else
+            {
+                this.displayObjectUpdateTransform();
+            }
+        }
+
+        // simply apply the matrix..
+        return this.worldTransform.applyInverse(position, point);
+    };
+
+    /**
+     * Renders the object using the WebGL renderer
+     *
+     * @param renderer {PIXI.WebGLRenderer} The renderer
+     */
+    DisplayObject.prototype.renderWebGL = function (renderer) // jshint unused:false
+    {
+        // OVERWRITE;
+    };
+
+    /**
+     * Renders the object using the Canvas renderer
+     *
+     * @param renderer {PIXI.CanvasRenderer} The renderer
+     */
+    DisplayObject.prototype.renderCanvas = function (renderer) // jshint unused:false
+    {
+        // OVERWRITE;
+    };
+
+    /**
+     * Set the parent Container of this DisplayObject
+     *
+     * @param container {PIXI.Container} The Container to add this DisplayObject to
+     * @return {PIXI.Container} The Container that this DisplayObject was added to
+     */
+    DisplayObject.prototype.setParent = function (container)
+    {
+        if (!container || !container.addChild)
+        {
+            throw new Error('setParent: Argument must be a Container');
+        }
+
+        container.addChild(this);
+        return container;
+    };
+
+    /**
+     * Convenience function to set the postion, scale, skew and pivot at once.
+     *
+     * @param [x=0] {number} The X position
+     * @param [y=0] {number} The Y position
+     * @param [scaleX=1] {number} The X scale value
+     * @param [scaleY=1] {number} The Y scale value
+     * @param [rotation=0] {number} The rotation
+     * @param [skewX=0] {number} The X skew value
+     * @param [skewY=0] {number} The Y skew value
+     * @param [pivotX=0] {number} The X pivot value
+     * @param [pivotY=0] {number} The Y pivot value
+     * @return {PIXI.DisplayObject} The DisplayObject instance
+     */
+    DisplayObject.prototype.setTransform = function(x, y, scaleX, scaleY, rotation, skewX, skewY, pivotX, pivotY) //jshint ignore:line
+    {
+        this.position.x = x || 0;
+        this.position.y = y || 0;
+        this.scale.x = !scaleX ? 1 : scaleX;
+        this.scale.y = !scaleY ? 1 : scaleY;
+        this.rotation = rotation || 0;
+        this.skew.x = skewX || 0;
+        this.skew.y = skewY || 0;
+        this.pivot.x = pivotX || 0;
+        this.pivot.y = pivotY || 0;
+        return this;
+    };
+
+    /**
+     * Base destroy method for generic display objects. This will automatically
+     * remove the display object from its parent Container as well as remove
+     * all current event listeners and internal references. Do not use a DisplayObject
+     * after calling `destroy`.
+     */
+    DisplayObject.prototype.destroy = function ()
+    {
+        this.removeAllListeners();
+        if (this.parent)
+        {
+            this.parent.removeChild(this);
+        }
+        this.transform = null;
+
+        this.parent = null;
+
+        this._bounds = null;
+        this._currentBounds = null;
+        this._mask = null;
+
+        this.filterArea = null;
+
+        this.interactive = false;
+        this.interactiveChildren = false;
+    };
+
+},{"../const":43,"../math":67,"./Bounds":44,"./Transform":47,"./TransformStatic":49,"eventemitter3":3}],47:[function(require,module,exports){
+    var math = require('../math'),
+        TransformBase = require('./TransformBase');
+
+
+    /**
+     * Generic class to deal with traditional 2D matrix transforms
+     * local transformation is calculated from position,scale,skew and rotation
+     *
+     * @class
+     * @extends PIXI.TransformBase
+     * @memberof PIXI
+     */
+    function Transform()
+    {
+        TransformBase.call(this);
+
+        /**
+         * The coordinate of the object relative to the local coordinates of the parent.
+         *
+         * @member {PIXI.Point}
+         */
+        this.position = new math.Point(0,0);
+
+        /**
+         * The scale factor of the object.
+         *
+         * @member {PIXI.Point}
+         */
+        this.scale = new math.Point(1,1);
+
+        /**
+         * The skew amount, on the x and y axis.
+         *
+         * @member {PIXI.ObservablePoint}
+         */
+        this.skew = new math.ObservablePoint(this.updateSkew, this, 0,0);
+
+        /**
+         * The pivot point of the displayObject that it rotates around
+         *
+         * @member {PIXI.Point}
+         */
+        this.pivot = new math.Point(0,0);
+
+        /**
+         * The rotation value of the object, in radians
+         *
+         * @member {Number}
+         * @private
+         */
+        this._rotation = 0;
+
+        this._sr = Math.sin(0);
+        this._cr = Math.cos(0);
+        this._cy  = Math.cos(0);//skewY);
+        this._sy  = Math.sin(0);//skewY);
+        this._nsx = Math.sin(0);//skewX);
+        this._cx  = Math.cos(0);//skewX);
+    }
+
+    Transform.prototype = Object.create(TransformBase.prototype);
+    Transform.prototype.constructor = Transform;
+
+    Transform.prototype.updateSkew = function ()
+    {
+        this._cy  = Math.cos(this.skew.y);
+        this._sy  = Math.sin(this.skew.y);
+        this._nsx = Math.sin(this.skew.x);
+        this._cx  = Math.cos(this.skew.x);
+    };
+
+    /**
+     * Updates only local matrix
+     */
+    Transform.prototype.updateLocalTransform = function() {
+        var lt = this.localTransform;
+        var a, b, c, d;
+
+        a  =  this._cr * this.scale.x;
+        b  =  this._sr * this.scale.x;
+        c  = -this._sr * this.scale.y;
+        d  =  this._cr * this.scale.y;
+
+        lt.a  = this._cy * a + this._sy * c;
+        lt.b  = this._cy * b + this._sy * d;
+        lt.c  = this._nsx * a + this._cx * c;
+        lt.d  = this._nsx * b + this._cx * d;
+    };
+
+    /**
+     * Updates the values of the object and applies the parent's transform.
+     * @param parentTransform {PIXI.Transform} The transform of the parent of this object
+     */
+    Transform.prototype.updateTransform = function (parentTransform)
+    {
+
+        var pt = parentTransform.worldTransform;
+        var wt = this.worldTransform;
+        var lt = this.localTransform;
+        var a, b, c, d;
+
+        a  =  this._cr * this.scale.x;
+        b  =  this._sr * this.scale.x;
+        c  = -this._sr * this.scale.y;
+        d  =  this._cr * this.scale.y;
+
+        lt.a  = this._cy * a + this._sy * c;
+        lt.b  = this._cy * b + this._sy * d;
+        lt.c  = this._nsx * a + this._cx * c;
+        lt.d  = this._nsx * b + this._cx * d;
+
+        lt.tx =  this.position.x - (this.pivot.x * lt.a + this.pivot.y * lt.c);
+        lt.ty =  this.position.y - (this.pivot.x * lt.b + this.pivot.y * lt.d);
+
+        // concat the parent matrix with the objects transform.
+        wt.a  = lt.a  * pt.a + lt.b  * pt.c;
+        wt.b  = lt.a  * pt.b + lt.b  * pt.d;
+        wt.c  = lt.c  * pt.a + lt.d  * pt.c;
+        wt.d  = lt.c  * pt.b + lt.d  * pt.d;
+        wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx;
+        wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty;
+
+        this._worldID ++;
+    };
+
+    /**
+     * Decomposes a matrix and sets the transforms properties based on it.
+     * @param {PIXI.Matrix} The matrix to decompose
+     */
+    Transform.prototype.setFromMatrix = function (matrix)
+    {
+        matrix.decompose(this);
+    };
+
+
+    Object.defineProperties(Transform.prototype, {
+        /**
+         * The rotation of the object in radians.
+         *
+         * @member {number}
+         * @memberof PIXI.Transform#
+         */
+        rotation: {
+            get: function () {
+                return this._rotation;
+            },
+            set: function (value) {
+                this._rotation = value;
+                this._sr = Math.sin(value);
+                this._cr = Math.cos(value);
+            }
+        }
+    });
+
+    module.exports = Transform;
+
+},{"../math":67,"./TransformBase":48}],48:[function(require,module,exports){
+    var math = require('../math');
+
+
+    /**
+     * Generic class to deal with traditional 2D matrix transforms
+     *
+     * @class
+     * @memberof PIXI
+     */
+    function TransformBase()
+    {
+        /**
+         * The global matrix transform. It can be swapped temporarily by some functions like getLocalBounds()
+         *
+         * @member {PIXI.Matrix}
+         */
+        this.worldTransform = new math.Matrix();
+        /**
+         * The local matrix transform
+         *
+         * @member {PIXI.Matrix}
+         */
+        this.localTransform = new math.Matrix();
+
+        this._worldID = 0;
+    }
+
+    TransformBase.prototype.constructor = TransformBase;
+
+    /**
+     * TransformBase does not have decomposition, so this function wont do anything
+     */
+    TransformBase.prototype.updateLocalTransform = function() { // jshint unused:false
+
+    };
+
+    /**
+     * Updates the values of the object and applies the parent's transform.
+     * @param  parentTransform {PIXI.TransformBase} The transform of the parent of this object
+     *
+     */
+    TransformBase.prototype.updateTransform = function (parentTransform)
+    {
+        var pt = parentTransform.worldTransform;
+        var wt = this.worldTransform;
+        var lt = this.localTransform;
+
+        // concat the parent matrix with the objects transform.
+        wt.a  = lt.a  * pt.a + lt.b  * pt.c;
+        wt.b  = lt.a  * pt.b + lt.b  * pt.d;
+        wt.c  = lt.c  * pt.a + lt.d  * pt.c;
+        wt.d  = lt.c  * pt.b + lt.d  * pt.d;
+        wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx;
+        wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty;
+
+        this._worldID ++;
+    };
+
+    /**
+     * Updates the values of the object and applies the parent's transform.
+     * @param  parentTransform {PIXI.Transform} The transform of the parent of this object
+     *
+     */
+    TransformBase.prototype.updateWorldTransform = TransformBase.prototype.updateTransform;
+
+    TransformBase.IDENTITY = new TransformBase();
+
+    module.exports = TransformBase;
+
+},{"../math":67}],49:[function(require,module,exports){
+    var math = require('../math'),
+        TransformBase = require('./TransformBase');
+
+    /**
+     * Transform that takes care about its versions
+     *
+     * @class
+     * @extends PIXI.TransformBase
+     * @memberof PIXI
+     */
+    function TransformStatic()
+    {
+        TransformBase.call(this);
+        /**
+         * The coordinate of the object relative to the local coordinates of the parent.
+         *
+         * @member {PIXI.ObservablePoint}
+         */
+        this.position = new math.ObservablePoint(this.onChange, this,0,0);
+
+        /**
+         * The scale factor of the object.
+         *
+         * @member {PIXI.ObservablePoint}
+         */
+        this.scale = new math.ObservablePoint(this.onChange, this,1,1);
+
+        /**
+         * The pivot point of the displayObject that it rotates around
+         *
+         * @member {PIXI.ObservablePoint}
+         */
+        this.pivot = new math.ObservablePoint(this.onChange, this,0, 0);
+
+        /**
+         * The skew amount, on the x and y axis.
+         *
+         * @member {PIXI.ObservablePoint}
+         */
+        this.skew = new math.ObservablePoint(this.updateSkew, this,0, 0);
+
+        this._rotation = 0;
+
+        this._sr = Math.sin(0);
+        this._cr = Math.cos(0);
+        this._cy  = Math.cos(0);//skewY);
+        this._sy  = Math.sin(0);//skewY);
+        this._nsx = Math.sin(0);//skewX);
+        this._cx  = Math.cos(0);//skewX);
+
+        this._localID = 0;
+        this._currentLocalID = 0;
+    }
+
+    TransformStatic.prototype = Object.create(TransformBase.prototype);
+    TransformStatic.prototype.constructor = TransformStatic;
+
+    TransformStatic.prototype.onChange = function ()
+    {
+        this._localID ++;
+    };
+
+    TransformStatic.prototype.updateSkew = function ()
+    {
+        this._cy  = Math.cos(this.skew._y);
+        this._sy  = Math.sin(this.skew._y);
+        this._nsx = Math.sin(this.skew._x);
+        this._cx  = Math.cos(this.skew._x);
+
+        this._localID ++;
+    };
+
+    /**
+     * Updates only local matrix
+     */
+    TransformStatic.prototype.updateLocalTransform = function() {
+        var lt = this.localTransform;
+        if(this._localID !== this._currentLocalID)
+        {
+            // get the matrix values of the displayobject based on its transform properties..
+            var a,b,c,d;
+
+            a  =  this._cr * this.scale._x;
+            b  =  this._sr * this.scale._x;
+            c  = -this._sr * this.scale._y;
+            d  =  this._cr * this.scale._y;
+
+            lt.a  = this._cy * a + this._sy * c;
+            lt.b  = this._cy * b + this._sy * d;
+            lt.c  = this._nsx * a + this._cx * c;
+            lt.d  = this._nsx * b + this._cx * d;
+
+            lt.tx =  this.position._x - (this.pivot._x * lt.a + this.pivot._y * lt.c);
+            lt.ty =  this.position._y - (this.pivot._x * lt.b + this.pivot._y * lt.d);
+            this._currentLocalID = this._localID;
+
+            // force an update..
+            this._parentID = -1;
+        }
+    };
+
+    /**
+     * Updates the values of the object and applies the parent's transform.
+     * @param parentTransform {PIXI.Transform} The transform of the parent of this object
+     *
+     */
+    TransformStatic.prototype.updateTransform = function (parentTransform)
+    {
+        var pt = parentTransform.worldTransform;
+        var wt = this.worldTransform;
+        var lt = this.localTransform;
+
+        if(this._localID !== this._currentLocalID)
+        {
+            // get the matrix values of the displayobject based on its transform properties..
+            var a,b,c,d;
+
+            a  =  this._cr * this.scale._x;
+            b  =  this._sr * this.scale._x;
+            c  = -this._sr * this.scale._y;
+            d  =  this._cr * this.scale._y;
+
+            lt.a  = this._cy * a + this._sy * c;
+            lt.b  = this._cy * b + this._sy * d;
+            lt.c  = this._nsx * a + this._cx * c;
+            lt.d  = this._nsx * b + this._cx * d;
+
+            lt.tx =  this.position._x - (this.pivot._x * lt.a + this.pivot._y * lt.c);
+            lt.ty =  this.position._y - (this.pivot._x * lt.b + this.pivot._y * lt.d);
+            this._currentLocalID = this._localID;
+
+            // force an update..
+            this._parentID = -1;
+        }
+
+        if(this._parentID !== parentTransform._worldID)
+        {
+            // concat the parent matrix with the objects transform.
+            wt.a  = lt.a  * pt.a + lt.b  * pt.c;
+            wt.b  = lt.a  * pt.b + lt.b  * pt.d;
+            wt.c  = lt.c  * pt.a + lt.d  * pt.c;
+            wt.d  = lt.c  * pt.b + lt.d  * pt.d;
+            wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx;
+            wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty;
+
+            this._parentID = parentTransform._worldID;
+
+            // update the id of the transform..
+            this._worldID ++;
+        }
+    };
+
+    /**
+     * Decomposes a matrix and sets the transforms properties based on it.
+     * @param {PIXI.Matrix} The matrix to decompose
+     */
+    TransformStatic.prototype.setFromMatrix = function (matrix)
+    {
+        matrix.decompose(this);
+        this._localID ++;
+    };
+
+    Object.defineProperties(TransformStatic.prototype, {
+        /**
+         * The rotation of the object in radians.
+         *
+         * @member {number}
+         * @memberof PIXI.TransformStatic#
+         */
+        rotation: {
+            get: function () {
+                return this._rotation;
+            },
+            set: function (value) {
+                this._rotation = value;
+                this._sr = Math.sin(value);
+                this._cr = Math.cos(value);
+                this._localID ++;
+            }
+        }
+    });
+
+    module.exports = TransformStatic;
+
+},{"../math":67,"./TransformBase":48}],50:[function(require,module,exports){
+    var Container = require('../display/Container'),
+        RenderTexture = require('../textures/RenderTexture'),
+        Texture = require('../textures/Texture'),
+        GraphicsData = require('./GraphicsData'),
+        Sprite = require('../sprites/Sprite'),
+        math = require('../math'),
+        CONST = require('../const'),
+        utils = require('../utils'),
+        Bounds = require('../display/Bounds'),
+        bezierCurveTo = require('./utils/bezierCurveTo'),
+        CanvasRenderer = require('../renderers/canvas/CanvasRenderer'),
+        canvasRenderer,
+        tempMatrix = new math.Matrix(),
+        tempPoint = new math.Point(),
+        tempColor1 = new Float32Array(4),
+        tempColor2 = new Float32Array(4);
+
+    /**
+     * The Graphics class contains methods used to draw primitive shapes such as lines, circles and
+     * rectangles to the display, and to color and fill them.
+     *
+     * @class
+     * @extends PIXI.Container
+     * @memberof PIXI
+     */
+    function Graphics()
+    {
+        Container.call(this);
+
+        /**
+         * The alpha value used when filling the Graphics object.
+         *
+         * @member {number}
+         * @default 1
+         */
+        this.fillAlpha = 1;
+
+        /**
+         * The width (thickness) of any lines drawn.
+         *
+         * @member {number}
+         * @default 0
+         */
+        this.lineWidth = 0;
+
+        /**
+         * The color of any lines drawn.
+         *
+         * @member {string}
+         * @default 0
+         */
+        this.lineColor = 0;
+
+        /**
+         * Graphics data
+         *
+         * @member {PIXI.GraphicsData[]}
+         * @private
+         */
+        this.graphicsData = [];
+
+        /**
+         * The tint applied to the graphic shape. This is a hex value. Apply a value of 0xFFFFFF to reset the tint.
+         *
+         * @member {number}
+         * @default 0xFFFFFF
+         */
+        this.tint = 0xFFFFFF;
+
+        /**
+         * The previous tint applied to the graphic shape. Used to compare to the current tint and check if theres change.
+         *
+         * @member {number}
+         * @private
+         * @default 0xFFFFFF
+         */
+        this._prevTint = 0xFFFFFF;
+
+        /**
+         * The blend mode to be applied to the graphic shape. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.
+         *
+         * @member {number}
+         * @default PIXI.BLEND_MODES.NORMAL;
+         * @see PIXI.BLEND_MODES
+         */
+        this.blendMode = CONST.BLEND_MODES.NORMAL;
+
+        /**
+         * Current path
+         *
+         * @member {PIXI.GraphicsData}
+         * @private
+         */
+        this.currentPath = null;
+
+        /**
+         * Array containing some WebGL-related properties used by the WebGL renderer.
+         *
+         * @member {object<number, object>}
+         * @private
+         */
+            // TODO - _webgl should use a prototype object, not a random undocumented object...
+        this._webGL = {};
+
+        /**
+         * Whether this shape is being used as a mask.
+         *
+         * @member {boolean}
+         */
+        this.isMask = false;
+
+        /**
+         * The bounds' padding used for bounds calculation.
+         *
+         * @member {number}
+         */
+        this.boundsPadding = 0;
+
+        /**
+         * A cache of the local bounds to prevent recalculation.
+         *
+         * @member {PIXI.Rectangle}
+         * @private
+         */
+        this._localBounds = new Bounds();
+
+        /**
+         * Used to detect if the graphics object has changed. If this is set to true then the graphics
+         * object will be recalculated.
+         *
+         * @member {boolean}
+         * @private
+         */
+        this.dirty = 0;
+
+        /**
+         * Used to detect if we need to do a fast rect check using the id compare method
+         * @type {Number}
+         */
+        this.fastRectDirty = -1;
+
+        /**
+         * Used to detect if we clear the graphics webGL data
+         * @type {Number}
+         */
+        this.clearDirty = 0;
+
+        /**
+         * Used to detect if we we need to recalculate local bounds
+         * @type {Number}
+         */
+        this.boundsDirty = -1;
+
+        /**
+         * Used to detect if the cached sprite object needs to be updated.
+         *
+         * @member {boolean}
+         * @private
+         */
+        this.cachedSpriteDirty = false;
+
+
+        this._spriteRect = null;
+        this._fastRect = false;
+
+        /**
+         * When cacheAsBitmap is set to true the graphics object will be rendered as if it was a sprite.
+         * This is useful if your graphics element does not change often, as it will speed up the rendering
+         * of the object in exchange for taking up texture memory. It is also useful if you need the graphics
+         * object to be anti-aliased, because it will be rendered using canvas. This is not recommended if
+         * you are constantly redrawing the graphics element.
+         *
+         * @name cacheAsBitmap
+         * @member {boolean}
+         * @memberof PIXI.Graphics#
+         * @default false
+         */
+    }
+
+    Graphics._SPRITE_TEXTURE = null;
+
+// constructor
+    Graphics.prototype = Object.create(Container.prototype);
+    Graphics.prototype.constructor = Graphics;
+    module.exports = Graphics;
+
+    /**
+     * Creates a new Graphics object with the same values as this one.
+     * Note that the only the properties of the object are cloned, not its transform (position,scale,etc)
+     *
+     * @return {PIXI.Graphics} A clone of the graphics object
+     */
+    Graphics.prototype.clone = function ()
+    {
+        var clone = new Graphics();
+
+        clone.renderable    = this.renderable;
+        clone.fillAlpha     = this.fillAlpha;
+        clone.lineWidth     = this.lineWidth;
+        clone.lineColor     = this.lineColor;
+        clone.tint          = this.tint;
+        clone.blendMode     = this.blendMode;
+        clone.isMask        = this.isMask;
+        clone.boundsPadding = this.boundsPadding;
+        clone.dirty         = 0;
+        clone.cachedSpriteDirty = this.cachedSpriteDirty;
+
+        // copy graphics data
+        for (var i = 0; i < this.graphicsData.length; ++i)
+        {
+            clone.graphicsData.push(this.graphicsData[i].clone());
+        }
+
+        clone.currentPath = clone.graphicsData[clone.graphicsData.length - 1];
+
+        clone.updateLocalBounds();
+
+        return clone;
+    };
+
+    /**
+     * Specifies the line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
+     *
+     * @param lineWidth {number} width of the line to draw, will update the objects stored style
+     * @param color {number} color of the line to draw, will update the objects stored style
+     * @param alpha {number} alpha of the line to draw, will update the objects stored style
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.lineStyle = function (lineWidth, color, alpha)
+    {
+        this.lineWidth = lineWidth || 0;
+        this.lineColor = color || 0;
+        this.lineAlpha = (alpha === undefined) ? 1 : alpha;
+
+        if (this.currentPath)
+        {
+            if (this.currentPath.shape.points.length)
+            {
+                // halfway through a line? start a new one!
+                var shape = new math.Polygon(this.currentPath.shape.points.slice(-2));
+                shape.closed = false;
+                this.drawShape(shape);
+            }
+            else
+            {
+                // otherwise its empty so lets just set the line properties
+                this.currentPath.lineWidth = this.lineWidth;
+                this.currentPath.lineColor = this.lineColor;
+                this.currentPath.lineAlpha = this.lineAlpha;
+            }
+        }
+
+        return this;
+    };
+
+    /**
+     * Moves the current drawing position to x, y.
+     *
+     * @param x {number} the X coordinate to move to
+     * @param y {number} the Y coordinate to move to
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.moveTo = function (x, y)
+    {
+        var shape = new math.Polygon([x,y]);
+        shape.closed = false;
+        this.drawShape(shape);
+
+        return this;
+    };
+
+    /**
+     * Draws a line using the current line style from the current drawing position to (x, y);
+     * The current drawing position is then set to (x, y).
+     *
+     * @param x {number} the X coordinate to draw to
+     * @param y {number} the Y coordinate to draw to
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.lineTo = function (x, y)
+    {
+        this.currentPath.shape.points.push(x, y);
+        this.dirty++;
+
+        return this;
+    };
+
+    /**
+     * Calculate the points for a quadratic bezier curve and then draws it.
+     * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c
+     *
+     * @param cpX {number} Control point x
+     * @param cpY {number} Control point y
+     * @param toX {number} Destination point x
+     * @param toY {number} Destination point y
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.quadraticCurveTo = function (cpX, cpY, toX, toY)
+    {
+        if (this.currentPath)
+        {
+            if (this.currentPath.shape.points.length === 0)
+            {
+                this.currentPath.shape.points = [0, 0];
+            }
+        }
+        else
+        {
+            this.moveTo(0,0);
+        }
+
+
+        var xa,
+            ya,
+            n = 20,
+            points = this.currentPath.shape.points;
+
+        if (points.length === 0)
+        {
+            this.moveTo(0, 0);
+        }
+
+        var fromX = points[points.length-2];
+        var fromY = points[points.length-1];
+
+        var j = 0;
+        for (var i = 1; i <= n; ++i)
+        {
+            j = i / n;
+
+            xa = fromX + ( (cpX - fromX) * j );
+            ya = fromY + ( (cpY - fromY) * j );
+
+            points.push( xa + ( ((cpX + ( (toX - cpX) * j )) - xa) * j ),
+                ya + ( ((cpY + ( (toY - cpY) * j )) - ya) * j ) );
+        }
+
+        this.dirty++;
+
+        return this;
+    };
+
+    /**
+     * Calculate the points for a bezier curve and then draws it.
+     *
+     * @param cpX {number} Control point x
+     * @param cpY {number} Control point y
+     * @param cpX2 {number} Second Control point x
+     * @param cpY2 {number} Second Control point y
+     * @param toX {number} Destination point x
+     * @param toY {number} Destination point y
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.bezierCurveTo = function (cpX, cpY, cpX2, cpY2, toX, toY)
+    {
+        if (this.currentPath)
+        {
+            if (this.currentPath.shape.points.length === 0)
+            {
+                this.currentPath.shape.points = [0, 0];
+            }
+        }
+        else
+        {
+            this.moveTo(0,0);
+        }
+
+        var points = this.currentPath.shape.points;
+
+        var fromX = points[points.length-2];
+        var fromY = points[points.length-1];
+
+        points.length -= 2;
+
+        bezierCurveTo(fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY, points);
+
+        this.dirty++;
+
+        return this;
+    };
+
+    /**
+     * The arcTo() method creates an arc/curve between two tangents on the canvas.
+     *
+     * "borrowed" from https://code.google.com/p/fxcanvas/ - thanks google!
+     *
+     * @param x1 {number} The x-coordinate of the beginning of the arc
+     * @param y1 {number} The y-coordinate of the beginning of the arc
+     * @param x2 {number} The x-coordinate of the end of the arc
+     * @param y2 {number} The y-coordinate of the end of the arc
+     * @param radius {number} The radius of the arc
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.arcTo = function (x1, y1, x2, y2, radius)
+    {
+        if (this.currentPath)
+        {
+            if (this.currentPath.shape.points.length === 0)
+            {
+                this.currentPath.shape.points.push(x1, y1);
+            }
+        }
+        else
+        {
+            this.moveTo(x1, y1);
+        }
+
+        var points = this.currentPath.shape.points,
+            fromX = points[points.length-2],
+            fromY = points[points.length-1],
+            a1 = fromY - y1,
+            b1 = fromX - x1,
+            a2 = y2   - y1,
+            b2 = x2   - x1,
+            mm = Math.abs(a1 * b2 - b1 * a2);
+
+        if (mm < 1.0e-8 || radius === 0)
+        {
+            if (points[points.length-2] !== x1 || points[points.length-1] !== y1)
+            {
+                points.push(x1, y1);
+            }
+        }
+        else
+        {
+            var dd = a1 * a1 + b1 * b1,
+                cc = a2 * a2 + b2 * b2,
+                tt = a1 * a2 + b1 * b2,
+                k1 = radius * Math.sqrt(dd) / mm,
+                k2 = radius * Math.sqrt(cc) / mm,
+                j1 = k1 * tt / dd,
+                j2 = k2 * tt / cc,
+                cx = k1 * b2 + k2 * b1,
+                cy = k1 * a2 + k2 * a1,
+                px = b1 * (k2 + j1),
+                py = a1 * (k2 + j1),
+                qx = b2 * (k1 + j2),
+                qy = a2 * (k1 + j2),
+                startAngle = Math.atan2(py - cy, px - cx),
+                endAngle   = Math.atan2(qy - cy, qx - cx);
+
+            this.arc(cx + x1, cy + y1, radius, startAngle, endAngle, b1 * a2 > b2 * a1);
+        }
+
+        this.dirty++;
+
+        return this;
+    };
+
+    /**
+     * The arc method creates an arc/curve (used to create circles, or parts of circles).
+     *
+     * @param cx {number} The x-coordinate of the center of the circle
+     * @param cy {number} The y-coordinate of the center of the circle
+     * @param radius {number} The radius of the circle
+     * @param startAngle {number} The starting angle, in radians (0 is at the 3 o'clock position of the arc's circle)
+     * @param endAngle {number} The ending angle, in radians
+     * @param [anticlockwise=false] {boolean} Specifies whether the drawing should be counterclockwise or clockwise. False is default, and indicates clockwise, while true indicates counter-clockwise.
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.arc = function(cx, cy, radius, startAngle, endAngle, anticlockwise)
+    {
+        anticlockwise = anticlockwise || false;
+
+        if (startAngle === endAngle)
+        {
+            return this;
+        }
+
+        if( !anticlockwise && endAngle <= startAngle )
+        {
+            endAngle += Math.PI * 2;
+        }
+        else if( anticlockwise && startAngle <= endAngle )
+        {
+            startAngle += Math.PI * 2;
+        }
+
+        var sweep = anticlockwise ? (startAngle - endAngle) * -1 : (endAngle - startAngle);
+        var segs =  Math.ceil(Math.abs(sweep) / (Math.PI * 2)) * 40;
+
+        if(sweep === 0)
+        {
+            return this;
+        }
+
+        var startX = cx + Math.cos(startAngle) * radius;
+        var startY = cy + Math.sin(startAngle) * radius;
+
+        if (this.currentPath)
+        {
+            this.currentPath.shape.points.push(startX, startY);
+        }
+        else
+        {
+            this.moveTo(startX, startY);
+        }
+
+        var points = this.currentPath.shape.points;
+
+        var theta = sweep/(segs*2);
+        var theta2 = theta*2;
+
+        var cTheta = Math.cos(theta);
+        var sTheta = Math.sin(theta);
+
+        var segMinus = segs - 1;
+
+        var remainder = ( segMinus % 1 ) / segMinus;
+
+        for(var i=0; i<=segMinus; i++)
+        {
+            var real =  i + remainder * i;
+
+
+            var angle = ((theta) + startAngle + (theta2 * real));
+
+            var c = Math.cos(angle);
+            var s = -Math.sin(angle);
+
+            points.push(( (cTheta *  c) + (sTheta * s) ) * radius + cx,
+                ( (cTheta * -s) + (sTheta * c) ) * radius + cy);
+        }
+
+        this.dirty++;
+
+        return this;
+    };
+
+    /**
+     * Specifies a simple one-color fill that subsequent calls to other Graphics methods
+     * (such as lineTo() or drawCircle()) use when drawing.
+     *
+     * @param color {number} the color of the fill
+     * @param alpha {number} the alpha of the fill
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.beginFill = function (color, alpha)
+    {
+        this.filling = true;
+        this.fillColor = color || 0;
+        this.fillAlpha = (alpha === undefined) ? 1 : alpha;
+
+        if (this.currentPath)
+        {
+            if (this.currentPath.shape.points.length <= 2)
+            {
+                this.currentPath.fill = this.filling;
+                this.currentPath.fillColor = this.fillColor;
+                this.currentPath.fillAlpha = this.fillAlpha;
+            }
+        }
+        return this;
+    };
+
+    /**
+     * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.
+     *
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.endFill = function ()
+    {
+        this.filling = false;
+        this.fillColor = null;
+        this.fillAlpha = 1;
+
+        return this;
+    };
+
+    /**
+     *
+     * @param x {number} The X coord of the top-left of the rectangle
+     * @param y {number} The Y coord of the top-left of the rectangle
+     * @param width {number} The width of the rectangle
+     * @param height {number} The height of the rectangle
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.drawRect = function ( x, y, width, height )
+    {
+        this.drawShape(new math.Rectangle(x,y, width, height));
+
+        return this;
+    };
+
+    /**
+     *
+     * @param x {number} The X coord of the top-left of the rectangle
+     * @param y {number} The Y coord of the top-left of the rectangle
+     * @param width {number} The width of the rectangle
+     * @param height {number} The height of the rectangle
+     * @param radius {number} Radius of the rectangle corners
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.drawRoundedRect = function ( x, y, width, height, radius )
+    {
+        this.drawShape(new math.RoundedRectangle(x, y, width, height, radius));
+
+        return this;
+    };
+
+    /**
+     * Draws a circle.
+     *
+     * @param x {number} The X coordinate of the center of the circle
+     * @param y {number} The Y coordinate of the center of the circle
+     * @param radius {number} The radius of the circle
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.drawCircle = function (x, y, radius)
+    {
+        this.drawShape(new math.Circle(x,y, radius));
+
+        return this;
+    };
+
+    /**
+     * Draws an ellipse.
+     *
+     * @param x {number} The X coordinate of the center of the ellipse
+     * @param y {number} The Y coordinate of the center of the ellipse
+     * @param width {number} The half width of the ellipse
+     * @param height {number} The half height of the ellipse
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.drawEllipse = function (x, y, width, height)
+    {
+        this.drawShape(new math.Ellipse(x, y, width, height));
+
+        return this;
+    };
+
+    /**
+     * Draws a polygon using the given path.
+     *
+     * @param path {number[]|PIXI.Point[]} The path data used to construct the polygon.
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.drawPolygon = function (path)
+    {
+        // prevents an argument assignment deopt
+        // see section 3.1: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments
+        var points = path;
+
+        var closed = true;
+
+        if (points instanceof math.Polygon)
+        {
+            closed = points.closed;
+            points = points.points;
+        }
+
+        if (!Array.isArray(points))
+        {
+            // prevents an argument leak deopt
+            // see section 3.2: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments
+            points = new Array(arguments.length);
+
+            for (var i = 0; i < points.length; ++i)
+            {
+                points[i] = arguments[i];
+            }
+        }
+
+        var shape = new math.Polygon(points);
+        shape.closed = closed;
+
+        this.drawShape(shape);
+
+        return this;
+    };
+
+    /**
+     * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
+     *
+     * @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
+     */
+    Graphics.prototype.clear = function ()
+    {
+        this.lineWidth = 0;
+        this.filling = false;
+
+        this.dirty++;
+        this.clearDirty++;
+        this.graphicsData = [];
+
+        return this;
+    };
+
+    /**
+     * True if graphics consists of one rectangle, and thus, can be drawn like a Sprite and masked with gl.scissor
+     * @returns {boolean}
+     */
+    Graphics.prototype.isFastRect = function() {
+        return this.graphicsData.length === 1 && this.graphicsData[0].shape.type === CONST.SHAPES.RECT && !this.graphicsData[0].lineWidth;
+    };
+
+    /**
+     * Renders the object using the WebGL renderer
+     *
+     * @param renderer {PIXI.WebGLRenderer}
+     * @private
+     */
+    Graphics.prototype._renderWebGL = function (renderer)
+    {
+        // if the sprite is not visible or the alpha is 0 then no need to render this element
+        if(this.dirty !== this.fastRectDirty)
+        {
+            this.fastRectDirty = this.dirty;
+            this._fastRect = this.isFastRect();
+        }
+
+        //TODO this check can be moved to dirty?
+        if(this._fastRect)
+        {
+            this._renderSpriteRect(renderer);
+        }
+        else
+        {
+            renderer.setObjectRenderer(renderer.plugins.graphics);
+            renderer.plugins.graphics.render(this);
+        }
+
+    };
+
+    Graphics.prototype._renderSpriteRect = function (renderer)
+    {
+        var rect = this.graphicsData[0].shape;
+        if(!this._spriteRect)
+        {
+            if(!Graphics._SPRITE_TEXTURE)
+            {
+                var canvas = document.createElement('canvas');
+                canvas.width = 10;
+                canvas.height = 10;
+                var context = canvas.getContext('2d');
+                context.fillStyle = 'white';
+                context.fillRect(0, 0, 10, 10);
+                Graphics._SPRITE_TEXTURE = Texture.fromCanvas(canvas);
+            }
+
+            this._spriteRect = new Sprite(Graphics._SPRITE_TEXTURE);
+        }
+        if (this.tint === 0xffffff) {
+            this._spriteRect.tint = this.graphicsData[0].fillColor;
+        } else {
+            var t1 = tempColor1;
+            var t2 = tempColor2;
+            utils.hex2rgb(this.graphicsData[0].fillColor, t1);
+            utils.hex2rgb(this.tint, t2);
+            t1[0] *= t2[0];
+            t1[1] *= t2[1];
+            t1[2] *= t2[2];
+            this._spriteRect.tint = utils.rgb2hex(t1);
+        }
+        this._spriteRect.alpha = this.graphicsData[0].fillAlpha;
+        this._spriteRect.worldAlpha = this.worldAlpha * this._spriteRect.alpha;
+
+        Graphics._SPRITE_TEXTURE._frame.width = rect.width;
+        Graphics._SPRITE_TEXTURE._frame.height = rect.height;
+
+        this._spriteRect.transform.worldTransform = this.transform.worldTransform;
+
+        this._spriteRect.anchor.set(-rect.x / rect.width, -rect.y / rect.height);
+        this._spriteRect.onAnchorUpdate();
+
+        this._spriteRect._renderWebGL(renderer);
+    };
+
+    /**
+     * Renders the object using the Canvas renderer
+     *
+     * @param renderer {PIXI.CanvasRenderer}
+     * @private
+     */
+    Graphics.prototype._renderCanvas = function (renderer)
+    {
+        if (this.isMask === true)
+        {
+            return;
+        }
+
+        renderer.plugins.graphics.render(this);
+    };
+
+    /**
+     * Retrieves the bounds of the graphic shape as a rectangle object
+     *
+     * @param [matrix] {PIXI.Matrix} The world transform matrix to use, defaults to this
+     *  object's worldTransform.
+     * @return {PIXI.Rectangle} the rectangular bounding area
+     */
+    Graphics.prototype._calculateBounds = function ()
+    {
+        if (!this.renderable)
+        {
+            return;
+        }
+
+        if (this.boundsDirty !== this.dirty)
+        {
+            this.boundsDirty = this.dirty;
+            this.updateLocalBounds();
+
+            this.dirty++;
+            this.cachedSpriteDirty = true;
+        }
+
+        var lb = this._localBounds;
+        this._bounds.addFrame(this.transform, lb.minX, lb.minY, lb.maxX, lb.maxY);
+    };
+
+    /**
+     * Tests if a point is inside this graphics object
+     *
+     * @param point {PIXI.Point} the point to test
+     * @return {boolean} the result of the test
+     */
+    Graphics.prototype.containsPoint = function( point )
+    {
+        this.worldTransform.applyInverse(point,  tempPoint);
+
+        var graphicsData = this.graphicsData;
+
+        for (var i = 0; i < graphicsData.length; i++)
+        {
+            var data = graphicsData[i];
+
+            if (!data.fill)
+            {
+                continue;
+            }
+
+            // only deal with fills..
+            if (data.shape)
+            {
+                if ( data.shape.contains( tempPoint.x, tempPoint.y ) )
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    };
+
+    /**
+     * Update the bounds of the object
+     *
+     */
+    Graphics.prototype.updateLocalBounds = function ()
+    {
+        var minX = Infinity;
+        var maxX = -Infinity;
+
+        var minY = Infinity;
+        var maxY = -Infinity;
+
+        if (this.graphicsData.length)
+        {
+            var shape, points, x, y, w, h;
+
+            for (var i = 0; i < this.graphicsData.length; i++)
+            {
+                var data = this.graphicsData[i];
+                var type = data.type;
+                var lineWidth = data.lineWidth;
+                shape = data.shape;
+
+                if (type === CONST.SHAPES.RECT || type === CONST.SHAPES.RREC)
+                {
+                    x = shape.x - lineWidth/2;
+                    y = shape.y - lineWidth/2;
+                    w = shape.width + lineWidth;
+                    h = shape.height + lineWidth;
+
+                    minX = x < minX ? x : minX;
+                    maxX = x + w > maxX ? x + w : maxX;
+
+                    minY = y < minY ? y : minY;
+                    maxY = y + h > maxY ? y + h : maxY;
+                }
+                else if (type === CONST.SHAPES.CIRC)
+                {
+                    x = shape.x;
+                    y = shape.y;
+                    w = shape.radius + lineWidth/2;
+                    h = shape.radius + lineWidth/2;
+
+                    minX = x - w < minX ? x - w : minX;
+                    maxX = x + w > maxX ? x + w : maxX;
+
+                    minY = y - h < minY ? y - h : minY;
+                    maxY = y + h > maxY ? y + h : maxY;
+                }
+                else if (type === CONST.SHAPES.ELIP)
+                {
+                    x = shape.x;
+                    y = shape.y;
+                    w = shape.width + lineWidth/2;
+                    h = shape.height + lineWidth/2;
+
+                    minX = x - w < minX ? x - w : minX;
+                    maxX = x + w > maxX ? x + w : maxX;
+
+                    minY = y - h < minY ? y - h : minY;
+                    maxY = y + h > maxY ? y + h : maxY;
+                }
+                else
+                {
+                    // POLY
+                    points = shape.points;
+
+                    for (var j = 0; j < points.length; j += 2)
+                    {
+                        x = points[j];
+                        y = points[j+1];
+
+                        minX = x-lineWidth < minX ? x-lineWidth : minX;
+                        maxX = x+lineWidth > maxX ? x+lineWidth : maxX;
+
+                        minY = y-lineWidth < minY ? y-lineWidth : minY;
+                        maxY = y+lineWidth > maxY ? y+lineWidth : maxY;
+                    }
+                }
+            }
+        }
+        else
+        {
+            minX = 0;
+            maxX = 0;
+            minY = 0;
+            maxY = 0;
+        }
+
+        var padding = this.boundsPadding;
+
+        this._localBounds.minX = minX - padding;
+        this._localBounds.maxX = maxX + padding * 2;
+
+        this._localBounds.minY = minY - padding;
+        this._localBounds.maxY = maxY + padding * 2;
+    };
+
+
+    /**
+     * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon.
+     *
+     * @param shape {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} The shape object to draw.
+     * @return {PIXI.GraphicsData} The generated GraphicsData object.
+     */
+    Graphics.prototype.drawShape = function (shape)
+    {
+        if (this.currentPath)
+        {
+            // check current path!
+            if (this.currentPath.shape.points.length <= 2)
+            {
+                this.graphicsData.pop();
+            }
+        }
+
+        this.currentPath = null;
+
+        var data = new GraphicsData(this.lineWidth, this.lineColor, this.lineAlpha, this.fillColor, this.fillAlpha, this.filling, shape);
+
+        this.graphicsData.push(data);
+
+        if (data.type === CONST.SHAPES.POLY)
+        {
+            data.shape.closed = data.shape.closed || this.filling;
+            this.currentPath = data;
+        }
+
+        this.dirty++;
+
+        return data;
+    };
+
+    Graphics.prototype.generateCanvasTexture = function(scaleMode, resolution)
+    {
+        resolution = resolution || 1;
+
+        var bounds = this.getLocalBounds();
+
+        var canvasBuffer = new RenderTexture.create(bounds.width * resolution, bounds.height * resolution);
+
+        if(!canvasRenderer)
+        {
+            canvasRenderer = new CanvasRenderer();
+        }
+
+        tempMatrix.tx = -bounds.x;
+        tempMatrix.ty = -bounds.y;
+
+        canvasRenderer.render(this, canvasBuffer, false, tempMatrix);
+
+        var texture = Texture.fromCanvas(canvasBuffer.baseTexture._canvasRenderTarget.canvas, scaleMode);
+        texture.baseTexture.resolution = resolution;
+
+        return texture;
+    };
+
+    Graphics.prototype.closePath = function ()
+    {
+        // ok so close path assumes next one is a hole!
+        var currentPath = this.currentPath;
+        if (currentPath && currentPath.shape)
+        {
+            currentPath.shape.close();
+        }
+        return this;
+    };
+
+    Graphics.prototype.addHole = function()
+    {
+        // this is a hole!
+        var hole = this.graphicsData.pop();
+
+        this.currentPath = this.graphicsData[this.graphicsData.length-1];
+
+        this.currentPath.addHole(hole.shape);
+        this.currentPath = null;
+
+        return this;
+    };
+
+    /**
+     * Destroys the Graphics object.
+     */
+    Graphics.prototype.destroy = function ()
+    {
+        Container.prototype.destroy.apply(this, arguments);
+
+        // destroy each of the GraphicsData objects
+        for (var i = 0; i < this.graphicsData.length; ++i) {
+            this.graphicsData[i].destroy();
+        }
+
+        // for each webgl data entry, destroy the WebGLGraphicsData
+        for (var id in this._webgl) {
+            for (var j = 0; j < this._webgl[id].data.length; ++j) {
+                this._webgl[id].data[j].destroy();
+            }
+        }
+
+        if(this._spriteRect)
+        {
+            this._spriteRect.destroy();
+        }
+        this.graphicsData = null;
+
+        this.currentPath = null;
+        this._webgl = null;
+        this._localBounds = null;
+    };
+
+},{"../const":43,"../display/Bounds":44,"../display/Container":45,"../math":67,"../renderers/canvas/CanvasRenderer":74,"../sprites/Sprite":98,"../textures/RenderTexture":108,"../textures/Texture":109,"../utils":116,"./GraphicsData":51,"./utils/bezierCurveTo":53}],51:[function(require,module,exports){
+    /**
+     * A GraphicsData object.
+     *
+     * @class
+     * @memberof PIXI
+     * @param lineWidth {number} the width of the line to draw
+     * @param lineColor {number} the color of the line to draw
+     * @param lineAlpha {number} the alpha of the line to draw
+     * @param fillColor {number} the color of the fill
+     * @param fillAlpha {number} the alpha of the fill
+     * @param fill      {boolean} whether or not the shape is filled with a colour
+     * @param shape     {PIXI.Circle|PIXI.Rectangle|PIXI.Ellipse|PIXI.Polygon} The shape object to draw.
+     */
+    function GraphicsData(lineWidth, lineColor, lineAlpha, fillColor, fillAlpha, fill, shape)
+    {
+        /*
+         * @member {number} the width of the line to draw
+         */
+        this.lineWidth = lineWidth;
+
+        /*
+         * @member {number} the color of the line to draw
+         */
+        this.lineColor = lineColor;
+
+        /*
+         * @member {number} the alpha of the line to draw
+         */
+        this.lineAlpha = lineAlpha;
+
+        /*
+         * @member {number} cached tint of the line to draw
+         */
+        this._lineTint = lineColor;
+
+        /*
+         * @member {number} the color of the fill
+         */
+        this.fillColor = fillColor;
+
+        /*
+         * @member {number} the alpha of the fill
+         */
+        this.fillAlpha = fillAlpha;
+
+        /*
+         * @member {number} cached tint of the fill
+         */
+        this._fillTint = fillColor;
+
+        /*
+         * @member {boolean} whether or not the shape is filled with a colour
+         */
+        this.fill = fill;
+
+        this.holes = [];
+
+        /*
+         * @member {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} The shape object to draw.
+         */
+        this.shape = shape;
+
+        /*
+         * @member {number} The type of the shape, see the Const.Shapes file for all the existing types,
+         */
+        this.type = shape.type;
+    }
+
+    GraphicsData.prototype.constructor = GraphicsData;
+    module.exports = GraphicsData;
+
+    /**
+     * Creates a new GraphicsData object with the same values as this one.
+     *
+     * @return {PIXI.GraphicsData} Cloned GraphicsData object
+     */
+    GraphicsData.prototype.clone = function ()
+    {
+        return new GraphicsData(
+            this.lineWidth,
+            this.lineColor,
+            this.lineAlpha,
+            this.fillColor,
+            this.fillAlpha,
+            this.fill,
+            this.shape
+        );
+    };
+
+    /**
+     *
+     *
+     */
+    GraphicsData.prototype.addHole = function (shape)
+    {
+        this.holes.push(shape);
+    };
+
+    /**
+     * Destroys the Graphics data.
+     */
+    GraphicsData.prototype.destroy = function () {
+        this.shape = null;
+        this.holes = null;
+    };
+
+},{}],52:[function(require,module,exports){
+    var CanvasRenderer = require('../../renderers/canvas/CanvasRenderer'),
+        CONST = require('../../const');
+
+    /**
+     * @author Mat Groves
+     *
+     * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/
+     * for creating the original pixi version!
+     * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer
+     *
+     * Heavily inspired by LibGDX's CanvasGraphicsRenderer:
+     * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/CanvasGraphicsRenderer.java
+     */
+
+    /**
+     * Renderer dedicated to drawing and batching graphics objects.
+     *
+     * @class
+     * @private
+     * @memberof PIXI
+     * @extends PIXI.ObjectRenderer
+     * @param renderer {PIXI.SystemRenderer} The current PIXI renderer.
+     */
+    function CanvasGraphicsRenderer(renderer)
+    {
+        this.renderer = renderer;
+    }
+
+
+    CanvasGraphicsRenderer.prototype.constructor = CanvasGraphicsRenderer;
+    module.exports = CanvasGraphicsRenderer;
+
+    CanvasRenderer.registerPlugin('graphics', CanvasGraphicsRenderer);
+
+    /*
+     * Renders a Graphics object to a canvas.
+     *
+     * @param graphics {PIXI.Graphics} the actual graphics object to render
+     * @param context {CanvasRenderingContext2D} the 2d drawing method of the canvas
+     */
+    CanvasGraphicsRenderer.prototype.render = function (graphics)
+    {
+        var renderer = this.renderer;
+        var context = renderer.context;
+        var worldAlpha = graphics.worldAlpha;
+        var transform = graphics.transform.worldTransform;
+        var resolution = renderer.resolution;
+
+        // if the tint has changed, set the graphics object to dirty.
+        if (this._prevTint !== this.tint) {
+            this.dirty = true;
+        }
+
+        context.setTransform(
+            transform.a * resolution,
+            transform.b * resolution,
+            transform.c * resolution,
+            transform.d * resolution,
+            transform.tx * resolution,
+            transform.ty * resolution
+        );
+
+
+        if (graphics.dirty)
+        {
+            this.updateGraphicsTint(graphics);
+            graphics.dirty = false;
+        }
+
+        renderer.setBlendMode(graphics.blendMode);
+
+        for (var i = 0; i < graphics.graphicsData.length; i++)
+        {
+            var data = graphics.graphicsData[i];
+            var shape = data.shape;
+
+            var fillColor = data._fillTint;
+            var lineColor = data._lineTint;
+
+            context.lineWidth = data.lineWidth;
+
+            if (data.type === CONST.SHAPES.POLY)
+            {
+                context.beginPath();
+
+                this.renderPolygon(shape.points, shape.closed, context);
+
+                for (var j = 0; j < data.holes.length; j++)
+                {
+                    var hole = data.holes[j];
+                    this.renderPolygon(hole.points, true, context);
+                }
+
+
+                if (data.fill)
+                {
+                    context.globalAlpha = data.fillAlpha * worldAlpha;
+                    context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6);
+                    context.fill();
+                }
+                if (data.lineWidth)
+                {
+                    context.globalAlpha = data.lineAlpha * worldAlpha;
+                    context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6);
+                    context.stroke();
+                }
+            }
+            else if (data.type === CONST.SHAPES.RECT)
+            {
+
+                if (data.fillColor || data.fillColor === 0)
+                {
+                    context.globalAlpha = data.fillAlpha * worldAlpha;
+                    context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6);
+                    context.fillRect(shape.x, shape.y, shape.width, shape.height);
+
+                }
+                if (data.lineWidth)
+                {
+                    context.globalAlpha = data.lineAlpha * worldAlpha;
+                    context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6);
+                    context.strokeRect(shape.x, shape.y, shape.width, shape.height);
+                }
+            }
+            else if (data.type === CONST.SHAPES.CIRC)
+            {
+                // TODO - need to be Undefined!
+                context.beginPath();
+                context.arc(shape.x, shape.y, shape.radius,0,2*Math.PI);
+                context.closePath();
+
+                if (data.fill)
+                {
+                    context.globalAlpha = data.fillAlpha * worldAlpha;
+                    context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6);
+                    context.fill();
+                }
+                if (data.lineWidth)
+                {
+                    context.globalAlpha = data.lineAlpha * worldAlpha;
+                    context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6);
+                    context.stroke();
+                }
+            }
+            else if (data.type === CONST.SHAPES.ELIP)
+            {
+                // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
+
+                var w = shape.width * 2;
+                var h = shape.height * 2;
+
+                var x = shape.x - w/2;
+                var y = shape.y - h/2;
+
+                context.beginPath();
+
+                var kappa = 0.5522848,
+                    ox = (w / 2) * kappa, // control point offset horizontal
+                    oy = (h / 2) * kappa, // control point offset vertical
+                    xe = x + w,           // x-end
+                    ye = y + h,           // y-end
+                    xm = x + w / 2,       // x-middle
+                    ym = y + h / 2;       // y-middle
+
+                context.moveTo(x, ym);
+                context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
+                context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
+                context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
+                context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
+
+                context.closePath();
+
+                if (data.fill)
+                {
+                    context.globalAlpha = data.fillAlpha * worldAlpha;
+                    context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6);
+                    context.fill();
+                }
+                if (data.lineWidth)
+                {
+                    context.globalAlpha = data.lineAlpha * worldAlpha;
+                    context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6);
+                    context.stroke();
+                }
+            }
+            else if (data.type === CONST.SHAPES.RREC)
+            {
+                var rx = shape.x;
+                var ry = shape.y;
+                var width = shape.width;
+                var height = shape.height;
+                var radius = shape.radius;
+
+                var maxRadius = Math.min(width, height) / 2 | 0;
+                radius = radius > maxRadius ? maxRadius : radius;
+
+                context.beginPath();
+                context.moveTo(rx, ry + radius);
+                context.lineTo(rx, ry + height - radius);
+                context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height);
+                context.lineTo(rx + width - radius, ry + height);
+                context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius);
+                context.lineTo(rx + width, ry + radius);
+                context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry);
+                context.lineTo(rx + radius, ry);
+                context.quadraticCurveTo(rx, ry, rx, ry + radius);
+                context.closePath();
+
+                if (data.fillColor || data.fillColor === 0)
+                {
+                    context.globalAlpha = data.fillAlpha * worldAlpha;
+                    context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6);
+                    context.fill();
+
+                }
+                if (data.lineWidth)
+                {
+                    context.globalAlpha = data.lineAlpha * worldAlpha;
+                    context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6);
+                    context.stroke();
+                }
+            }
+        }
+    };
+
+    /*
+     * Updates the tint of a graphics object
+     *
+     * @private
+     * @param graphics {PIXI.Graphics} the graphics that will have its tint updated
+     *
+     */
+    CanvasGraphicsRenderer.prototype.updateGraphicsTint = function (graphics)
+    {
+        graphics._prevTint = graphics.tint;
+
+        var tintR = (graphics.tint >> 16 & 0xFF) / 255;
+        var tintG = (graphics.tint >> 8 & 0xFF) / 255;
+        var tintB = (graphics.tint & 0xFF)/ 255;
+
+        for (var i = 0; i < graphics.graphicsData.length; i++)
+        {
+            var data = graphics.graphicsData[i];
+
+            var fillColor = data.fillColor | 0;
+            var lineColor = data.lineColor | 0;
+
+            // super inline cos im an optimization NAZI :)
+            data._fillTint = (((fillColor >> 16 & 0xFF) / 255 * tintR*255 << 16) + ((fillColor >> 8 & 0xFF) / 255 * tintG*255 << 8) +  (fillColor & 0xFF) / 255 * tintB*255);
+            data._lineTint = (((lineColor >> 16 & 0xFF) / 255 * tintR*255 << 16) + ((lineColor >> 8 & 0xFF) / 255 * tintG*255 << 8) +  (lineColor & 0xFF) / 255 * tintB*255);
+        }
+    };
+
+    CanvasGraphicsRenderer.prototype.renderPolygon = function (points, close, context)
+    {
+        context.moveTo(points[0], points[1]);
+
+        for (var j=1; j < points.length/2; j++)
+        {
+            context.lineTo(points[j * 2], points[j * 2 + 1]);
+        }
+
+        if (close)
+        {
+            context.closePath();
+        }
+    };
+
+    /*
+     * destroy graphics object
+     *
+     */
+    CanvasGraphicsRenderer.prototype.destroy = function ()
+    {
+        this.renderer = null;
+    };
+
+},{"../../const":43,"../../renderers/canvas/CanvasRenderer":74}],53:[function(require,module,exports){
+
+    /**
+     * Calculate the points for a bezier curve and then draws it.
+     *
+     * Ignored from docs since it is not directly exposed.
+     *
+     * @ignore
+     * @param fromX {number} Starting point x
+     * @param fromY {number} Starting point y
+     * @param cpX {number} Control point x
+     * @param cpY {number} Control point y
+     * @param cpX2 {number} Second Control point x
+     * @param cpY2 {number} Second Control point y
+     * @param toX {number} Destination point x
+     * @param toY {number} Destination point y
+     * @param [path=number[]] Path array to push points into
+     * @return {PIXI.Graphics}
+     */
+    var bezierCurveTo = function (fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY, path) // jshint ignore:line
+    {
+        path = path || [];
+
+        var n = 20,
+            dt,
+            dt2,
+            dt3,
+            t2,
+            t3;
+
+        path.push(fromX, fromY);
+
+        var j = 0;
+
+        for (var i = 1; i <= n; ++i)
+        {
+            j = i / n;
+
+            dt = (1 - j);
+            dt2 = dt * dt;
+            dt3 = dt2 * dt;
+
+            t2 = j * j;
+            t3 = t2 * j;
+
+            path.push( dt3 * fromX + 3 * dt2 * j * cpX + 3 * dt * t2 * cpX2 + t3 * toX,
+                dt3 * fromY + 3 * dt2 * j * cpY + 3 * dt * t2 * cpY2 + t3 * toY);
+        }
+
+        return path;
+    };
+
+    module.exports = bezierCurveTo;
+
+},{}],54:[function(require,module,exports){
+    var utils = require('../../utils'),
+        CONST = require('../../const'),
+        ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'),
+        WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'),
+        WebGLGraphicsData = require('./WebGLGraphicsData'),
+        PrimitiveShader = require('./shaders/PrimitiveShader'),
+
+    // some drawing functions..
+        buildPoly = require('./utils/buildPoly'),
+        buildRectangle = require('./utils/buildRectangle'),
+        buildRoundedRectangle = require('./utils/buildRoundedRectangle'),
+        buildCircle = require('./utils/buildCircle');
+
+
+
+    /**
+     * Renders the graphics object.
+     *
+     * @class
+     * @memberof PIXI
+     * @extends PIXI.ObjectRenderer
+     * @param renderer {PIXI.WebGLRenderer} The renderer this object renderer works for.
+     */
+    function GraphicsRenderer(renderer)
+    {
+        ObjectRenderer.call(this, renderer);
+
+        this.graphicsDataPool = [];
+
+        this.primitiveShader = null;
+
+        this.gl = renderer.gl;
+
+        // easy access!
+        this.CONTEXT_UID = 0;
+    }
+
+    GraphicsRenderer.prototype = Object.create(ObjectRenderer.prototype);
+    GraphicsRenderer.prototype.constructor = GraphicsRenderer;
+    module.exports = GraphicsRenderer;
+
+    WebGLRenderer.registerPlugin('graphics', GraphicsRenderer);
+
+    /**
+     * Called when there is a WebGL context change
+     *
+     * @private
+     *
+     */
+    GraphicsRenderer.prototype.onContextChange = function()
+    {
+        this.gl = this.renderer.gl;
+        this.CONTEXT_UID = this.renderer.CONTEXT_UID;
+        this.primitiveShader = new PrimitiveShader(this.gl);
+    };
+
+    /**
+     * Destroys this renderer.
+     *
+     */
+    GraphicsRenderer.prototype.destroy = function ()
+    {
+        ObjectRenderer.prototype.destroy.call(this);
+
+        for (var i = 0; i < this.graphicsDataPool.length; ++i) {
+            this.graphicsDataPool[i].destroy();
+        }
+
+        this.graphicsDataPool = null;
+    };
+
+    /**
+     * Renders a graphics object.
+     *
+     * @param graphics {PIXI.Graphics} The graphics object to render.
+     */
+    GraphicsRenderer.prototype.render = function(graphics)
+    {
+        var renderer = this.renderer;
+        var gl = renderer.gl;
+
+        var webGLData;
+
+        var webGL = graphics._webGL[this.CONTEXT_UID];
+
+        if (!webGL || graphics.dirty !== webGL.dirty )
+        {
+
+            this.updateGraphics(graphics);
+
+            webGL = graphics._webGL[this.CONTEXT_UID];
+        }
+
+
+
+        // This  could be speeded up for sure!
+        var shader = this.primitiveShader;
+        renderer.bindShader(shader);
+        renderer.state.setBlendMode( graphics.blendMode );
+
+        for (var i = 0, n = webGL.data.length; i < n; i++)
+        {
+            webGLData = webGL.data[i];
+            var shaderTemp = webGLData.shader;
+
+            renderer.bindShader(shaderTemp);
+            shaderTemp.uniforms.translationMatrix = graphics.transform.worldTransform.toArray(true);
+            shaderTemp.uniforms.tint = utils.hex2rgb(graphics.tint);
+            shaderTemp.uniforms.alpha = graphics.worldAlpha;
+
+            webGLData.vao.bind()
+                .draw(gl.TRIANGLE_STRIP,  webGLData.indices.length)
+                .unbind();
+        }
+    };
+
+    /**
+     * Updates the graphics object
+     *
+     * @private
+     * @param graphics {PIXI.Graphics} The graphics object to update
+     */
+    GraphicsRenderer.prototype.updateGraphics = function(graphics)
+    {
+        var gl = this.renderer.gl;
+
+        // get the contexts graphics object
+        var webGL = graphics._webGL[this.CONTEXT_UID];
+
+        // if the graphics object does not exist in the webGL context time to create it!
+        if (!webGL)
+        {
+            webGL = graphics._webGL[this.CONTEXT_UID] = {lastIndex:0, data:[], gl:gl, clearDirty:-1, dirty:-1};
+
+        }
+
+        // flag the graphics as not dirty as we are about to update it...
+        webGL.dirty = graphics.dirty;
+
+        var i;
+
+        // if the user cleared the graphics object we will need to clear every object
+        if (graphics.clearDirty !== webGL.clearDirty)
+        {
+            webGL.clearDirty = graphics.clearDirty;
+
+            // loop through and return all the webGLDatas to the object pool so than can be reused later on
+            for (i = 0; i < webGL.data.length; i++)
+            {
+                var graphicsData = webGL.data[i];
+                this.graphicsDataPool.push( graphicsData );
+            }
+
+            // clear the array and reset the index..
+            webGL.data = [];
+            webGL.lastIndex = 0;
+        }
+
+        var webGLData;
+
+        // loop through the graphics datas and construct each one..
+        // if the object is a complex fill then the new stencil buffer technique will be used
+        // other wise graphics objects will be pushed into a batch..
+        for (i = webGL.lastIndex; i < graphics.graphicsData.length; i++)
+        {
+            var data = graphics.graphicsData[i];
+
+            //TODO - this can be simplified
+            webGLData = this.getWebGLData(webGL, 0);
+
+            if (data.type === CONST.SHAPES.POLY)
+            {
+                buildPoly(data, webGLData);
+            }
+            if (data.type === CONST.SHAPES.RECT)
+            {
+                buildRectangle(data, webGLData);
+            }
+            else if (data.type === CONST.SHAPES.CIRC || data.type === CONST.SHAPES.ELIP)
+            {
+                buildCircle(data, webGLData);
+            }
+            else if (data.type === CONST.SHAPES.RREC)
+            {
+                buildRoundedRectangle(data, webGLData);
+            }
+
+            webGL.lastIndex++;
+        }
+
+        // upload all the dirty data...
+        for (i = 0; i < webGL.data.length; i++)
+        {
+            webGLData = webGL.data[i];
+
+            if (webGLData.dirty)
+            {
+                webGLData.upload();
+            }
+        }
+    };
+
+    /**
+     *
+     * @private
+     * @param webGL {WebGLRenderingContext} the current WebGL drawing context
+     * @param type {number} TODO @Alvin
+     */
+    GraphicsRenderer.prototype.getWebGLData = function (webGL, type)
+    {
+        var webGLData = webGL.data[webGL.data.length-1];
+
+        if (!webGLData || webGLData.points.length > 320000)
+        {
+            webGLData = this.graphicsDataPool.pop() || new WebGLGraphicsData(this.renderer.gl, this.primitiveShader, this.renderer.state.attribsState);
+            webGLData.reset(type);
+            webGL.data.push(webGLData);
+        }
+
+        webGLData.dirty = true;
+
+        return webGLData;
+    };
+
+},{"../../const":43,"../../renderers/webgl/WebGLRenderer":81,"../../renderers/webgl/utils/ObjectRenderer":91,"../../utils":116,"./WebGLGraphicsData":55,"./shaders/PrimitiveShader":56,"./utils/buildCircle":57,"./utils/buildPoly":59,"./utils/buildRectangle":60,"./utils/buildRoundedRectangle":61}],55:[function(require,module,exports){
+    var glCore = require('pixi-gl-core');
+
+
+    /**
+     * An object containing WebGL specific properties to be used by the WebGL renderer
+     *
+     * @class
+     * @private
+     * @memberof PIXI
+     * @param gl {WebGLRenderingContext} The current WebGL drawing context
+     * @param shader {PIXI.Shader} The shader
+     * @param attribsState {object} The state for the VAO
+     */
+    function WebGLGraphicsData(gl, shader, attribsState)
+    {
+
+        /**
+         * The current WebGL drawing context
+         *
+         * @member {WebGLRenderingContext}
+         */
+        this.gl = gl;
+
+        //TODO does this need to be split before uploding??
+        /**
+         * An array of color components (r,g,b)
+         * @member {number[]}
+         */
+        this.color = [0,0,0]; // color split!
+
+        /**
+         * An array of points to draw
+         * @member {PIXI.Point[]}
+         */
+        this.points = [];
+
+        /**
+         * The indices of the vertices
+         * @member {number[]}
+         */
+        this.indices = [];
+        /**
+         * The main buffer
+         * @member {WebGLBuffer}
+         */
+        this.buffer = glCore.GLBuffer.createVertexBuffer(gl);
+
+        /**
+         * The index buffer
+         * @member {WebGLBuffer}
+         */
+        this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl);
+
+        /**
+         * Whether this graphics is dirty or not
+         * @member {boolean}
+         */
+        this.dirty = true;
+
+        this.glPoints = null;
+        this.glIndices = null;
+
+        /**
+         *
+         * @member {PIXI.Shader}
+         */
+        this.shader = shader;
+
+        this.vao =  new glCore.VertexArrayObject(gl, attribsState)
+            .addIndex(this.indexBuffer)
+            .addAttribute(this.buffer, shader.attributes.aVertexPosition, gl.FLOAT, false, 4 * 6, 0)
+            .addAttribute(this.buffer, shader.attributes.aColor, gl.FLOAT, false, 4 * 6, 2 * 4);
+
+
+    }
+
+    WebGLGraphicsData.prototype.constructor = WebGLGraphicsData;
+    module.exports = WebGLGraphicsData;
+
+    /**
+     * Resets the vertices and the indices
+     */
+    WebGLGraphicsData.prototype.reset = function ()
+    {
+        this.points.length = 0;
+        this.indices.length = 0;
+    };
+
+    /**
+     * Binds the buffers and uploads the data
+     */
+    WebGLGraphicsData.prototype.upload = function ()
+    {
+        this.glPoints = new Float32Array(this.points);
+        this.buffer.upload( this.glPoints );
+
+        this.glIndices = new Uint16Array(this.indices);
+        this.indexBuffer.upload( this.glIndices );
+
+        this.dirty = false;
+    };
+
+
+
+    /**
+     * Empties all the data
+     */
+    WebGLGraphicsData.prototype.destroy = function ()
+    {
+        this.color = null;
+        this.points = null;
+        this.indices = null;
+
+        this.vao.destroy();
+        this.buffer.destroy();
+        this.indexBuffer.destroy();
+
+        this.gl = null;
+
+        this.buffer = null;
+        this.indexBuffer = null;
+
+        this.glPoints = null;
+        this.glIndices = null;
+    };
+
+},{"pixi-gl-core":12}],56:[function(require,module,exports){
+    var Shader = require('../../../Shader');
+
+    /**
+     * This shader is used to draw simple primitive shapes for {@link PIXI.Graphics}.
+     *
+     * @class
+     * @memberof PIXI
+     * @extends PIXI.Shader
+     * @param gl {WebGLRenderingContext} The webgl shader manager this shader works for.
+     */
+    function PrimitiveShader(gl)
+    {
+        Shader.call(this,
+            gl,
+            // vertex shader
+            [
+                'attribute vec2 aVertexPosition;',
+                'attribute vec4 aColor;',
+
+                'uniform mat3 translationMatrix;',
+                'uniform mat3 projectionMatrix;',
+
+                'uniform float alpha;',
+                'uniform vec3 tint;',
+
+                'varying vec4 vColor;',
+
+                'void main(void){',
+                '   gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',
+                '   vColor = aColor * vec4(tint * alpha, alpha);',
+                '}'
+            ].join('\n'),
+            // fragment shader
+            [
+                'varying vec4 vColor;',
+
+                'void main(void){',
+                '   gl_FragColor = vColor;',
+                '}'
+            ].join('\n')
+        );
+    }
+
+    PrimitiveShader.prototype = Object.create(Shader.prototype);
+    PrimitiveShader.prototype.constructor = PrimitiveShader;
+
+    module.exports = PrimitiveShader;
+
+},{"../../../Shader":42}],57:[function(require,module,exports){
+    var buildLine = require('./buildLine'),
+        CONST = require('../../../const'),
+        utils = require('../../../utils');
+
+    /**
+     * Builds a circle to draw
+     *
+     * Ignored from docs since it is not directly exposed.
+     *
+     * @ignore
+     * @private
+     * @param graphicsData {PIXI.WebGLGraphicsData} The graphics object to draw
+     * @param webGLData {object} an object containing all the webGL-specific information to create this shape
+     */
+    var buildCircle = function (graphicsData, webGLData)
+    {
+        // need to convert points to a nice regular data
+        var circleData = graphicsData.shape;
+        var x = circleData.x;
+        var y = circleData.y;
+        var width;
+        var height;
+
+        // TODO - bit hacky??
+        if (graphicsData.type === CONST.SHAPES.CIRC)
+        {
+            width = circleData.radius;
+            height = circleData.radius;
+        }
+        else
+        {
+            width = circleData.width;
+            height = circleData.height;
+        }
+
+        var totalSegs = Math.floor(30 * Math.sqrt(circleData.radius)) || Math.floor(15 * Math.sqrt(circleData.width + circleData.height));
+        var seg = (Math.PI * 2) / totalSegs ;
+
+        var i = 0;
+
+        if (graphicsData.fill)
+        {
+            var color = utils.hex2rgb(graphicsData.fillColor);
+            var alpha = graphicsData.fillAlpha;
+
+            var r = color[0] * alpha;
+            var g = color[1] * alpha;
+            var b = color[2] * alpha;
+
+            var verts = webGLData.points;
+            var indices = webGLData.indices;
+
+            var vecPos = verts.length/6;
+
+            indices.push(vecPos);
+
+            for (i = 0; i < totalSegs + 1 ; i++)
+            {
+                verts.push(x,y, r, g, b, alpha);
+
+                verts.push(x + Math.sin(seg * i) * width,
+                    y + Math.cos(seg * i) * height,
+                    r, g, b, alpha);
+
+                indices.push(vecPos++, vecPos++);
+            }
+
+            indices.push(vecPos-1);
+        }
+
+        if (graphicsData.lineWidth)
+        {
+            var tempPoints = graphicsData.points;
+
+            graphicsData.points = [];
+
+            for (i = 0; i < totalSegs + 1; i++)
+            {
+                graphicsData.points.push(x + Math.sin(seg * i) * width,
+                    y + Math.cos(seg * i) * height);
+            }
+
+            buildLine(graphicsData, webGLData);
+
+            graphicsData.points = tempPoints;
+        }
+    };
+
+
+    module.exports = buildCircle;
+
+},{"../../../const":43,"../../../utils":116,"./buildLine":58}],58:[function(require,module,exports){
+    var math = require('../../../math'),
+        utils = require('../../../utils');
+
+    /**
+     * Builds a line to draw
+     *
+     * Ignored from docs since it is not directly exposed.
+     *
+     * @ignore
+     * @private
+     * @param graphicsData {PIXI.WebGLGraphicsData} The graphics object containing all the necessary properties
+     * @param webGLData {object} an object containing all the webGL-specific information to create this shape
+     */
+    var buildLine = function (graphicsData, webGLData)
+    {
+        // TODO OPTIMISE!
+        var i = 0;
+        var points = graphicsData.points;
+
+        if (points.length === 0)
+        {
+            return;
+        }
+        // if the line width is an odd number add 0.5 to align to a whole pixel
+        // commenting this out fixes #711 and #1620
+        // if (graphicsData.lineWidth%2)
+        // {
+        //     for (i = 0; i < points.length; i++)
+        //     {
+        //         points[i] += 0.5;
+        //     }
+        // }
+
+        // get first and last point.. figure out the middle!
+        var firstPoint = new math.Point(points[0], points[1]);
+        var lastPoint = new math.Point(points[points.length - 2], points[points.length - 1]);
+
+        // if the first point is the last point - gonna have issues :)
+        if (firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y)
+        {
+            // need to clone as we are going to slightly modify the shape..
+            points = points.slice();
+
+            points.pop();
+            points.pop();
+
+            lastPoint = new math.Point(points[points.length - 2], points[points.length - 1]);
+
+            var midPointX = lastPoint.x + (firstPoint.x - lastPoint.x) *0.5;
+            var midPointY = lastPoint.y + (firstPoint.y - lastPoint.y) *0.5;
+
+            points.unshift(midPointX, midPointY);
+            points.push(midPointX, midPointY);
+        }
+
+        var verts = webGLData.points;
+        var indices = webGLData.indices;
+        var length = points.length / 2;
+        var indexCount = points.length;
+        var indexStart = verts.length/6;
+
+        // DRAW the Line
+        var width = graphicsData.lineWidth / 2;
+
+        // sort color
+        var color = utils.hex2rgb(graphicsData.lineColor);
+        var alpha = graphicsData.lineAlpha;
+        var r = color[0] * alpha;
+        var g = color[1] * alpha;
+        var b = color[2] * alpha;
+
+        var px, py, p1x, p1y, p2x, p2y, p3x, p3y;
+        var perpx, perpy, perp2x, perp2y, perp3x, perp3y;
+        var a1, b1, c1, a2, b2, c2;
+        var denom, pdist, dist;
+
+        p1x = points[0];
+        p1y = points[1];
+
+        p2x = points[2];
+        p2y = points[3];
+
+        perpx = -(p1y - p2y);
+        perpy =  p1x - p2x;
+
+        dist = Math.sqrt(perpx*perpx + perpy*perpy);
+
+        perpx /= dist;
+        perpy /= dist;
+        perpx *= width;
+        perpy *= width;
+
+        // start
+        verts.push(p1x - perpx , p1y - perpy,
+            r, g, b, alpha);
+
+        verts.push(p1x + perpx , p1y + perpy,
+            r, g, b, alpha);
+
+        for (i = 1; i < length-1; i++)
+        {
+            p1x = points[(i-1)*2];
+            p1y = points[(i-1)*2 + 1];
+
+            p2x = points[(i)*2];
+            p2y = points[(i)*2 + 1];
+
+            p3x = points[(i+1)*2];
+            p3y = points[(i+1)*2 + 1];
+
+            perpx = -(p1y - p2y);
+            perpy = p1x - p2x;
+
+            dist = Math.sqrt(perpx*perpx + perpy*perpy);
+            perpx /= dist;
+            perpy /= dist;
+            perpx *= width;
+            perpy *= width;
+
+            perp2x = -(p2y - p3y);
+            perp2y = p2x - p3x;
+
+            dist = Math.sqrt(perp2x*perp2x + perp2y*perp2y);
+            perp2x /= dist;
+            perp2y /= dist;
+            perp2x *= width;
+            perp2y *= width;
+
+            a1 = (-perpy + p1y) - (-perpy + p2y);
+            b1 = (-perpx + p2x) - (-perpx + p1x);
+            c1 = (-perpx + p1x) * (-perpy + p2y) - (-perpx + p2x) * (-perpy + p1y);
+            a2 = (-perp2y + p3y) - (-perp2y + p2y);
+            b2 = (-perp2x + p2x) - (-perp2x + p3x);
+            c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y);
+
+            denom = a1*b2 - a2*b1;
+
+            if (Math.abs(denom) < 0.1 )
+            {
+
+                denom+=10.1;
+                verts.push(p2x - perpx , p2y - perpy,
+                    r, g, b, alpha);
+
+                verts.push(p2x + perpx , p2y + perpy,
+                    r, g, b, alpha);
+
+                continue;
+            }
+
+            px = (b1*c2 - b2*c1)/denom;
+            py = (a2*c1 - a1*c2)/denom;
+
+
+            pdist = (px -p2x) * (px -p2x) + (py -p2y) * (py -p2y);
+
+
+            if (pdist > 140 * 140)
+            {
+                perp3x = perpx - perp2x;
+                perp3y = perpy - perp2y;
+
+                dist = Math.sqrt(perp3x*perp3x + perp3y*perp3y);
+                perp3x /= dist;
+                perp3y /= dist;
+                perp3x *= width;
+                perp3y *= width;
+
+                verts.push(p2x - perp3x, p2y -perp3y);
+                verts.push(r, g, b, alpha);
+
+                verts.push(p2x + perp3x, p2y +perp3y);
+                verts.push(r, g, b, alpha);
+
+                verts.push(p2x - perp3x, p2y -perp3y);
+                verts.push(r, g, b, alpha);
+
+                indexCount++;
+            }
+            else
+            {
+
+                verts.push(px , py);
+                verts.push(r, g, b, alpha);
+
+                verts.push(p2x - (px-p2x), p2y - (py - p2y));
+                verts.push(r, g, b, alpha);
+            }
+        }
+
+        p1x = points[(length-2)*2];
+        p1y = points[(length-2)*2 + 1];
+
+        p2x = points[(length-1)*2];
+        p2y = points[(length-1)*2 + 1];
+
+        perpx = -(p1y - p2y);
+        perpy = p1x - p2x;
+
+        dist = Math.sqrt(perpx*perpx + perpy*perpy);
+        perpx /= dist;
+        perpy /= dist;
+        perpx *= width;
+        perpy *= width;
+
+        verts.push(p2x - perpx , p2y - perpy);
+        verts.push(r, g, b, alpha);
+
+        verts.push(p2x + perpx , p2y + perpy);
+        verts.push(r, g, b, alpha);
+
+        indices.push(indexStart);
+
+        for (i = 0; i < indexCount; i++)
+        {
+            indices.push(indexStart++);
+        }
+
+        indices.push(indexStart-1);
+    };
+
+    module.exports = buildLine;
+
+},{"../../../math":67,"../../../utils":116}],59:[function(require,module,exports){
+    var buildLine = require('./buildLine'),
+        utils = require('../../../utils'),
+        earcut = require('earcut');
+
+    /**
+     * Builds a polygon to draw
+     *
+     * Ignored from docs since it is not directly exposed.
+     *
+     * @ignore
+     * @private
+     * @param graphicsData {PIXI.WebGLGraphicsData} The graphics object containing all the necessary properties
+     * @param webGLData {object} an object containing all the webGL-specific information to create this shape
+     */
+    var buildPoly = function (graphicsData, webGLData)
+    {
+        graphicsData.points = graphicsData.shape.points.slice();
+
+        var points = graphicsData.points;
+
+        if(graphicsData.fill && points.length >= 6)
+        {
+            var holeArray = [];
+            // Process holes..
+            var holes = graphicsData.holes;
+
+            for (var i = 0; i < holes.length; i++) {
+                var hole = holes[i];
+
+                holeArray.push(points.length/2);
+
+                points = points.concat(hole.points);
+            }
+
+            // get first and last point.. figure out the middle!
+            var verts = webGLData.points;
+            var indices = webGLData.indices;
+
+            var length = points.length / 2;
+
+            // sort color
+            var color = utils.hex2rgb(graphicsData.fillColor);
+            var alpha = graphicsData.fillAlpha;
+            var r = color[0] * alpha;
+            var g = color[1] * alpha;
+            var b = color[2] * alpha;
+
+            var triangles = earcut(points, holeArray, 2);
+
+            if (!triangles) {
+                return;
+            }
+
+            var vertPos = verts.length / 6;
+
+            for (i = 0; i < triangles.length; i+=3)
+            {
+                indices.push(triangles[i] + vertPos);
+                indices.push(triangles[i] + vertPos);
+                indices.push(triangles[i+1] + vertPos);
+                indices.push(triangles[i+2] +vertPos);
+                indices.push(triangles[i+2] + vertPos);
+            }
+
+            for (i = 0; i < length; i++)
+            {
+                verts.push(points[i * 2], points[i * 2 + 1],
+                    r, g, b, alpha);
+            }
+        }
+
+        if (graphicsData.lineWidth > 0)
+        {
+            buildLine(graphicsData, webGLData);
+        }
+    };
+
+
+    module.exports = buildPoly;
+
+},{"../../../utils":116,"./buildLine":58,"earcut":2}],60:[function(require,module,exports){
+    var buildLine = require('./buildLine'),
+        utils = require('../../../utils');
+
+    /**
+     * Builds a rectangle to draw
+     *
+     * Ignored from docs since it is not directly exposed.
+     *
+     * @ignore
+     * @private
+     * @param graphicsData {PIXI.WebGLGraphicsData} The graphics object containing all the necessary properties
+     * @param webGLData {object} an object containing all the webGL-specific information to create this shape
+     */
+    var buildRectangle = function (graphicsData, webGLData)
+    {
+        // --- //
+        // need to convert points to a nice regular data
+        //
+        var rectData = graphicsData.shape;
+        var x = rectData.x;
+        var y = rectData.y;
+        var width = rectData.width;
+        var height = rectData.height;
+
+        if (graphicsData.fill)
+        {
+            var color = utils.hex2rgb(graphicsData.fillColor);
+            var alpha = graphicsData.fillAlpha;
+
+            var r = color[0] * alpha;
+            var g = color[1] * alpha;
+            var b = color[2] * alpha;
+
+            var verts = webGLData.points;
+            var indices = webGLData.indices;
+
+            var vertPos = verts.length/6;
+
+            // start
+            verts.push(x, y);
+            verts.push(r, g, b, alpha);
+
+            verts.push(x + width, y);
+            verts.push(r, g, b, alpha);
+
+            verts.push(x , y + height);
+            verts.push(r, g, b, alpha);
+
+            verts.push(x + width, y + height);
+            verts.push(r, g, b, alpha);
+
+            // insert 2 dead triangles..
+            indices.push(vertPos, vertPos, vertPos+1, vertPos+2, vertPos+3, vertPos+3);
+        }
+
+        if (graphicsData.lineWidth)
+        {
+            var tempPoints = graphicsData.points;
+
+            graphicsData.points = [x, y,
+                x + width, y,
+                x + width, y + height,
+                x, y + height,
+                x, y];
+
+
+            buildLine(graphicsData, webGLData);
+
+            graphicsData.points = tempPoints;
+        }
+    };
+
+    module.exports = buildRectangle;
+
+},{"../../../utils":116,"./buildLine":58}],61:[function(require,module,exports){
+    var earcut = require('earcut'),
+        buildLine = require('./buildLine'),
+        utils = require('../../../utils');
+
+    /**
+     * Builds a rounded rectangle to draw
+     *
+     * Ignored from docs since it is not directly exposed.
+     *
+     * @ignore
+     * @private
+     * @param graphicsData {PIXI.WebGLGraphicsData} The graphics object containing all the necessary properties
+     * @param webGLData {object} an object containing all the webGL-specific information to create this shape
+     */
+    var buildRoundedRectangle = function (graphicsData, webGLData)
+    {
+        var rrectData = graphicsData.shape;
+        var x = rrectData.x;
+        var y = rrectData.y;
+        var width = rrectData.width;
+        var height = rrectData.height;
+
+        var radius = rrectData.radius;
+
+        var recPoints = [];
+        recPoints.push(x, y + radius);
+        quadraticBezierCurve(x, y + height - radius, x, y + height, x + radius, y + height, recPoints);
+        quadraticBezierCurve(x + width - radius, y + height, x + width, y + height, x + width, y + height - radius, recPoints);
+        quadraticBezierCurve(x + width, y + radius, x + width, y, x + width - radius, y, recPoints);
+        quadraticBezierCurve(x + radius, y, x, y, x, y + radius + 0.0000000001, recPoints);
+
+        // this tiny number deals with the issue that occurs when points overlap and earcut fails to triangulate the item.
+        // TODO - fix this properly, this is not very elegant.. but it works for now.
+
+        if (graphicsData.fill)
+        {
+            var color = utils.hex2rgb(graphicsData.fillColor);
+            var alpha = graphicsData.fillAlpha;
+
+            var r = color[0] * alpha;
+            var g = color[1] * alpha;
+            var b = color[2] * alpha;
+
+            var verts = webGLData.points;
+            var indices = webGLData.indices;
+
+            var vecPos = verts.length/6;
+
+            var triangles = earcut(recPoints, null, 2);
+
+            var i = 0;
+            for (i = 0; i < triangles.length; i+=3)
+            {
+                indices.push(triangles[i] + vecPos);
+                indices.push(triangles[i] + vecPos);
+                indices.push(triangles[i+1] + vecPos);
+                indices.push(triangles[i+2] + vecPos);
+                indices.push(triangles[i+2] + vecPos);
+            }
+
+            for (i = 0; i < recPoints.length; i++)
+            {
+                verts.push(recPoints[i], recPoints[++i], r, g, b, alpha);
+            }
+        }
+
+        if (graphicsData.lineWidth)
+        {
+            var tempPoints = graphicsData.points;
+
+            graphicsData.points = recPoints;
+
+            buildLine(graphicsData, webGLData);
+
+            graphicsData.points = tempPoints;
+        }
+    };
+
+    /**
+     * Calculate the points for a quadratic bezier curve. (helper function..)
+     * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c
+     *
+     * Ignored from docs since it is not directly exposed.
+     *
+     * @ignore
+     * @private
+     * @param fromX {number} Origin point x
+     * @param fromY {number} Origin point x
+     * @param cpX {number} Control point x
+     * @param cpY {number} Control point y
+     * @param toX {number} Destination point x
+     * @param toY {number} Destination point y
+     * @param [out] {number[]} The output array to add points into. If not passed, a new array is created.
+     * @return {number[]} an array of points
+     */
+    var quadraticBezierCurve = function (fromX, fromY, cpX, cpY, toX, toY, out)// jshint ignore:line
+    {
+        var xa,
+            ya,
+            xb,
+            yb,
+            x,
+            y,
+            n = 20,
+            points = out || [];
+
+        function getPt(n1 , n2, perc) {
+            var diff = n2 - n1;
+
+            return n1 + ( diff * perc );
+        }
+
+        var j = 0;
+        for (var i = 0; i <= n; i++ ) {
+            j = i / n;
+
+            // The Green Line
+            xa = getPt( fromX , cpX , j );
+            ya = getPt( fromY , cpY , j );
+            xb = getPt( cpX , toX , j );
+            yb = getPt( cpY , toY , j );
+
+            // The Black Dot
+            x = getPt( xa , xb , j );
+            y = getPt( ya , yb , j );
+
+            points.push(x, y);
+        }
+
+        return points;
+    };
+
+
+    module.exports = buildRoundedRectangle;
+
+},{"../../../utils":116,"./buildLine":58,"earcut":2}],62:[function(require,module,exports){
+    /**
+     * @file        Main export of the PIXI core library
+     * @author      Mat Groves <mat@goodboydigital.com>
+     * @copyright   2013-2015 GoodBoyDigital
+     * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}
+     */
+
+    /**
+     * @namespace PIXI
+     */
+// export core and const. We assign core to const so that the non-reference types in const remain in-tact
+    var core = module.exports = Object.assign(require('./const'), require('./math'), {
+        // utils
+        utils: require('./utils'),
+        ticker: require('./ticker'),
+
+        // display
+        DisplayObject:          require('./display/DisplayObject'),
+        Container:              require('./display/Container'),
+        Transform:              require('./display/Transform'),
+        TransformStatic:        require('./display/TransformStatic'),
+        TransformBase:          require('./display/TransformBase'),
+
+        // sprites
+        Sprite:                 require('./sprites/Sprite'),
+        CanvasSpriteRenderer:     require('./sprites/canvas/CanvasSpriteRenderer'),
+        CanvasTinter:           require('./sprites/canvas/CanvasTinter'),
+        SpriteRenderer:         require('./sprites/webgl/SpriteRenderer'),
+
+        // text
+        Text:                   require('./text/Text'),
+        TextStyle:              require('./text/TextStyle'),
+        // primitives
+        Graphics:               require('./graphics/Graphics'),
+        GraphicsData:           require('./graphics/GraphicsData'),
+        GraphicsRenderer:       require('./graphics/webgl/GraphicsRenderer'),
+        CanvasGraphicsRenderer: require('./graphics/canvas/CanvasGraphicsRenderer'),
+
+        // textures
+        Texture:                require('./textures/Texture'),
+        BaseTexture:            require('./textures/BaseTexture'),
+        RenderTexture:          require('./textures/RenderTexture'),
+        BaseRenderTexture:      require('./textures/BaseRenderTexture'),
+        VideoBaseTexture:       require('./textures/VideoBaseTexture'),
+        TextureUvs:             require('./textures/TextureUvs'),
+
+        // renderers - canvas
+        CanvasRenderer:         require('./renderers/canvas/CanvasRenderer'),
+        CanvasRenderTarget:     require('./renderers/canvas/utils/CanvasRenderTarget'),
+
+        // renderers - webgl
+        Shader:                 require('./Shader'),
+        WebGLRenderer:          require('./renderers/webgl/WebGLRenderer'),
+        WebGLManager:           require('./renderers/webgl/managers/WebGLManager'),
+        ObjectRenderer:         require('./renderers/webgl/utils/ObjectRenderer'),
+        RenderTarget:           require('./renderers/webgl/utils/RenderTarget'),
+        Quad:                   require('./renderers/webgl/utils/Quad'),
+
+        // filters - webgl
+        SpriteMaskFilter:       require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'),
+        Filter:                 require('./renderers/webgl/filters/Filter'),
+
+        glCore:                   require('pixi-gl-core'),
+
+        /**
+         * This helper function will automatically detect which renderer you should be using.
+         * WebGL is the preferred renderer as it is a lot faster. If webGL is not supported by
+         * the browser then this function will return a canvas renderer
+         *
+         * @memberof PIXI
+         * @param width=800 {number} the width of the renderers view
+         * @param height=600 {number} the height of the renderers view
+         * @param [options] {object} The optional renderer parameters
+         * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional
+         * @param [options.transparent=false] {boolean} If the render view is transparent, default false
+         * @param [options.antialias=false] {boolean} sets antialias (only applicable in chrome at the moment)
+         * @param [options.preserveDrawingBuffer=false] {boolean} enables drawing buffer preservation, enable this if you
+         *      need to call toDataUrl on the webgl context
+         * @param [options.resolution=1] {number} The resolution / device pixel ratio of the renderer, retina would be 2
+         * @param [noWebGL=false] {boolean} prevents selection of WebGL renderer, even if such is present
+         *
+         * @return {WebGLRenderer|CanvasRenderer} Returns WebGL renderer if available, otherwise CanvasRenderer
+         */
+        autoDetectRenderer: function (width, height, options, noWebGL)
+        {
+            width = width || 800;
+            height = height || 600;
+
+            if (!noWebGL && core.utils.isWebGLSupported())
+            {
+                return new core.WebGLRenderer(width, height, options);
+            }
+
+            return new core.CanvasRenderer(width, height, options);
+        }
+    });
+
+},{"./Shader":42,"./const":43,"./display/Container":45,"./display/DisplayObject":46,"./display/Transform":47,"./display/TransformBase":48,"./display/TransformStatic":49,"./graphics/Graphics":50,"./graphics/GraphicsData":51,"./graphics/canvas/CanvasGraphicsRenderer":52,"./graphics/webgl/GraphicsRenderer":54,"./math":67,"./renderers/canvas/CanvasRenderer":74,"./renderers/canvas/utils/CanvasRenderTarget":76,"./renderers/webgl/WebGLRenderer":81,"./renderers/webgl/filters/Filter":83,"./renderers/webgl/filters/spriteMask/SpriteMaskFilter":86,"./renderers/webgl/managers/WebGLManager":90,"./renderers/webgl/utils/ObjectRenderer":91,"./renderers/webgl/utils/Quad":92,"./renderers/webgl/utils/RenderTarget":93,"./sprites/Sprite":98,"./sprites/canvas/CanvasSpriteRenderer":99,"./sprites/canvas/CanvasTinter":100,"./sprites/webgl/SpriteRenderer":102,"./text/Text":104,"./text/TextStyle":105,"./textures/BaseRenderTexture":106,"./textures/BaseTexture":107,"./textures/RenderTexture":108,"./textures/Texture":109,"./textures/TextureUvs":110,"./textures/VideoBaseTexture":111,"./ticker":113,"./utils":116,"pixi-gl-core":12}],63:[function(require,module,exports){
+// Your friendly neighbour https://en.wikipedia.org/wiki/Dihedral_group of order 16
+
+    var ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1];
+    var uy = [0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1];
+    var vx = [0, -1, -1, -1, 0, 1, 1, 1, 0, 1, 1, 1, 0, -1, -1, -1];
+    var vy = [1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, 1, 1, 1, 0, -1];
+    var tempMatrices = [];
+    var Matrix = require('./Matrix');
+
+    var mul = [];
+
+    function signum(x) {
+        if (x < 0) {
+            return -1;
+        }
+        if (x > 0) {
+            return 1;
+        }
+        return 0;
+    }
+
+    function init() {
+        for (var i = 0; i < 16; i++) {
+            var row = [];
+            mul.push(row);
+            for (var j = 0; j < 16; j++) {
+                var _ux = signum(ux[i] * ux[j] + vx[i] * uy[j]);
+                var _uy = signum(uy[i] * ux[j] + vy[i] * uy[j]);
+                var _vx = signum(ux[i] * vx[j] + vx[i] * vy[j]);
+                var _vy = signum(uy[i] * vx[j] + vy[i] * vy[j]);
+                for (var k = 0; k < 16; k++) {
+                    if (ux[k] === _ux && uy[k] === _uy && vx[k] === _vx && vy[k] === _vy) {
+                        row.push(k);
+                        break;
+                    }
+                }
+            }
+        }
+
+        for (i=0;i<16;i++) {
+            var mat = new Matrix();
+            mat.set(ux[i], uy[i], vx[i], vy[i], 0, 0);
+            tempMatrices.push(mat);
+        }
+    }
+
+    init();
+
+    /**
+     * Implements Dihedral Group D_8, see [group D4]{@link http://mathworld.wolfram.com/DihedralGroupD4.html}, D8 is the same but with diagonals
+     * Used for texture rotations
+     * Vector xX(i), xY(i) is U-axis of sprite with rotation i
+     * Vector yY(i), yY(i) is V-axis of sprite with rotation i
+     * Rotations: 0 grad (0), 90 grad (2), 180 grad (4), 270 grad (6)
+     * Mirrors: vertical (8), main diagonal (10), horizontal (12), reverse diagonal (14)
+     * This is the small part of gameofbombs.com portal system. It works.
+     * @author Ivan @ivanpopelyshev
+     *
+     * @namespace PIXI.GroupD8
+     */
+    var GroupD8 = {
+        E: 0,
+        SE: 1,
+        S: 2,
+        SW: 3,
+        W: 4,
+        NW: 5,
+        N: 6,
+        NE: 7,
+        MIRROR_VERTICAL: 8,
+        MIRROR_HORIZONTAL: 12,
+        uX: function (ind) {
+            return ux[ind];
+        },
+        uY: function (ind) {
+            return uy[ind];
+        },
+        vX: function (ind) {
+            return vx[ind];
+        },
+        vY: function (ind) {
+            return vy[ind];
+        },
+        inv: function (rotation) {
+            if (rotation & 8) {
+                return rotation & 15;
+            }
+            return (-rotation) & 7;
+        },
+        add: function (rotationSecond, rotationFirst) {
+            return mul[rotationSecond][rotationFirst];
+        },
+        sub: function (rotationSecond, rotationFirst) {
+            return mul[rotationSecond][GroupD8.inv(rotationFirst)];
+        },
+        /**
+         * Adds 180 degrees to rotation. Commutative operation
+         * @param rotation
+         * @returns {number}
+         */
+        rotate180: function (rotation) {
+            return rotation ^ 4;
+        },
+        /**
+         * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+         * @param rotation
+         * @returns {boolean}
+         */
+        isSwapWidthHeight: function(rotation) {
+            return (rotation & 3) === 2;
+        },
+        byDirection: function (dx, dy) {
+            if (Math.abs(dx) * 2 <= Math.abs(dy)) {
+                if (dy >= 0) {
+                    return GroupD8.S;
+                }
+                else {
+                    return GroupD8.N;
+                }
+            } else if (Math.abs(dy) * 2 <= Math.abs(dx)) {
+                if (dx > 0) {
+                    return GroupD8.E;
+                }
+                else {
+                    return GroupD8.W;
+                }
+            } else {
+                if (dy > 0) {
+                    if (dx > 0) {
+                        return GroupD8.SE;
+                    }
+                    else {
+                        return GroupD8.SW;
+                    }
+                }
+                else if (dx > 0) {
+                    return GroupD8.NE;
+                }
+                else {
+                    return GroupD8.NW;
+                }
+            }
+        },
+        /**
+         * Helps sprite to compensate texture packer rotation.
+         * @param matrix {PIXI.Matrix} sprite world matrix
+         * @param rotation {number}
+         * @param tx {number|*} sprite anchoring
+         * @param ty {number|*} sprite anchoring
+         */
+        matrixAppendRotationInv: function (matrix, rotation, tx, ty) {
+            //Packer used "rotation", we use "inv(rotation)"
+            var mat = tempMatrices[GroupD8.inv(rotation)];
+            tx = tx || 0;
+            ty = ty || 0;
+            mat.tx = tx;
+            mat.ty = ty;
+            matrix.append(mat);
+        }
+    };
+
+    module.exports = GroupD8;
+
+},{"./Matrix":64}],64:[function(require,module,exports){
+// @todo - ignore the too many parameters warning for now
+// should either fix it or change the jshint config
+// jshint -W072
+
+    var Point = require('./Point');
+
+    /**
+     * The pixi Matrix class as an object, which makes it a lot faster,
+     * here is a representation of it :
+     * | a | b | tx|
+     * | c | d | ty|
+     * | 0 | 0 | 1 |
+     *
+     * @class
+     * @memberof PIXI
+     */
+    function Matrix()
+    {
+        /**
+         * @member {number}
+         * @default 1
+         */
+        this.a = 1;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.b = 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.c = 0;
+
+        /**
+         * @member {number}
+         * @default 1
+         */
+        this.d = 1;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.tx = 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.ty = 0;
+
+        this.array = null;
+    }
+
+    Matrix.prototype.constructor = Matrix;
+    module.exports = Matrix;
+
+    /**
+     * Creates a Matrix object based on the given array. The Element to Matrix mapping order is as follows:
+     *
+     * a = array[0]
+     * b = array[1]
+     * c = array[3]
+     * d = array[4]
+     * tx = array[2]
+     * ty = array[5]
+     *
+     * @param array {number[]} The array that the matrix will be populated from.
+     */
+    Matrix.prototype.fromArray = function (array)
+    {
+        this.a = array[0];
+        this.b = array[1];
+        this.c = array[3];
+        this.d = array[4];
+        this.tx = array[2];
+        this.ty = array[5];
+    };
+
+
+    /**
+     * sets the matrix properties
+     *
+     * @param {number} a
+     * @param {number} b
+     * @param {number} c
+     * @param {number} d
+     * @param {number} tx
+     * @param {number} ty
+     *
+     * @return {PIXI.Matrix} This matrix. Good for chaining method calls.
+     */
+    Matrix.prototype.set = function (a, b, c, d, tx, ty)
+    {
+        this.a = a;
+        this.b = b;
+        this.c = c;
+        this.d = d;
+        this.tx = tx;
+        this.ty = ty;
+
+        return this;
+    };
+
+
+    /**
+     * Creates an array from the current Matrix object.
+     *
+     * @param transpose {boolean} Whether we need to transpose the matrix or not
+     * @param [out=new Float32Array(9)] {Float32Array} If provided the array will be assigned to out
+     * @return {number[]} the newly created array which contains the matrix
+     */
+    Matrix.prototype.toArray = function (transpose, out)
+    {
+        if (!this.array)
+        {
+            this.array = new Float32Array(9);
+        }
+
+        var array = out || this.array;
+
+        if (transpose)
+        {
+            array[0] = this.a;
+            array[1] = this.b;
+            array[2] = 0;
+            array[3] = this.c;
+            array[4] = this.d;
+            array[5] = 0;
+            array[6] = this.tx;
+            array[7] = this.ty;
+            array[8] = 1;
+        }
+        else
+        {
+            array[0] = this.a;
+            array[1] = this.c;
+            array[2] = this.tx;
+            array[3] = this.b;
+            array[4] = this.d;
+            array[5] = this.ty;
+            array[6] = 0;
+            array[7] = 0;
+            array[8] = 1;
+        }
+
+        return array;
+    };
+
+    /**
+     * Get a new position with the current transformation applied.
+     * Can be used to go from a child's coordinate space to the world coordinate space. (e.g. rendering)
+     *
+     * @param pos {PIXI.Point} The origin
+     * @param [newPos] {PIXI.Point} The point that the new position is assigned to (allowed to be same as input)
+     * @return {PIXI.Point} The new point, transformed through this matrix
+     */
+    Matrix.prototype.apply = function (pos, newPos)
+    {
+        newPos = newPos || new Point();
+
+        var x = pos.x;
+        var y = pos.y;
+
+        newPos.x = this.a * x + this.c * y + this.tx;
+        newPos.y = this.b * x + this.d * y + this.ty;
+
+        return newPos;
+    };
+
+    /**
+     * Get a new position with the inverse of the current transformation applied.
+     * Can be used to go from the world coordinate space to a child's coordinate space. (e.g. input)
+     *
+     * @param pos {PIXI.Point} The origin
+     * @param [newPos] {PIXI.Point} The point that the new position is assigned to (allowed to be same as input)
+     * @return {PIXI.Point} The new point, inverse-transformed through this matrix
+     */
+    Matrix.prototype.applyInverse = function (pos, newPos)
+    {
+        newPos = newPos || new Point();
+
+        var id = 1 / (this.a * this.d + this.c * -this.b);
+
+        var x = pos.x;
+        var y = pos.y;
+
+        newPos.x = this.d * id * x + -this.c * id * y + (this.ty * this.c - this.tx * this.d) * id;
+        newPos.y = this.a * id * y + -this.b * id * x + (-this.ty * this.a + this.tx * this.b) * id;
+
+        return newPos;
+    };
+
+    /**
+     * Translates the matrix on the x and y.
+     *
+     * @param {number} x How much to translate x by
+     * @param {number} y How much to translate y by
+     * @return {PIXI.Matrix} This matrix. Good for chaining method calls.
+     */
+    Matrix.prototype.translate = function (x, y)
+    {
+        this.tx += x;
+        this.ty += y;
+
+        return this;
+    };
+
+    /**
+     * Applies a scale transformation to the matrix.
+     *
+     * @param {number} x The amount to scale horizontally
+     * @param {number} y The amount to scale vertically
+     * @return {PIXI.Matrix} This matrix. Good for chaining method calls.
+     */
+    Matrix.prototype.scale = function (x, y)
+    {
+        this.a *= x;
+        this.d *= y;
+        this.c *= x;
+        this.b *= y;
+        this.tx *= x;
+        this.ty *= y;
+
+        return this;
+    };
+
+
+    /**
+     * Applies a rotation transformation to the matrix.
+     *
+     * @param {number} angle - The angle in radians.
+     * @return {PIXI.Matrix} This matrix. Good for chaining method calls.
+     */
+    Matrix.prototype.rotate = function (angle)
+    {
+        var cos = Math.cos( angle );
+        var sin = Math.sin( angle );
+
+        var a1 = this.a;
+        var c1 = this.c;
+        var tx1 = this.tx;
+
+        this.a = a1 * cos-this.b * sin;
+        this.b = a1 * sin+this.b * cos;
+        this.c = c1 * cos-this.d * sin;
+        this.d = c1 * sin+this.d * cos;
+        this.tx = tx1 * cos - this.ty * sin;
+        this.ty = tx1 * sin + this.ty * cos;
+
+        return this;
+    };
+
+    /**
+     * Appends the given Matrix to this Matrix.
+     *
+     * @param {PIXI.Matrix} matrix
+     * @return {PIXI.Matrix} This matrix. Good for chaining method calls.
+     */
+    Matrix.prototype.append = function (matrix)
+    {
+        var a1 = this.a;
+        var b1 = this.b;
+        var c1 = this.c;
+        var d1 = this.d;
+
+        this.a  = matrix.a * a1 + matrix.b * c1;
+        this.b  = matrix.a * b1 + matrix.b * d1;
+        this.c  = matrix.c * a1 + matrix.d * c1;
+        this.d  = matrix.c * b1 + matrix.d * d1;
+
+        this.tx = matrix.tx * a1 + matrix.ty * c1 + this.tx;
+        this.ty = matrix.tx * b1 + matrix.ty * d1 + this.ty;
+
+        return this;
+    };
+
+    /**
+     * Sets the matrix based on all the available properties
+     *
+     * @param {number} x Position on the x axis
+     * @param {number} y Position on the y axis
+     * @param {number} pivotX Pivot on the x axis
+     * @param {number} pivotY Pivot on the y axis
+     * @param {number} scaleX Scale on the x axis
+     * @param {number} scaleY Scale on the y axis
+     * @param {number} rotation Rotation in radians
+     * @param {number} skewX Skew on the x axis
+     * @param {number} skewY Skew on the y axis
+     *
+     * @return {PIXI.Matrix} This matrix. Good for chaining method calls.
+     */
+    Matrix.prototype.setTransform = function (x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY)
+    {
+        var a, b, c, d, sr, cr, cy, sy, nsx, cx;
+
+        sr  = Math.sin(rotation);
+        cr  = Math.cos(rotation);
+        cy  = Math.cos(skewY);
+        sy  = Math.sin(skewY);
+        nsx = -Math.sin(skewX);
+        cx  =  Math.cos(skewX);
+
+        a  =  cr * scaleX;
+        b  =  sr * scaleX;
+        c  = -sr * scaleY;
+        d  =  cr * scaleY;
+
+        this.a  = cy * a + sy * c;
+        this.b  = cy * b + sy * d;
+        this.c  = nsx * a + cx * c;
+        this.d  = nsx * b + cx * d;
+
+        this.tx = x + ( pivotX * a + pivotY * c );
+        this.ty = y + ( pivotX * b + pivotY * d );
+
+        return this;
+    };
+
+    /**
+     * Prepends the given Matrix to this Matrix.
+     *
+     * @param {PIXI.Matrix} matrix
+     * @return {PIXI.Matrix} This matrix. Good for chaining method calls.
+     */
+    Matrix.prototype.prepend = function(matrix)
+    {
+        var tx1 = this.tx;
+
+        if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1)
+        {
+            var a1 = this.a;
+            var c1 = this.c;
+            this.a  = a1*matrix.a+this.b*matrix.c;
+            this.b  = a1*matrix.b+this.b*matrix.d;
+            this.c  = c1*matrix.a+this.d*matrix.c;
+            this.d  = c1*matrix.b+this.d*matrix.d;
+        }
+
+        this.tx = tx1*matrix.a+this.ty*matrix.c+matrix.tx;
+        this.ty = tx1*matrix.b+this.ty*matrix.d+matrix.ty;
+
+        return this;
+    };
+
+    /**
+     * Decomposes the matrix (x, y, scaleX, scaleY, and rotation) and sets the properties on to a transform.
+     * @param transform {PIXI.Transform|PIXI.TransformStatic} the transform to apply the properties to.
+     * @return {PIXI.Transform|PIXI.TransformStatic} The transform with the newly applied properies
+     */
+    Matrix.prototype.decompose = function(transform)
+    {
+        // sort out rotation / skew..
+        var a = this.a,
+            b = this.b,
+            c = this.c,
+            d = this.d;
+
+        var skewX = Math.atan2(-c, d);
+        var skewY = Math.atan2(b, a);
+
+        var delta = Math.abs(1-skewX/skewY);
+
+        if (delta < 0.00001)
+        {
+            transform.rotation = skewY;
+
+            if (a < 0 && d >= 0)
+            {
+                transform.rotation += (transform.rotation <= 0) ? Math.PI : -Math.PI;
+            }
+
+            transform.skew.x = transform.skew.y = 0;
+
+        }
+        else
+        {
+            transform.skew.x = skewX;
+            transform.skew.y = skewY;
+        }
+
+        // next set scale
+        transform.scale.x = Math.sqrt(a * a + b * b);
+        transform.scale.y = Math.sqrt(c * c + d * d);
+
+        // next set position
+        transform.position.x = this.tx;
+        transform.position.y = this.ty;
+
+        return transform;
+    };
+
+
+    /**
+     * Inverts this matrix
+     *
+     * @return {PIXI.Matrix} This matrix. Good for chaining method calls.
+     */
+    Matrix.prototype.invert = function()
+    {
+        var a1 = this.a;
+        var b1 = this.b;
+        var c1 = this.c;
+        var d1 = this.d;
+        var tx1 = this.tx;
+        var n = a1*d1-b1*c1;
+
+        this.a = d1/n;
+        this.b = -b1/n;
+        this.c = -c1/n;
+        this.d = a1/n;
+        this.tx = (c1*this.ty-d1*tx1)/n;
+        this.ty = -(a1*this.ty-b1*tx1)/n;
+
+        return this;
+    };
+
+
+    /**
+     * Resets this Matix to an identity (default) matrix.
+     *
+     * @return {PIXI.Matrix} This matrix. Good for chaining method calls.
+     */
+    Matrix.prototype.identity = function ()
+    {
+        this.a = 1;
+        this.b = 0;
+        this.c = 0;
+        this.d = 1;
+        this.tx = 0;
+        this.ty = 0;
+
+        return this;
+    };
+
+    /**
+     * Creates a new Matrix object with the same values as this one.
+     *
+     * @return {PIXI.Matrix} A copy of this matrix. Good for chaining method calls.
+     */
+    Matrix.prototype.clone = function ()
+    {
+        var matrix = new Matrix();
+        matrix.a = this.a;
+        matrix.b = this.b;
+        matrix.c = this.c;
+        matrix.d = this.d;
+        matrix.tx = this.tx;
+        matrix.ty = this.ty;
+
+        return matrix;
+    };
+
+    /**
+     * Changes the values of the given matrix to be the same as the ones in this matrix
+     *
+     * @return {PIXI.Matrix} The matrix given in parameter with its values updated.
+     */
+    Matrix.prototype.copy = function (matrix)
+    {
+        matrix.a = this.a;
+        matrix.b = this.b;
+        matrix.c = this.c;
+        matrix.d = this.d;
+        matrix.tx = this.tx;
+        matrix.ty = this.ty;
+
+        return matrix;
+    };
+
+    /**
+     * A default (identity) matrix
+     *
+     * @static
+     * @const
+     */
+    Matrix.IDENTITY = new Matrix();
+
+    /**
+     * A temp matrix
+     *
+     * @static
+     * @const
+     */
+    Matrix.TEMP_MATRIX = new Matrix();
+
+},{"./Point":66}],65:[function(require,module,exports){
+    /**
+     * The Point object represents a location in a two-dimensional coordinate system, where x represents
+     * the horizontal axis and y represents the vertical axis.
+     * An observable point is a point that triggers a callback when the point's position is changed.
+     *
+     * @class
+     * @memberof PIXI
+     * @param cb {Function} callback when changed
+     * @param scope {Object} owner of callback
+     * @param [x=0] {number} position of the point on the x axis
+     * @param [y=0] {number} position of the point on the y axis
+     */
+    function ObservablePoint(cb, scope, x, y)
+    {
+        this._x = x || 0;
+        this._y = y || 0;
+
+        this.cb = cb;
+        this.scope = scope;
+    }
+
+    ObservablePoint.prototype.constructor = ObservablePoint;
+    module.exports = ObservablePoint;
+
+
+
+    Object.defineProperties(ObservablePoint.prototype, {
+        /**
+         * The position of the displayObject on the x axis relative to the local coordinates of the parent.
+         *
+         * @member {number}
+         * @memberof PIXI.ObservablePoint#
+         */
+        x: {
+            get: function ()
+            {
+                return this._x;
+            },
+            set: function (value)
+            {
+                if (this._x !== value) {
+                    this._x = value;
+                    this.cb.call(this.scope);
+                }
+            }
+        },
+        /**
+         * The position of the displayObject on the x axis relative to the local coordinates of the parent.
+         *
+         * @member {number}
+         * @memberof PIXI.ObservablePoint#
+         */
+        y: {
+            get: function ()
+            {
+                return this._y;
+            },
+            set: function (value)
+            {
+                if (this._y !== value) {
+                    this._y = value;
+                    this.cb.call(this.scope);
+                }
+            }
+        }
+    });
+
+    /**
+     * Sets the point to a new x and y position.
+     * If y is omitted, both x and y will be set to x.
+     *
+     * @param [x=0] {number} position of the point on the x axis
+     * @param [y=0] {number} position of the point on the y axis
+     */
+    ObservablePoint.prototype.set = function (x, y)
+    {
+        var _x = x || 0;
+        var _y = y || ( (y !== 0) ? _x : 0 );
+        if (this._x !== _x || this._y !== _y)
+        {
+            this._x = _x;
+            this._y = _y;
+            this.cb.call(this.scope);
+        }
+    };
+
+    /**
+     * Copies the data from another point
+     *
+     * @param point {PIXI.Point|PIXI.ObservablePoint} point to copy from
+     */
+    ObservablePoint.prototype.copy = function (point)
+    {
+        if (this._x !== point.x || this._y !== point.y)
+        {
+            this._x = point.x;
+            this._y = point.y;
+            this.cb.call(this.scope);
+        }
+    };
+
+},{}],66:[function(require,module,exports){
+    /**
+     * The Point object represents a location in a two-dimensional coordinate system, where x represents
+     * the horizontal axis and y represents the vertical axis.
+     *
+     * @class
+     * @memberof PIXI
+     * @param [x=0] {number} position of the point on the x axis
+     * @param [y=0] {number} position of the point on the y axis
+     */
+    function Point(x, y)
+    {
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.x = x || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.y = y || 0;
+    }
+
+    Point.prototype.constructor = Point;
+    module.exports = Point;
+
+    /**
+     * Creates a clone of this point
+     *
+     * @return {PIXI.Point} a copy of the point
+     */
+    Point.prototype.clone = function ()
+    {
+        return new Point(this.x, this.y);
+    };
+
+    /**
+     * Copies x and y from the given point
+     *
+     * @param p {PIXI.Point}
+     */
+    Point.prototype.copy = function (p) {
+        this.set(p.x, p.y);
+    };
+
+    /**
+     * Returns true if the given point is equal to this point
+     *
+     * @param p {PIXI.Point}
+     * @returns {boolean} Whether the given point equal to this point
+     */
+    Point.prototype.equals = function (p) {
+        return (p.x === this.x) && (p.y === this.y);
+    };
+
+    /**
+     * Sets the point to a new x and y position.
+     * If y is omitted, both x and y will be set to x.
+     *
+     * @param [x=0] {number} position of the point on the x axis
+     * @param [y=0] {number} position of the point on the y axis
+     */
+    Point.prototype.set = function (x, y)
+    {
+        this.x = x || 0;
+        this.y = y || ( (y !== 0) ? this.x : 0 ) ;
+    };
+
+},{}],67:[function(require,module,exports){
+    /**
+     * Math classes and utilities mixed into PIXI namespace.
+     *
+     * @lends PIXI
+     */
+    module.exports = {
+        // These will be mixed to be made publicly available,
+        // while this module is used internally in core
+        // to avoid circular dependencies and cut down on
+        // internal module requires.
+
+        Point:              require('./Point'),
+        ObservablePoint:    require('./ObservablePoint'),
+        Matrix:             require('./Matrix'),
+        GroupD8:            require('./GroupD8'),
+
+        Circle:             require('./shapes/Circle'),
+        Ellipse:            require('./shapes/Ellipse'),
+        Polygon:            require('./shapes/Polygon'),
+        Rectangle:          require('./shapes/Rectangle'),
+        RoundedRectangle:   require('./shapes/RoundedRectangle')
+    };
+
+},{"./GroupD8":63,"./Matrix":64,"./ObservablePoint":65,"./Point":66,"./shapes/Circle":68,"./shapes/Ellipse":69,"./shapes/Polygon":70,"./shapes/Rectangle":71,"./shapes/RoundedRectangle":72}],68:[function(require,module,exports){
+    var Rectangle = require('./Rectangle'),
+        CONST = require('../../const');
+
+    /**
+     * The Circle object can be used to specify a hit area for displayObjects
+     *
+     * @class
+     * @memberof PIXI
+     * @param x {number} The X coordinate of the center of this circle
+     * @param y {number} The Y coordinate of the center of this circle
+     * @param radius {number} The radius of the circle
+     */
+    function Circle(x, y, radius)
+    {
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.x = x || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.y = y || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.radius = radius || 0;
+
+        /**
+         * The type of the object, mainly used to avoid `instanceof` checks
+         *
+         * @member {number}
+         * @readOnly
+         * @default CONST.SHAPES.CIRC
+         * @see PIXI.SHAPES
+         */
+        this.type = CONST.SHAPES.CIRC;
+    }
+
+    Circle.prototype.constructor = Circle;
+    module.exports = Circle;
+
+    /**
+     * Creates a clone of this Circle instance
+     *
+     * @return {PIXI.Circle} a copy of the Circle
+     */
+    Circle.prototype.clone = function ()
+    {
+        return new Circle(this.x, this.y, this.radius);
+    };
+
+    /**
+     * Checks whether the x and y coordinates given are contained within this circle
+     *
+     * @param x {number} The X coordinate of the point to test
+     * @param y {number} The Y coordinate of the point to test
+     * @return {boolean} Whether the x/y coordinates are within this Circle
+     */
+    Circle.prototype.contains = function (x, y)
+    {
+        if (this.radius <= 0)
+        {
+            return false;
+        }
+
+        var dx = (this.x - x),
+            dy = (this.y - y),
+            r2 = this.radius * this.radius;
+
+        dx *= dx;
+        dy *= dy;
+
+        return (dx + dy <= r2);
+    };
+
+    /**
+     * Returns the framing rectangle of the circle as a Rectangle object
+     *
+     * @return {PIXI.Rectangle} the framing rectangle
+     */
+    Circle.prototype.getBounds = function ()
+    {
+        return new Rectangle(this.x - this.radius, this.y - this.radius, this.radius * 2, this.radius * 2);
+    };
+
+},{"../../const":43,"./Rectangle":71}],69:[function(require,module,exports){
+    var Rectangle = require('./Rectangle'),
+        CONST = require('../../const');
+
+    /**
+     * The Ellipse object can be used to specify a hit area for displayObjects
+     *
+     * @class
+     * @memberof PIXI
+     * @param x {number} The X coordinate of the center of the ellipse
+     * @param y {number} The Y coordinate of the center of the ellipse
+     * @param width {number} The half width of this ellipse
+     * @param height {number} The half height of this ellipse
+     */
+    function Ellipse(x, y, width, height)
+    {
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.x = x || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.y = y || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.width = width || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.height = height || 0;
+
+        /**
+         * The type of the object, mainly used to avoid `instanceof` checks
+         *
+         * @member {number}
+         * @readOnly
+         * @default CONST.SHAPES.ELIP
+         * @see PIXI.SHAPES
+         */
+        this.type = CONST.SHAPES.ELIP;
+    }
+
+    Ellipse.prototype.constructor = Ellipse;
+    module.exports = Ellipse;
+
+    /**
+     * Creates a clone of this Ellipse instance
+     *
+     * @return {PIXI.Ellipse} a copy of the ellipse
+     */
+    Ellipse.prototype.clone = function ()
+    {
+        return new Ellipse(this.x, this.y, this.width, this.height);
+    };
+
+    /**
+     * Checks whether the x and y coordinates given are contained within this ellipse
+     *
+     * @param x {number} The X coordinate of the point to test
+     * @param y {number} The Y coordinate of the point to test
+     * @return {boolean} Whether the x/y coords are within this ellipse
+     */
+    Ellipse.prototype.contains = function (x, y)
+    {
+        if (this.width <= 0 || this.height <= 0)
+        {
+            return false;
+        }
+
+        //normalize the coords to an ellipse with center 0,0
+        var normx = ((x - this.x) / this.width),
+            normy = ((y - this.y) / this.height);
+
+        normx *= normx;
+        normy *= normy;
+
+        return (normx + normy <= 1);
+    };
+
+    /**
+     * Returns the framing rectangle of the ellipse as a Rectangle object
+     *
+     * @return {PIXI.Rectangle} the framing rectangle
+     */
+    Ellipse.prototype.getBounds = function ()
+    {
+        return new Rectangle(this.x - this.width, this.y - this.height, this.width, this.height);
+    };
+
+},{"../../const":43,"./Rectangle":71}],70:[function(require,module,exports){
+    var Point = require('../Point'),
+        CONST = require('../../const');
+
+    /**
+     * @class
+     * @memberof PIXI
+     * @param points_ {PIXI.Point[]|number[]|...PIXI.Point|...number} This can be an array of Points that form the polygon,
+     *      a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
+     *      all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
+     *      arguments passed can be flat x,y values e.g. `new Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are
+     *      Numbers.
+     */
+    function Polygon(points_)
+    {
+        // prevents an argument assignment deopt
+        // see section 3.1: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments
+        var points = points_;
+
+        //if points isn't an array, use arguments as the array
+        if (!Array.isArray(points))
+        {
+            // prevents an argument leak deopt
+            // see section 3.2: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments
+            points = new Array(arguments.length);
+
+            for (var a = 0; a < points.length; ++a) {
+                points[a] = arguments[a];
+            }
+        }
+
+        // if this is an array of points, convert it to a flat array of numbers
+        if (points[0] instanceof Point)
+        {
+            var p = [];
+            for (var i = 0, il = points.length; i < il; i++)
+            {
+                p.push(points[i].x, points[i].y);
+            }
+
+            points = p;
+        }
+
+        this.closed = true;
+
+        /**
+         * An array of the points of this polygon
+         *
+         * @member {number[]}
+         */
+        this.points = points;
+
+        /**
+         * The type of the object, mainly used to avoid `instanceof` checks
+         *
+         * @member {number}
+         * @readOnly
+         * @default CONST.SHAPES.POLY
+         * @see PIXI.SHAPES
+         */
+        this.type = CONST.SHAPES.POLY;
+    }
+
+    Polygon.prototype.constructor = Polygon;
+    module.exports = Polygon;
+
+    /**
+     * Creates a clone of this polygon
+     *
+     * @return {PIXI.Polygon} a copy of the polygon
+     */
+    Polygon.prototype.clone = function ()
+    {
+        return new Polygon(this.points.slice());
+    };
+
+
+    Polygon.prototype.close = function ()
+    {
+        var points = this.points;
+
+        // close the poly if the value is true!
+        if (points[0] !== points[points.length-2] || points[1] !== points[points.length-1])
+        {
+            points.push(points[0], points[1]);
+        }
+    };
+
+    /**
+     * Checks whether the x and y coordinates passed to this function are contained within this polygon
+     *
+     * @param x {number} The X coordinate of the point to test
+     * @param y {number} The Y coordinate of the point to test
+     * @return {boolean} Whether the x/y coordinates are within this polygon
+     */
+    Polygon.prototype.contains = function (x, y)
+    {
+        var inside = false;
+
+        // use some raycasting to test hits
+        // https://github.com/substack/point-in-polygon/blob/master/index.js
+        var length = this.points.length / 2;
+
+        for (var i = 0, j = length - 1; i < length; j = i++)
+        {
+            var xi = this.points[i * 2], yi = this.points[i * 2 + 1],
+                xj = this.points[j * 2], yj = this.points[j * 2 + 1],
+                intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
+
+            if (intersect)
+            {
+                inside = !inside;
+            }
+        }
+
+        return inside;
+    };
+
+},{"../../const":43,"../Point":66}],71:[function(require,module,exports){
+    var CONST = require('../../const');
+
+    /**
+     * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height.
+     *
+     * @class
+     * @memberof PIXI
+     * @param x {number} The X coordinate of the upper-left corner of the rectangle
+     * @param y {number} The Y coordinate of the upper-left corner of the rectangle
+     * @param width {number} The overall width of this rectangle
+     * @param height {number} The overall height of this rectangle
+     */
+    function Rectangle(x, y, width, height)
+    {
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.x = x || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.y = y || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.width = width || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.height = height || 0;
+
+        /**
+         * The type of the object, mainly used to avoid `instanceof` checks
+         *
+         * @member {number}
+         * @readOnly
+         * @default CONST.SHAPES.RECT
+         * @see PIXI.SHAPES
+         */
+        this.type = CONST.SHAPES.RECT;
+    }
+
+    Rectangle.prototype.constructor = Rectangle;
+    module.exports = Rectangle;
+
+
+    Object.defineProperties(Rectangle.prototype, {
+        /**
+         * returns the left edge of the rectangle
+         *
+         * @member {number}
+         * @memberof PIXI.Rectangle#
+         */
+        left: {
+            get: function ()
+            {
+                return this.x;
+            }
+        },
+
+        /**
+         * returns the right edge of the rectangle
+         *
+         * @member {number}
+         * @memberof PIXI.Rectangle
+         */
+        right: {
+            get: function ()
+            {
+                return this.x + this.width;
+            }
+        },
+
+        /**
+         * returns the top edge of the rectangle
+         *
+         * @member {number}
+         * @memberof PIXI.Rectangle
+         */
+        top: {
+            get: function ()
+            {
+                return this.y;
+            }
+        },
+
+        /**
+         * returns the bottom edge of the rectangle
+         *
+         * @member {number}
+         * @memberof PIXI.Rectangle
+         */
+        bottom: {
+            get: function ()
+            {
+                return this.y + this.height;
+            }
+        }
+
+    });
+
+    /**
+     * A constant empty rectangle.
+     *
+     * @static
+     * @constant
+     */
+    Rectangle.EMPTY = new Rectangle(0, 0, 0, 0);
+
+
+    /**
+     * Creates a clone of this Rectangle
+     *
+     * @return {PIXI.Rectangle} a copy of the rectangle
+     */
+    Rectangle.prototype.clone = function ()
+    {
+        return new Rectangle(this.x, this.y, this.width, this.height);
+    };
+
+    Rectangle.prototype.copy = function (rectangle)
+    {
+        this.x = rectangle.x;
+        this.y = rectangle.y;
+        this.width = rectangle.width;
+        this.height = rectangle.height;
+
+        return this;
+    };
+
+    /**
+     * Checks whether the x and y coordinates given are contained within this Rectangle
+     *
+     * @param x {number} The X coordinate of the point to test
+     * @param y {number} The Y coordinate of the point to test
+     * @return {boolean} Whether the x/y coordinates are within this Rectangle
+     */
+    Rectangle.prototype.contains = function (x, y)
+    {
+        if (this.width <= 0 || this.height <= 0)
+        {
+            return false;
+        }
+
+        if (x >= this.x && x < this.x + this.width)
+        {
+            if (y >= this.y && y < this.y + this.height)
+            {
+                return true;
+            }
+        }
+
+        return false;
+    };
+
+    Rectangle.prototype.pad = function (paddingX, paddingY)
+    {
+        paddingX = paddingX || 0;
+        paddingY = paddingY || ( (paddingY !== 0) ? paddingX : 0 );
+
+        this.x -= paddingX;
+        this.y -= paddingY;
+
+        this.width += paddingX * 2;
+        this.height += paddingY * 2;
+    };
+
+    Rectangle.prototype.fit = function (rectangle)
+    {
+        if (this.x < rectangle.x)
+        {
+            this.width += this.x;
+            if(this.width < 0) {
+                this.width = 0;
+            }
+
+            this.x = rectangle.x;
+        }
+
+        if (this.y < rectangle.y)
+        {
+            this.height += this.y;
+            if(this.height < 0) {
+                this.height = 0;
+            }
+            this.y = rectangle.y;
+        }
+
+        if ( this.x + this.width > rectangle.x + rectangle.width )
+        {
+            this.width = rectangle.width - this.x;
+            if(this.width < 0) {
+                this.width = 0;
+            }
+        }
+
+        if ( this.y + this.height > rectangle.y + rectangle.height )
+        {
+            this.height = rectangle.height - this.y;
+            if(this.height < 0) {
+                this.height = 0;
+            }
+        }
+    };
+
+    Rectangle.prototype.enlarge = function (rect)
+    {
+
+        if (rect === Rectangle.EMPTY)
+        {
+            return;
+        }
+
+        var x1 = Math.min(this.x, rect.x);
+        var x2 = Math.max(this.x + this.width, rect.x + rect.width);
+        var y1 = Math.min(this.y, rect.y);
+        var y2 = Math.max(this.y + this.height, rect.y + rect.height);
+        this.x = x1;
+        this.width = x2 - x1;
+        this.y = y1;
+        this.height = y2 - y1;
+    };
+
+},{"../../const":43}],72:[function(require,module,exports){
+    var CONST = require('../../const');
+
+    /**
+     * The Rounded Rectangle object is an area that has nice rounded corners, as indicated by its top-left corner point (x, y) and by its width and its height and its radius.
+     *
+     * @class
+     * @memberof PIXI
+     * @param x {number} The X coordinate of the upper-left corner of the rounded rectangle
+     * @param y {number} The Y coordinate of the upper-left corner of the rounded rectangle
+     * @param width {number} The overall width of this rounded rectangle
+     * @param height {number} The overall height of this rounded rectangle
+     * @param radius {number} Controls the radius of the rounded corners
+     */
+    function RoundedRectangle(x, y, width, height, radius)
+    {
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.x = x || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.y = y || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.width = width || 0;
+
+        /**
+         * @member {number}
+         * @default 0
+         */
+        this.height = height || 0;
+
+        /**
+         * @member {number}
+         * @default 20
+         */
+        this.radius = radius || 20;
+
+        /**
+         * The type of the object, mainly used to avoid `instanceof` checks
+         *
+         * @member {number}
+         * @readonly
+         * @default CONST.SHAPES.RREC
+         * @see PIXI.SHAPES
+         */
+        this.type = CONST.SHAPES.RREC;
+    }
+
+    RoundedRectangle.prototype.constructor = RoundedRectangle;
+    module.exports = RoundedRectangle;
+
+    /**
+     * Creates a clone of this Rounded Rectangle
+     *
+     * @return {PIXI.RoundedRectangle} a copy of the rounded rectangle
+     */
+    RoundedRectangle.prototype.clone = function ()
+    {
+        return new RoundedRectangle(this.x, this.y, this.width, this.height, this.radius);
+    };
+
+    /**
+     * Checks whether the x and y coordinates given are contained within this Rounded Rectangle
+     *
+     * @param x {number} The X coordinate of the point to test
+     * @param y {number} The Y coordinate of the point to test
+     * @return {boolean} Whether the x/y coordinates are within this Rounded Rectangle
+     */
+    RoundedRectangle.prototype.contains = function (x, y)
+    {
+        if (this.width <= 0 || this.height <= 0)
+        {
+            return false;
+        }
+
+        if (x >= this.x && x <= this.x + this.width)
+        {
+            if (y >= this.y && y <= this.y + this.height)
+            {
+                return true;
+            }
+        }
+
+        return false;
+    };
+
+},{"../../const":43}],73:[function(require,module,exports){
+    var utils = require('../utils'),
+        math = require('../math'),
+        CONST = require('../const'),
+        Container = require('../display/Container'),
+        RenderTexture = require('../textures/RenderTexture'),
+        EventEmitter = require('eventemitter3'),
+        tempMatrix = new math.Matrix();
+    /**
+     * The CanvasRenderer draws the scene and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL.
+     * Don't forget to add the CanvasRenderer.view to your DOM or you will not see anything :)
+     *
+     * @class
+     * @memberof PIXI
+     * @param system {string} The name of the system this renderer is for.
+     * @param [width=800] {number} the width of the canvas view
+     * @param [height=600] {number} the height of the canvas view
+     * @param [options] {object} The optional renderer parameters
+     * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional
+     * @param [options.transparent=false] {boolean} If the render view is transparent, default false
+     * @param [options.autoResize=false] {boolean} If the render view is automatically resized, default false
+     * @param [options.antialias=false] {boolean} sets antialias (only applicable in chrome at the moment)
+     * @param [options.resolution=1] {number} The resolution / device pixel ratio of the renderer. The resolution of the renderer retina would be 2.
+     * @param [options.clearBeforeRender=true] {boolean} This sets if the CanvasRenderer will clear the canvas or
+     *      not before the new render pass.
+     * @param [options.backgroundColor=0x000000] {number} The background color of the rendered area (shown if not transparent).
+     * @param [options.roundPixels=false] {boolean} If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.
+     */
+    function SystemRenderer(system, width, height, options)
+    {
+        EventEmitter.call(this);
+
+        utils.sayHello(system);
+
+        // prepare options
+        if (options)
+        {
+            for (var i in CONST.DEFAULT_RENDER_OPTIONS)
+            {
+                if (typeof options[i] === 'undefined')
+                {
+                    options[i] = CONST.DEFAULT_RENDER_OPTIONS[i];
+                }
+            }
+        }
+        else
+        {
+            options = CONST.DEFAULT_RENDER_OPTIONS;
+        }
+
+        /**
+         * The type of the renderer.
+         *
+         * @member {number}
+         * @default PIXI.RENDERER_TYPE.UNKNOWN
+         * @see PIXI.RENDERER_TYPE
+         */
+        this.type = CONST.RENDERER_TYPE.UNKNOWN;
+
+        /**
+         * The width of the canvas view
+         *
+         * @member {number}
+         * @default 800
+         */
+        this.width = width || 800;
+
+        /**
+         * The height of the canvas view
+         *
+         * @member {number}
+         * @default 600
+         */
+        this.height = height || 600;
+
+        /**
+         * The canvas element that everything is drawn to
+         *
+         * @member {HTMLCanvasElement}
+         */
+        this.view = options.view || document.createElement('canvas');
+
+        /**
+         * The resolution / device pixel ratio of the renderer
+         *
+         * @member {number}
+         * @default 1
+         */
+        this.resolution = options.resolution;
+
+        /**
+         * Whether the render view is transparent
+         *
+         * @member {boolean}
+         */
+        this.transparent = options.transparent;
+
+        /**
+         * Whether the render view should be resized automatically
+         *
+         * @member {boolean}
+         */
+        this.autoResize = options.autoResize || false;
+
+        /**
+         * Tracks the blend modes useful for this renderer.
+         *
+         * @member {object<string, mixed>}
+         */
+        this.blendModes = null;
+
+        /**
+         * The value of the preserveDrawingBuffer flag affects whether or not the contents of the stencil buffer is retained after rendering.
+         *
+         * @member {boolean}
+         */
+        this.preserveDrawingBuffer = options.preserveDrawingBuffer;
+
+        /**
+         * This sets if the CanvasRenderer will clear the canvas or not before the new render pass.
+         * If the scene is NOT transparent Pixi will use a canvas sized fillRect operation every frame to set the canvas background color.
+         * If the scene is transparent Pixi will use clearRect to clear the canvas every frame.
+         * Disable this by setting this to false. For example if your game has a canvas filling background image you often don't need this set.
+         *
+         * @member {boolean}
+         * @default
+         */
+        this.clearBeforeRender = options.clearBeforeRender;
+
+        /**
+         * If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.
+         * Handy for crisp pixel art and speed on legacy devices.
+         *
+         * @member {boolean}
+         */
+        this.roundPixels = options.roundPixels;
+
+        /**
+         * The background color as a number.
+         *
+         * @member {number}
+         * @private
+         */
+        this._backgroundColor = 0x000000;
+
+        /**
+         * The background color as an [R, G, B] array.
+         *
+         * @member {number[]}
+         * @private
+         */
+        this._backgroundColorRgba = [0, 0, 0, 0];
+
+        /**
+         * The background color as a string.
+         *
+         * @member {string}
+         * @private
+         */
+        this._backgroundColorString = '#000000';
+
+        this.backgroundColor = options.backgroundColor || this._backgroundColor; // run bg color setter
+
+        /**
+         * This temporary display object used as the parent of the currently being rendered item
+         *
+         * @member {PIXI.DisplayObject}
+         * @private
+         */
+        this._tempDisplayObjectParent = new Container();
+
+        /**
+         * The last root object that the renderer tried to render.
+         *
+         * @member {PIXI.DisplayObject}
+         * @private
+         */
+        this._lastObjectRendered = this._tempDisplayObjectParent;
+    }
+
+// constructor
+    SystemRenderer.prototype = Object.create(EventEmitter.prototype);
+    SystemRenderer.prototype.constructor = SystemRenderer;
+    module.exports = SystemRenderer;
+
+    Object.defineProperties(SystemRenderer.prototype, {
+        /**
+         * The background color to fill if not transparent
+         *
+         * @member {number}
+         * @memberof PIXI.SystemRenderer#
+         */
+        backgroundColor:
+        {
+            get: function ()
+            {
+                return this._backgroundColor;
+            },
+            set: function (val)
+            {
+                this._backgroundColor = val;
+                this._backgroundColorString = utils.hex2string(val);
+                utils.hex2rgb(val, this._backgroundColorRgba);
+            }
+        }
+    });
+
+    /**
+     * Resizes the canvas view to the specified width and height
+     *
+     * @param width {number} the new width of the canvas view
+     * @param height {number} the new height of the canvas view
+     */
+    SystemRenderer.prototype.resize = function (width, height) {
+        this.width = width * this.resolution;
+        this.height = height * this.resolution;
+
+        this.view.width = this.width;
+        this.view.height = this.height;
+
+        if (this.autoResize)
+        {
+            this.view.style.width = this.width / this.resolution + 'px';
+            this.view.style.height = this.height / this.resolution + 'px';
+        }
+    };
+
+    /**
+     * Useful function that returns a texture of the display object that can then be used to create sprites
+     * This can be quite useful if your displayObject is complicated and needs to be reused multiple times.
+     *
+     * @param displayObject {PIXI.DisplayObject} The displayObject the object will be generated from
+     * @param scaleMode {number} Should be one of the scaleMode consts
+     * @param resolution {number} The resolution / device pixel ratio of the texture being generated
+     * @return {PIXI.Texture} a texture of the graphics object
+     */
+    SystemRenderer.prototype.generateTexture = function (displayObject, scaleMode, resolution) {
+
+        var bounds = displayObject.getLocalBounds();
+
+        var renderTexture = RenderTexture.create(bounds.width | 0, bounds.height | 0, scaleMode, resolution);
+
+        tempMatrix.tx = -bounds.x;
+        tempMatrix.ty = -bounds.y;
+
+        this.render(displayObject, renderTexture, false, tempMatrix, true);
+
+        return renderTexture;
+    };
+
+    /**
+     * Removes everything from the renderer and optionally removes the Canvas DOM element.
+     *
+     * @param [removeView=false] {boolean} Removes the Canvas element from the DOM.
+     */
+    SystemRenderer.prototype.destroy = function (removeView) {
+        if (removeView && this.view.parentNode)
+        {
+            this.view.parentNode.removeChild(this.view);
+        }
+
+        this.type = CONST.RENDERER_TYPE.UNKNOWN;
+
+        this.width = 0;
+        this.height = 0;
+
+        this.view = null;
+
+        this.resolution = 0;
+
+        this.transparent = false;
+
+        this.autoResize = false;
+
+        this.blendModes = null;
+
+        this.preserveDrawingBuffer = false;
+        this.clearBeforeRender = false;
+
+        this.roundPixels = false;
+
+        this._backgroundColor = 0;
+        this._backgroundColorRgba = null;
+        this._backgroundColorString = null;
+
+        this.backgroundColor = 0;
+        this._tempDisplayObjectParent = null;
+        this._lastObjectRendered = null;
+    };
+
+},{"../const":43,"../display/Container":45,"../math":67,"../textures/RenderTexture":108,"../utils":116,"eventemitter3":3}],74:[function(require,module,exports){
+    var SystemRenderer = require('../SystemRenderer'),
+        CanvasMaskManager = require('./utils/CanvasMaskManager'),
+        CanvasRenderTarget = require('./utils/CanvasRenderTarget'),
+        mapCanvasBlendModesToPixi = require('./utils/mapCanvasBlendModesToPixi'),
+        utils = require('../../utils'),
+        CONST = require('../../const');
+
+    /**
+     * The CanvasRenderer draws the scene and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL.
+     * Don't forget to add the CanvasRenderer.view to your DOM or you will not see anything :)
+     *
+     * @class
+     * @memberof PIXI
+     * @extends PIXI.SystemRenderer
+     * @param [width=800] {number} the width of the canvas view
+     * @param [height=600] {number} the height of the canvas view
+     * @param [options] {object} The optional renderer parameters
+     * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional
+     * @param [options.transparent=false] {boolean} If the render view is transparent, default false
+     * @param [options.autoResize=false] {boolean} If the render view is automatically resized, default false
+     * @param [options.antialias=false] {boolean} sets antialias (only applicable in chrome at the moment)
+     * @param [options.resolution=1] {number} The resolution / device pixel ratio of the renderer. The resolution of the renderer retina would be 2.
+     * @param [options.clearBeforeRender=true] {boolean} This sets if the CanvasRenderer will clear the canvas or
+     *      not before the new render pass.
+     * @param [options.roundPixels=false] {boolean} If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.
+     */
+    function CanvasRenderer(width, height, options)
+    {
+        options = options || {};
+
+        SystemRenderer.call(this, 'Canvas', width, height, options);
+
+        this.type = CONST.RENDERER_TYPE.CANVAS;
+
+        /**
+         * The canvas 2d context that everything is drawn with.
+         *
+         * @member {CanvasRenderingContext2D}
+         */
+        this.rootContext = this.view.getContext('2d', { alpha: this.transparent });
+        this.rootResolution = this.resolution;
+
+        /**
+         * Boolean flag controlling canvas refresh.
+         *
+         * @member {boolean}
+         */
+        this.refresh = true;
+
+        /**
+         * Instance of a CanvasMaskManager, handles masking when using the canvas renderer.
+         *
+         * @member {PIXI.CanvasMaskManager}
+         */
+        this.maskManager = new CanvasMaskManager(this);
+
+        /**
+         * The canvas property used to set the canvas smoothing property.
+         *
+         * @member {string}
+         */
+        this.smoothProperty = 'imageSmoothingEnabled';
+
+        if (!this.rootContext.imageSmoothingEnabled)
+        {
+            if (this.rootContext.webkitImageSmoothingEnabled)
+            {
+                this.smoothProperty = 'webkitImageSmoothingEnabled';
+            }
+            else if (this.rootContext.mozImageSmoothingEnabled)
+            {
+                this.smoothProperty = 'mozImageSmoothingEnabled';
+            }
+            else if (this.rootContext.oImageSmoothingEnabled)
+            {
+                this.smoothProperty = 'oImageSmoothingEnabled';
+            }
+            else if (this.rootContext.msImageSmoothingEnabled)
+            {
+                this.smoothProperty = 'msImageSmoothingEnabled';
+            }
+        }
+
+        this.initPlugins();
+
+        this.blendModes = mapCanvasBlendModesToPixi();
+        this._activeBlendMode = null;
+
+        this.context = null;
+        this.renderingToScreen = false;
+
+        this.resize(width, height);
+    }
+
+// constructor
+    CanvasRenderer.prototype = Object.create(SystemRenderer.prototype);
+    CanvasRenderer.prototype.constructor =  CanvasRenderer;
+    module.exports = CanvasRenderer;
+    utils.pluginTarget.mixin(CanvasRenderer);
+
+
+    /**
+     * Renders the object to this canvas view
+     *
+     * @param displayObject {PIXI.DisplayObject} The object to be rendered
+     * @param [renderTexture] {PIXI.RenderTexture} A render texture to be rendered to. If unset, it will render to the root context.
+     * @param [clear=false] {boolean} Whether to clear the canvas before drawing
+     * @param [transform] {PIXI.Transform} A transformation to be applied
+     * @param [skipUpdateTransform=false] {boolean} Whether to skip the update transform
+     */
+    CanvasRenderer.prototype.render = function (displayObject, renderTexture, clear, transform, skipUpdateTransform)
+    {
+
+        if (!this.view){
+            return;
+        }
+
+        // can be handy to know!
+        this.renderingToScreen = !renderTexture;
+
+        this.emit('prerender');
+
+        if(renderTexture)
+        {
+            renderTexture = renderTexture.baseTexture || renderTexture;
+
+            if(!renderTexture._canvasRenderTarget)
+            {
+
+                renderTexture._canvasRenderTarget = new CanvasRenderTarget(renderTexture.width, renderTexture.height, renderTexture.resolution);
+                renderTexture.source = renderTexture._canvasRenderTarget.canvas;
+                renderTexture.valid = true;
+            }
+
+            this.context = renderTexture._canvasRenderTarget.context;
+            this.resolution = renderTexture._canvasRenderTarget.resolution;
+        }
+        else
+        {
+
+            this.context = this.rootContext;
+            this.resolution = this.rootResolution;
+        }
+
+        var context = this.context;
+
+        if(!renderTexture)
+        {
+            this._lastObjectRendered = displayObject;
+        }
+
+
+
+
+        if(!skipUpdateTransform)
+        {
+            // update the scene graph
+            var cacheParent = displayObject.parent;
+            var tempWt = this._tempDisplayObjectParent.transform.worldTransform;
+
+            if(transform)
+            {
+                transform.copy(tempWt);
+            }
+            else
+            {
+                tempWt.identity();
+            }
+
+            displayObject.parent = this._tempDisplayObjectParent;
+            displayObject.updateTransform();
+            displayObject.parent = cacheParent;
+            // displayObject.hitArea = //TODO add a temp hit area
+        }
+
+
+        context.setTransform(1, 0, 0, 1, 0, 0);
+        context.globalAlpha = 1;
+        context.globalCompositeOperation = this.blendModes[CONST.BLEND_MODES.NORMAL];
+
+        if (navigator.isCocoonJS && this.view.screencanvas)
+        {
+            context.fillStyle = 'black';
+            context.clear();
+        }
+
+        if(clear !== undefined ? clear : this.clearBeforeRender)
+        {
+            if (this.renderingToScreen) {
+                if (this.transparent) {
+                    context.clearRect(0, 0, this.width, this.height);
+                }
+                else {
+                    context.fillStyle = this._backgroundColorString;
+                    context.fillRect(0, 0, this.width, this.height);
+                }
+            } //else {
+            //TODO: implement background for CanvasRenderTarget or RenderTexture?
+            //}
+        }
+
+        // TODO RENDER TARGET STUFF HERE..
+        var tempContext = this.context;
+
+        this.context = context;
+        displayObject.renderCanvas(this);
+        this.context = tempContext;
+
+        this.emit('postrender');
+    };
+
+
+    CanvasRenderer.prototype.setBlendMode = function (blendMode)
+    {
+        if(this._activeBlendMode === blendMode) {
+            return;
+        }
+
+        this.context.globalCompositeOperation = this.blendModes[blendMode];
+    };
+
+    /**
+     * Removes everything from the renderer and optionally removes the Canvas DOM element.
+     *
+     * @param [removeView=false] {boolean} Removes the Canvas element from the DOM.
+     */
+    CanvasRenderer.prototype.destroy = function (removeView)
+    {
+        this.destroyPlugins();
+
+        // call the base destroy
+        SystemRenderer.prototype.destroy.call(this, removeView);
+
+        this.context = null;
+
+        this.refresh = true;
+
+        this.maskManager.destroy();
+        this.maskManager = null;
+
+        this.smoothProperty = null;
+    };
+
+    /**
+     * Resizes the canvas view to the specified width and height.
+     *
+     * @extends PIXI.SystemRenderer#resize
+     *
+     * @param width {number} The new width of the canvas view
+     * @param height {number} The new height of the canvas view
+     */
+    CanvasRenderer.prototype.resize = function (width, height)
+    {
+        SystemRenderer.prototype.resize.call(this, width, height);
+
+        //reset the scale mode.. oddly this seems to be reset when the canvas is resized.
+        //surely a browser bug?? Let pixi fix that for you..
+        if(this.smoothProperty)
+        {
+            this.rootContext[this.smoothProperty] = (CONST.SCALE_MODES.DEFAULT === CONST.SCALE_MODES.LINEAR);
+        }
+
+    };
+
+},{"../../const":43,"../../utils":116,"../SystemRenderer":73,"./utils/CanvasMaskManager":75,"./utils/CanvasRenderTarget":76,"./utils/mapCanvasBlendModesToPixi":78}],75:[function(require,module,exports){
+    var CONST = require('../../../const');
+    /**
+     * A set of functions used to handle masking.
+     *
+     * @class
+     * @memberof PIXI
+     */
+    function CanvasMaskManager(renderer)
+    {
+        this.renderer = renderer;
+    }
+
+    CanvasMaskManager.prototype.constructor = CanvasMaskManager;
+    module.exports = CanvasMaskManager;
+
+    /**
+     * This method adds it to the current stack of masks.
+     *
+     * @param maskData {object} the maskData that will be pushed
+     */
+    CanvasMaskManager.prototype.pushMask = function (maskData)
+    {
+        var renderer = this.renderer;
+
+        renderer.context.save();
+
+        var cacheAlpha = maskData.alpha;
+        var transform = maskData.transform.worldTransform;
+        var resolution = renderer.resolution;
+
+        renderer.context.setTransform(
+            transform.a * resolution,
+            transform.b * resolution,
+            transform.c * resolution,
+            transform.d * resolution,
+            transform.tx * resolution,
+            transform.ty * resolution
+        );
+
+        //TODO suport sprite alpha masks??
+        //lots of effort required. If demand is great enough..
+        if(!maskData._texture)
+        {
+            this.renderGraphicsShape(maskData);
+            renderer.context.clip();
+        }
+
+        maskData.worldAlpha = cacheAlpha;
+    };
+
+    CanvasMaskManager.prototype.renderGraphicsShape = function (graphics)
+    {
+        var context = this.renderer.context;
+        var len = graphics.graphicsData.length;
+
+        if (len === 0)
+        {
+            return;
+        }
+
+        context.beginPath();
+
+        for (var i = 0; i < len; i++)
+        {
+            var data = graphics.graphicsData[i];
+            var shape = data.shape;
+
+            if (data.type === CONST.SHAPES.POLY)
+            {
+
+                var points = shape.points;
+
+                context.moveTo(points[0], points[1]);
+
+                for (var j=1; j < points.length/2; j++)
+                {
+                    context.lineTo(points[j * 2], points[j * 2 + 1]);
+                }
+
+                // if the first and last point are the same close the path - much neater :)
+                if (points[0] === points[points.length-2] && points[1] === points[points.length-1])
+                {
+                    context.closePath();
+                }
+
+            }
+            else if (data.type === CONST.SHAPES.RECT)
+            {
+                context.rect(shape.x, shape.y, shape.width, shape.height);
+                context.closePath();
+            }
+            else if (data.type === CONST.SHAPES.CIRC)
+            {
+                // TODO - need to be Undefined!
+                context.arc(shape.x, shape.y, shape.radius, 0, 2 * Math.PI);
+                context.closePath();
+            }
+            else if (data.type === CONST.SHAPES.ELIP)
+            {
+
+                // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
+
+                var w = shape.width * 2;
+                var h = shape.height * 2;
+
+                var x = shape.x - w/2;
+                var y = shape.y - h/2;
+
+                var kappa = 0.5522848,
+                    ox = (w / 2) * kappa, // control point offset horizontal
+                    oy = (h / 2) * kappa, // control point offset vertical
+                    xe = x + w,           // x-end
+                    ye = y + h,           // y-end
+                    xm = x + w / 2,       // x-middle
+                    ym = y + h / 2;       // y-middle
+
+                context.moveTo(x, ym);
+                context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
+                context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
+                context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
+                context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
+                context.closePath();
+            }
+            else if (data.type === CONST.SHAPES.RREC)
+            {
+
+                var rx = shape.x;
+                var ry = shape.y;
+                var width = shape.width;
+                var height = shape.height;
+                var radius = shape.radius;
+
+                var maxRadius = Math.min(width, height) / 2 | 0;
+                radius = radius > maxRadius ? maxRadius : radius;
+
+                context.moveTo(rx, ry + radius);
+                context.lineTo(rx, ry + height - radius);
+                context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height);
+                context.lineTo(rx + width - radius, ry + height);
+                context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius);
+                context.lineTo(rx + width, ry + radius);
+                context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry);
+                context.lineTo(rx + radius, ry);
+                context.quadraticCurveTo(rx, ry, rx, ry + radius);
+                context.closePath();
+            }
+        }
+    };
+
+    /**
+     * Restores the current drawing context to the state it was before the mask was applied.
+     *
+     * @param renderer {PIXI.WebGLRenderer|PIXI.CanvasRenderer} The renderer context to use.
+     */
+    CanvasMaskManager.prototype.popMask = function (renderer)
+    {
+        renderer.context.restore();
+    };
+
+    CanvasMaskManager.prototype.destroy = function () {};
+
+},{"../../../const":43}],76:[function(require,module,exports){
+    var CONST = require('../../../const');
+
+    /**
+     * Creates a Canvas element of the given size.
+     *
+     * @class
+     * @memberof PIXI
+     * @param width {number} the width for the newly created canvas
+     * @param height {number} the height for the newly created canvas
+     * @param [resolution=1] The resolution / device pixel ratio of the canvas
+     */
+    function CanvasRenderTarget(width, height, resolution)
+    {
+        /**
+         * The Canvas object that belongs to this CanvasRenderTarget.
+         *
+         * @member {HTMLCanvasElement}
+         */
+        this.canvas = document.createElement('canvas');
+
+        /**
+         * A CanvasRenderingContext2D object representing a two-dimensional rendering context.
+         *
+         * @member {CanvasRenderingContext2D}
+         */
+        this.context = this.canvas.getContext('2d');
+
+        this.resolution = resolution || CONST.RESOLUTION;
+
+        this.resize(width, height);
+    }
+
+    CanvasRenderTarget.prototype.constructor = CanvasRenderTarget;
+    module.exports = CanvasRenderTarget;
+
+    Object.defineProperties(CanvasRenderTarget.prototype, {
+        /**
+         * The width of the canvas buffer in pixels.
+         *
+         * @member {number}
+         * @memberof PIXI.CanvasRenderTarget#
+         */
+        width: {
+            get: function ()
+            {
+                return this.canvas.width;
+            },
+            set: function (val)
+            {
+                this.canvas.width = val;
+            }
+        },
+        /**
+         * The height of the canvas buffer in pixels.
+         *
+         * @member {number}
+         * @memberof PIXI.CanvasRenderTarget#
+         */
+        height: {
+            get: function ()
+            {
+                return this.canvas.height;
+            },
+            set: function (val)
+            {
+                this.canvas.height = val;
+            }
+        }
+    });
+
+    /**
+     * Clears the canvas that was created by the CanvasRenderTarget class.
+     *
+     * @private
+     */
+    CanvasRenderTarget.prototype.clear = function ()
+    {
+        this.context.setTransform(1, 0, 0, 1, 0, 0);
+        this.context.clearRect(0,0, this.canvas.width, this.canvas.height);
+    };
+
+    /**
+     * Resizes the canvas to the specified width and height.
+     *
+     * @param width {number} the new width of the canvas
+     * @param height {number} the new height of the canvas
+     */
+    CanvasRenderTarget.prototype.resize = function (width, height)
+    {
+
+        this.canvas.width = width * this.resolution;
+        this.canvas.height = height * this.resolution;
+    };
+
+    /**
+     * Destroys this canvas.
+     *
+     */
+    CanvasRenderTarget.prototype.destroy = function ()
+    {
+        this.context = null;
+        this.canvas = null;
+    };
+
+},{"../../../const":43}],77:[function(require,module,exports){
+
+
+    /**
+     * Creates a little colored canvas
+     * @return {canvas} a small canvas element
+     */
+    var createColoredCanvas = function(color)
+    {
+        var canvas = document.createElement('canvas');
+        canvas.width = 6;
+        canvas.height = 1;
+
+        var context = canvas.getContext('2d');
+        context.fillStyle = color;
+        context.fillRect(0,0,6,1);
+        return canvas;
+    };
+
+
+    /**
+     * Checks whether the Canvas BlendModes are supported by the current browser
+     *
+     * @return {boolean} whether they are supported
+     */
+    var canUseNewCanvasBlendModes = function ()
+    {
+        if (typeof document === 'undefined')
+        {
+            return false;
+        }
+
+        var magenta = createColoredCanvas('#ff00ff');
+        var yellow = createColoredCanvas('#ffff00');
+
+        var canvas = document.createElement('canvas');
+        canvas.width = 6;
+        canvas.height = 1;
+
+        var context = canvas.getContext('2d');
+        context.globalCompositeOperation = 'multiply';
+        context.drawImage(magenta, 0, 0);
+        context.drawImage(yellow, 2, 0);
+
+        var imageData = context.getImageData(2,0,1,1);
+
+        if (!imageData)
+        {
+            return false;
+        }
+
+        var data = imageData.data;
+
+        return (data[0] === 255 && data[1] === 0 && data[2] === 0);
+    };
+
+
+    module.exports = canUseNewCanvasBlendModes;
+
+},{}],78:[function(require,module,exports){
+    var CONST = require('../../../const'),
+        canUseNewCanvasBlendModes = require('./canUseNewCanvasBlendModes');
+
+    /**
+     * Maps blend combinations to Canvas
+     * @class
+     * @memberof PIXI
+     * @param array
+     */
+    function mapCanvasBlendModesToPixi(array)
+    {
+        array = array || [];
+
+        if (canUseNewCanvasBlendModes())
+        {
+            array[CONST.BLEND_MODES.NORMAL]        = 'source-over';
+            array[CONST.BLEND_MODES.ADD]           = 'lighter'; //IS THIS OK???
+            array[CONST.BLEND_MODES.MULTIPLY]      = 'multiply';
+            array[CONST.BLEND_MODES.SCREEN]        = 'screen';
+            array[CONST.BLEND_MODES.OVERLAY]       = 'overlay';
+            array[CONST.BLEND_MODES.DARKEN]        = 'darken';
+            array[CONST.BLEND_MODES.LIGHTEN]       = 'lighten';
+            array[CONST.BLEND_MODES.COLOR_DODGE]   = 'color-dodge';
+            array[CONST.BLEND_MODES.COLOR_BURN]    = 'color-burn';
+            array[CONST.BLEND_MODES.HARD_LIGHT]    = 'hard-light';
+            array[CONST.BLEND_MODES.SOFT_LIGHT]    = 'soft-light';
+            array[CONST.BLEND_MODES.DIFFERENCE]    = 'difference';
+            array[CONST.BLEND_MODES.EXCLUSION]     = 'exclusion';
+            array[CONST.BLEND_MODES.HUE]           = 'hue';
+            array[CONST.BLEND_MODES.SATURATION]    = 'saturate';
+            array[CONST.BLEND_MODES.COLOR]         = 'color';
+            array[CONST.BLEND_MODES.LUMINOSITY]    = 'luminosity';
+        }
+        else
+        {
+            // this means that the browser does not support the cool new blend modes in canvas 'cough' ie 'cough'
+            array[CONST.BLEND_MODES.NORMAL]        = 'source-over';
+            array[CONST.BLEND_MODES.ADD]           = 'lighter'; //IS THIS OK???
+            array[CONST.BLEND_MODES.MULTIPLY]      = 'source-over';
+            array[CONST.BLEND_MODES.SCREEN]        = 'source-over';
+            array[CONST.BLEND_MODES.OVERLAY]       = 'source-over';
+            array[CONST.BLEND_MODES.DARKEN]        = 'source-over';
+            array[CONST.BLEND_MODES.LIGHTEN]       = 'source-over';
+            array[CONST.BLEND_MODES.COLOR_DODGE]   = 'source-over';
+            array[CONST.BLEND_MODES.COLOR_BURN]    = 'source-over';
+            array[CONST.BLEND_MODES.HARD_LIGHT]    = 'source-over';
+            array[CONST.BLEND_MODES.SOFT_LIGHT]    = 'source-over';
+            array[CONST.BLEND_MODES.DIFFERENCE]    = 'source-over';
+            array[CONST.BLEND_MODES.EXCLUSION]     = 'source-over';
+            array[CONST.BLEND_MODES.HUE]           = 'source-over';
+            array[CONST.BLEND_MODES.SATURATION]    = 'source-over';
+            array[CONST.BLEND_MODES.COLOR]         = 'source-over';
+            array[CONST.BLEND_MODES.LUMINOSITY]    = 'source-over';
+        }
+
+        return array;
+    }
+
+    module.exports = mapCanvasBlendModesToPixi;
+
+},{"../../../const":43,"./canUseNewCanvasBlendModes":77}],79:[function(require,module,exports){
+
+    var CONST = require('../../const');
+
+    /**
+     * TextureGarbageCollector. This class manages the GPU and ensures that it does not get clogged up with textures that are no longer being used.
+     *
+     * @class
+     * @memberof PIXI
+     * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.
+     */
+    function TextureGarbageCollector(renderer)
+    {
+        this.renderer = renderer;
+
+        this.count = 0;
+        this.checkCount = 0;
+        this.maxIdle = 60 * 60;
+        this.checkCountMax = 60 * 10;
+
+        this.mode = CONST.GC_MODES.DEFAULT;
+    }
+
+    TextureGarbageCollector.prototype.constructor = TextureGarbageCollector;
+    module.exports = TextureGarbageCollector;
+
+    /**
+     * Checks to see when the last time a texture was used
+     * if the texture has not been used for a specified amount of time it will be removed from the GPU
+     */
+    TextureGarbageCollector.prototype.update = function()
+    {
+        this.count++;
+
+        if(this.mode === CONST.GC_MODES.MANUAL)
+        {
+            return;
+        }
+
+        this.checkCount++;
+
+
+        if(this.checkCount > this.checkCountMax)
+        {
+            this.checkCount = 0;
+
+            this.run();
+        }
+    };
+
+    /**
+     * Checks to see when the last time a texture was used
+     * if the texture has not been used for a specified amount of time it will be removed from the GPU
+     */
+    TextureGarbageCollector.prototype.run = function()
+    {
+        var tm = this.renderer.textureManager;
+        var managedTextures =  tm._managedTextures;
+        var wasRemoved = false;
+        var i,j;
+
+        for (i = 0; i < managedTextures.length; i++)
+        {
+            var texture = managedTextures[i];
+
+            // only supports non generated textures at the moment!
+            if (!texture._glRenderTargets && this.count - texture.touched > this.maxIdle)
+            {
+                tm.destroyTexture(texture, true);
+                managedTextures[i] = null;
+                wasRemoved = true;
+            }
+        }
+
+        if (wasRemoved)
+        {
+            j = 0;
+
+            for (i = 0; i < managedTextures.length; i++)
+            {
+                if (managedTextures[i] !== null)
+                {
+                    managedTextures[j++] = managedTextures[i];
+                }
+            }
+
+            managedTextures.length = j;
+        }
+    };
+
+    /**
+     * Removes all the textures within the specified displayObject and its children from the GPU
+     *
+     * @param displayObject {PIXI.DisplayObject} the displayObject to remove the textures from.
+     */
+    TextureGarbageCollector.prototype.unload = function( displayObject )
+    {
+        var tm = this.renderer.textureManager;
+
+        if(displayObject._texture)
+        {
+            tm.destroyTexture(displayObject._texture, true);
+        }
+
+        for (var i = displayObject.children.length - 1; i >= 0; i--) {
+
+            this.unload(displayObject.children[i]);
+
+        }
+    };
+
+},{"../../const":43}],80:[function(require,module,exports){
+    var GLTexture = require('pixi-gl-core').GLTexture,
+        CONST = require('../../const'),
+        RenderTarget = require('./utils/RenderTarget'),
+        utils = require('../../utils');
+
+    /**
+     * Helper class to create a webGL Texture
+     *
+     * @class
+     * @memberof PIXI
+     * @param renderer {PIXI.WebGLRenderer} A reference to the current renderer
+     */
+    var TextureManager = function(renderer)
+    {
+        /**
+         * A reference to the current renderer
+         *
+         * @member {PIXI.WebGLRenderer}
+         */
+        this.renderer = renderer;
+
+        /**
+         * The current WebGL rendering context
+         *
+         * @member {WebGLRenderingContext}
+         */
+        this.gl = renderer.gl;
+
+        /**
+         * Track textures in the renderer so we can no longer listen to them on destruction.
+         *
+         * @member {Array<*>}
+         * @private
+         */
+        this._managedTextures = [];
+    };
+
+    TextureManager.prototype.bindTexture = function()
+    {
+    };
+
+
+    TextureManager.prototype.getTexture = function()
+    {
+    };
+
+    /**
+     * Updates and/or Creates a WebGL texture for the renderer's context.
+     *
+     * @param texture {PIXI.BaseTexture|PIXI.Texture} the texture to update
+     */
+    TextureManager.prototype.updateTexture = function(texture)
+    {
+        texture = texture.baseTexture || texture;
+
+        var isRenderTexture = !!texture._glRenderTargets;
+
+        if (!texture.hasLoaded)
+        {
+            return;
+        }
+
+        var glTexture = texture._glTextures[this.renderer.CONTEXT_UID];
+
+        if (!glTexture)
+        {
+            if(isRenderTexture)
+            {
+                var renderTarget = new RenderTarget(this.gl, texture.width, texture.height, texture.scaleMode, texture.resolution);
+                renderTarget.resize(texture.width, texture.height);
+                texture._glRenderTargets[this.renderer.CONTEXT_UID] = renderTarget;
+                glTexture = renderTarget.texture;
+            }
+            else
+            {
+                glTexture = new GLTexture(this.gl);
+                glTexture.premultiplyAlpha = true;
+                glTexture.upload(texture.source);
+            }
+
+            texture._glTextures[this.renderer.CONTEXT_UID] = glTexture;
+
+            texture.on('update', this.updateTexture, this);
+            texture.on('dispose', this.destroyTexture, this);
+
+            this._managedTextures.push(texture);
+
+            if(texture.isPowerOfTwo)
+            {
+                if(texture.mipmap)
+                {
+                    glTexture.enableMipmap();
+                }
+
+                if(texture.wrapMode === CONST.WRAP_MODES.CLAMP)
+                {
+                    glTexture.enableWrapClamp();
+                }
+                else if(texture.wrapMode === CONST.WRAP_MODES.REPEAT)
+                {
+                    glTexture.enableWrapRepeat();
+                }
+                else
+                {
+                    glTexture.enableWrapMirrorRepeat();
+                }
+            }
+            else
+            {
+                glTexture.enableWrapClamp();
+            }
+
+            if(texture.scaleMode === CONST.SCALE_MODES.NEAREST)
+            {
+                glTexture.enableNearestScaling();
+            }
+            else
+            {
+                glTexture.enableLinearScaling();
+            }
+        }
+        else
+        {
+            // the textur ealrady exists so we only need to update it..
+            if(isRenderTexture)
+            {
+                texture._glRenderTargets[this.renderer.CONTEXT_UID].resize(texture.width, texture.height);
+            }
+            else
+            {
+                glTexture.upload(texture.source);
+            }
+        }
+
+        return  glTexture;
+    };
+
+    /**
+     * Deletes the texture from WebGL
+     *
+     * @param texture {PIXI.BaseTexture|PIXI.Texture} the texture to destroy
+     * @param [skipRemove=false] {boolean} Whether to skip removing the texture from the TextureManager.
+     */
+    TextureManager.prototype.destroyTexture = function(texture, skipRemove)
+    {
+        texture = texture.baseTexture || texture;
+
+        if (!texture.hasLoaded)
+        {
+            return;
+        }
+
+        if (texture._glTextures[this.renderer.CONTEXT_UID])
+        {
+            texture._glTextures[this.renderer.CONTEXT_UID].destroy();
+            texture.off('update', this.updateTexture, this);
+            texture.off('dispose', this.destroyTexture, this);
+
+
+            delete texture._glTextures[this.renderer.CONTEXT_UID];
+
+            if (!skipRemove)
+            {
+                var i = this._managedTextures.indexOf(texture);
+                if (i !== -1) {
+                    utils.removeItems(this._managedTextures, i, 1);
+                }
+            }
+        }
+    };
+
+    /**
+     * Deletes all the textures from WebGL
+     */
+    TextureManager.prototype.removeAll = function()
+    {
+        // empty all the old gl textures as they are useless now
+        for (var i = 0; i < this._managedTextures.length; ++i)
+        {
+            var texture = this._managedTextures[i];
+            if (texture._glTextures[this.renderer.CONTEXT_UID])
+            {
+                delete texture._glTextures[this.renderer.CONTEXT_UID];
+            }
+        }
+    };
+
+    /**
+     * Destroys this manager and removes all its textures
+     */
+    TextureManager.prototype.destroy = function()
+    {
+        // destroy managed textures
+        for (var i = 0; i < this._managedTextures.length; ++i)
+        {
+            var texture = this._managedTextures[i];
+            this.destroyTexture(texture, true);
+            texture.off('update', this.updateTexture, this);
+            texture.off('dispose', this.destroyTexture, this);
+        }
+
+        this._managedTextures = null;
+    };
+
+    module.exports = TextureManager;
+
+},{"../../const":43,"../../utils":116,"./utils/RenderTarget":93,"pixi-gl-core":12}],81:[function(require,module,exports){
+    var SystemRenderer = require('../SystemRenderer'),
+        MaskManager = require('./managers/MaskManager'),
+        StencilManager = require('./managers/StencilManager'),
+        FilterManager = require('./managers/FilterManager'),
+        RenderTarget = require('./utils/RenderTarget'),
+        ObjectRenderer = require('./utils/ObjectRenderer'),
+        TextureManager = require('./TextureManager'),
+        TextureGarbageCollector = require('./TextureGarbageCollector'),
+        WebGLState = require('./WebGLState'),
+        createContext = require('pixi-gl-core').createContext,
+        mapWebGLDrawModesToPixi = require('./utils/mapWebGLDrawModesToPixi'),
+        validateContext = require('./utils/validateContext'),
+        utils = require('../../utils'),
+        glCore = require('pixi-gl-core'),
+        CONST = require('../../const');
+
+    var CONTEXT_UID = 0;
+
+    /**
+     * The WebGLRenderer draws the scene and all its content onto a webGL enabled canvas. This renderer
+     * should be used for browsers that support webGL. This Render works by automatically managing webGLBatchs.
+     * So no need for Sprite Batches or Sprite Clouds.
+     * Don't forget to add the view to your DOM or you will not see anything :)
+     *
+     * @class
+     * @memberof PIXI
+     * @extends PIXI.SystemRenderer
+     * @param [width=0] {number} the width of the canvas view
+     * @param [height=0] {number} the height of the canvas view
+     * @param [options] {object} The optional renderer parameters
+     * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional
+     * @param [options.transparent=false] {boolean} If the render view is transparent, default false
+     * @param [options.autoResize=false] {boolean} If the render view is automatically resized, default false
+     * @param [options.antialias=false] {boolean} sets antialias. If not available natively then FXAA antialiasing is used
+     * @param [options.forceFXAA=false] {boolean} forces FXAA antialiasing to be used over native. FXAA is faster, but may not always look as great
+     * @param [options.resolution=1] {number} The resolution / device pixel ratio of the renderer. The resolution of the renderer retina would be 2.
+     * @param [options.clearBeforeRender=true] {boolean} This sets if the CanvasRenderer will clear the canvas or
+     *      not before the new render pass. If you wish to set this to false, you *must* set preserveDrawingBuffer to `true`.
+     * @param [options.preserveDrawingBuffer=false] {boolean} enables drawing buffer preservation, enable this if
+     *      you need to call toDataUrl on the webgl context.
+     * @param [options.roundPixels=false] {boolean} If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.
+     */
+    function WebGLRenderer(width, height, options)
+    {
+        options = options || {};
+
+        SystemRenderer.call(this, 'WebGL', width, height, options);
+        /**
+         * The type of this renderer as a standardised const
+         *
+         * @member {number}
+         * @see PIXI.RENDERER_TYPE
+         */
+        this.type = CONST.RENDERER_TYPE.WEBGL;
+
+        this.handleContextLost = this.handleContextLost.bind(this);
+        this.handleContextRestored = this.handleContextRestored.bind(this);
+
+        this.view.addEventListener('webglcontextlost', this.handleContextLost, false);
+        this.view.addEventListener('webglcontextrestored', this.handleContextRestored, false);
+
+        /**
+         * The options passed in to create a new webgl context.
+         *
+         * @member {object}
+         * @private
+         */
+        this._contextOptions = {
+            alpha: this.transparent,
+            antialias: options.antialias,
+            premultipliedAlpha: this.transparent && this.transparent !== 'notMultiplied',
+            stencil: true,
+            preserveDrawingBuffer: options.preserveDrawingBuffer
+        };
+
+        this._backgroundColorRgba[3] = this.transparent ? 0 : 1;
+
+        /**
+         * Manages the masks using the stencil buffer.
+         *
+         * @member {PIXI.MaskManager}
+         */
+        this.maskManager = new MaskManager(this);
+
+        /**
+         * Manages the stencil buffer.
+         *
+         * @member {PIXI.StencilManager}
+         */
+        this.stencilManager = new StencilManager(this);
+
+        /**
+         * An empty renderer.
+         *
+         * @member {PIXI.ObjectRenderer}
+         */
+        this.emptyRenderer = new ObjectRenderer(this);
+
+        /**
+         * The currently active ObjectRenderer.
+         *
+         * @member {PIXI.ObjectRenderer}
+         */
+        this.currentRenderer = this.emptyRenderer;
+
+        this.initPlugins();
+
+        /**
+         * The current WebGL rendering context, it is created here
+         *
+         * @member {WebGLRenderingContext}
+         */
+        // initialize the context so it is ready for the managers.
+        if(options.context)
+        {
+            // checks to see if a context is valid..
+            validateContext(options.context);
+        }
+
+        this.gl = options.context || createContext(this.view, this._contextOptions);
+
+        this.CONTEXT_UID = CONTEXT_UID++;
+
+        /**
+         * The currently active ObjectRenderer.
+         *
+         * @member {PIXI.WebGLState}
+         */
+        this.state = new WebGLState(this.gl);
+
+        this.renderingToScreen = true;
+
+
+
+        this._initContext();
+
+        /**
+         * Manages the filters.
+         *
+         * @member {PIXI.FilterManager}
+         */
+        this.filterManager = new FilterManager(this);
+        // map some webGL blend and drawmodes..
+        this.drawModes = mapWebGLDrawModesToPixi(this.gl);
+
+
+        /**
+         * Holds the current shader
+         *
+         * @member {PIXI.Shader}
+         */
+        this._activeShader = null;
+
+        /**
+         * Holds the current render target
+         *
+         * @member {PIXI.RenderTarget}
+         */
+        this._activeRenderTarget = null;
+        this._activeTextureLocation = 999;
+        this._activeTexture = null;
+
+        this.setBlendMode(0);
+
+
+    }
+
+// constructor
+    WebGLRenderer.prototype = Object.create(SystemRenderer.prototype);
+    WebGLRenderer.prototype.constructor = WebGLRenderer;
+    module.exports = WebGLRenderer;
+    utils.pluginTarget.mixin(WebGLRenderer);
+
+    /**
+     * Creates the WebGL context
+     *
+     * @private
+     */
+    WebGLRenderer.prototype._initContext = function ()
+    {
+        var gl = this.gl;
+
+        // create a texture manager...
+        this.textureManager = new TextureManager(this);
+        this.textureGC = new TextureGarbageCollector(this);
+
+        this.state.resetToDefault();
+
+        this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true);
+        this.rootRenderTarget.clearColor = this._backgroundColorRgba;
+
+
+        this.bindRenderTarget(this.rootRenderTarget);
+
+        this.emit('context', gl);
+
+        // setup the width/height properties and gl viewport
+        this.resize(this.width, this.height);
+    };
+
+    /**
+     * Renders the object to its webGL view
+     *
+     * @param displayObject {PIXI.DisplayObject} the object to be rendered
+     * @param renderTexture {PIXI.RenderTexture}
+     * @param [clear] {boolean} Should the canvas be cleared before the new render
+     * @param [transform] {PIXI.Transform}
+     * @param [skipUpdateTransform] {boolean}
+     */
+    WebGLRenderer.prototype.render = function (displayObject, renderTexture, clear, transform, skipUpdateTransform)
+    {
+
+        // can be handy to know!
+        this.renderingToScreen = !renderTexture;
+
+        this.emit('prerender');
+
+
+        // no point rendering if our context has been blown up!
+        if (!this.gl || this.gl.isContextLost())
+        {
+            return;
+        }
+
+        if(!renderTexture)
+        {
+            this._lastObjectRendered = displayObject;
+        }
+
+        if(!skipUpdateTransform)
+        {
+            // update the scene graph
+            var cacheParent = displayObject.parent;
+            displayObject.parent = this._tempDisplayObjectParent;
+            displayObject.updateTransform();
+            displayObject.parent = cacheParent;
+            // displayObject.hitArea = //TODO add a temp hit area
+        }
+
+        this.bindRenderTexture(renderTexture, transform);
+
+        this.currentRenderer.start();
+
+        if(clear !== undefined ? clear : this.clearBeforeRender)
+        {
+            this._activeRenderTarget.clear();
+        }
+
+        displayObject.renderWebGL(this);
+
+        // apply transform..
+        this.currentRenderer.flush();
+
+        //this.setObjectRenderer(this.emptyRenderer);
+
+        this.textureGC.update();
+
+        this.emit('postrender');
+    };
+
+    /**
+     * Changes the current renderer to the one given in parameter
+     *
+     * @param objectRenderer {PIXI.ObjectRenderer} The object renderer to use.
+     */
+    WebGLRenderer.prototype.setObjectRenderer = function (objectRenderer)
+    {
+        if (this.currentRenderer === objectRenderer)
+        {
+            return;
+        }
+
+        this.currentRenderer.stop();
+        this.currentRenderer = objectRenderer;
+        this.currentRenderer.start();
+    };
+
+    /**
+     * This shoudl be called if you wish to do some custom rendering
+     * It will basically render anything that may be batched up such as sprites
+     *
+     */
+    WebGLRenderer.prototype.flush = function ()
+    {
+        this.setObjectRenderer(this.emptyRenderer);
+    };
+
+    /**
+     * Resizes the webGL view to the specified width and height.
+     *
+     * @param width {number} the new width of the webGL view
+     * @param height {number} the new height of the webGL view
+     */
+    WebGLRenderer.prototype.resize = function (width, height)
+    {
+        //  if(width * this.resolution === this.width && height * this.resolution === this.height)return;
+
+        SystemRenderer.prototype.resize.call(this, width, height);
+
+        this.rootRenderTarget.resize(width, height);
+
+        if(this._activeRenderTarget === this.rootRenderTarget)
+        {
+            this.rootRenderTarget.activate();
+
+            if(this._activeShader)
+            {
+                this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true);
+            }
+        }
+    };
+
+    /**
+     * Resizes the webGL view to the specified width and height.
+     *
+     * @param blendMode {number} the desired blend mode
+     */
+    WebGLRenderer.prototype.setBlendMode = function (blendMode)
+    {
+        this.state.setBlendMode(blendMode);
+    };
+
+    /**
+     * Erases the active render target and fills the drawing area with a colour
+     *
+     * @param [clearColor] {number} The colour
+     */
+    WebGLRenderer.prototype.clear = function (clearColor)
+    {
+        this._activeRenderTarget.clear(clearColor);
+    };
+
+    /**
+     * Sets the transform of the active render target to the given matrix
+     *
+     * @param matrix {PIXI.Matrix} The transformation matrix
+     */
+    WebGLRenderer.prototype.setTransform = function (matrix)
+    {
+        this._activeRenderTarget.transform = matrix;
+    };
+
+
+    /**
+     * Binds a render texture for rendering
+     *
+     * @param renderTexture {PIXI.RenderTexture} The render texture to render
+     * @param transform     {PIXI.Transform}     The transform to be applied to the render texture
+     */
+    WebGLRenderer.prototype.bindRenderTexture = function (renderTexture, transform)
+    {
+        var renderTarget;
+
+        if(renderTexture)
+        {
+            var baseTexture = renderTexture.baseTexture;
+            var gl = this.gl;
+
+            if(!baseTexture._glRenderTargets[this.CONTEXT_UID])
+            {
+
+                this.textureManager.updateTexture(baseTexture);
+                gl.bindTexture(gl.TEXTURE_2D, null);
+            }
+            else
+            {
+                // the texture needs to be unbound if its being rendererd too..
+                this._activeTextureLocation = baseTexture._id;
+                gl.activeTexture(gl.TEXTURE0 + baseTexture._id);
+                gl.bindTexture(gl.TEXTURE_2D, null);
+            }
+
+
+            renderTarget =  baseTexture._glRenderTargets[this.CONTEXT_UID];
+            renderTarget.setFrame(renderTexture.frame);
+        }
+        else
+        {
+            renderTarget = this.rootRenderTarget;
+        }
+
+        renderTarget.transform = transform;
+        this.bindRenderTarget(renderTarget);
+
+        return this;
+    };
+
+    /**
+     * Changes the current render target to the one given in parameter
+     *
+     * @param renderTarget {PIXI.RenderTarget} the new render target
+     */
+    WebGLRenderer.prototype.bindRenderTarget = function (renderTarget)
+    {
+        if(renderTarget !== this._activeRenderTarget)
+        {
+            this._activeRenderTarget = renderTarget;
+            renderTarget.activate();
+
+            if(this._activeShader)
+            {
+                this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true);
+            }
+
+
+            this.stencilManager.setMaskStack( renderTarget.stencilMaskStack );
+        }
+
+        return this;
+    };
+
+    /**
+     * Changes the current shader to the one given in parameter
+     *
+     * @param shader {PIXI.Shader} the new shader
+     */
+    WebGLRenderer.prototype.bindShader = function (shader)
+    {
+        //TODO cache
+        if(this._activeShader !== shader)
+        {
+            this._activeShader = shader;
+            shader.bind();
+
+            // automatically set the projection matrix
+            shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true);
+        }
+
+        return this;
+    };
+
+    /**
+     * Binds the texture ... @mat
+     *
+     * @param texture {PIXI.Texture} the new texture
+     * @param location {number} the texture location
+     */
+    WebGLRenderer.prototype.bindTexture = function (texture, location)
+    {
+        texture = texture.baseTexture || texture;
+
+        var gl = this.gl;
+
+        //TODO test perf of cache?
+        location = location || 0;
+
+        if(this._activeTextureLocation !== location)//
+        {
+            this._activeTextureLocation = location;
+            gl.activeTexture(gl.TEXTURE0 + location );
+        }
+
+        //TODO - can we cache this texture too?
+        this._activeTexture = texture;
+
+        if (!texture._glTextures[this.CONTEXT_UID])
+        {
+            // this will also bind the texture..
+            this.textureManager.updateTexture(texture);
+
+        }
+        else
+        {
+            texture.touched = this.textureGC.count;
+            // bind the current texture
+            texture._glTextures[this.CONTEXT_UID].bind();
+        }
+
+        return this;
+    };
+
+    WebGLRenderer.prototype.createVao = function ()
+    {
+        return new glCore.VertexArrayObject(this.gl, this.state.attribState);
+    };
+
+    /**
+     * Resets the WebGL state so you can render things however you fancy!
+     */
+    WebGLRenderer.prototype.reset = function ()
+    {
+        this.setObjectRenderer(this.emptyRenderer);
+
+        this._activeShader = null;
+        this._activeRenderTarget = this.rootRenderTarget;
+        this._activeTextureLocation = 999;
+        this._activeTexture = null;
+
+        // bind the main frame buffer (the screen);
+        this.rootRenderTarget.activate();
+
+        this.state.resetToDefault();
+
+        return this;
+    };
+
+    /**
+     * Handles a lost webgl context
+     *
+     * @private
+     */
+    WebGLRenderer.prototype.handleContextLost = function (event)
+    {
+        event.preventDefault();
+    };
+
+    /**
+     * Handles a restored webgl context
+     *
+     * @private
+     */
+    WebGLRenderer.prototype.handleContextRestored = function ()
+    {
+        this._initContext();
+        this.textureManager.removeAll();
+    };
+
+    /**
+     * Removes everything from the renderer (event listeners, spritebatch, etc...)
+     *
+     * @param [removeView=false] {boolean} Removes the Canvas element from the DOM.  https://github.com/pixijs/pixi.js/issues/2233
+     */
+    WebGLRenderer.prototype.destroy = function (removeView)
+    {
+        this.destroyPlugins();
+
+        // remove listeners
+        this.view.removeEventListener('webglcontextlost', this.handleContextLost);
+        this.view.removeEventListener('webglcontextrestored', this.handleContextRestored);
+
+        this.textureManager.destroy();
+
+        // call base destroy
+        SystemRenderer.prototype.destroy.call(this, removeView);
+
+        this.uid = 0;
+
+        // destroy the managers
+        this.maskManager.destroy();
+        this.stencilManager.destroy();
+        this.filterManager.destroy();
+
+        this.maskManager = null;
+        this.filterManager = null;
+        this.textureManager = null;
+        this.currentRenderer = null;
+
+        this.handleContextLost = null;
+        this.handleContextRestored = null;
+
+        this._contextOptions = null;
+        this.gl.useProgram(null);
+
+        if(this.gl.getExtension('WEBGL_lose_context'))
+        {
+            this.gl.getExtension('WEBGL_lose_context').loseContext();
+        }
+
+        this.gl = null;
+
+        // this = null;
+    };
+
+},{"../../const":43,"../../utils":116,"../SystemRenderer":73,"./TextureGarbageCollector":79,"./TextureManager":80,"./WebGLState":82,"./managers/FilterManager":87,"./managers/MaskManager":88,"./managers/StencilManager":89,"./utils/ObjectRenderer":91,"./utils/RenderTarget":93,"./utils/mapWebGLDrawModesToPixi":96,"./utils/validateContext":97,"pixi-gl-core":12}],82:[function(require,module,exports){
+    var mapWebGLBlendModesToPixi = require('./utils/mapWebGLBlendModesToPixi');
+
+    /**
+     * A WebGL state machines
+     *
+     * @memberof PIXI
+     * @class
+     * @param gl {WebGLRenderingContext} The current WebGL rendering context
+     */
+    function WebGLState(gl)
+    {
+        /**
+         * The current active state
+         *
+         * @member {Uint8Array}
+         */
+        this.activeState = new Uint8Array(16);
+
+        /**
+         * The default state
+         *
+         * @member {Uint8Array}
+         */
+        this.defaultState = new Uint8Array(16);
+
+        // default blend mode..
+        this.defaultState[0] = 1;
+
+        /**
+         * The current state index in the stack
+         *
+         * @member {number}
+         * @private
+         */
+        this.stackIndex = 0;
+
+        /**
+         * The stack holding all the different states
+         *
+         * @member {Array<*>}
+         * @private
+         */
+        this.stack = [];
+
+        /**
+         * The current WebGL rendering context
+         *
+         * @member {WebGLRenderingContext}
+         */
+        this.gl = gl;
+
+        this.maxAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
+
+        this.attribState = {tempAttribState:new Array(this.maxAttribs),
+            attribState:new Array(this.maxAttribs)};
+
+        this.blendModes = mapWebGLBlendModesToPixi(gl);
+
+        // check we have vao..
+        this.nativeVaoExtension = (
+        gl.getExtension('OES_vertex_array_object') ||
+        gl.getExtension('MOZ_OES_vertex_array_object') ||
+        gl.getExtension('WEBKIT_OES_vertex_array_object')
+        );
+    }
+
+    /**
+     * Pushes a new active state
+     */
+    WebGLState.prototype.push = function()
+    {
+        // next state..
+        var state = this.stack[++this.stackIndex];
+
+        if(!state)
+        {
+            state = this.stack[this.stackIndex] = new Uint8Array(16);
+        }
+
+        // copy state..
+        // set active state so we can force overrides of gl state
+        for (var i = 0; i < this.activeState.length; i++)
+        {
+            this.activeState[i] = state[i];
+        }
+    };
+
+    var BLEND = 0,
+        DEPTH_TEST = 1,
+        FRONT_FACE = 2,
+        CULL_FACE = 3,
+        BLEND_FUNC = 4;
+
+    /**
+     * Pops a state out
+     */
+    WebGLState.prototype.pop = function()
+    {
+        var state = this.stack[--this.stackIndex];
+        this.setState(state);
+    };
+
+    /**
+     * Sets the current state
+     * @param state {number}
+     */
+    WebGLState.prototype.setState = function(state)
+    {
+        this.setBlend(state[BLEND]);
+        this.setDepthTest(state[DEPTH_TEST]);
+        this.setFrontFace(state[FRONT_FACE]);
+        this.setCullFace(state[CULL_FACE]);
+        this.setBlendMode(state[BLEND_FUNC]);
+    };
+
+    /**
+     * Sets the blend mode ? @mat
+     * @param value {number}
+     */
+    WebGLState.prototype.setBlend = function(value)
+    {
+        if(this.activeState[BLEND] === value|0) {
+            return;
+        }
+
+        this.activeState[BLEND] = value|0;
+
+        var gl = this.gl;
+
+        if(value)
+        {
+            gl.enable(gl.BLEND);
+        }
+        else
+        {
+            gl.disable(gl.BLEND);
+        }
+    };
+
+    /**
+     * Sets the blend mode ? @mat
+     * @param value {number}
+     */
+    WebGLState.prototype.setBlendMode = function(value)
+    {
+        if(value === this.activeState[BLEND_FUNC]) {
+            return;
+        }
+
+        this.activeState[BLEND_FUNC] = value;
+
+        this.gl.blendFunc(this.blendModes[value][0], this.blendModes[value][1]);
+    };
+
+    /**
+     * Sets the depth test @mat
+     * @param value {number}
+     */
+    WebGLState.prototype.setDepthTest = function(value)
+    {
+        if(this.activeState[DEPTH_TEST] === value|0) {
+            return;
+        }
+
+        this.activeState[DEPTH_TEST] = value|0;
+
+        var gl = this.gl;
+
+        if(value)
+        {
+            gl.enable(gl.DEPTH_TEST);
+        }
+        else
+        {
+            gl.disable(gl.DEPTH_TEST);
+        }
+    };
+
+    /**
+     * Sets the depth test @mat
+     * @param value {number}
+     */
+    WebGLState.prototype.setCullFace = function(value)
+    {
+        if(this.activeState[CULL_FACE] === value|0) {
+            return;
+        }
+
+        this.activeState[CULL_FACE] = value|0;
+
+        var gl = this.gl;
+
+        if(value)
+        {
+            gl.enable(gl.CULL_FACE);
+        }
+        else
+        {
+            gl.disable(gl.CULL_FACE);
+        }
+    };
+
+    /**
+     * Sets the depth test @mat
+     * @param value {number}
+     */
+    WebGLState.prototype.setFrontFace = function(value)
+    {
+        if(this.activeState[FRONT_FACE] === value|0) {
+            return;
+        }
+
+        this.activeState[FRONT_FACE] = value|0;
+
+        var gl = this.gl;
+
+        if(value)
+        {
+            gl.frontFace(gl.CW);
+        }
+        else
+        {
+            gl.frontFace(gl.CCW);
+        }
+    };
+
+    /**
+     * Disables all the vaos in use
+     */
+    WebGLState.prototype.resetAttributes = function()
+    {
+        var i;
+
+        for ( i = 0; i < this.attribState.tempAttribState.length; i++) {
+            this.attribState.tempAttribState[i] = 0;
+        }
+
+        for ( i = 0; i < this.attribState.attribState.length; i++) {
+            this.attribState.attribState[i] = 0;
+        }
+
+        var gl = this.gl;
+
+        // im going to assume one is always active for performance reasons.
+        for (i = 1; i < this.maxAttribs; i++)
+        {
+            gl.disableVertexAttribArray(i);
+        }
+    };
+
+//used
+    /**
+     * Resets all the logic and disables the vaos
+     */
+    WebGLState.prototype.resetToDefault = function()
+    {
+
+        // unbind any VAO if they exist..
+        if(this.nativeVaoExtension)
+        {
+            this.nativeVaoExtension.bindVertexArrayOES(null);
+        }
+
+
+        // reset all attributs..
+        this.resetAttributes();
+
+        // set active state so we can force overrides of gl state
+        for (var i = 0; i < this.activeState.length; i++)
+        {
+            this.activeState[i] = 32;
+        }
+
+        var gl = this.gl;
+        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+
+
+        this.setState(this.defaultState);
+    };
+
+    module.exports = WebGLState;
+
+},{"./utils/mapWebGLBlendModesToPixi":95}],83:[function(require,module,exports){
+    var extractUniformsFromSrc = require('./extractUniformsFromSrc'),
+        utils = require('../../../utils'),
+        CONST = require('../../../const'),
+        SOURCE_KEY_MAP = {};
+
+// var math = require('../../../math');
+    /**
+     * @class
+     * @memberof PIXI
+     * @extends PIXI.Shader
+     * @param [vertexSrc] {string} The source of the vertex shader.
+     * @param [uniforms] {object} Custom uniforms to use to augment the built-in ones.
+     * @param [fragmentSrc] {string} The source of the fragment shader.
+     */
+    function Filter(vertexSrc, fragmentSrc, uniforms)
+    {
+
+        /**
+         * The vertex shader.
+         *
+         * @member {string}
+         */
+        this.vertexSrc = vertexSrc || Filter.defaultVertexSrc;
+
+        /**
+         * The fragment shader.
+         *
+         * @member {string}
+         */
+        this.fragmentSrc = fragmentSrc || Filter.defaultFragmentSrc;
+
+        this.blendMode = CONST.BLEND_MODES.NORMAL;
+
+        // pull out the vertex and shader uniforms if they are not specified..
+        // currently this does not extract structs only default types
+        this.uniformData = uniforms || extractUniformsFromSrc( this.vertexSrc, this.fragmentSrc, 'projectionMatrix|uSampler');
+
+        this.uniforms = {};
+
+        for (var i in this.uniformData)
+        {
+            this.uniforms[i] = this.uniformData[i].value;
+        }
+
+        // this is where we store shader references..
+        // TODO we could cache this!
+        this.glShaders = [];
+
+        // used for cacheing.. sure there is a better way!
+        if(!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+        {
+            SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = utils.uid();
+        }
+
+        this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+
+        /**
+         * The padding of the filter. Some filters require extra space to breath such as a blur. Increasing this will add extra width and height to the bounds of the object that the filter is applied to.
+         */
+        this.padding = 4;
+
+        /**
+         * The resolution of the filter. Setting this to be lower will lower the quality but increase the performance of the filter.
+         * @member {number}
+         */
+        this.resolution = 1;
+
+        /**
+         * If enabled is true the filter is applied, if false it will not.
+         * @member {boolean}
+         */
+        this.enabled = true;
+    }
+
+// constructor
+//Filter.prototype.constructor = Filter;
+    module.exports = Filter;
+
+// var tempMatrix = new math.Matrix();
+
+    Filter.prototype.apply = function(filterManager, input, output, clear)
+    {
+        // --- //
+        //  this.uniforms.filterMatrix = filterManager.calculateSpriteMatrix(tempMatrix, window.panda );
+
+        // do as you please!
+
+        filterManager.applyFilter(this, input, output, clear);
+
+        // or just do a regular render..
+    };
+
+    /**
+     * The default vertex shader source
+     *
+     * @static
+     * @constant
+     */
+    Filter.defaultVertexSrc = [
+        'attribute vec2 aVertexPosition;',
+        'attribute vec2 aTextureCoord;',
+
+        'uniform mat3 projectionMatrix;',
+        'uniform mat3 filterMatrix;',
+
+        'varying vec2 vTextureCoord;',
+        'varying vec2 vFilterCoord;',
+
+        'void main(void){',
+        '   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',
+        '   vFilterCoord = ( filterMatrix * vec3( aTextureCoord, 1.0)  ).xy;',
+        '   vTextureCoord = aTextureCoord ;',
+        '}'
+    ].join('\n');
+
+    /**
+     * The default fragment shader source
+     *
+     * @static
+     * @constant
+     */
+    Filter.defaultFragmentSrc = [
+        'varying vec2 vTextureCoord;',
+        'varying vec2 vFilterCoord;',
+
+        'uniform sampler2D uSampler;',
+        'uniform sampler2D filterSampler;',
+
+        'void main(void){',
+        '   vec4 masky = texture2D(filterSampler, vFilterCoord);',
+        '   vec4 sample = texture2D(uSampler, vTextureCoord);',
+        '   vec4 color;',
+        '   if(mod(vFilterCoord.x, 1.0) > 0.5)',
+        '   {',
+        '     color = vec4(1.0, 0.0, 0.0, 1.0);',
+        '   }',
+        '   else',
+        '   {',
+        '     color = vec4(0.0, 1.0, 0.0, 1.0);',
+        '   }',
+        // '   gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);',
+        '   gl_FragColor = mix(sample, masky, 0.5);',
+        '   gl_FragColor *= sample.a;',
+        '}'
+    ].join('\n');
+
+},{"../../../const":43,"../../../utils":116,"./extractUniformsFromSrc":84}],84:[function(require,module,exports){
+    var defaultValue = require('pixi-gl-core').shader.defaultValue;
+
+    function extractUniformsFromSrc(vertexSrc, fragmentSrc, mask)
+    {
+        var vertUniforms = extractUniformsFromString(vertexSrc, mask);
+        var fragUniforms = extractUniformsFromString(fragmentSrc, mask);
+
+        return Object.assign(vertUniforms, fragUniforms);
+    }
+
+
+    function extractUniformsFromString(string)
+    {
+        var maskRegex = new RegExp('^(projectionMatrix|uSampler|filterArea)$');
+
+        var uniforms = {};
+        var nameSplit;
+
+
+        // clean the lines a little - remove extra spaces / teabs etc
+        // then split along ';'
+        var lines = string.replace(/\s+/g,' ')
+            .split(/\s*;\s*/);
+
+        // loop through..
+        for (var i = 0; i < lines.length; i++)
+        {
+            var line = lines[i].trim();
+
+            if(line.indexOf('uniform') > -1)
+            {
+                var splitLine = line.split(' ');
+                var type = splitLine[1];
+
+                var name = splitLine[2];
+                var size = 1;
+
+                if(name.indexOf('[') > -1)
+                {
+                    // array!
+                    nameSplit = name.split(/\[|\]/);
+                    name = nameSplit[0];
+                    size *= Number(nameSplit[1]);
+                }
+
+                if(!name.match(maskRegex))
+                {
+                    uniforms[name] = {
+                        value:defaultValue(type, size),
+                        name:name,
+                        type:type
+                    };
+                }
+            }
+        }
+
+        return uniforms;
+    }
+
+    module.exports = extractUniformsFromSrc;
+
+},{"pixi-gl-core":12}],85:[function(require,module,exports){
+    var math = require('../../../math');
+
+    /*
+     * Calculates the mapped matrix
+     * @param filterArea {Rectangle} The filter area
+     * @param sprite {Sprite} the target sprite
+     * @param outputMatrix {Matrix} @alvin
+     */
+// TODO playing around here.. this is temporary - (will end up in the shader)
+// thia returns a matrix that will normalise map filter cords in the filter to screen space
+    var calculateScreenSpaceMatrix = function (outputMatrix, filterArea, textureSize)
+    {
+        //var worldTransform = sprite.worldTransform.copy(math.Matrix.TEMP_MATRIX),
+        // var texture = {width:1136, height:700};//sprite._texture.baseTexture;
+
+        // TODO unwrap?
+        var mappedMatrix = outputMatrix.identity();
+
+        mappedMatrix.translate(filterArea.x / textureSize.width, filterArea.y / textureSize.height );
+
+        mappedMatrix.scale( textureSize.width , textureSize.height );
+
+        return mappedMatrix;
+
+    };
+
+    var calculateNormalizedScreenSpaceMatrix = function (outputMatrix, filterArea, textureSize)
+    {
+        var mappedMatrix = outputMatrix.identity();
+
+        mappedMatrix.translate(filterArea.x / textureSize.width, filterArea.y / textureSize.height );
+
+        var translateScaleX = (textureSize.width / filterArea.width);
+        var translateScaleY = (textureSize.height / filterArea.height);
+
+        mappedMatrix.scale( translateScaleX , translateScaleY );
+
+        return mappedMatrix;
+    };
+
+// this will map the filter coord so that a texture can be used based on the transform of a sprite
+    var calculateSpriteMatrix = function (outputMatrix, filterArea, textureSize, sprite)
+    {
+        var worldTransform = sprite.worldTransform.copy(math.Matrix.TEMP_MATRIX),
+            texture = sprite._texture.baseTexture;
+
+        // TODO unwrap?
+        var mappedMatrix = outputMatrix.identity();
+
+        // scale..
+        var ratio = textureSize.height / textureSize.width;
+
+        mappedMatrix.translate(filterArea.x / textureSize.width, filterArea.y / textureSize.height );
+
+        mappedMatrix.scale(1 , ratio);
+
+        var translateScaleX = (textureSize.width / texture.width);
+        var translateScaleY = (textureSize.height / texture.height);
+
+        worldTransform.tx /= texture.width * translateScaleX;
+
+        //this...?  free beer for anyone who can explain why this makes sense!
+        worldTransform.ty /= texture.width * translateScaleX;
+        // worldTransform.ty /= texture.height * translateScaleY;
+
+        worldTransform.invert();
+        mappedMatrix.prepend(worldTransform);
+
+        // apply inverse scale..
+        mappedMatrix.scale(1 , 1/ratio);
+
+        mappedMatrix.scale( translateScaleX , translateScaleY );
+
+        mappedMatrix.translate(sprite.anchor.x, sprite.anchor.y);
+
+        return mappedMatrix;
+    };
+
+    module.exports = {
+        calculateScreenSpaceMatrix:calculateScreenSpaceMatrix,
+        calculateNormalizedScreenSpaceMatrix:calculateNormalizedScreenSpaceMatrix,
+        calculateSpriteMatrix:calculateSpriteMatrix
+    };
+
+},{"../../../math":67}],86:[function(require,module,exports){
+    var Filter = require('../Filter'),
+        math =  require('../../../../math');
+
+// @see https://github.com/substack/brfs/issues/25
+
+    /**
+     * The SpriteMaskFilter class
+     *
+     * @class
+     * @extends PIXI.Filter
+     * @memberof PIXI
+     * @param sprite {PIXI.Sprite} the target sprite
+     */
+    function SpriteMaskFilter(sprite)
+    {
+        var maskMatrix = new math.Matrix();
+
+        Filter.call(this,
+            "#define GLSLIFY 1\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\nuniform mat3 otherMatrix;\n\nvarying vec2 vMaskCoord;\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n    vTextureCoord = aTextureCoord;\n    vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0)  ).xy;\n}\n",
+            "#define GLSLIFY 1\nvarying vec2 vMaskCoord;\nvarying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\nuniform float alpha;\nuniform sampler2D mask;\n\nvoid main(void)\n{\n    // check clip! this will stop the mask bleeding out from the edges\n    vec2 text = abs( vMaskCoord - 0.5 );\n    text = step(0.5, text);\n    float clip = 1.0 - max(text.y, text.x);\n    vec4 original = texture2D(uSampler, vTextureCoord);\n    vec4 masky = texture2D(mask, vMaskCoord);\n    original *= (masky.r * masky.a * alpha * clip);\n    gl_FragColor = original;\n}\n"
+        );
+
+        sprite.renderable = false;
+
+        this.maskSprite = sprite;
+        this.maskMatrix = maskMatrix;
+    }
+
+    SpriteMaskFilter.prototype = Object.create(Filter.prototype);
+    SpriteMaskFilter.prototype.constructor = SpriteMaskFilter;
+    module.exports = SpriteMaskFilter;
+
+    /**
+     * Applies the filter
+     *
+     * @param filterManager {PIXI.FilterManager} The renderer to retrieve the filter from
+     * @param input {PIXI.RenderTarget}
+     * @param output {PIXI.RenderTarget}
+     */
+    SpriteMaskFilter.prototype.apply = function (filterManager, input, output)
+    {
+        var maskSprite = this.maskSprite;
+
+        this.uniforms.mask = maskSprite._texture;
+        this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite );
+        this.uniforms.alpha = maskSprite.worldAlpha;
+
+        filterManager.applyFilter(this, input, output);
+    };
+
+},{"../../../../math":67,"../Filter":83}],87:[function(require,module,exports){
+
+    var WebGLManager = require('./WebGLManager'),
+        RenderTarget = require('../utils/RenderTarget'),
+        Quad = require('../utils/Quad'),
+        math =  require('../../../math'),
+        Shader = require('../../../Shader'),
+        filterTransforms = require('../filters/filterTransforms'),
+        bitTwiddle = require('bit-twiddle');
+
+    var FilterState = function()
+    {
+        this.renderTarget = null;
+        this.sourceFrame = new math.Rectangle();
+        this.destinationFrame = new math.Rectangle();
+        this.filters = [];
+        this.target = null;
+        this.resolution = 1;
+    };
+
+
+    /**
+     * @class
+     * @memberof PIXI
+     * @extends PIXI.WebGLManager
+     * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.
+     */
+    function FilterManager(renderer)
+    {
+        WebGLManager.call(this, renderer);
+
+        this.gl = this.renderer.gl;
+        // know about sprites!
+        this.quad = new Quad(this.gl, renderer.state.attribState);
+
+        this.shaderCache = {};
+        // todo add default!
+        this.pool = {};
+
+        this.filterData = null;
+    }
+
+    FilterManager.prototype = Object.create(WebGLManager.prototype);
+    FilterManager.prototype.constructor = FilterManager;
+    module.exports = FilterManager;
+
+    FilterManager.prototype.pushFilter = function(target, filters)
+    {
+        var renderer = this.renderer;
+
+        var filterData = this.filterData;
+
+        if(!filterData)
+        {
+            filterData = this.renderer._activeRenderTarget.filterStack;
+
+            // add new stack
+            var filterState = new FilterState();
+            filterState.sourceFrame = filterState.destinationFrame = this.renderer._activeRenderTarget.size;
+            filterState.renderTarget = renderer._activeRenderTarget;
+
+            this.renderer._activeRenderTarget.filterData = filterData = {
+                index:0,
+                stack:[filterState]
+            };
+
+            this.filterData = filterData;
+        }
+
+        // get the current filter state..
+        var currentState = filterData.stack[++filterData.index];
+        if(!currentState)
+        {
+            currentState = filterData.stack[filterData.index] = new FilterState();
+        }
+
+        // for now we go off the filter of the first resolution..
+        var resolution = filters[0].resolution;
+        var padding = filters[0].padding;
+        var targetBounds = target.filterArea || target.getBounds(true);
+        var sourceFrame = currentState.sourceFrame;
+        var destinationFrame = currentState.destinationFrame;
+
+        sourceFrame.x = ((targetBounds.x * resolution) | 0) / resolution;
+        sourceFrame.y = ((targetBounds.y * resolution) | 0) / resolution;
+        sourceFrame.width = ((targetBounds.width * resolution) | 0) / resolution;
+        sourceFrame.height = ((targetBounds.height * resolution) | 0) / resolution;
+
+        if(filterData.stack[0].renderTarget.transform)
+        {//jshint ignore:line
+
+
+        }
+        else
+        {
+            sourceFrame.fit(filterData.stack[0].destinationFrame);
+        }
+
+        // lets pplay the padding After we fit the element to the screen.
+        // this should stop the strange side effects that can occour when cropping to the edges
+        sourceFrame.pad(padding);
+
+
+
+        destinationFrame.width = sourceFrame.width;
+        destinationFrame.height = sourceFrame.height;
+
+        var renderTarget = this.getPotRenderTarget(renderer.gl, sourceFrame.width, sourceFrame.height, resolution);
+
+        currentState.target = target;
+        currentState.filters = filters;
+        currentState.resolution = resolution;
+        currentState.renderTarget = renderTarget;
+
+        // bind the render taget to draw the shape in the top corner..
+
+        renderTarget.setFrame(destinationFrame, sourceFrame);
+        // bind the render target
+        renderer.bindRenderTarget(renderTarget);
+
+        // clear the renderTarget
+        renderer.clear();//[0.5,0.5,0.5, 1.0]);
+    };
+
+    FilterManager.prototype.popFilter = function()
+    {
+        var filterData = this.filterData;
+
+        var lastState = filterData.stack[filterData.index-1];
+        var currentState = filterData.stack[filterData.index];
+
+        this.quad.map(currentState.renderTarget.size, currentState.sourceFrame).upload();
+
+        var filters = currentState.filters;
+
+        if(filters.length === 1)
+        {
+            filters[0].apply(this, currentState.renderTarget, lastState.renderTarget, false);
+            this.freePotRenderTarget(currentState.renderTarget);
+        }
+        else
+        {
+            var flip = currentState.renderTarget;
+            var flop = this.getPotRenderTarget(this.renderer.gl, currentState.sourceFrame.width, currentState.sourceFrame.height, 1);
+            flop.setFrame(currentState.destinationFrame, currentState.sourceFrame);
+
+            for (var i = 0; i < filters.length-1; i++)
+            {
+                filters[i].apply(this, flip, flop, true);
+
+                var t = flip;
+                flip = flop;
+                flop = t;
+            }
+
+            filters[i].apply(this, flip, lastState.renderTarget, false);
+
+            this.freePotRenderTarget(flip);
+            this.freePotRenderTarget(flop);
+        }
+
+        filterData.index--;
+
+        if(filterData.index === 0)
+        {
+            this.filterData = null;
+        }
+    };
+
+    FilterManager.prototype.applyFilter = function (filter, input, output, clear)
+    {
+        var renderer = this.renderer;
+        var shader = filter.glShaders[renderer.CONTEXT_UID];
+
+        // cacheing..
+        if(!shader)
+        {
+            if(filter.glShaderKey)
+            {
+                shader = this.shaderCache[filter.glShaderKey];
+
+                if(!shader)
+                {
+                    shader = filter.glShaders[renderer.CONTEXT_UID] = this.shaderCache[filter.glShaderKey] = new Shader(this.gl, filter.vertexSrc, filter.fragmentSrc);
+                }
+            }
+            else
+            {
+                shader = filter.glShaders[renderer.CONTEXT_UID] = new Shader(this.gl, filter.vertexSrc, filter.fragmentSrc);
+            }
+
+            //TODO - this only needs to be done once?
+            this.quad.initVao(shader);
+        }
+
+        renderer.bindRenderTarget(output);
+
+
+
+        if(clear)
+        {
+            var gl = renderer.gl;
+
+            gl.disable(gl.SCISSOR_TEST);
+            renderer.clear();//[1, 1, 1, 1]);
+            gl.enable(gl.SCISSOR_TEST);
+        }
+
+        // in case the render target is being masked using a scissor rect
+        if(output === renderer.maskManager.scissorRenderTarget)
+        {
+            renderer.maskManager.pushScissorMask(null, renderer.maskManager.scissorData);
+        }
+
+        renderer.bindShader(shader);
+
+        // this syncs the pixi filters  uniforms with glsl uniforms
+        this.syncUniforms(shader, filter);
+
+        // bind the input texture..
+        input.texture.bind(0);
+        // when you manually bind a texture, please switch active texture location to it
+        renderer._activeTextureLocation = 0;
+
+        renderer.state.setBlendMode( filter.blendMode );
+
+        this.quad.draw();
+    };
+
+// this returns a matrix that will normalise map filter cords in the filter to screen space
+    FilterManager.prototype.syncUniforms = function (shader, filter)
+    {
+        var uniformData = filter.uniformData;
+        var uniforms = filter.uniforms;
+
+        // 0 is reserverd for the pixi texture so we start at 1!
+        var textureCount = 1;
+        var currentState;
+
+        if(shader.uniforms.data.filterArea)
+        {
+            currentState = this.filterData.stack[this.filterData.index];
+            var filterArea = shader.uniforms.filterArea;
+
+            filterArea[0] = currentState.renderTarget.size.width;
+            filterArea[1] = currentState.renderTarget.size.height;
+            filterArea[2] = currentState.sourceFrame.x;
+            filterArea[3] = currentState.sourceFrame.y;
+
+            shader.uniforms.filterArea = filterArea;
+        }
+
+        // use this to clamp displaced texture coords so they belong to filterArea
+        // see displacementFilter fragment shader for an example
+        if(shader.uniforms.data.filterClamp)
+        {
+            currentState = this.filterData.stack[this.filterData.index];
+            var filterClamp = shader.uniforms.filterClamp;
+
+            filterClamp[0] = 0.5 / currentState.renderTarget.size.width;
+            filterClamp[1] = 0.5 / currentState.renderTarget.size.height;
+            filterClamp[2] = (currentState.sourceFrame.width - 0.5) / currentState.renderTarget.size.width;
+            filterClamp[3] = (currentState.sourceFrame.height - 0.5) / currentState.renderTarget.size.height;
+
+            shader.uniforms.filterClamp = filterClamp;
+        }
+
+        var val;
+        //TODO Cacheing layer..
+        for(var i in uniformData)
+        {
+            if(uniformData[i].type === 'sampler2D')
+            {
+                shader.uniforms[i] = textureCount;
+
+                if(uniforms[i].baseTexture)
+                {
+                    this.renderer.bindTexture(uniforms[i].baseTexture, textureCount);
+                }
+                else
+                {
+                    // this is helpful as renderTargets can also be set.
+                    // Although thinking about it, we could probably
+                    // make the filter texture cache return a RenderTexture
+                    // rather than a renderTarget
+                    var gl = this.renderer.gl;
+                    this.renderer._activeTextureLocation = gl.TEXTURE0 + textureCount;
+                    gl.activeTexture(gl.TEXTURE0 + textureCount );
+                    uniforms[i].texture.bind();
+                }
+
+                textureCount++;
+            }
+            else if(uniformData[i].type === 'mat3')
+            {
+                // check if its pixi matrix..
+                if(uniforms[i].a !== undefined)
+                {
+                    shader.uniforms[i] = uniforms[i].toArray(true);
+                }
+                else
+                {
+                    shader.uniforms[i] = uniforms[i];
+                }
+            }
+            else if(uniformData[i].type === 'vec2')
+            {
+                //check if its a point..
+                if(uniforms[i].x !== undefined)
+                {
+                    val = shader.uniforms[i] || new Float32Array(2);
+                    val[0] = uniforms[i].x;
+                    val[1] = uniforms[i].y;
+                    shader.uniforms[i] = val;
+                }
+                else
+                {
+                    shader.uniforms[i] = uniforms[i];
+                }
+            }
+            else if(uniformData[i].type === 'float')
+            {
+                if(shader.uniforms.data[i].value !== uniformData[i])
+                {
+                    shader.uniforms[i] = uniforms[i];
+                }
+            }
+            else
+            {
+                shader.uniforms[i] = uniforms[i];
+            }
+        }
+    };
+
+
+    FilterManager.prototype.getRenderTarget = function(clear, resolution)
+    {
+        var currentState = this.filterData.stack[this.filterData.index];
+        var renderTarget = this.getPotRenderTarget(this.renderer.gl, currentState.sourceFrame.width, currentState.sourceFrame.height, resolution || currentState.resolution);
+        renderTarget.setFrame(currentState.destinationFrame, currentState.sourceFrame);
+
+        return renderTarget;
+    };
+
+    FilterManager.prototype.returnRenderTarget = function(renderTarget)
+    {
+        return this.freePotRenderTarget(renderTarget);
+    };
+
+    /*
+     * Calculates the mapped matrix
+     * @param filterArea {Rectangle} The filter area
+     * @param sprite {Sprite} the target sprite
+     * @param outputMatrix {Matrix} @alvin
+     */
+// TODO playing around here.. this is temporary - (will end up in the shader)
+// thia returns a matrix that will normalise map filter cords in the filter to screen space
+    FilterManager.prototype.calculateScreenSpaceMatrix = function (outputMatrix)
+    {
+        var currentState = this.filterData.stack[this.filterData.index];
+        return filterTransforms.calculateScreenSpaceMatrix(outputMatrix,  currentState.sourceFrame, currentState.renderTarget.size);
+    };
+
+    /**
+     * Multiply vTextureCoord to this matrix to achieve (0,0,1,1) for filterArea
+     *
+     * @param outputMatrix {PIXI.Matrix}
+     */
+    FilterManager.prototype.calculateNormalizedScreenSpaceMatrix = function (outputMatrix)
+    {
+        var currentState = this.filterData.stack[this.filterData.index];
+
+        return filterTransforms.calculateNormalizedScreenSpaceMatrix(outputMatrix, currentState.sourceFrame, currentState.renderTarget.size, currentState.destinationFrame);
+    };
+
+// this will map the filter coord so that a texture can be used based on the transform of a sprite
+    FilterManager.prototype.calculateSpriteMatrix = function (outputMatrix, sprite)
+    {
+        var currentState = this.filterData.stack[this.filterData.index];
+        return filterTransforms.calculateSpriteMatrix(outputMatrix, currentState.sourceFrame, currentState.renderTarget.size, sprite);
+    };
+
+    FilterManager.prototype.destroy = function()
+    {
+        this.shaderCache = [];
+        this.emptyPool();
+    };
+
+
+
+//TODO move to a seperate class could be on renderer?
+//also - could cause issue with multiple contexts?
+    FilterManager.prototype.getPotRenderTarget = function(gl, minWidth, minHeight, resolution)
+    {
+        //TODO you coud return a bigger texture if there is not one in the pool?
+        minWidth = bitTwiddle.nextPow2(minWidth * resolution);
+        minHeight = bitTwiddle.nextPow2(minHeight * resolution);
+
+        var key = ((minWidth & 0xFFFF) << 16) | ( minHeight & 0xFFFF);
+
+        if(!this.pool[key]) {
+            this.pool[key] = [];
+        }
+
+        var renderTarget = this.pool[key].pop() || new RenderTarget(gl, minWidth, minHeight, null, 1);
+
+        //manually tweak the resolution...
+        //this will not modify the size of the frame buffer, just its resolution.
+        renderTarget.resolution = resolution;
+        renderTarget.defaultFrame.width = renderTarget.size.width = minWidth / resolution;
+        renderTarget.defaultFrame.height = renderTarget.size.height = minHeight / resolution;
+        return renderTarget;
+    };
+
+    FilterManager.prototype.emptyPool = function()
+    {
+        for (var i in this.pool)
+        {
+            var textures = this.pool[i];
+            if(textures)
+            {
+                for (var j = 0; j < textures.length; j++)
+                {
+                    textures[j].destroy(true);
+                }
+            }
+        }
+
+        this.pool = {};
+    };
+
+    FilterManager.prototype.freePotRenderTarget = function(renderTarget)
+    {
+        var minWidth = renderTarget.size.width * renderTarget.resolution;
+        var minHeight = renderTarget.size.height * renderTarget.resolution;
+
+        var key = ((minWidth & 0xFFFF) << 16) | (minHeight & 0xFFFF);
+        this.pool[key].push(renderTarget);
+    };
+
+},{"../../../Shader":42,"../../../math":67,"../filters/filterTransforms":85,"../utils/Quad":92,"../utils/RenderTarget":93,"./WebGLManager":90,"bit-twiddle":1}],88:[function(require,module,exports){
+    var WebGLManager = require('./WebGLManager'),
+        AlphaMaskFilter = require('../filters/spriteMask/SpriteMaskFilter');
+
+    /**
+     * @class
+     * @memberof PIXI
+     * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.
+     */
+    function MaskManager(renderer)
+    {
+        WebGLManager.call(this, renderer);
+
+        //TODO - we don't need both!
+        this.scissor = false;
+        this.scissorData = null;
+        this.scissorRenderTarget = null;
+
+        this.enableScissor = true;
+
+        this.alphaMaskPool = [];
+        this.alphaMaskIndex = 0;
+    }
+
+    MaskManager.prototype = Object.create(WebGLManager.prototype);
+    MaskManager.prototype.constructor = MaskManager;
+    module.exports = MaskManager;
+
+    /**
+     * Applies the Mask and adds it to the current filter stack.
+     *
+     * @param target {PIXI.DisplayObject} Display Object to push the mask to
+     * @param maskData {PIXI.Sprite|PIXI.Graphics}
+     */
+    MaskManager.prototype.pushMask = function (target, maskData)
+    {
+        if (maskData.texture)
+        {
+            this.pushSpriteMask(target, maskData);
+        }
+        else
+        {
+            if(this.enableScissor && !this.scissor && !this.renderer.stencilManager.stencilMaskStack.length && maskData.isFastRect())
+            {
+                var matrix = maskData.worldTransform;
+
+                var rot = Math.atan2(matrix.b, matrix.a);
+
+                // use the nearest degree!
+                rot = Math.round(rot * (180/Math.PI));
+
+                if(rot % 90)
+                {
+                    this.pushStencilMask(maskData);
+                }
+                else
+                {
+                    this.pushScissorMask(target, maskData);
+                }
+            }
+            else
+            {
+                this.pushStencilMask(maskData);
+            }
+        }
+    };
+
+    /**
+     * Removes the last mask from the mask stack and doesn't return it.
+     *
+     * @param target {PIXI.DisplayObject} Display Object to pop the mask from
+     * @param maskData {Array<*>}
+     */
+    MaskManager.prototype.popMask = function (target, maskData)
+    {
+        if (maskData.texture)
+        {
+            this.popSpriteMask(target, maskData);
+        }
+        else
+        {
+            if(this.enableScissor && !this.renderer.stencilManager.stencilMaskStack.length)
+            {
+                this.popScissorMask(target, maskData);
+            }
+            else
+            {
+                this.popStencilMask(target, maskData);
+            }
+
+        }
+    };
+
+    /**
+     * Applies the Mask and adds it to the current filter stack.
+     *
+     * @param target {PIXI.RenderTarget} Display Object to push the sprite mask to
+     * @param maskData {PIXI.Sprite} Sprite to be used as the mask
+     */
+    MaskManager.prototype.pushSpriteMask = function (target, maskData)
+    {
+        var alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex];
+
+        if (!alphaMaskFilter)
+        {
+            alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex] = [new AlphaMaskFilter(maskData)];
+        }
+
+        alphaMaskFilter[0].resolution = this.renderer.resolution;
+        alphaMaskFilter[0].maskSprite = maskData;
+
+        //TODO - may cause issues!
+        target.filterArea = maskData.getBounds(true);
+
+        this.renderer.filterManager.pushFilter(target, alphaMaskFilter);
+
+        this.alphaMaskIndex++;
+    };
+
+    /**
+     * Removes the last filter from the filter stack and doesn't return it.
+     *
+     */
+    MaskManager.prototype.popSpriteMask = function ()
+    {
+        this.renderer.filterManager.popFilter();
+        this.alphaMaskIndex--;
+    };
+
+
+    /**
+     * Applies the Mask and adds it to the current filter stack.
+     *
+     * @param maskData {Array<*>}
+     */
+    MaskManager.prototype.pushStencilMask = function (maskData)
+    {
+        this.renderer.currentRenderer.stop();
+        this.renderer.stencilManager.pushStencil(maskData);
+    };
+
+    /**
+     * Removes the last filter from the filter stack and doesn't return it.
+     *
+     */
+    MaskManager.prototype.popStencilMask = function ()
+    {
+        this.renderer.currentRenderer.stop();
+        this.renderer.stencilManager.popStencil();
+    };
+
+    /**
+     *
+     * @param target {PIXI.RenderTarget} Display Object to push the scissor mask to
+     * @param maskData
+     */
+    MaskManager.prototype.pushScissorMask = function (target, maskData)
+    {
+        maskData.renderable = true;
+
+        var renderTarget = this.renderer._activeRenderTarget;
+
+        var bounds = maskData.getBounds();
+
+        bounds.fit(renderTarget.size);
+        maskData.renderable = false;
+
+        this.renderer.gl.enable(this.renderer.gl.SCISSOR_TEST);
+
+        var resolution = this.renderer.resolution;
+        this.renderer.gl.scissor(bounds.x * resolution,
+            (renderTarget.root ? renderTarget.size.height - bounds.y - bounds.height : bounds.y) * resolution,
+            bounds.width * resolution,
+            bounds.height * resolution);
+
+        this.scissorRenderTarget = renderTarget;
+        this.scissorData = maskData;
+        this.scissor = true;
+    };
+
+    /**
+     *
+     *
+     */
+    MaskManager.prototype.popScissorMask = function ()
+    {
+        this.scissorRenderTarget = null;
+        this.scissorData = null;
+        this.scissor = false;
+
+        // must be scissor!
+        var gl = this.renderer.gl;
+        gl.disable(gl.SCISSOR_TEST);
+    };
+
+},{"../filters/spriteMask/SpriteMaskFilter":86,"./WebGLManager":90}],89:[function(require,module,exports){
+    var WebGLManager = require('./WebGLManager');
+
+    /**
+     * @class
+     * @memberof PIXI
+     * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.
+     */
+    function StencilManager(renderer)
+    {
+        WebGLManager.call(this, renderer);
+        this.stencilMaskStack = null;
+    }
+
+    StencilManager.prototype = Object.create(WebGLManager.prototype);
+    StencilManager.prototype.constructor = StencilManager;
+    module.exports = StencilManager;
+
+    /**
+     * Changes the mask stack that is used by this manager.
+     *
+     * @param stencilMaskStack {PIXI.Graphics[]} The mask stack
+     */
+    StencilManager.prototype.setMaskStack = function ( stencilMaskStack )
+    {
+        this.stencilMaskStack = stencilMaskStack;
+
+        var gl = this.renderer.gl;
+
+        if (stencilMaskStack.length === 0)
+        {
+            gl.disable(gl.STENCIL_TEST);
+        }
+        else
+        {
+            gl.enable(gl.STENCIL_TEST);
+        }
+    };
+
+    /**
+     * Applies the Mask and adds it to the current filter stack. @alvin
+     *
+     * @param graphics {PIXI.Graphics}
+     */
+    StencilManager.prototype.pushStencil = function (graphics)
+    {
+        this.renderer.setObjectRenderer(this.renderer.plugins.graphics);
+
+        this.renderer._activeRenderTarget.attachStencilBuffer();
+
+        var gl = this.renderer.gl,
+            sms = this.stencilMaskStack;
+
+        if (sms.length === 0)
+        {
+            gl.enable(gl.STENCIL_TEST);
+            gl.clear(gl.STENCIL_BUFFER_BIT);
+            gl.stencilFunc(gl.ALWAYS,1,1);
+        }
+
+        sms.push(graphics);
+
+        gl.colorMask(false, false, false, false);
+        gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR);
+
+        this.renderer.plugins.graphics.render(graphics);
+
+        gl.colorMask(true, true, true, true);
+        gl.stencilFunc(gl.NOTEQUAL,0, sms.length);
+        gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
+    };
+
+    /**
+     * TODO @alvin
+     */
+    StencilManager.prototype.popStencil = function ()
+    {
+        this.renderer.setObjectRenderer(this.renderer.plugins.graphics);
+
+        var gl = this.renderer.gl,
+            sms = this.stencilMaskStack;
+
+        var graphics = sms.pop();
+
+        if (sms.length === 0)
+        {
+            // the stack is empty!
+            gl.disable(gl.STENCIL_TEST);
+        }
+        else
+        {
+            gl.colorMask(false, false, false, false);
+            gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR);
+
+            this.renderer.plugins.graphics.render(graphics);
+
+            gl.colorMask(true, true, true, true);
+            gl.stencilFunc(gl.NOTEQUAL, 0, sms.length);
+            gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
+        }
+    };
+
+    /**
+     * Destroys the mask stack.
+     *
+     */
+    StencilManager.prototype.destroy = function ()
+    {
+        WebGLManager.prototype.destroy.call(this);
+
+        this.stencilMaskStack.stencilStack = null;
+    };
+
+},{"./WebGLManager":90}],90:[function(require,module,exports){
+    /**
+     * @class
+     * @memberof PIXI
+     * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.
+     */
+    function WebGLManager(renderer)
+    {
+        /**
+         * The renderer this manager works for.
+         *
+         * @member {PIXI.WebGLRenderer}
+         */
+        this.renderer = renderer;
+
+        this.renderer.on('context', this.onContextChange, this);
+    }
+
+    WebGLManager.prototype.constructor = WebGLManager;
+    module.exports = WebGLManager;
+
+    /**
+     * Generic method called when there is a WebGL context change.
+     *
+     */
+    WebGLManager.prototype.onContextChange = function ()
+    {
+        // do some codes init!
+    };
+
+    /**
+     * Generic destroy methods to be overridden by the subclass
+     *
+     */
+    WebGLManager.prototype.destroy = function ()
+    {
+        this.renderer.off('context', this.onContextChange, this);
+
+        this.renderer = null;
+    };
+
+},{}],91:[function(require,module,exports){
+    var WebGLManager = require('../managers/WebGLManager');
+
+    /**
+     * Base for a common object renderer that can be used as a system renderer plugin.
+     *
+     * @class
+     * @extends PIXI.WebGLManager
+     * @memberof PIXI
+     * @param renderer {PIXI.WebGLRenderer} The renderer this object renderer works for.
+     */
+    function ObjectRenderer(renderer)
+    {
+        WebGLManager.call(this, renderer);
+    }
+
+
+    ObjectRenderer.prototype = Object.create(WebGLManager.prototype);
+    ObjectRenderer.prototype.constructor = ObjectRenderer;
+    module.exports = ObjectRenderer;
+
+    /**
+     * Starts the renderer and sets the shader
+     *
+     */
+    ObjectRenderer.prototype.start = function ()
+    {
+        // set the shader..
+    };
+
+    /**
+     * Stops the renderer
+     *
+     */
+    ObjectRenderer.prototype.stop = function ()
+    {
+        this.flush();
+    };
+
+    /**
+     * Stub method for rendering content and emptying the current batch.
+     *
+     */
+    ObjectRenderer.prototype.flush = function ()
+    {
+        // flush!
+    };
+
+    /**
+     * Renders an object
+     *
+     * @param object {PIXI.DisplayObject} The object to render.
+     */
+    ObjectRenderer.prototype.render = function (object) // jshint unused:false
+    {
+        // render the object
+    };
+
+},{"../managers/WebGLManager":90}],92:[function(require,module,exports){
+    var glCore = require('pixi-gl-core'),
+        createIndicesForQuads = require('../../../utils/createIndicesForQuads');
+
+    /**
+     * Helper class to create a quad
+     *
+     * @class
+     * @memberof PIXI
+     * @param gl {WebGLRenderingContext} The gl context for this quad to use.
+     * @param state {object} TODO: Description
+     */
+    function Quad(gl, state)
+    {
+        /*
+         * the current WebGL drawing context
+         *
+         * @member {WebGLRenderingContext}
+         */
+        this.gl = gl;
+
+        /**
+         * An array of vertices
+         *
+         * @member {Float32Array}
+         */
+        this.vertices = new Float32Array([
+            -1,-1,
+            1,-1,
+            1,1,
+            -1,1
+        ]);
+
+        /**
+         * The Uvs of the quad
+         *
+         * @member {Float32Array}
+         */
+        this.uvs = new Float32Array([
+            0,0,
+            1,0,
+            1,1,
+            0,1
+        ]);
+
+        this.interleaved = new Float32Array(8 * 2);
+
+        for (var i = 0; i < 4; i++) {
+            this.interleaved[i*4] = this.vertices[(i*2)];
+            this.interleaved[(i*4)+1] = this.vertices[(i*2)+1];
+            this.interleaved[(i*4)+2] = this.uvs[i*2];
+            this.interleaved[(i*4)+3] = this.uvs[(i*2)+1];
+        }
+
+        /*
+         * @member {Uint16Array} An array containing the indices of the vertices
+         */
+        this.indices = createIndicesForQuads(1);
+
+        /*
+         * @member {glCore.GLBuffer} The vertex buffer
+         */
+        this.vertexBuffer = glCore.GLBuffer.createVertexBuffer(gl, this.interleaved, gl.STATIC_DRAW);
+
+        /*
+         * @member {glCore.GLBuffer} The index buffer
+         */
+        this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW);
+
+        /*
+         * @member {glCore.VertexArrayObject} The index buffer
+         */
+        this.vao = new glCore.VertexArrayObject(gl, state);
+
+    }
+
+    Quad.prototype.constructor = Quad;
+
+    /**
+     * Initialises the vaos and uses the shader
+     * @param shader {PIXI.Shader} the shader to use
+     */
+    Quad.prototype.initVao = function(shader)
+    {
+        this.vao.clear()
+            .addIndex(this.indexBuffer)
+            .addAttribute(this.vertexBuffer, shader.attributes.aVertexPosition, this.gl.FLOAT, false, 4 * 4, 0)
+            .addAttribute(this.vertexBuffer, shader.attributes.aTextureCoord, this.gl.FLOAT, false, 4 * 4, 2 * 4);
+    };
+
+    /**
+     * Maps two Rectangle to the quad
+     * @param targetTextureFrame {PIXI.Rectangle} the first rectangle
+     * @param destinationFrame {PIXI.Rectangle} the second rectangle
+     */
+    Quad.prototype.map = function(targetTextureFrame, destinationFrame)
+    {
+        var x = 0; //destinationFrame.x / targetTextureFrame.width;
+        var y = 0; //destinationFrame.y / targetTextureFrame.height;
+
+        this.uvs[0] = x;
+        this.uvs[1] = y;
+
+        this.uvs[2] = x + destinationFrame.width / targetTextureFrame.width;
+        this.uvs[3] = y;
+
+        this.uvs[4] = x + destinationFrame.width / targetTextureFrame.width;
+        this.uvs[5] = y + destinationFrame.height / targetTextureFrame.height;
+
+        this.uvs[6] = x;
+        this.uvs[7] = y + destinationFrame.height / targetTextureFrame.height;
+
+        /// -----
+        x = destinationFrame.x;
+        y = destinationFrame.y;
+
+        this.vertices[0] = x;
+        this.vertices[1] = y;
+
+        this.vertices[2] = x + destinationFrame.width;
+        this.vertices[3] = y;
+
+        this.vertices[4] = x + destinationFrame.width;
+        this.vertices[5] = y + destinationFrame.height;
+
+        this.vertices[6] = x;
+        this.vertices[7] = y + destinationFrame.height;
+
+        return this;
+    };
+
+    /**
+     * Draws the quad
+     */
+    Quad.prototype.draw = function()
+    {
+        this.vao.bind()
+            .draw(this.gl.TRIANGLES, 6, 0)
+            .unbind();
+
+        return this;
+    };
+
+    /**
+     * Binds the buffer and uploads the data
+     */
+    Quad.prototype.upload = function()
+    {
+        for (var i = 0; i < 4; i++) {
+            this.interleaved[i*4] = this.vertices[(i*2)];
+            this.interleaved[(i*4)+1] = this.vertices[(i*2)+1];
+            this.interleaved[(i*4)+2] = this.uvs[i*2];
+            this.interleaved[(i*4)+3] = this.uvs[(i*2)+1];
+        }
+
+        this.vertexBuffer.upload(this.interleaved);
+
+        return this;
+    };
+
+    /**
+     * Removes this quad from WebGL
+     */
+    Quad.prototype.destroy = function()
+    {
+        var gl = this.gl;
+
+        gl.deleteBuffer(this.vertexBuffer);
+        gl.deleteBuffer(this.indexBuffer);
+    };
+
+    module.exports = Quad;
+
+},{"../../../utils/createIndicesForQuads":114,"pixi-gl-core":12}],93:[function(require,module,exports){
+    var math = require('../../../math'),
+        CONST = require('../../../const'),
+        GLFramebuffer = require('pixi-gl-core').GLFramebuffer;
+
+    /**
+     * @author Mat Groves http://matgroves.com/ @Doormat23
+     */
+
+    /**
+     * @class
+     * @memberof PIXI
+     * @param gl {WebGLRenderingContext} the current WebGL drawing context
+     * @param [width=0] {number} the horizontal range of the filter
+     * @param [height=0] {number} the vertical range of the filter
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @param [resolution=1] {number} The current resolution / device pixel ratio
+     * @param [root=false] {boolean} Whether this object is the root element or not
+     */
+    var RenderTarget = function(gl, width, height, scaleMode, resolution, root)
+    {
+        //TODO Resolution could go here ( eg low res blurs )
+
+        /**
+         * The current WebGL drawing context.
+         *
+         * @member {WebGLRenderingContext}
+         */
+        this.gl = gl;
+
+        // next time to create a frame buffer and texture
+
+        /**
+         * A frame buffer
+         *
+         * @member {PIXI.glCore.GLFramebuffer}
+         */
+        this.frameBuffer = null;
+
+        /**
+         * The texture
+         *
+         * @member {PIXI.glCore.GLTexture}
+         */
+        this.texture = null;
+
+        /**
+         * The background colour of this render target, as an array of [r,g,b,a] values
+         *
+         * @member {number[]}
+         */
+        this.clearColor = [0, 0, 0, 0];
+
+        /**
+         * The size of the object as a rectangle
+         *
+         * @member {PIXI.Rectangle}
+         */
+        this.size = new math.Rectangle(0, 0, 1, 1);
+
+        /**
+         * The current resolution / device pixel ratio
+         *
+         * @member {number}
+         * @default 1
+         */
+        this.resolution = resolution || CONST.RESOLUTION;
+
+        /**
+         * The projection matrix
+         *
+         * @member {PIXI.Matrix}
+         */
+        this.projectionMatrix = new math.Matrix();
+
+        /**
+         * The object's transform
+         *
+         * @member {PIXI.Matrix}
+         */
+        this.transform = null;
+
+        /**
+         * The frame.
+         *
+         * @member {PIXI.Rectangle}
+         */
+        this.frame = null;
+
+        /**
+         * The stencil buffer stores masking data for the render target
+         *
+         * @member {glCore.GLBuffer}
+         */
+        this.defaultFrame = new math.Rectangle();
+        this.destinationFrame = null;
+        this.sourceFrame = null;
+
+        /**
+         * The stencil buffer stores masking data for the render target
+         *
+         * @member {glCore.GLBuffer}
+         */
+        this.stencilBuffer = null;
+
+        /**
+         * The data structure for the stencil masks
+         *
+         * @member {PIXI.Graphics[]}
+         */
+        this.stencilMaskStack = [];
+
+        /**
+         * Stores filter data for the render target
+         *
+         * @member {object[]}
+         */
+        this.filterData = null;
+
+        /**
+         * The scale mode.
+         *
+         * @member {number}
+         * @default PIXI.SCALE_MODES.DEFAULT
+         * @see PIXI.SCALE_MODES
+         */
+        this.scaleMode = scaleMode || CONST.SCALE_MODES.DEFAULT;
+
+        /**
+         * Whether this object is the root element or not
+         *
+         * @member {boolean}
+         */
+        this.root = root;
+
+
+        if (!this.root)
+        {
+            this.frameBuffer = GLFramebuffer.createRGBA(gl, 100, 100);
+
+            if( this.scaleMode === CONST.SCALE_MODES.NEAREST)
+            {
+                this.frameBuffer.texture.enableNearestScaling();
+            }
+            else
+            {
+                this.frameBuffer.texture.enableLinearScaling();
+
+            }
+            /*
+             A frame buffer needs a target to render to..
+             create a texture and bind it attach it to the framebuffer..
+             */
+
+            // this is used by the base texture
+            this.texture = this.frameBuffer.texture;
+        }
+        else
+        {
+            // make it a null framebuffer..
+            this.frameBuffer = new GLFramebuffer(gl, 100, 100);
+            this.frameBuffer.framebuffer = null;
+
+        }
+
+        this.setFrame();
+
+        this.resize(width, height);
+    };
+
+    RenderTarget.prototype.constructor = RenderTarget;
+    module.exports = RenderTarget;
+
+    /**
+     * Clears the filter texture.
+     *
+     * @param [clearColor=this.clearColor] {number[]} Array of [r,g,b,a] to clear the framebuffer
+     */
+    RenderTarget.prototype.clear = function(clearColor)
+    {
+        var cc = clearColor || this.clearColor;
+        this.frameBuffer.clear(cc[0],cc[1],cc[2],cc[3]);//r,g,b,a);
+    };
+
+    /**
+     * Binds the stencil buffer.
+     *
+     */
+    RenderTarget.prototype.attachStencilBuffer = function()
+    {
+        //TODO check if stencil is done?
+        /**
+         * The stencil buffer is used for masking in pixi
+         * lets create one and then add attach it to the framebuffer..
+         */
+        if (!this.root)
+        {
+            this.frameBuffer.enableStencil();
+        }
+    };
+
+    RenderTarget.prototype.setFrame = function(destinationFrame, sourceFrame)
+    {
+        this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame;
+        this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame;
+    };
+
+    /**
+     * Binds the buffers and initialises the viewport.
+     *
+     */
+    RenderTarget.prototype.activate = function()
+    {
+        //TOOD refactor usage of frame..
+        var gl = this.gl;
+
+        // make surethe texture is unbound!
+        this.frameBuffer.bind();
+
+        this.calculateProjection( this.destinationFrame, this.sourceFrame );
+
+        if(this.transform)
+        {
+            this.projectionMatrix.append(this.transform);
+        }
+
+        //TODO add a check as them may be the same!
+        if(this.destinationFrame !== this.sourceFrame)
+        {
+
+            gl.enable(gl.SCISSOR_TEST);
+            gl.scissor(this.destinationFrame.x | 0,this.destinationFrame.y | 0, (this.destinationFrame.width * this.resolution) | 0, (this.destinationFrame.height* this.resolution) | 0);
+        }
+        else
+        {
+            gl.disable(gl.SCISSOR_TEST);
+        }
+
+
+        // TODO - does not need to be updated all the time??
+        gl.viewport(this.destinationFrame.x | 0,this.destinationFrame.y | 0, (this.destinationFrame.width * this.resolution) | 0, (this.destinationFrame.height * this.resolution)|0);
+
+
+    };
+
+
+    /**
+     * Updates the projection matrix based on a projection frame (which is a rectangle)
+     *
+     */
+    RenderTarget.prototype.calculateProjection = function (destinationFrame, sourceFrame)
+    {
+        var pm = this.projectionMatrix;
+
+        sourceFrame = sourceFrame || destinationFrame;
+
+        pm.identity();
+
+        // TODO: make dest scale source
+        if (!this.root)
+        {
+            pm.a = 1 / destinationFrame.width*2;
+            pm.d = 1 / destinationFrame.height*2;
+
+            pm.tx = -1 - sourceFrame.x * pm.a;
+            pm.ty = -1 - sourceFrame.y * pm.d;
+        }
+        else
+        {
+            pm.a = 1 / destinationFrame.width*2;
+            pm.d = -1 / destinationFrame.height*2;
+
+            pm.tx = -1 - sourceFrame.x * pm.a;
+            pm.ty = 1 - sourceFrame.y * pm.d;
+        }
+    };
+
+
+    /**
+     * Resizes the texture to the specified width and height
+     *
+     * @param width {Number} the new width of the texture
+     * @param height {Number} the new height of the texture
+     */
+    RenderTarget.prototype.resize = function (width, height)
+    {
+        width = width | 0;
+        height = height | 0;
+
+        if (this.size.width === width && this.size.height === height)
+        {
+            return;
+        }
+
+        this.size.width = width;
+        this.size.height = height;
+
+        this.defaultFrame.width = width;
+        this.defaultFrame.height = height;
+
+
+        this.frameBuffer.resize(width * this.resolution, height * this.resolution);
+
+        var projectionFrame = this.frame || this.size;
+
+        this.calculateProjection( projectionFrame );
+    };
+
+    /**
+     * Destroys the render target.
+     *
+     */
+    RenderTarget.prototype.destroy = function ()
+    {
+        this.frameBuffer.destroy();
+
+        this.frameBuffer = null;
+        this.texture = null;
+    };
+
+},{"../../../const":43,"../../../math":67,"pixi-gl-core":12}],94:[function(require,module,exports){
+    var glCore = require('pixi-gl-core');
+
+    var fragTemplate = [
+        'precision mediump float;',
+        'void main(void){',
+        'float test = 0.1;',
+        '%forloop%',
+        'gl_FragColor = vec4(0.0);',
+        '}'
+    ].join('\n');
+
+    var checkMaxIfStatmentsInShader = function(maxIfs, gl)
+    {
+        var createTempContext = !gl;
+
+        if(createTempContext)
+        {
+            var tinyCanvas = document.createElement('canvas');
+            tinyCanvas.width = 1;
+            tinyCanvas.height = 1;
+
+            gl = glCore.createContext(tinyCanvas);
+        }
+
+        var shader = gl.createShader(gl.FRAGMENT_SHADER);
+
+        while(true)
+        {
+            var fragmentSrc = fragTemplate.replace(/%forloop%/gi, generateIfTestSrc(maxIfs));
+
+            gl.shaderSource(shader, fragmentSrc);
+            gl.compileShader(shader);
+
+            if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
+            {
+                maxIfs = (maxIfs/2)|0;
+            }
+            else
+            {
+                // valid!
+                break;
+            }
+        }
+
+        if(createTempContext)
+        {
+            // get rid of context
+            if(gl.getExtension('WEBGL_lose_context'))
+            {
+                gl.getExtension('WEBGL_lose_context').loseContext();
+            }
+        }
+
+        return maxIfs;
+    };
+
+
+
+    function generateIfTestSrc(maxIfs)
+    {
+        var src = '';
+
+        for (var i = 0; i < maxIfs; i++)
+        {
+            if(i > 0)
+            {
+                src += '\nelse ';
+            }
+
+            if(i < maxIfs-1)
+            {
+                src += 'if(test == ' + i + '.0){}';
+            }
+        }
+
+        return src;
+    }
+
+    module.exports = checkMaxIfStatmentsInShader;
+
+},{"pixi-gl-core":12}],95:[function(require,module,exports){
+    var CONST = require('../../../const');
+
+    /**
+     * Maps gl blend combinations to WebGL
+     * @class
+     * @memberof PIXI
+     * @param gl {WebGLRenderingContext} The current WebGL drawing context
+     * @param array
+     */
+    function mapWebGLBlendModesToPixi(gl, array)
+    {
+        array = array || [];
+
+        //TODO - premultiply alpha would be different.
+        //add a boolean for that!
+        array[CONST.BLEND_MODES.NORMAL]        = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.ADD]           = [gl.ONE,       gl.DST_ALPHA];
+        array[CONST.BLEND_MODES.MULTIPLY]      = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.SCREEN]        = [gl.ONE,       gl.ONE_MINUS_SRC_COLOR];
+        array[CONST.BLEND_MODES.OVERLAY]       = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.DARKEN]        = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.LIGHTEN]       = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.COLOR_DODGE]   = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.COLOR_BURN]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.HARD_LIGHT]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.SOFT_LIGHT]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.DIFFERENCE]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.EXCLUSION]     = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.HUE]           = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.SATURATION]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.COLOR]         = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+        array[CONST.BLEND_MODES.LUMINOSITY]    = [gl.ONE,       gl.ONE_MINUS_SRC_ALPHA];
+
+        return array;
+    }
+
+    module.exports = mapWebGLBlendModesToPixi;
+
+},{"../../../const":43}],96:[function(require,module,exports){
+    var CONST = require('../../../const');
+
+    /**
+     * Generic Mask Stack data structure
+     * @class
+     * @memberof PIXI
+     * @param gl {WebGLRenderingContext} The current WebGL drawing context
+     * @param object
+     */
+    function mapWebGLDrawModesToPixi(gl, object)
+    {
+        object= object || {};
+
+        object[CONST.DRAW_MODES.POINTS]         = gl.POINTS;
+        object[CONST.DRAW_MODES.LINES]          = gl.LINES;
+        object[CONST.DRAW_MODES.LINE_LOOP]      = gl.LINE_LOOP;
+        object[CONST.DRAW_MODES.LINE_STRIP]     = gl.LINE_STRIP;
+        object[CONST.DRAW_MODES.TRIANGLES]      = gl.TRIANGLES;
+        object[CONST.DRAW_MODES.TRIANGLE_STRIP] = gl.TRIANGLE_STRIP;
+        object[CONST.DRAW_MODES.TRIANGLE_FAN]   = gl.TRIANGLE_FAN;
+
+    }
+
+    module.exports = mapWebGLDrawModesToPixi;
+
+},{"../../../const":43}],97:[function(require,module,exports){
+
+
+    function validateContext(gl)
+    {
+        var attributes = gl.getContextAttributes();
+
+        // this is going to be fairly simple for now.. but at least we have rom to grow!
+        if(!attributes.stencil)
+        {
+            console.warn('Provided WebGL context does not have a stencil buffer, masks may not render correctly'); // jshint ignore:line
+        }
+    }
+
+    module.exports = validateContext;
+
+},{}],98:[function(require,module,exports){
+    var math = require('../math'),
+        Texture = require('../textures/Texture'),
+        Container = require('../display/Container'),
+        utils = require('../utils'),
+        CONST = require('../const'),
+        tempPoint = new math.Point();
+
+    /**
+     * The Sprite object is the base for all textured objects that are rendered to the screen
+     *
+     * A sprite can be created directly from an image like this:
+     *
+     * ```js
+     * var sprite = new PIXI.Sprite.fromImage('assets/image.png');
+     * ```
+     *
+     * @class
+     * @extends PIXI.Container
+     * @memberof PIXI
+     * @param texture {PIXI.Texture} The texture for this sprite
+     */
+    function Sprite(texture)
+    {
+        Container.call(this);
+
+        /**
+         * The anchor sets the origin point of the texture.
+         * The default is 0,0 this means the texture's origin is the top left
+         * Setting the anchor to 0.5,0.5 means the texture's origin is centered
+         * Setting the anchor to 1,1 would mean the texture's origin point will be the bottom right corner
+         *
+         * @member {PIXI.ObservablePoint}
+         */
+        this.anchor = new math.ObservablePoint(this.onAnchorUpdate, this);
+
+        /**
+         * The texture that the sprite is using
+         *
+         * @member {PIXI.Texture}
+         * @private
+         */
+        this._texture = null;
+
+        /**
+         * The width of the sprite (this is initially set by the texture)
+         *
+         * @member {number}
+         * @private
+         */
+        this._width = 0;
+
+        /**
+         * The height of the sprite (this is initially set by the texture)
+         *
+         * @member {number}
+         * @private
+         */
+        this._height = 0;
+
+        /**
+         * The tint applied to the sprite. This is a hex value. A value of 0xFFFFFF will remove any tint effect.
+         *
+         * @member {number}
+         * @default 0xFFFFFF
+         */
+        this._tint = null;
+        this._tintRGB = null;
+        this.tint = 0xFFFFFF;
+
+        /**
+         * The blend mode to be applied to the sprite. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.
+         *
+         * @member {number}
+         * @default PIXI.BLEND_MODES.NORMAL
+         * @see PIXI.BLEND_MODES
+         */
+        this.blendMode = CONST.BLEND_MODES.NORMAL;
+
+        /**
+         * The shader that will be used to render the sprite. Set to null to remove a current shader.
+         *
+         * @member {PIXI.AbstractFilter|PIXI.Shader}
+         */
+        this.shader = null;
+
+        /**
+         * An internal cached value of the tint.
+         *
+         * @member {number}
+         * @default 0xFFFFFF
+         * @private
+         */
+        this.cachedTint = 0xFFFFFF;
+
+        // call texture setter
+        this.texture = texture || Texture.EMPTY;
+
+        /**
+         * this is used to store the vertex data of the sprite (basically a quad)
+         * @type {Float32Array}
+         */
+        this.vertexData = new Float32Array(8);
+
+        /**
+         * this is used to calculate the bounds of the object IF it is a trimmed sprite
+         * @type {Float32Array}
+         */
+        this.vertexTrimmedData = null;
+
+        this._transformID = -1;
+        this._textureID = -1;
+    }
+
+// constructor
+    Sprite.prototype = Object.create(Container.prototype);
+    Sprite.prototype.constructor = Sprite;
+    module.exports = Sprite;
+
+    Object.defineProperties(Sprite.prototype, {
+        /**
+         * The width of the sprite, setting this will actually modify the scale to achieve the value set
+         *
+         * @member {number}
+         * @memberof PIXI.Sprite#
+         */
+        width: {
+            get: function ()
+            {
+                return Math.abs(this.scale.x) * this.texture.orig.width;
+            },
+            set: function (value)
+            {
+                var sign = utils.sign(this.scale.x) || 1;
+                this.scale.x = sign * value / this.texture.orig.width;
+                this._width = value;
+            }
+        },
+
+        /**
+         * The height of the sprite, setting this will actually modify the scale to achieve the value set
+         *
+         * @member {number}
+         * @memberof PIXI.Sprite#
+         */
+        height: {
+            get: function ()
+            {
+                return  Math.abs(this.scale.y) * this.texture.orig.height;
+            },
+            set: function (value)
+            {
+                var sign = utils.sign(this.scale.y) || 1;
+                this.scale.y = sign * value / this.texture.orig.height;
+                this._height = value;
+            }
+        },
+
+        tint: {
+            get: function ()
+            {
+                return  this._tint;
+            },
+            set: function (value)
+            {
+                this._tint = value;
+                this._tintRGB = (value >> 16) + (value & 0xff00) + ((value & 0xff) << 16);
+            }
+        },
+
+        /**
+         * The texture that the sprite is using
+         *
+         * @member {PIXI.Texture}
+         * @memberof PIXI.Sprite#
+         */
+        texture: {
+            get: function ()
+            {
+                return  this._texture;
+            },
+            set: function (value)
+            {
+                if (this._texture === value)
+                {
+                    return;
+                }
+
+                this._texture = value;
+                this.cachedTint = 0xFFFFFF;
+
+                this._textureID = -1;
+
+                if (value)
+                {
+                    // wait for the texture to load
+                    if (value.baseTexture.hasLoaded)
+                    {
+                        this._onTextureUpdate();
+                    }
+                    else
+                    {
+                        value.once('update', this._onTextureUpdate, this);
+                    }
+                }
+            }
+        }
+    });
+
+    /**
+     * When the texture is updated, this event will fire to update the scale and frame
+     *
+     * @private
+     */
+    Sprite.prototype._onTextureUpdate = function ()
+    {
+        this._textureID = -1;
+
+        // so if _width is 0 then width was not set..
+        if (this._width)
+        {
+            this.scale.x = utils.sign(this.scale.x) * this._width / this.texture.orig.width;
+        }
+
+        if (this._height)
+        {
+            this.scale.y = utils.sign(this.scale.y) * this._height / this.texture.orig.height;
+        }
+    };
+
+    Sprite.prototype.onAnchorUpdate = function()
+    {
+        this._transformID = -1;
+    };
+
+    /**
+     * calculates worldTransform * vertices, store it in vertexData
+     */
+    Sprite.prototype.calculateVertices = function ()
+    {
+        if(this._transformID === this.transform._worldID && this._textureID === this._texture._updateID)
+        {
+            return;
+        }
+
+        this._transformID = this.transform._worldID;
+        this._textureID = this._texture._updateID;
+
+        // set the vertex data
+
+        var texture = this._texture,
+            wt = this.transform.worldTransform,
+            a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty,
+            vertexData = this.vertexData,
+            w0, w1, h0, h1,
+            trim = texture.trim,
+            orig = texture.orig;
+
+        if (trim)
+        {
+            // if the sprite is trimmed and is not a tilingsprite then we need to add the extra space before transforming the sprite coords..
+            w1 = trim.x - this.anchor._x * orig.width;
+            w0 = w1 + trim.width;
+
+            h1 = trim.y - this.anchor._y * orig.height;
+            h0 = h1 + trim.height;
+
+        }
+        else
+        {
+            w0 = orig.width * (1-this.anchor._x);
+            w1 = orig.width * -this.anchor._x;
+
+            h0 = orig.height * (1-this.anchor._y);
+            h1 = orig.height * -this.anchor._y;
+        }
+
+        // xy
+        vertexData[0] = a * w1 + c * h1 + tx;
+        vertexData[1] = d * h1 + b * w1 + ty;
+
+        // xy
+        vertexData[2] = a * w0 + c * h1 + tx;
+        vertexData[3] = d * h1 + b * w0 + ty;
+
+        // xy
+        vertexData[4] = a * w0 + c * h0 + tx;
+        vertexData[5] = d * h0 + b * w0 + ty;
+
+        // xy
+        vertexData[6] = a * w1 + c * h0 + tx;
+        vertexData[7] = d * h0 + b * w1 + ty;
+    };
+
+    /**
+     * calculates worldTransform * vertices for a non texture with a trim. store it in vertexTrimmedData
+     * This is used to ensure that the true width and height of a trimmed texture is respected
+     */
+    Sprite.prototype.calculateTrimmedVertices = function ()
+    {
+        if(!this.vertexTrimmedData)
+        {
+            this.vertexTrimmedData = new Float32Array(8);
+        }
+
+        // lets do some special trim code!
+        var texture = this._texture,
+            vertexData = this.vertexTrimmedData,
+            orig = texture.orig;
+
+        // lets calculate the new untrimmed bounds..
+        var wt = this.transform.worldTransform,
+            a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty,
+            w0, w1, h0, h1;
+
+        w0 = (orig.width ) * (1-this.anchor._x);
+        w1 = (orig.width ) * -this.anchor._x;
+
+        h0 = orig.height * (1-this.anchor._y);
+        h1 = orig.height * -this.anchor._y;
+
+        // xy
+        vertexData[0] = a * w1 + c * h1 + tx;
+        vertexData[1] = d * h1 + b * w1 + ty;
+
+        // xy
+        vertexData[2] = a * w0 + c * h1 + tx;
+        vertexData[3] = d * h1 + b * w0 + ty;
+
+        // xy
+        vertexData[4] = a * w0 + c * h0 + tx;
+        vertexData[5] = d * h0 + b * w0 + ty;
+
+        // xy
+        vertexData[6] = a * w1 + c * h0 + tx;
+        vertexData[7] = d * h0 + b * w1 + ty;
+    };
+
+    /**
+     *
+     * Renders the object using the WebGL renderer
+     *
+     * @param renderer {PIXI.WebGLRenderer}
+     * @private
+     */
+    Sprite.prototype._renderWebGL = function (renderer)
+    {
+        this.calculateVertices();
+
+        renderer.setObjectRenderer(renderer.plugins.sprite);
+        renderer.plugins.sprite.render(this);
+    };
+
+    /**
+     * Renders the object using the Canvas renderer
+     *
+     * @param renderer {PIXI.CanvasRenderer} The renderer
+     * @private
+     */
+    Sprite.prototype._renderCanvas = function (renderer)
+    {
+        renderer.plugins.sprite.render(this);
+    };
+
+
+    Sprite.prototype._calculateBounds = function ()
+    {
+
+        var trim = this._texture.trim,
+            orig = this._texture.orig;
+
+        //First lets check to see if the current texture has a trim..
+        if (!trim || trim.width === orig.width && trim.height === orig.height) {
+
+            // no trim! lets use the usual calculations..
+            this.calculateVertices();
+            this._bounds.addQuad(this.vertexData);
+        }
+        else
+        {
+            // lets calculate a special trimmed bounds...
+            this.calculateTrimmedVertices();
+            this._bounds.addQuad(this.vertexTrimmedData);
+        }
+    };
+
+    /**
+     * Gets the local bounds of the sprite object.
+     *
+     */
+
+    Sprite.prototype.getLocalBounds = function (rect)
+    {
+        // we can do a fast local bounds if the sprite has no children!
+        if(this.children.length === 0)
+        {
+
+            this._bounds.minX = -this._texture.orig.width * this.anchor._x;
+            this._bounds.minY = -this._texture.orig.height * this.anchor._y;
+            this._bounds.maxX = this._texture.orig.width;
+            this._bounds.maxY = this._texture.orig.height;
+
+            if(!rect)
+            {
+                if(!this._localBoundsRect)
+                {
+                    this._localBoundsRect = new math.Rectangle();
+                }
+
+                rect = this._localBoundsRect;
+            }
+
+            return this._bounds.getRectangle(rect);
+        }
+        else
+        {
+            return Container.prototype.getLocalBounds.call(this, rect);
+        }
+
+    };
+
+    /**
+     * Tests if a point is inside this sprite
+     *
+     * @param point {PIXI.Point} the point to test
+     * @return {boolean} the result of the test
+     */
+    Sprite.prototype.containsPoint = function( point )
+    {
+        this.worldTransform.applyInverse(point,  tempPoint);
+
+        var width = this._texture.orig.width;
+        var height = this._texture.orig.height;
+        var x1 = -width * this.anchor.x;
+        var y1;
+
+        if ( tempPoint.x > x1 && tempPoint.x < x1 + width )
+        {
+            y1 = -height * this.anchor.y;
+
+            if ( tempPoint.y > y1 && tempPoint.y < y1 + height )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    };
+
+
+    /**
+     * Destroys this sprite and optionally its texture and children
+     *
+     * @param [options] {object|boolean} Options parameter. A boolean will act as if all options have been set to that value
+     * @param [options.children=false] {boolean} if set to true, all the children will have their destroy
+     *      method called as well. 'options' will be passed on to those calls.
+     * @param [options.texture=false] {boolean} Should it destroy the current texture of the sprite as well
+     * @param [options.baseTexture=false] {boolean} Should it destroy the base texture of the sprite as well
+     */
+    Sprite.prototype.destroy = function (options)
+    {
+        Container.prototype.destroy.call(this, options);
+
+        this.anchor = null;
+
+        var destroyTexture = typeof options === 'boolean' ? options : options && options.texture;
+        if (destroyTexture)
+        {
+            var destroyBaseTexture = typeof options === 'boolean' ? options : options && options.baseTexture;
+            this._texture.destroy(!!destroyBaseTexture);
+        }
+
+        this._texture = null;
+        this.shader = null;
+    };
+
+// some helper functions..
+
+    /**
+     * Helper function that creates a new sprite based on the source you provide.
+     * The source can be - frame id, image url, video url, canvas element, video element, base texture
+     *
+     * @static
+     * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from
+     * @return {PIXI.Texture} The newly created texture
+     */
+    Sprite.from = function (source)
+    {
+        return new Sprite(Texture.from(source));
+    };
+
+    /**
+     * Helper function that creates a sprite that will contain a texture from the TextureCache based on the frameId
+     * The frame ids are created when a Texture packer file has been loaded
+     *
+     * @static
+     * @param frameId {string} The frame Id of the texture in the cache
+     * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the frameId
+     */
+    Sprite.fromFrame = function (frameId)
+    {
+        var texture = utils.TextureCache[frameId];
+
+        if (!texture)
+        {
+            throw new Error('The frameId "' + frameId + '" does not exist in the texture cache');
+        }
+
+        return new Sprite(texture);
+    };
+
+    /**
+     * Helper function that creates a sprite that will contain a texture based on an image url
+     * If the image is not in the texture cache it will be loaded
+     *
+     * @static
+     * @param imageId {string} The image url of the texture
+     * @param [crossorigin=(auto)] {boolean} if you want to specify the cross-origin parameter
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} if you want to specify the scale mode, see {@link PIXI.SCALE_MODES} for possible values
+     * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the image id
+     */
+    Sprite.fromImage = function (imageId, crossorigin, scaleMode)
+    {
+        return new Sprite(Texture.fromImage(imageId, crossorigin, scaleMode));
+    };
+
+},{"../const":43,"../display/Container":45,"../math":67,"../textures/Texture":109,"../utils":116}],99:[function(require,module,exports){
+    var CanvasRenderer = require('../../renderers/canvas/CanvasRenderer'),
+        CONST = require('../../const'),
+        math = require('../../math'),
+        canvasRenderWorldTransform = new math.Matrix(),
+        CanvasTinter = require('./CanvasTinter');
+
+    /**
+     * @author Mat Groves
+     *
+     * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/
+     * for creating the original pixi version!
+     * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer
+     *
+     * Heavily inspired by LibGDX's CanvasSpriteRenderer:
+     * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/CanvasSpriteRenderer.java
+     */
+
+    /**
+     * Renderer dedicated to drawing and batching sprites.
+     *
+     * @class
+     * @private
+     * @memberof PIXI
+     * @extends PIXI.ObjectRenderer
+     * @param renderer {PIXI.WebGLRenderer} The renderer sprite this batch works for.
+     */
+    function CanvasSpriteRenderer(renderer)
+    {
+        this.renderer = renderer;
+    }
+
+
+    CanvasSpriteRenderer.prototype.constructor = CanvasSpriteRenderer;
+    module.exports = CanvasSpriteRenderer;
+
+    CanvasRenderer.registerPlugin('sprite', CanvasSpriteRenderer);
+
+    /**
+     * Renders the sprite object.
+     *
+     * @param sprite {PIXI.Sprite} the sprite to render when using this spritebatch
+     */
+    CanvasSpriteRenderer.prototype.render = function (sprite)
+    {
+        var texture = sprite._texture,
+            renderer = this.renderer,
+            wt = sprite.transform.worldTransform,
+            dx,
+            dy,
+            width = texture._frame.width,
+            height = texture._frame.height;
+
+        if (texture.orig.width <= 0 || texture.orig.height <= 0 || !texture.baseTexture.source)
+        {
+            return;
+        }
+
+        renderer.setBlendMode(sprite.blendMode);
+
+        //  Ignore null sources
+        if (texture.valid)
+        {
+            renderer.context.globalAlpha = sprite.worldAlpha;
+
+            // If smoothingEnabled is supported and we need to change the smoothing property for sprite texture
+            var smoothingEnabled = texture.baseTexture.scaleMode === CONST.SCALE_MODES.LINEAR;
+            if (renderer.smoothProperty && renderer.context[renderer.smoothProperty] !== smoothingEnabled)
+            {
+                renderer.context[renderer.smoothProperty] = smoothingEnabled;
+            }
+
+            if (texture.trim) {
+                dx = texture.trim.width/2 + texture.trim.x - sprite.anchor.x * texture.orig.width;
+                dy = texture.trim.height/2 + texture.trim.y - sprite.anchor.y * texture.orig.height;
+            } else {
+                dx = (0.5 - sprite.anchor.x) * texture.orig.width;
+                dy = (0.5 - sprite.anchor.y) * texture.orig.height;
+            }
+            if(texture.rotate) {
+                wt.copy(canvasRenderWorldTransform);
+                wt = canvasRenderWorldTransform;
+                math.GroupD8.matrixAppendRotationInv(wt, texture.rotate, dx, dy);
+                // the anchor has already been applied above, so lets set it to zero
+                dx = 0;
+                dy = 0;
+            }
+            dx -= width/2;
+            dy -= height/2;
+            // Allow for pixel rounding
+            if (renderer.roundPixels)
+            {
+                renderer.context.setTransform(
+                    wt.a,
+                    wt.b,
+                    wt.c,
+                    wt.d,
+                    (wt.tx * renderer.resolution) | 0,
+                    (wt.ty * renderer.resolution) | 0
+                );
+
+                dx = dx | 0;
+                dy = dy | 0;
+            }
+            else
+            {
+                renderer.context.setTransform(
+                    wt.a,
+                    wt.b,
+                    wt.c,
+                    wt.d,
+                    wt.tx * renderer.resolution,
+                    wt.ty * renderer.resolution
+                );
+            }
+
+            var resolution = texture.baseTexture.resolution;
+
+            if (sprite.tint !== 0xFFFFFF)
+            {
+                if (sprite.cachedTint !== sprite.tint)
+                {
+                    sprite.cachedTint = sprite.tint;
+
+                    // TODO clean up caching - how to clean up the caches?
+                    sprite.tintedTexture = CanvasTinter.getTintedTexture(sprite, sprite.tint);
+                }
+
+                renderer.context.drawImage(
+                    sprite.tintedTexture,
+                    0,
+                    0,
+                    width * resolution,
+                    height * resolution,
+                    dx * renderer.resolution,
+                    dy * renderer.resolution,
+                    width * renderer.resolution,
+                    height * renderer.resolution
+                );
+            }
+            else
+            {
+
+                renderer.context.drawImage(
+                    texture.baseTexture.source,
+                    texture._frame.x * resolution,
+                    texture._frame.y * resolution,
+                    width * resolution,
+                    height * resolution,
+                    dx  * renderer.resolution,
+                    dy  * renderer.resolution,
+                    width * renderer.resolution,
+                    height * renderer.resolution
+                );
+            }
+        }
+    };
+
+    /**
+     * destroy the sprite object.
+     *
+     */
+    CanvasSpriteRenderer.prototype.destroy = function (){
+        this.renderer = null;
+    };
+
+},{"../../const":43,"../../math":67,"../../renderers/canvas/CanvasRenderer":74,"./CanvasTinter":100}],100:[function(require,module,exports){
+    var utils = require('../../utils'),
+        canUseNewCanvasBlendModes = require('../../renderers/canvas/utils/canUseNewCanvasBlendModes');
+
+    /**
+     * Utility methods for Sprite/Texture tinting.
+     *
+     * @namespace PIXI.CanvasTinter
+     */
+    var CanvasTinter = module.exports = {
+        /**
+         * Basically this method just needs a sprite and a color and tints the sprite with the given color.
+         *
+         * @memberof PIXI.CanvasTinter
+         * @param sprite {PIXI.Sprite} the sprite to tint
+         * @param color {number} the color to use to tint the sprite with
+         * @return {HTMLCanvasElement} The tinted canvas
+         */
+        getTintedTexture: function (sprite, color)
+        {
+            var texture = sprite.texture;
+
+            color = CanvasTinter.roundColor(color);
+
+            var stringColor = '#' + ('00000' + ( color | 0).toString(16)).substr(-6);
+
+            texture.tintCache = texture.tintCache || {};
+
+            if (texture.tintCache[stringColor])
+            {
+                return texture.tintCache[stringColor];
+            }
+
+            // clone texture..
+            var canvas = CanvasTinter.canvas || document.createElement('canvas');
+
+            //CanvasTinter.tintWithPerPixel(texture, stringColor, canvas);
+            CanvasTinter.tintMethod(texture, color, canvas);
+
+            if (CanvasTinter.convertTintToImage)
+            {
+                // is this better?
+                var tintImage = new Image();
+                tintImage.src = canvas.toDataURL();
+
+                texture.tintCache[stringColor] = tintImage;
+            }
+            else
+            {
+                texture.tintCache[stringColor] = canvas;
+                // if we are not converting the texture to an image then we need to lose the reference to the canvas
+                CanvasTinter.canvas = null;
+            }
+
+            return canvas;
+        },
+
+        /**
+         * Tint a texture using the 'multiply' operation.
+         *
+         * @memberof PIXI.CanvasTinter
+         * @param texture {PIXI.Texture} the texture to tint
+         * @param color {number} the color to use to tint the sprite with
+         * @param canvas {HTMLCanvasElement} the current canvas
+         */
+        tintWithMultiply: function (texture, color, canvas)
+        {
+            var context = canvas.getContext( '2d' );
+            var crop = texture._frame.clone();
+            var resolution = texture.baseTexture.resolution;
+
+            crop.x *= resolution;
+            crop.y *= resolution;
+            crop.width *= resolution;
+            crop.height *= resolution;
+
+            canvas.width = crop.width;
+            canvas.height = crop.height;
+
+            context.fillStyle = '#' + ('00000' + ( color | 0).toString(16)).substr(-6);
+
+            context.fillRect(0, 0, crop.width, crop.height);
+
+            context.globalCompositeOperation = 'multiply';
+
+            context.drawImage(
+                texture.baseTexture.source,
+                crop.x,
+                crop.y,
+                crop.width,
+                crop.height,
+                0,
+                0,
+                crop.width,
+                crop.height
+            );
+
+            context.globalCompositeOperation = 'destination-atop';
+
+            context.drawImage(
+                texture.baseTexture.source,
+                crop.x,
+                crop.y,
+                crop.width,
+                crop.height,
+                0,
+                0,
+                crop.width,
+                crop.height
+            );
+        },
+
+        /**
+         * Tint a texture using the 'overlay' operation.
+         *
+         * @memberof PIXI.CanvasTinter
+         * @param texture {PIXI.Texture} the texture to tint
+         * @param color {number} the color to use to tint the sprite with
+         * @param canvas {HTMLCanvasElement} the current canvas
+         */
+        tintWithOverlay: function (texture, color, canvas)
+        {
+            var context = canvas.getContext( '2d' );
+            var crop = texture._frame.clone();
+            var resolution = texture.baseTexture.resolution;
+
+            crop.x *= resolution;
+            crop.y *= resolution;
+            crop.width *= resolution;
+            crop.height *= resolution;
+
+            canvas.width = crop.width;
+            canvas.height = crop.height;
+
+            context.globalCompositeOperation = 'copy';
+            context.fillStyle = '#' + ('00000' + ( color | 0).toString(16)).substr(-6);
+            context.fillRect(0, 0, crop.width, crop.height);
+
+            context.globalCompositeOperation = 'destination-atop';
+            context.drawImage(
+                texture.baseTexture.source,
+                crop.x,
+                crop.y,
+                crop.width,
+                crop.height,
+                0,
+                0,
+                crop.width,
+                crop.height
+            );
+
+            // context.globalCompositeOperation = 'copy';
+        },
+
+        /**
+         * Tint a texture pixel per pixel.
+         *
+         * @memberof PIXI.CanvasTinter
+         * @param texture {PIXI.Texture} the texture to tint
+         * @param color {number} the color to use to tint the sprite with
+         * @param canvas {HTMLCanvasElement} the current canvas
+         */
+        tintWithPerPixel: function (texture, color, canvas)
+        {
+            var context = canvas.getContext( '2d' );
+            var crop = texture._frame.clone();
+            var resolution = texture.baseTexture.resolution;
+
+            crop.x *= resolution;
+            crop.y *= resolution;
+            crop.width *= resolution;
+            crop.height *= resolution;
+
+            canvas.width = crop.width;
+            canvas.height = crop.height;
+
+            context.globalCompositeOperation = 'copy';
+            context.drawImage(
+                texture.baseTexture.source,
+                crop.x,
+                crop.y,
+                crop.width,
+                crop.height,
+                0,
+                0,
+                crop.width,
+                crop.height
+            );
+
+            var rgbValues = utils.hex2rgb(color);
+            var r = rgbValues[0], g = rgbValues[1], b = rgbValues[2];
+
+            var pixelData = context.getImageData(0, 0, crop.width, crop.height);
+
+            var pixels = pixelData.data;
+
+            for (var i = 0; i < pixels.length; i += 4)
+            {
+                pixels[i+0] *= r;
+                pixels[i+1] *= g;
+                pixels[i+2] *= b;
+            }
+
+            context.putImageData(pixelData, 0, 0);
+        },
+
+        /**
+         * Rounds the specified color according to the CanvasTinter.cacheStepsPerColorChannel.
+         *
+         * @memberof PIXI.CanvasTinter
+         * @param color {number} the color to round, should be a hex color
+         */
+        roundColor: function (color)
+        {
+            var step = CanvasTinter.cacheStepsPerColorChannel;
+
+            var rgbValues = utils.hex2rgb(color);
+
+            rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
+            rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
+            rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
+
+            return utils.rgb2hex(rgbValues);
+        },
+
+        /**
+         * Number of steps which will be used as a cap when rounding colors.
+         *
+         * @memberof PIXI.CanvasTinter
+         * @type {number}
+         */
+        cacheStepsPerColorChannel: 8,
+
+        /**
+         * Tint cache boolean flag.
+         *
+         * @memberof PIXI.CanvasTinter
+         * @type {boolean}
+         */
+        convertTintToImage: false,
+
+        /**
+         * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method.
+         *
+         * @memberof PIXI.CanvasTinter
+         * @type {boolean}
+         */
+        canUseMultiply: canUseNewCanvasBlendModes(),
+
+        /**
+         * The tinting method that will be used.
+         *
+         * @memberof PIXI.CanvasTinter
+         * @type {tintMethodFunctionType}
+         */
+        tintMethod: 0
+    };
+
+    CanvasTinter.tintMethod = CanvasTinter.canUseMultiply ? CanvasTinter.tintWithMultiply :  CanvasTinter.tintWithPerPixel;
+
+    /**
+     * The tintMethod type.
+     *
+     * @memberof PIXI.CanvasTinter
+     * @callback tintMethodFunctionType
+     * @param texture {PIXI.Texture} the texture to tint
+     * @param color {number} the color to use to tint the sprite with
+     * @param canvas {HTMLCanvasElement} the current canvas
+     */
+
+},{"../../renderers/canvas/utils/canUseNewCanvasBlendModes":77,"../../utils":116}],101:[function(require,module,exports){
+
+
+    var Buffer = function(size)
+    {
+
+        this.vertices = new ArrayBuffer(size);
+
+        /**
+         * View on the vertices as a Float32Array for positions
+         *
+         * @member {Float32Array}
+         */
+        this.float32View = new Float32Array(this.vertices);
+
+        /**
+         * View on the vertices as a Uint32Array for uvs
+         *
+         * @member {Float32Array}
+         */
+        this.uint32View = new Uint32Array(this.vertices);
+    };
+
+    module.exports = Buffer;
+
+    Buffer.prototype.destroy = function(){
+        this.vertices = null;
+        this.positions = null;
+        this.uvs = null;
+        this.colors  = null;
+    };
+},{}],102:[function(require,module,exports){
+    var ObjectRenderer = require('../../renderers/webgl/utils/ObjectRenderer'),
+        WebGLRenderer = require('../../renderers/webgl/WebGLRenderer'),
+        createIndicesForQuads = require('../../utils/createIndicesForQuads'),
+        generateMultiTextureShader = require('./generateMultiTextureShader'),
+        checkMaxIfStatmentsInShader = require('../../renderers/webgl/utils/checkMaxIfStatmentsInShader'),
+        Buffer = require('./BatchBuffer'),
+        CONST = require('../../const'),
+        glCore = require('pixi-gl-core'),
+        bitTwiddle = require('bit-twiddle');
+
+    var TICK = 0;
+    /**
+     * Renderer dedicated to drawing and batching sprites.
+     *
+     * @class
+     * @private
+     * @memberof PIXI
+     * @extends PIXI.ObjectRenderer
+     * @param renderer {PIXI.WebGLRenderer} The renderer this sprite batch works for.
+     */
+    function SpriteRenderer(renderer)
+    {
+        ObjectRenderer.call(this, renderer);
+
+        /**
+         * Number of values sent in the vertex buffer.
+         * positionX, positionY, colorR, colorG, colorB = 5
+         *
+         * @member {number}
+         */
+        this.vertSize = 5;
+
+        /**
+         * The size of the vertex information in bytes.
+         *
+         * @member {number}
+         */
+        this.vertByteSize = this.vertSize * 4;
+
+        /**
+         * The number of images in the SpriteBatch before it flushes.
+         *
+         * @member {number}
+         */
+        this.size = CONST.SPRITE_BATCH_SIZE; // 2000 is a nice balance between mobile / desktop
+
+        // the total number of bytes in our batch
+        // var numVerts = this.size * 4 * this.vertByteSize;
+
+        this.buffers = [];
+        for (var i = 1; i <= bitTwiddle.nextPow2(this.size); i*=2) {
+            var numVertsTemp = i * 4 * this.vertByteSize;
+            this.buffers.push(new Buffer(numVertsTemp));
+        }
+
+        /**
+         * Holds the indices of the geometry (quads) to draw
+         *
+         * @member {Uint16Array}
+         */
+        this.indices = createIndicesForQuads(this.size);
+
+        /**
+         * The default shaders that is used if a sprite doesn't have a more specific one.
+         * there is a shader for each number of textures that can be rendererd.
+         * These shaders will also be generated on the fly as required.
+         * @member {PIXI.Shader[]}
+         */
+        this.shaders = null;
+
+        this.currentIndex = 0;
+        TICK =0;
+        this.groups = [];
+
+        for (var k = 0; k < this.size; k++)
+        {
+            this.groups[k] = {textures:[], textureCount:0, ids:[], size:0, start:0, blend:0};
+        }
+
+        this.sprites = [];
+
+        this.vertexBuffers = [];
+        this.vaos = [];
+
+        this.vaoMax = 2;
+        this.vertexCount = 0;
+
+        this.renderer.on('prerender', this.onPrerender, this);
+    }
+
+
+    SpriteRenderer.prototype = Object.create(ObjectRenderer.prototype);
+    SpriteRenderer.prototype.constructor = SpriteRenderer;
+    module.exports = SpriteRenderer;
+
+    WebGLRenderer.registerPlugin('sprite', SpriteRenderer);
+
+    /**
+     * Sets up the renderer context and necessary buffers.
+     *
+     * @private
+     */
+    SpriteRenderer.prototype.onContextChange = function ()
+    {
+        var gl = this.renderer.gl;
+
+        // step 1: first check max textures the GPU can handle.
+        this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), CONST.SPRITE_MAX_TEXTURES);
+
+        // step 2: check the maximum number of if statements the shader can have too..
+        this.MAX_TEXTURES = checkMaxIfStatmentsInShader( this.MAX_TEXTURES, gl );
+
+        this.shaders = new Array(this.MAX_TEXTURES);
+        this.shaders[0] = generateMultiTextureShader(gl, 1);
+        this.shaders[1] = generateMultiTextureShader(gl, 2);
+
+        // create a couple of buffers
+        this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW);
+
+        // we use the second shader as the first one depending on your browser may omit aTextureId
+        // as it is not used by the shader so is optimized out.
+        var shader = this.shaders[1];
+
+        for (var i = 0; i < this.vaoMax; i++) {
+            this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW);
+
+            // build the vao object that will render..
+            this.vaos[i] = this.renderer.createVao()
+                .addIndex(this.indexBuffer)
+                .addAttribute(this.vertexBuffers[i], shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0)
+                .addAttribute(this.vertexBuffers[i], shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4)
+                .addAttribute(this.vertexBuffers[i], shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4)
+                .addAttribute(this.vertexBuffers[i], shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4);
+        }
+
+        this.vao = this.vaos[0];
+        this.currentBlendMode = 99999;
+    };
+
+    SpriteRenderer.prototype.onPrerender = function ()
+    {
+        this.vertexCount = 0;
+    };
+
+    /**
+     * Renders the sprite object.
+     *
+     * @param sprite {PIXI.Sprite} the sprite to render when using this spritebatch
+     */
+    SpriteRenderer.prototype.render = function (sprite)
+    {
+        //TODO set blend modes..
+        // check texture..
+        if (this.currentIndex >= this.size)
+        {
+            this.flush();
+        }
+
+
+        // get the uvs for the texture
+
+
+        // if the uvs have not updated then no point rendering just yet!
+        if (!sprite.texture._uvs)
+        {
+            return;
+        }
+
+        // push a texture.
+        // increment the batchsize
+        this.sprites[this.currentIndex++] = sprite;
+    };
+
+    /**
+     * Renders the content and empties the current batch.
+     *
+     */
+    SpriteRenderer.prototype.flush = function ()
+    {
+        if (this.currentIndex === 0) {
+            return;
+        }
+
+        var gl = this.renderer.gl;
+
+        var np2 = bitTwiddle.nextPow2(this.currentIndex);
+        var log2 = bitTwiddle.log2(np2);
+        var buffer = this.buffers[log2];
+
+        var sprites = this.sprites;
+        var groups = this.groups;
+
+        var float32View = buffer.float32View;
+        var uint32View = buffer.uint32View;
+
+        var index = 0;
+        var nextTexture;
+        var currentTexture;
+        var groupCount = 1;
+        var textureCount = 0;
+        var currentGroup = groups[0];
+        var vertexData;
+        var tint;
+        var uvs;
+        var textureId;
+        var blendMode = sprites[0].blendMode;
+        var shader;
+
+        currentGroup.textureCount = 0;
+        currentGroup.start = 0;
+        currentGroup.blend = blendMode;
+
+        TICK++;
+
+        for (var i = 0; i < this.currentIndex; i++)
+        {
+            // upload the sprite elemetns...
+            // they have all ready been calculated so we just need to push them into the buffer.
+            var sprite = sprites[i];
+
+            nextTexture = sprite._texture.baseTexture;
+
+            if(blendMode !== sprite.blendMode)
+            {
+                blendMode = sprite.blendMode;
+
+                // force the batch to break!
+                currentTexture = null;
+                textureCount = this.MAX_TEXTURES;
+                TICK++;
+            }
+
+            if(currentTexture !== nextTexture)
+            {
+                currentTexture = nextTexture;
+
+                if(nextTexture._enabled !== TICK)
+                {
+                    if(textureCount === this.MAX_TEXTURES)
+                    {
+                        TICK++;
+
+                        textureCount = 0;
+
+                        currentGroup.size = i - currentGroup.start;
+
+                        currentGroup = groups[groupCount++];
+                        currentGroup.textureCount = 0;
+                        currentGroup.blend = blendMode;
+                        currentGroup.start = i;
+                    }
+
+                    nextTexture._enabled = TICK;
+                    nextTexture._id = textureCount;
+
+                    currentGroup.textures[currentGroup.textureCount++] = nextTexture;
+                    textureCount++;
+                }
+
+            }
+
+            vertexData = sprite.vertexData;
+
+            //TODO this sum does not need to be set each frame..
+            tint = sprite._tintRGB + (sprite.worldAlpha * 255 << 24);
+            uvs = sprite._texture._uvs.uvsUint32;
+            textureId = nextTexture._id;
+
+            if (this.renderer.roundPixels)
+            {
+                var resolution = this.renderer.resolution;
+
+                //xy
+                float32View[index] = ((vertexData[0] * resolution) | 0) / resolution;
+                float32View[index+1] = ((vertexData[1] * resolution) | 0) / resolution;
+
+                // xy
+                float32View[index+5] = ((vertexData[2] * resolution) | 0) / resolution;
+                float32View[index+6] = ((vertexData[3] * resolution) | 0) / resolution;
+
+                // xy
+                float32View[index+10] = ((vertexData[4] * resolution) | 0) / resolution;
+                float32View[index+11] = ((vertexData[5] * resolution) | 0) / resolution;
+
+                // xy
+                float32View[index+15] = ((vertexData[6] * resolution) | 0) / resolution;
+                float32View[index+16] = ((vertexData[7] * resolution) | 0) / resolution;
+
+            }
+            else
+            {
+                //xy
+                float32View[index] = vertexData[0];
+                float32View[index+1] = vertexData[1];
+
+                // xy
+                float32View[index+5] = vertexData[2];
+                float32View[index+6] = vertexData[3];
+
+                // xy
+                float32View[index+10] = vertexData[4];
+                float32View[index+11] = vertexData[5];
+
+                // xy
+                float32View[index+15] = vertexData[6];
+                float32View[index+16] = vertexData[7];
+            }
+
+            uint32View[index+2] = uvs[0];
+            uint32View[index+7] = uvs[1];
+            uint32View[index+12] = uvs[2];
+            uint32View[index+17] = uvs[3];
+
+            uint32View[index+3] = uint32View[index+8] = uint32View[index+13] = uint32View[index+18] = tint;
+            float32View[index+4] = float32View[index+9] = float32View[index+14] = float32View[index+19] = textureId;
+
+            index += 20;
+        }
+
+        currentGroup.size = i - currentGroup.start;
+
+        this.vertexCount++;
+
+        if(this.vaoMax <= this.vertexCount)
+        {
+            this.vaoMax++;
+            shader = this.shaders[1];
+            this.vertexBuffers[this.vertexCount] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW);
+            // build the vao object that will render..
+            this.vaos[this.vertexCount] = this.renderer.createVao()
+                .addIndex(this.indexBuffer)
+                .addAttribute(this.vertexBuffers[this.vertexCount], shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0)
+                .addAttribute(this.vertexBuffers[this.vertexCount], shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4)
+                .addAttribute(this.vertexBuffers[this.vertexCount], shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4)
+                .addAttribute(this.vertexBuffers[this.vertexCount], shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4);
+        }
+
+        this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0);
+        this.vao = this.vaos[this.vertexCount].bind();
+
+        /// render the groups..
+        for (i = 0; i < groupCount; i++) {
+
+            var group = groups[i];
+            var groupTextureCount = group.textureCount;
+            shader = this.shaders[groupTextureCount-1];
+
+            if(!shader)
+            {
+                shader = this.shaders[groupTextureCount-1] = generateMultiTextureShader(gl, groupTextureCount);
+                //console.log("SHADER generated for " + textureCount + " textures")
+            }
+
+            this.renderer.bindShader(shader);
+
+            for (var j = 0; j < groupTextureCount; j++)
+            {
+                this.renderer.bindTexture(group.textures[j], j);
+            }
+
+            // set the blend mode..
+            this.renderer.state.setBlendMode( group.blend );
+
+            gl.drawElements(gl.TRIANGLES, group.size * 6, gl.UNSIGNED_SHORT, group.start * 6 * 2);
+        }
+
+        // reset elements for the next flush
+        this.currentIndex = 0;
+    };
+
+    /**
+     * Starts a new sprite batch.
+     *
+     */
+    SpriteRenderer.prototype.start = function ()
+    {
+        //this.renderer.bindShader(this.shader);
+        //TICK %= 1000;
+    };
+
+    SpriteRenderer.prototype.stop = function ()
+    {
+        this.flush();
+        this.vao.unbind();
+    };
+    /**
+     * Destroys the SpriteBatch.
+     *
+     */
+    SpriteRenderer.prototype.destroy = function ()
+    {
+        for (var i = 0; i < this.vaoMax; i++) {
+            this.vertexBuffers[i].destroy();
+            this.vaos[i].destroy();
+        }
+
+        this.indexBuffer.destroy();
+
+        this.renderer.off('prerender', this.onPrerender, this);
+        ObjectRenderer.prototype.destroy.call(this);
+
+        for (i = 0; i < this.shaders.length; i++) {
+
+            if(this.shaders[i])
+            {
+                this.shaders[i].destroy();
+            }
+        }
+
+        this.vertexBuffers = null;
+        this.vaos = null;
+        this.indexBuffer = null;
+        this.indices = null;
+
+        this.sprites = null;
+
+        for (i = 0; i < this.buffers.length; i++) {
+            this.buffers[i].destroy();
+        }
+
+    };
+
+},{"../../const":43,"../../renderers/webgl/WebGLRenderer":81,"../../renderers/webgl/utils/ObjectRenderer":91,"../../renderers/webgl/utils/checkMaxIfStatmentsInShader":94,"../../utils/createIndicesForQuads":114,"./BatchBuffer":101,"./generateMultiTextureShader":103,"bit-twiddle":1,"pixi-gl-core":12}],103:[function(require,module,exports){
+    var Shader = require('../../Shader');
+
+
+    var fragTemplate = [
+        'varying vec2 vTextureCoord;',
+        'varying vec4 vColor;',
+        'varying float vTextureId;',
+        'uniform sampler2D uSamplers[%count%];',
+
+        'void main(void){',
+        'vec4 color;',
+        'float textureId = floor(vTextureId+0.5);',
+        '%forloop%',
+        'gl_FragColor = color * vColor;',
+        '}'
+    ].join('\n');
+
+    function generateMultiTextureShader(gl, maxTextures)
+    {
+        var vertexSrc = "#define GLSLIFY 1\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\nattribute vec4 aColor;\nattribute float aTextureId;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\nvarying float vTextureId;\n\nvoid main(void){\n   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n   vTextureCoord = aTextureCoord;\n   vTextureId = aTextureId;\n   vColor = vec4(aColor.rgb * aColor.a, aColor.a);\n}\n";
+        var fragmentSrc = fragTemplate;
+
+        fragmentSrc = fragmentSrc.replace(/%count%/gi, maxTextures);
+        fragmentSrc = fragmentSrc.replace(/%forloop%/gi, generateSampleSrc(maxTextures));
+
+        var shader = new Shader(gl, vertexSrc, fragmentSrc, {aVertexPosition:3, aColor:2, aTextureCoord:1, aTextureId:0});
+
+        var sampleValues = [];
+        for (var i = 0; i < maxTextures; i++)
+        {
+            sampleValues[i] = i;
+        }
+
+        shader.bind();
+        shader.uniforms.uSamplers = sampleValues;
+
+        return shader;
+    }
+
+    function generateSampleSrc(maxTextures)
+    {
+        var src = '';
+
+        src += '\n';
+        src += '\n';
+
+        for (var i = 0; i < maxTextures; i++)
+        {
+            if(i > 0)
+            {
+                src += '\nelse ';
+            }
+
+            if(i < maxTextures-1)
+            {
+                src += 'if(textureId == ' + i + '.0)';
+            }
+
+            src += '\n{';
+            src += '\n\tcolor = texture2D(uSamplers['+i+'], vTextureCoord);';
+            src += '\n}';
+        }
+
+        src += '\n';
+        src += '\n';
+
+        return src;
+    }
+
+
+
+    module.exports = generateMultiTextureShader;
+
+},{"../../Shader":42}],104:[function(require,module,exports){
+    var Sprite = require('../sprites/Sprite'),
+        Texture = require('../textures/Texture'),
+        math = require('../math'),
+        utils = require('../utils'),
+        CONST = require('../const'),
+        TextStyle = require('./TextStyle');
+
+    var defaultDestroyOptions = {
+        texture:true,
+        children:false,
+        baseTexture:true
+    };
+    /**
+     * A Text Object will create a line or multiple lines of text. To split a line you can use '\n' in your text string,
+     * or add a wordWrap property set to true and and wordWrapWidth property with a value in the style object.
+     *
+     * A Text can be created directly from a string and a style object
+     *
+     * ```js
+     * var text = new PIXI.Text('This is a pixi text',{fontFamily : 'Arial', fontSize: 24, fill : 0xff1010, align : 'center'});
+     * ```
+     *
+     * @class
+     * @extends PIXI.Sprite
+     * @memberof PIXI
+     * @param text {string} The string that you would like the text to display
+     * @param [style] {object|PIXI.TextStyle} The style parameters
+     */
+    function Text(text, style)
+    {
+        /**
+         * The canvas element that everything is drawn to
+         *
+         * @member {HTMLCanvasElement}
+         */
+        this.canvas = document.createElement('canvas');
+
+        /**
+         * The canvas 2d context that everything is drawn with
+         * @member {HTMLCanvasElement}
+         */
+        this.context = this.canvas.getContext('2d');
+
+        /**
+         * The resolution / device pixel ratio of the canvas. This is set automatically by the renderer.
+         * @member {number}
+         * @default 1
+         */
+        this.resolution = CONST.RESOLUTION;
+
+        /**
+         * Private tracker for the current text.
+         *
+         * @member {string}
+         * @private
+         */
+        this._text = null;
+
+        /**
+         * Private tracker for the current style.
+         *
+         * @member {object}
+         * @private
+         */
+        this._style = null;
+        /**
+         * Private listener to track style changes.
+         *
+         * @member {Function}
+         * @private
+         */
+        this._styleListener = null;
+
+        /**
+         * Private tracker for the current font.
+         *
+         * @member {string}
+         * @private
+         */
+        this._font = '';
+
+        var texture = Texture.fromCanvas(this.canvas);
+        texture.orig = new math.Rectangle();
+        texture.trim = new math.Rectangle();
+        Sprite.call(this, texture);
+
+        this.text = text;
+        this.style = style;
+
+        this.localStyleID = -1;
+    }
+
+// constructor
+    Text.prototype = Object.create(Sprite.prototype);
+    Text.prototype.constructor = Text;
+    module.exports = Text;
+
+    Text.fontPropertiesCache = {};
+    Text.fontPropertiesCanvas = document.createElement('canvas');
+    Text.fontPropertiesContext = Text.fontPropertiesCanvas.getContext('2d');
+
+    Object.defineProperties(Text.prototype, {
+        /**
+         * The width of the Text, setting this will actually modify the scale to achieve the value set
+         *
+         * @member {number}
+         * @memberof PIXI.Text#
+         */
+        width: {
+            get: function ()
+            {
+                this.updateText(true);
+
+                return Math.abs(this.scale.x) * this.texture.orig.width;
+            },
+            set: function (value)
+            {
+                this.updateText(true);
+
+                var sign = utils.sign(this.scale.x) || 1;
+                this.scale.x = sign * value / this.texture.orig.width;
+                this._width = value;
+            }
+        },
+
+        /**
+         * The height of the Text, setting this will actually modify the scale to achieve the value set
+         *
+         * @member {number}
+         * @memberof PIXI.Text#
+         */
+        height: {
+            get: function ()
+            {
+                this.updateText(true);
+
+                return Math.abs(this.scale.y) * this._texture.orig.height;
+            },
+            set: function (value)
+            {
+                this.updateText(true);
+
+                var sign = utils.sign(this.scale.y) || 1;
+                this.scale.y = sign * value / this.texture.orig.height;
+                this._height = value;
+            }
+        },
+
+        /**
+         * Set the style of the text. Set up an event listener to listen for changes on the style object and mark the text as dirty.
+         *
+         * @member {object|PIXI.TextStyle}
+         * @memberof PIXI.Text#
+         */
+        style: {
+            get: function ()
+            {
+                return this._style;
+            },
+            set: function (style)
+            {
+
+                style = style || {};
+                if (style instanceof TextStyle)
+                {
+                    this._style = style;
+                }
+                else
+                {
+                    this._style = new TextStyle(style);
+                }
+
+                this.localStyleID = -1;
+                this.dirty = true;
+            }
+        },
+
+        /**
+         * Set the copy for the text object. To split a line you can use '\n'.
+         *
+         * @member {string}
+         * @memberof PIXI.Text#
+         */
+        text: {
+            get: function()
+            {
+                return this._text;
+            },
+            set: function (text){
+
+                text = text || ' ';
+                text = text.toString();
+
+                if (this._text === text)
+                {
+                    return;
+                }
+                this._text = text;
+                this.dirty = true;
+            }
+        }
+    });
+
+    /**
+     * Renders text and updates it when needed
+     * @param respectDirty {boolean} Whether to abort updating the text if the Text isn't dirty and the function is called.
+     * @private
+     */
+    Text.prototype.updateText = function (respectDirty)
+    {
+        var style = this._style;
+
+        // check if style has changed..
+        if(this.localStyleID !== style.styleID)
+        {
+            this.dirty = true;
+            this.localStyleID = style.styleID;
+        }
+
+        if (!this.dirty && respectDirty) {
+            return;
+        }
+
+        // build canvas api font setting from invididual components. Convert a numeric style.fontSize to px
+        var fontSizeString = (typeof style.fontSize === 'number') ? style.fontSize + 'px' : style.fontSize;
+        this._font = style.fontStyle + ' ' + style.fontVariant + ' ' + style.fontWeight + ' ' + fontSizeString + ' ' + style.fontFamily;
+
+        this.context.font = this._font;
+
+        // word wrap
+        // preserve original text
+        var outputText = style.wordWrap ? this.wordWrap(this._text) : this._text;
+
+        // split text into lines
+        var lines = outputText.split(/(?:\r\n|\r|\n)/);
+
+        // calculate text width
+        var lineWidths = new Array(lines.length);
+        var maxLineWidth = 0;
+        var fontProperties = this.determineFontProperties(this._font);
+
+        var i;
+        for (i = 0; i < lines.length; i++)
+        {
+            var lineWidth = this.context.measureText(lines[i]).width + ((lines[i].length - 1) * style.letterSpacing);
+            lineWidths[i] = lineWidth;
+            maxLineWidth = Math.max(maxLineWidth, lineWidth);
+        }
+
+        var width = maxLineWidth + style.strokeThickness;
+        if (style.dropShadow)
+        {
+            width += style.dropShadowDistance;
+        }
+
+        width += style.padding * 2;
+
+        this.canvas.width = Math.ceil( ( width + this.context.lineWidth ) * this.resolution );
+
+        // calculate text height
+        var lineHeight = this.style.lineHeight || fontProperties.fontSize + style.strokeThickness;
+
+        var height = Math.max(lineHeight, fontProperties.fontSize  + style.strokeThickness) + (lines.length - 1) * lineHeight;
+        if (style.dropShadow)
+        {
+            height += style.dropShadowDistance;
+        }
+
+        this.canvas.height = Math.ceil( ( height + this._style.padding * 2 ) * this.resolution );
+
+        this.context.scale( this.resolution, this.resolution);
+
+        if (navigator.isCocoonJS)
+        {
+            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
+
+        }
+
+//    this.context.fillStyle="#FF0000";
+//    this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
+
+        this.context.font = this._font;
+        this.context.strokeStyle = style.stroke;
+        this.context.lineWidth = style.strokeThickness;
+        this.context.textBaseline = style.textBaseline;
+        this.context.lineJoin = style.lineJoin;
+        this.context.miterLimit = style.miterLimit;
+
+        var linePositionX;
+        var linePositionY;
+
+        if (style.dropShadow)
+        {
+            if (style.dropShadowBlur > 0) {
+                this.context.shadowColor = style.dropShadowColor;
+                this.context.shadowBlur = style.dropShadowBlur;
+            } else {
+                this.context.fillStyle = style.dropShadowColor;
+            }
+
+            var xShadowOffset = Math.cos(style.dropShadowAngle) * style.dropShadowDistance;
+            var yShadowOffset = Math.sin(style.dropShadowAngle) * style.dropShadowDistance;
+
+            for (i = 0; i < lines.length; i++)
+            {
+                linePositionX = style.strokeThickness / 2;
+                linePositionY = (style.strokeThickness / 2 + i * lineHeight) + fontProperties.ascent;
+
+                if (style.align === 'right')
+                {
+                    linePositionX += maxLineWidth - lineWidths[i];
+                }
+                else if (style.align === 'center')
+                {
+                    linePositionX += (maxLineWidth - lineWidths[i]) / 2;
+                }
+
+                if (style.fill)
+                {
+                    this.drawLetterSpacing(lines[i], linePositionX + xShadowOffset + style.padding, linePositionY + yShadowOffset + style.padding);
+
+                    if (style.stroke && style.strokeThickness)
+                    {
+                        this.context.strokeStyle = style.dropShadowColor;
+                        this.drawLetterSpacing(lines[i], linePositionX + xShadowOffset + style.padding, linePositionY + yShadowOffset + style.padding, true);
+                        this.context.strokeStyle = style.stroke;
+                    }
+                }
+            }
+        }
+
+        //set canvas text styles
+        this.context.fillStyle = this._generateFillStyle(style, lines);
+
+        //draw lines line by line
+        for (i = 0; i < lines.length; i++)
+        {
+            linePositionX = style.strokeThickness / 2;
+            linePositionY = (style.strokeThickness / 2 + i * lineHeight) + fontProperties.ascent;
+
+            if (style.align === 'right')
+            {
+                linePositionX += maxLineWidth - lineWidths[i];
+            }
+            else if (style.align === 'center')
+            {
+                linePositionX += (maxLineWidth - lineWidths[i]) / 2;
+            }
+
+            if (style.stroke && style.strokeThickness)
+            {
+                this.drawLetterSpacing(lines[i], linePositionX + style.padding, linePositionY + style.padding, true);
+            }
+
+            if (style.fill)
+            {
+                this.drawLetterSpacing(lines[i], linePositionX + style.padding, linePositionY + style.padding);
+            }
+        }
+
+        this.updateTexture();
+    };
+
+    /**
+     * Render the text with letter-spacing.
+     * @param {string} text - The text to draw
+     * @param {number} x - Horizontal position to draw the text
+     * @param {number} y - Vertical position to draw the text
+     * @param {boolean} isStroke - Is this drawing for the outside stroke of the text? If not, it's for the inside fill
+     * @private
+     */
+    Text.prototype.drawLetterSpacing = function(text, x, y, isStroke)
+    {
+        var style = this._style;
+
+        // letterSpacing of 0 means normal
+        var letterSpacing = style.letterSpacing;
+
+        if (letterSpacing === 0)
+        {
+            if (isStroke)
+            {
+                this.context.strokeText(text, x, y);
+            }
+            else
+            {
+                this.context.fillText(text, x, y);
+            }
+            return;
+        }
+
+        var characters = String.prototype.split.call(text, ''),
+            index = 0,
+            current,
+            currentPosition = x;
+
+        while (index < text.length)
+        {
+            current = characters[index++];
+            if (isStroke)
+            {
+                this.context.strokeText(current, currentPosition, y);
+            }
+            else
+            {
+                this.context.fillText(current, currentPosition, y);
+            }
+            currentPosition += this.context.measureText(current).width + letterSpacing;
+        }
+    };
+
+    /**
+     * Updates texture size based on canvas size
+     *
+     * @private
+     */
+    Text.prototype.updateTexture = function ()
+    {
+        var texture = this._texture;
+        var style = this._style;
+
+        texture.baseTexture.hasLoaded = true;
+        texture.baseTexture.resolution = this.resolution;
+
+        texture.baseTexture.realWidth = this.canvas.width;
+        texture.baseTexture.realHeight = this.canvas.height;
+        texture.baseTexture.width = this.canvas.width / this.resolution;
+        texture.baseTexture.height = this.canvas.height / this.resolution;
+        texture.trim.width = texture._frame.width = this.canvas.width / this.resolution;
+        texture.trim.height = texture._frame.height = this.canvas.height / this.resolution;
+
+        texture.trim.x = -style.padding;
+        texture.trim.y = -style.padding;
+
+        texture.orig.width = texture._frame.width- style.padding*2;
+        texture.orig.height = texture._frame.height - style.padding*2;
+
+        //call sprite onTextureUpdate to update scale if _width or _height were set
+        this._onTextureUpdate();
+
+        texture.baseTexture.emit('update',  texture.baseTexture);
+
+        this.dirty = false;
+    };
+
+    /**
+     * Renders the object using the WebGL renderer
+     *
+     * @param renderer {PIXI.WebGLRenderer} The renderer
+     */
+    Text.prototype.renderWebGL = function (renderer)
+    {
+        if(this.resolution !== renderer.resolution)
+        {
+            this.resolution = renderer.resolution;
+            this.dirty = true;
+        }
+
+        this.updateText(true);
+
+        Sprite.prototype.renderWebGL.call(this, renderer);
+    };
+
+    /**
+     * Renders the object using the Canvas renderer
+     *
+     * @param renderer {PIXI.CanvasRenderer} The renderer
+     * @private
+     */
+    Text.prototype._renderCanvas = function (renderer)
+    {
+        if(this.resolution !== renderer.resolution)
+        {
+            this.resolution = renderer.resolution;
+            this.dirty = true;
+        }
+
+        this.updateText(true);
+
+        Sprite.prototype._renderCanvas.call(this, renderer);
+    };
+
+    /**
+     * Calculates the ascent, descent and fontSize of a given fontStyle
+     *
+     * @param fontStyle {string} String representing the style of the font
+     * @return {Object} Font properties object
+     * @private
+     */
+    Text.prototype.determineFontProperties = function (fontStyle)
+    {
+        var properties = Text.fontPropertiesCache[fontStyle];
+
+        if (!properties)
+        {
+            properties = {};
+
+            var canvas = Text.fontPropertiesCanvas;
+            var context = Text.fontPropertiesContext;
+
+            context.font = fontStyle;
+
+            var width = Math.ceil(context.measureText('|MÉq').width);
+            var baseline = Math.ceil(context.measureText('M').width);
+            var height = 2 * baseline;
+
+            baseline = baseline * 1.4 | 0;
+
+            canvas.width = width;
+            canvas.height = height;
+
+            context.fillStyle = '#f00';
+            context.fillRect(0, 0, width, height);
+
+            context.font = fontStyle;
+
+            context.textBaseline = 'alphabetic';
+            context.fillStyle = '#000';
+            context.fillText('|MÉq', 0, baseline);
+
+            var imagedata = context.getImageData(0, 0, width, height).data;
+            var pixels = imagedata.length;
+            var line = width * 4;
+
+            var i, j;
+
+            var idx = 0;
+            var stop = false;
+
+            // ascent. scan from top to bottom until we find a non red pixel
+            for (i = 0; i < baseline; i++)
+            {
+                for (j = 0; j < line; j += 4)
+                {
+                    if (imagedata[idx + j] !== 255)
+                    {
+                        stop = true;
+                        break;
+                    }
+                }
+                if (!stop)
+                {
+                    idx += line;
+                }
+                else
+                {
+                    break;
+                }
+            }
+
+            properties.ascent = baseline - i;
+
+            idx = pixels - line;
+            stop = false;
+
+            // descent. scan from bottom to top until we find a non red pixel
+            for (i = height; i > baseline; i--)
+            {
+                for (j = 0; j < line; j += 4)
+                {
+                    if (imagedata[idx + j] !== 255)
+                    {
+                        stop = true;
+                        break;
+                    }
+                }
+                if (!stop)
+                {
+                    idx -= line;
+                }
+                else
+                {
+                    break;
+                }
+            }
+
+            properties.descent = i - baseline;
+            properties.fontSize = properties.ascent + properties.descent;
+
+            Text.fontPropertiesCache[fontStyle] = properties;
+        }
+
+        return properties;
+    };
+
+    /**
+     * Applies newlines to a string to have it optimally fit into the horizontal
+     * bounds set by the Text object's wordWrapWidth property.
+     *
+     * @param text {string} String to apply word wrapping to
+     * @return {string} New string with new lines applied where required
+     * @private
+     */
+    Text.prototype.wordWrap = function (text)
+    {
+        // Greedy wrapping algorithm that will wrap words as the line grows longer
+        // than its horizontal bounds.
+        var result = '';
+        var lines = text.split('\n');
+        var wordWrapWidth = this._style.wordWrapWidth;
+        for (var i = 0; i < lines.length; i++)
+        {
+            var spaceLeft = wordWrapWidth;
+            var words = lines[i].split(' ');
+            for (var j = 0; j < words.length; j++)
+            {
+                var wordWidth = this.context.measureText(words[j]).width;
+                if (this._style.breakWords && wordWidth > wordWrapWidth)
+                {
+                    // Word should be split in the middle
+                    var characters = words[j].split('');
+                    for (var c = 0; c < characters.length; c++)
+                    {
+                        var characterWidth = this.context.measureText(characters[c]).width;
+                        if (characterWidth > spaceLeft)
+                        {
+                            result += '\n' + characters[c];
+                            spaceLeft = wordWrapWidth - characterWidth;
+                        }
+                        else
+                        {
+                            if (c === 0)
+                            {
+                                result += ' ';
+                            }
+                            result += characters[c];
+                            spaceLeft -= characterWidth;
+                        }
+                    }
+                }
+                else
+                {
+                    var wordWidthWithSpace = wordWidth + this.context.measureText(' ').width;
+                    if (j === 0 || wordWidthWithSpace > spaceLeft)
+                    {
+                        // Skip printing the newline if it's the first word of the line that is
+                        // greater than the word wrap width.
+                        if (j > 0)
+                        {
+                            result += '\n';
+                        }
+                        result += words[j];
+                        spaceLeft = wordWrapWidth - wordWidth;
+                    }
+                    else
+                    {
+                        spaceLeft -= wordWidthWithSpace;
+                        result += ' ' + words[j];
+                    }
+                }
+            }
+
+            if (i < lines.length-1)
+            {
+                result += '\n';
+            }
+        }
+        return result;
+    };
+
+    /**
+     * calculates the bounds of the Text as a rectangle. The bounds calculation takes the worldTransform into account.
+     */
+    Text.prototype._calculateBounds = function ()
+    {
+        this.updateText(true);
+        this.calculateVertices();
+        // if we have already done this on THIS frame.
+        this._bounds.addQuad(this.vertexData);
+    };
+
+    /**
+     * Method to be called upon a TextStyle change.
+     * @private
+     */
+    Text.prototype._onStyleChange = function ()
+    {
+        this.dirty = true;
+    };
+
+    /**
+     * Generates the fill style. Can automatically generate a gradient based on the fill style being an array
+     * @return string|Number|CanvasGradient
+     * @private
+     */
+    Text.prototype._generateFillStyle = function (style, lines)
+    {
+        if (!Array.isArray(style.fill))
+        {
+            return style.fill;
+        }
+        else
+        {
+            // cocoon on canvas+ cannot generate textures, so use the first colour instead
+            if ( navigator.isCocoonJS ) {
+                return style.fill[0];
+            }
+
+            // the gradient will be evenly spaced out according to how large the array is.
+            // ['#FF0000', '#00FF00', '#0000FF'] would created stops at 0.25, 0.5 and 0.75
+            var i;
+            var gradient;
+            var totalIterations;
+            var currentIteration;
+            var stop;
+
+            var width = this.canvas.width / this.resolution;
+            var height = this.canvas.height / this.resolution;
+
+            if (style.fillGradientType === CONST.TEXT_GRADIENT.LINEAR_VERTICAL)
+            {
+                // start the gradient at the top center of the canvas, and end at the bottom middle of the canvas
+                gradient = this.context.createLinearGradient(width / 2, 0, width / 2, height);
+
+                // we need to repeat the gradient so that each invididual line of text has the same vertical gradient effect
+                // ['#FF0000', '#00FF00', '#0000FF'] over 2 lines would create stops at 0.125, 0.25, 0.375, 0.625, 0.75, 0.875
+                totalIterations = ( style.fill.length + 1 ) * lines.length;
+                currentIteration = 0;
+                for (i = 0; i < lines.length; i++)
+                {
+                    currentIteration += 1;
+                    for (var j = 0; j < style.fill.length; j++)
+                    {
+                        stop = (currentIteration / totalIterations);
+                        gradient.addColorStop(stop, style.fill[j]);
+                        currentIteration++;
+                    }
+                }
+            }
+            else
+            {
+                // start the gradient at the center left of the canvas, and end at the center right of the canvas
+                gradient = this.context.createLinearGradient(0, height / 2, width, height / 2);
+
+                // can just evenly space out the gradients in this case, as multiple lines makes no difference to an even left to right gradient
+                totalIterations = style.fill.length + 1;
+                currentIteration = 1;
+
+                for (i = 0; i < style.fill.length; i++)
+                {
+                    stop = currentIteration / totalIterations;
+                    gradient.addColorStop(stop, style.fill[i]);
+                    currentIteration++;
+                }
+            }
+
+            return gradient;
+        }
+    };
+
+    /**
+     * Destroys this text object.
+     * Note* Unlike a Sprite, a Text object will automatically destroy its baseTexture and texture as
+     * the majorety of the time the texture will not be shared with any other Sprites.
+     *
+     * @param [options] {object|boolean} Options parameter. A boolean will act as if all options have been set to that value
+     * @param [options.children=false] {boolean} if set to true, all the children will have their destroy
+     *      method called as well. 'options' will be passed on to those calls.
+     * @param [options.texture=true] {boolean} Should it destroy the current texture of the sprite as well
+     * @param [options.baseTexture=true] {boolean} Should it destroy the base texture of the sprite as well
+     */
+    Text.prototype.destroy = function (options)
+    {
+        if (typeof options === 'boolean') {
+            options = { children: options };
+        }
+
+        options =  Object.assign({}, defaultDestroyOptions, options);
+
+        Sprite.prototype.destroy.call(this, options);
+
+        // make sure to reset the the context and canvas.. dont want this hanging around in memory!
+        this.context = null;
+        this.canvas = null;
+
+        this._style = null;
+    };
+
+},{"../const":43,"../math":67,"../sprites/Sprite":98,"../textures/Texture":109,"../utils":116,"./TextStyle":105}],105:[function(require,module,exports){
+    var CONST = require('../const'),
+        utils = require('../utils');
+
+    /**
+     * A TextStyle Object decorates a Text Object. It can be shared between
+     * multiple Text objects. Changing the style will update all text objects using it.
+     *
+     * @class
+     * @memberof PIXI
+     * @param [style] {object} The style parameters
+     * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text
+     * @param [style.breakWords=false] {boolean} Indicates if lines can be wrapped within words, it needs wordWrap to be set to true
+     * @param [style.dropShadow=false] {boolean} Set a drop shadow for the text
+     * @param [style.dropShadowAngle=Math.PI/6] {number} Set a angle of the drop shadow
+     * @param [style.dropShadowBlur=0] {number} Set a shadow blur radius
+     * @param [style.dropShadowColor='#000000'] {string} A fill style to be used on the dropshadow e.g 'red', '#00FF00'
+     * @param [style.dropShadowDistance=5] {number} Set a distance of the drop shadow
+     * @param [style.fill='black'] {string|string[]|number|number[]|CanvasGradient|CanvasPattern} A canvas fillstyle that will be used on the
+     *      text e.g 'red', '#00FF00'. Can be an array to create a gradient eg ['#000000','#FFFFFF'] @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle|MDN}
+     * @param [style.fillGradientType=PIXI.TEXT_GRADIENT.LINEAR_VERTICAL] {number} If fills styles are supplied, this can change the type/direction of the gradient. See {@link PIXI.TEXT_GRADIENT} for possible values
+     * @param [style.fontFamily='Arial'] {string} The font family
+     * @param [style.fontSize=26] {number|string} The font size (as a number it converts to px, but as a string, equivalents are '26px','20pt','160%' or '1.6em')
+     * @param [style.fontStyle='normal'] {string} The font style ('normal', 'italic' or 'oblique')
+     * @param [style.fontVariant='normal'] {string} The font variant ('normal' or 'small-caps')
+     * @param [style.fontWeight='normal'] {string} The font weight ('normal', 'bold', 'bolder', 'lighter' and '100', '200', '300', '400', '500', '600', '700', 800' or '900')
+     * @param [style.letterSpacing=0] {number} The amount of spacing between letters, default is 0
+     * @param [style.lineHeight] {number} The line height, a number that represents the vertical space that a letter uses
+     * @param [style.lineJoin='miter'] {string} The lineJoin property sets the type of corner created, it can resolve
+     *      spiked text issues. Default is 'miter' (creates a sharp corner).
+     * @param [style.miterLimit=10] {number} The miter limit to use when using the 'miter' lineJoin mode. This can reduce
+     *      or increase the spikiness of rendered text.
+     * @param [style.padding=0] {number} Occasionally some fonts are cropped on top or bottom. Adding some padding will
+     *      prevent this from happening by adding padding to the top and bottom of text height.
+     * @param [style.stroke='black'] {string|number} A canvas fillstyle that will be used on the text stroke e.g 'blue', '#FCFF00'
+     * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke)
+     * @param [style.textBaseline='alphabetic'] {string} The baseline of the text that is rendered.
+     * @param [style.wordWrap=false] {boolean} Indicates if word wrap should be used
+     * @param [style.wordWrapWidth=100] {number} The width at which text will wrap, it needs wordWrap to be set to true
+     */
+    function TextStyle(style)
+    {
+        this.styleID = 0;
+        Object.assign(this, this._defaults, style);
+    }
+
+    TextStyle.prototype.constructor = TextStyle;
+    module.exports = TextStyle;
+
+// Default settings. Explained in the constructor.
+    TextStyle.prototype._defaults = {
+        align: 'left',
+        breakWords: false,
+        dropShadow: false,
+        dropShadowAngle: Math.PI / 6,
+        dropShadowBlur: 0,
+        dropShadowColor: '#000000',
+        dropShadowDistance: 5,
+        fill: 'black',
+        fillGradientType: CONST.TEXT_GRADIENT.LINEAR_VERTICAL,
+        fontFamily: 'Arial',
+        fontSize: 26,
+        fontStyle: 'normal',
+        fontVariant: 'normal',
+        fontWeight: 'normal',
+        letterSpacing: 0,
+        lineHeight: 0,
+        lineJoin: 'miter',
+        miterLimit: 10,
+        padding: 0,
+        stroke: 'black',
+        strokeThickness: 0,
+        textBaseline: 'alphabetic',
+        wordWrap: false,
+        wordWrapWidth: 100
+    };
+
+    /**
+     * Creates a new TextStyle object with the same values as this one.
+     * Note that the only the properties of the object are cloned.
+     *
+     * @return {PIXI.TextStyle} New cloned TextStyle object
+     */
+    TextStyle.prototype.clone = function ()
+    {
+        var clonedProperties = {};
+        for (var key in this._defaults)
+        {
+            clonedProperties[key] = this[key];
+        }
+        return new TextStyle(clonedProperties);
+    };
+
+    /**
+     * Resets all properties to the defaults specified in TextStyle.prototype._default
+     */
+    TextStyle.prototype.reset = function ()
+    {
+        Object.assign(this, this._defaults);
+    };
+
+    /**
+     * Create setters and getters for each of the style properties. Converts colors where necessary.
+     */
+    Object.defineProperties(TextStyle.prototype, {
+        align: {
+            get: function ()
+            {
+                return this._align;
+            },
+            set: function (align)
+            {
+                if (this._align !== align)
+                {
+                    this._align = align;
+                    this.styleID++;
+                }
+            }
+        },
+
+        breakWords: {
+            get: function ()
+            {
+                return this._breakWords;
+            },
+            set: function (breakWords)
+            {
+                if (this._breakWords !== breakWords)
+                {
+                    this._breakWords = breakWords;
+                    this.styleID++;
+                }
+            }
+        },
+
+        dropShadow: {
+            get: function ()
+            {
+                return this._dropShadow;
+            },
+            set: function (dropShadow)
+            {
+                if (this._dropShadow !== dropShadow)
+                {
+                    this._dropShadow = dropShadow;
+                    this.styleID++;
+                }
+            }
+        },
+
+        dropShadowAngle: {
+            get: function ()
+            {
+                return this._dropShadowAngle;
+            },
+            set: function (dropShadowAngle)
+            {
+                if (this._dropShadowAngle !== dropShadowAngle)
+                {
+                    this._dropShadowAngle = dropShadowAngle;
+                    this.styleID++;
+                }
+            }
+        },
+
+        dropShadowBlur: {
+            get: function ()
+            {
+                return this._dropShadowBlur;
+            },
+            set: function (dropShadowBlur)
+            {
+                if (this._dropShadowBlur !== dropShadowBlur)
+                {
+                    this._dropShadowBlur = dropShadowBlur;
+                    this.styleID++;
+                }
+            }
+        },
+
+        dropShadowColor: {
+            get: function ()
+            {
+                return this._dropShadowColor;
+            },
+            set: function (dropShadowColor)
+            {
+                var outputColor = getColor(dropShadowColor);
+                if (this._dropShadowColor !== outputColor)
+                {
+                    this._dropShadowColor = outputColor;
+                    this.styleID++;
+                }
+            }
+        },
+
+        dropShadowDistance: {
+            get: function ()
+            {
+                return this._dropShadowDistance;
+            },
+            set: function (dropShadowDistance)
+            {
+                if (this._dropShadowDistance !== dropShadowDistance)
+                {
+                    this._dropShadowDistance = dropShadowDistance;
+                    this.styleID++;
+                }
+            }
+        },
+
+        fill: {
+            get: function ()
+            {
+                return this._fill;
+            },
+            set: function (fill)
+            {
+                var outputColor = getColor(fill);
+                if (this._fill !== outputColor)
+                {
+                    this._fill = outputColor;
+                    this.styleID++;
+                }
+            }
+        },
+
+        fillGradientType: {
+            get: function ()
+            {
+                return this._fillGradientType;
+            },
+            set: function (fillGradientType)
+            {
+                if (this._fillGradientType !== fillGradientType)
+                {
+                    this._fillGradientType = fillGradientType;
+                    this.styleID++;
+                }
+            }
+        },
+
+        fontFamily: {
+            get: function ()
+            {
+                return this._fontFamily;
+            },
+            set: function (fontFamily)
+            {
+                if (this.fontFamily !== fontFamily)
+                {
+                    this._fontFamily = fontFamily;
+                    this.styleID++;
+                }
+            }
+        },
+
+        fontSize: {
+            get: function ()
+            {
+                return this._fontSize;
+            },
+            set: function (fontSize)
+            {
+                if (this._fontSize !== fontSize)
+                {
+                    this._fontSize = fontSize;
+                    this.styleID++;
+                }
+            }
+        },
+
+        fontStyle: {
+            get: function ()
+            {
+                return this._fontStyle;
+            },
+            set: function (fontStyle)
+            {
+                if (this._fontStyle !== fontStyle)
+                {
+                    this._fontStyle = fontStyle;
+                    this.styleID++;
+                }
+            }
+        },
+
+        fontVariant: {
+            get: function ()
+            {
+                return this._fontVariant;
+            },
+            set: function (fontVariant)
+            {
+                if (this._fontVariant !== fontVariant)
+                {
+                    this._fontVariant = fontVariant;
+                    this.styleID++;
+                }
+            }
+        },
+
+        fontWeight: {
+            get: function ()
+            {
+                return this._fontWeight;
+            },
+            set: function (fontWeight)
+            {
+                if (this._fontWeight !== fontWeight)
+                {
+                    this._fontWeight = fontWeight;
+                    this.styleID++;
+                }
+            }
+        },
+
+        letterSpacing: {
+            get: function ()
+            {
+                return this._letterSpacing;
+            },
+            set: function (letterSpacing)
+            {
+                if (this._letterSpacing !== letterSpacing)
+                {
+                    this._letterSpacing = letterSpacing;
+                    this.styleID++;
+                }
+            }
+        },
+
+        lineHeight: {
+            get: function ()
+            {
+                return this._lineHeight;
+            },
+            set: function (lineHeight)
+            {
+                if (this._lineHeight !== lineHeight)
+                {
+                    this._lineHeight = lineHeight;
+                    this.styleID++;
+                }
+            }
+        },
+
+        lineJoin: {
+            get: function ()
+            {
+                return this._lineJoin;
+            },
+            set: function (lineJoin)
+            {
+                if (this._lineJoin !== lineJoin)
+                {
+                    this._lineJoin = lineJoin;
+                    this.styleID++;
+                }
+            }
+        },
+
+        miterLimit: {
+            get: function ()
+            {
+                return this._miterLimit;
+            },
+            set: function (miterLimit)
+            {
+                if (this._miterLimit !== miterLimit)
+                {
+                    this._miterLimit = miterLimit;
+                    this.styleID++;
+                }
+            }
+        },
+
+        padding: {
+            get: function ()
+            {
+                return this._padding;
+            },
+            set: function (padding)
+            {
+                if (this._padding !== padding)
+                {
+                    this._padding = padding;
+                    this.styleID++;
+                }
+            }
+        },
+
+        stroke: {
+            get: function ()
+            {
+                return this._stroke;
+            },
+            set: function (stroke)
+            {
+                var outputColor = getColor(stroke);
+                if (this._stroke !== outputColor)
+                {
+                    this._stroke = outputColor;
+                    this.styleID++;
+                }
+            }
+        },
+
+        strokeThickness: {
+            get: function ()
+            {
+                return this._strokeThickness;
+            },
+            set: function (strokeThickness)
+            {
+                if (this._strokeThickness !== strokeThickness)
+                {
+                    this._strokeThickness = strokeThickness;
+                    this.styleID++;
+                }
+            }
+        },
+
+        textBaseline: {
+            get: function ()
+            {
+                return this._textBaseline;
+            },
+            set: function (textBaseline)
+            {
+                if (this._textBaseline !== textBaseline)
+                {
+                    this._textBaseline = textBaseline;
+                    this.styleID++;
+                }
+            }
+        },
+
+        wordWrap: {
+            get: function ()
+            {
+                return this._wordWrap;
+            },
+            set: function (wordWrap)
+            {
+                if (this._wordWrap !== wordWrap)
+                {
+                    this._wordWrap = wordWrap;
+                    this.styleID++;
+                }
+            }
+        },
+
+        wordWrapWidth: {
+            get: function ()
+            {
+                return this._wordWrapWidth;
+            },
+            set: function (wordWrapWidth)
+            {
+                if (this._wordWrapWidth !== wordWrapWidth)
+                {
+                    this._wordWrapWidth = wordWrapWidth;
+                    this.styleID++;
+                }
+            }
+        }
+    });
+
+    /**
+     * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string.
+     *
+     * @return {string} The color as a string.
+     */
+    function getColor(color)
+    {
+        if (typeof color === 'number')
+        {
+            return utils.hex2string(color);
+        }
+        else if (Array.isArray(color))
+        {
+            for (var i = 0; i < color.length; ++i)
+            {
+                if (typeof color[i] === 'number')
+                {
+                    color[i] = utils.hex2string(color[i]);
+                }
+            }
+        }
+
+        return color;
+    }
+
+},{"../const":43,"../utils":116}],106:[function(require,module,exports){
+    var BaseTexture = require('./BaseTexture'),
+        CONST = require('../const');
+
+    /**
+     * A BaseRenderTexture is a special texture that allows any Pixi display object to be rendered to it.
+     *
+     * __Hint__: All DisplayObjects (i.e. Sprites) that render to a BaseRenderTexture should be preloaded
+     * otherwise black rectangles will be drawn instead.
+     *
+     * A BaseRenderTexture takes a snapshot of any Display Object given to its render method. The position
+     * and rotation of the given Display Objects is ignored. For example:
+     *
+     * ```js
+     * var renderer = PIXI.autoDetectRenderer(1024, 1024, { view: canvas, ratio: 1 });
+     * var BaserenderTexture = new PIXI.BaseRenderTexture(renderer, 800, 600);
+     * var sprite = PIXI.Sprite.fromImage("spinObj_01.png");
+     *
+     * sprite.position.x = 800/2;
+     * sprite.position.y = 600/2;
+     * sprite.anchor.x = 0.5;
+     * sprite.anchor.y = 0.5;
+     *
+     * BaserenderTexture.render(sprite);
+     * ```
+     *
+     * The Sprite in this case will be rendered to a position of 0,0. To render this sprite at its actual
+     * position a Container should be used:
+     *
+     * ```js
+     * var doc = new PIXI.Container();
+     *
+     * doc.addChild(sprite);
+     *
+     * var baseRenderTexture = new PIXI.BaserenderTexture(100, 100);
+     * var renderTexture = new PIXI.RenderTexture(baseRenderTexture);
+     *
+     * renderer.render(doc, renderTexture);  // Renders to center of RenderTexture
+     * ```
+     *
+     * @class
+     * @extends PIXI.BaseTexture
+     * @memberof PIXI
+     * @param [width=100] {number} The width of the base render texture
+     * @param [height=100] {number} The height of the base render texture
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @param [resolution=1] {number} The resolution / device pixel ratio of the texture being generated
+     */
+    function BaseRenderTexture(width, height, scaleMode, resolution)
+    {
+        BaseTexture.call(this, null, scaleMode);
+
+        this.resolution = resolution || CONST.RESOLUTION;
+
+        this.width = width || 100;
+        this.height = height || 100;
+
+        this.realWidth = this.width * this.resolution;
+        this.realHeight = this.height * this.resolution;
+
+        this.scaleMode = scaleMode || CONST.SCALE_MODES.DEFAULT;
+        this.hasLoaded = true;
+
+        /**
+         * A map of renderer IDs to webgl renderTargets
+         *
+         * @member {object<number, WebGLTexture>}
+         * @private
+         */
+        this._glRenderTargets = [];
+
+        /**
+         * A reference to the canvas render target (we only need one as this can be shared accross renderers)
+         *
+         * @member {object<number, WebGLTexture>}
+         * @private
+         */
+        this._canvasRenderTarget = null;
+
+        /**
+         * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered.
+         *
+         * @member {boolean}
+         */
+        this.valid = false;
+    }
+
+    BaseRenderTexture.prototype = Object.create(BaseTexture.prototype);
+    BaseRenderTexture.prototype.constructor = BaseRenderTexture;
+    module.exports = BaseRenderTexture;
+
+    /**
+     * Resizes the BaseRenderTexture.
+     *
+     * @param width {number} The width to resize to.
+     * @param height {number} The height to resize to.
+     */
+    BaseRenderTexture.prototype.resize = function (width, height)
+    {
+
+        if (width === this.width && height === this.height)
+        {
+            return;
+        }
+
+        this.valid = (width > 0 && height > 0);
+
+        this.width = width;
+        this.height = height;
+
+        this.realWidth = this.width * this.resolution;
+        this.realHeight = this.height * this.resolution;
+
+        if (!this.valid)
+        {
+            return;
+        }
+
+        this.emit('update', this);
+
+    };
+
+    /**
+     * Destroys this texture
+     *
+     */
+    BaseRenderTexture.prototype.destroy = function ()
+    {
+        BaseTexture.prototype.destroy.call(this, true);
+        this.renderer = null;
+    };
+
+
+},{"../const":43,"./BaseTexture":107}],107:[function(require,module,exports){
+    var utils = require('../utils'),
+        CONST = require('../const'),
+        EventEmitter = require('eventemitter3'),
+        determineCrossOrigin = require('../utils/determineCrossOrigin'),
+        bitTwiddle = require('bit-twiddle');
+
+    /**
+     * A texture stores the information that represents an image. All textures have a base texture.
+     *
+     * @class
+     * @memberof PIXI
+     * @param [source ]{HTMLImageElement|HTMLCanvasElement} the source object of the texture.
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @param [resolution=1] {number} The resolution / device pixel ratio of the texture
+     */
+    function BaseTexture(source, scaleMode, resolution)
+    {
+        EventEmitter.call(this);
+
+        this.uid = utils.uid();
+
+        this.touched = 0;
+
+        /**
+         * The resolution / device pixel ratio of the texture
+         *
+         * @member {number}
+         * @default 1
+         */
+        this.resolution = resolution || CONST.RESOLUTION;
+
+        /**
+         * The width of the base texture set when the image has loaded
+         *
+         * @member {number}
+         * @readonly
+         */
+        this.width = 100;
+
+        /**
+         * The height of the base texture set when the image has loaded
+         *
+         * @member {number}
+         * @readonly
+         */
+        this.height = 100;
+
+        // TODO docs
+        // used to store the actual dimensions of the source
+        /**
+         * Used to store the actual width of the source of this texture
+         *
+         * @member {number}
+         * @readonly
+         */
+        this.realWidth = 100;
+        /**
+         * Used to store the actual height of the source of this texture
+         *
+         * @member {number}
+         * @readonly
+         */
+        this.realHeight = 100;
+
+        /**
+         * The scale mode to apply when scaling this texture
+         *
+         * @member {number}
+         * @default PIXI.SCALE_MODES.DEFAULT
+         * @see PIXI.SCALE_MODES
+         */
+        this.scaleMode = scaleMode || CONST.SCALE_MODES.DEFAULT;
+
+        /**
+         * Set to true once the base texture has successfully loaded.
+         *
+         * This is never true if the underlying source fails to load or has no texture data.
+         *
+         * @member {boolean}
+         * @readonly
+         */
+        this.hasLoaded = false;
+
+        /**
+         * Set to true if the source is currently loading.
+         *
+         * If an Image source is loading the 'loaded' or 'error' event will be
+         * dispatched when the operation ends. An underyling source that is
+         * immediately-available bypasses loading entirely.
+         *
+         * @member {boolean}
+         * @readonly
+         */
+        this.isLoading = false;
+
+        /**
+         * The image source that is used to create the texture.
+         *
+         * TODO: Make this a setter that calls loadSource();
+         *
+         * @member {HTMLImageElement|HTMLCanvasElement}
+         * @readonly
+         */
+        this.source = null; // set in loadSource, if at all
+
+        /**
+         * Controls if RGB channels should be pre-multiplied by Alpha  (WebGL only)
+         * All blend modes, and shaders written for default value. Change it on your own risk.
+         *
+         * @member {boolean}
+         * @default true
+         */
+        this.premultipliedAlpha = true;
+
+        /**
+         * The image url of the texture
+         *
+         * @member {string}
+         */
+        this.imageUrl = null;
+
+        /**
+         * Wether or not the texture is a power of two, try to use power of two textures as much as you can
+         * @member {boolean}
+         * @private
+         */
+        this.isPowerOfTwo = false;
+
+        // used for webGL
+
+        /**
+         *
+         * Set this to true if a mipmap of this texture needs to be generated. This value needs to be set before the texture is used
+         * Also the texture must be a power of two size to work
+         *
+         * @member {boolean}
+         * @see PIXI.MIPMAP_TEXTURES
+         */
+        this.mipmap = CONST.MIPMAP_TEXTURES;
+
+        /**
+         *
+         * WebGL Texture wrap mode
+         *
+         * @member {number}
+         * @see PIXI.WRAP_MODES
+         */
+        this.wrapMode = CONST.WRAP_MODES.DEFAULT;
+
+        /**
+         * A map of renderer IDs to webgl textures
+         *
+         * @member {object<number, WebGLTexture>}
+         * @private
+         */
+        this._glTextures = [];
+        this._enabled = 0;
+        this._id = 0;
+
+        // if no source passed don't try to load
+        if (source)
+        {
+            this.loadSource(source);
+        }
+
+        /**
+         * Fired when a not-immediately-available source finishes loading.
+         *
+         * @event loaded
+         * @memberof PIXI.BaseTexture#
+         * @protected
+         */
+
+        /**
+         * Fired when a not-immediately-available source fails to load.
+         *
+         * @event error
+         * @memberof PIXI.BaseTexture#
+         * @protected
+         */
+    }
+
+    BaseTexture.prototype = Object.create(EventEmitter.prototype);
+    BaseTexture.prototype.constructor = BaseTexture;
+    module.exports = BaseTexture;
+
+    /**
+     * Updates the texture on all the webgl renderers, this also assumes the src has changed.
+     *
+     * @fires update
+     */
+    BaseTexture.prototype.update = function ()
+    {
+        this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width;
+        this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height;
+
+        this.width = this.realWidth / this.resolution;
+        this.height = this.realHeight / this.resolution;
+
+        this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight);
+
+        this.emit('update', this);
+    };
+
+    /**
+     * Load a source.
+     *
+     * If the source is not-immediately-available, such as an image that needs to be
+     * downloaded, then the 'loaded' or 'error' event will be dispatched in the future
+     * and `hasLoaded` will remain false after this call.
+     *
+     * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is:
+     *
+     *     if (texture.hasLoaded) {
+ *        // texture ready for use
+ *     } else if (texture.isLoading) {
+ *        // listen to 'loaded' and/or 'error' events on texture
+ *     } else {
+ *        // not loading, not going to load UNLESS the source is reloaded
+ *        // (it may still make sense to listen to the events)
+ *     }
+     *
+     * @protected
+     * @param source {HTMLImageElement|HTMLCanvasElement} the source object of the texture.
+     */
+    BaseTexture.prototype.loadSource = function (source)
+    {
+        var wasLoading = this.isLoading;
+        this.hasLoaded = false;
+        this.isLoading = false;
+
+        if (wasLoading && this.source)
+        {
+            this.source.onload = null;
+            this.source.onerror = null;
+        }
+
+        this.source = source;
+
+        // Apply source if loaded. Otherwise setup appropriate loading monitors.
+        if ((this.source.complete || this.source.getContext) && this.source.width && this.source.height)
+        {
+            this._sourceLoaded();
+        }
+        else if (!source.getContext)
+        {
+
+            // Image fail / not ready
+            this.isLoading = true;
+
+            var scope = this;
+
+            source.onload = function ()
+            {
+                source.onload = null;
+                source.onerror = null;
+
+                if (!scope.isLoading)
+                {
+                    return;
+                }
+
+                scope.isLoading = false;
+                scope._sourceLoaded();
+
+                scope.emit('loaded', scope);
+            };
+
+            source.onerror = function ()
+            {
+                source.onload = null;
+                source.onerror = null;
+
+                if (!scope.isLoading)
+                {
+                    return;
+                }
+
+                scope.isLoading = false;
+                scope.emit('error', scope);
+            };
+
+            // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element
+            //   "The value of `complete` can thus change while a script is executing."
+            // So complete needs to be re-checked after the callbacks have been added..
+            // NOTE: complete will be true if the image has no src so best to check if the src is set.
+            if (source.complete && source.src)
+            {
+                this.isLoading = false;
+
+                // ..and if we're complete now, no need for callbacks
+                source.onload = null;
+                source.onerror = null;
+
+                if (source.width && source.height)
+                {
+                    this._sourceLoaded();
+
+                    // If any previous subscribers possible
+                    if (wasLoading)
+                    {
+                        this.emit('loaded', this);
+                    }
+                }
+                else
+                {
+                    // If any previous subscribers possible
+                    if (wasLoading)
+                    {
+                        this.emit('error', this);
+                    }
+                }
+            }
+        }
+    };
+
+    /**
+     * Used internally to update the width, height, and some other tracking vars once
+     * a source has successfully loaded.
+     *
+     * @private
+     */
+    BaseTexture.prototype._sourceLoaded = function ()
+    {
+        this.hasLoaded = true;
+        this.update();
+    };
+
+    /**
+     * Destroys this base texture
+     *
+     */
+    BaseTexture.prototype.destroy = function ()
+    {
+        if (this.imageUrl)
+        {
+            delete utils.BaseTextureCache[this.imageUrl];
+            delete utils.TextureCache[this.imageUrl];
+
+            this.imageUrl = null;
+
+            if (!navigator.isCocoonJS)
+            {
+                this.source.src = '';
+            }
+        }
+        else if (this.source && this.source._pixiId)
+        {
+            delete utils.BaseTextureCache[this.source._pixiId];
+        }
+
+        this.source = null;
+
+        this.dispose();
+    };
+
+    /**
+     * Frees the texture from WebGL memory without destroying this texture object.
+     * This means you can still use the texture later which will upload it to GPU
+     * memory again.
+     *
+     */
+    BaseTexture.prototype.dispose = function ()
+    {
+        this.emit('dispose', this);
+
+        // this should no longer be needed, the renderers should cleanup all the gl textures.
+        // this._glTextures = {};
+    };
+
+    /**
+     * Changes the source image of the texture.
+     * The original source must be an Image element.
+     *
+     * @param newSrc {string} the path of the image
+     */
+    BaseTexture.prototype.updateSourceImage = function (newSrc)
+    {
+        this.source.src = newSrc;
+
+        this.loadSource(this.source);
+    };
+
+    /**
+     * Helper function that creates a base texture from the given image url.
+     * If the image is not in the base texture cache it will be created and loaded.
+     *
+     * @static
+     * @param imageUrl {string} The image url of the texture
+     * @param [crossorigin=(auto)] {boolean} Should use anonymous CORS? Defaults to true if the URL is not a data-URI.
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @return PIXI.BaseTexture
+     */
+    BaseTexture.fromImage = function (imageUrl, crossorigin, scaleMode)
+    {
+        var baseTexture = utils.BaseTextureCache[imageUrl];
+
+        if (!baseTexture)
+        {
+            // new Image() breaks tex loading in some versions of Chrome.
+            // See https://code.google.com/p/chromium/issues/detail?id=238071
+            var image = new Image();//document.createElement('img');
+
+
+            if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0)
+            {
+                image.crossOrigin = determineCrossOrigin(imageUrl);
+            }
+
+            baseTexture = new BaseTexture(image, scaleMode);
+            baseTexture.imageUrl = imageUrl;
+
+            image.src = imageUrl;
+
+            utils.BaseTextureCache[imageUrl] = baseTexture;
+
+            // if there is an @2x at the end of the url we are going to assume its a highres image
+            baseTexture.resolution = utils.getResolutionOfUrl(imageUrl);
+        }
+
+        return baseTexture;
+    };
+
+    /**
+     * Helper function that creates a base texture from the given canvas element.
+     *
+     * @static
+     * @param canvas {HTMLCanvasElement} The canvas element source of the texture
+     * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @return PIXI.BaseTexture
+     */
+    BaseTexture.fromCanvas = function (canvas, scaleMode)
+    {
+        if (!canvas._pixiId)
+        {
+            canvas._pixiId = 'canvas_' + utils.uid();
+        }
+
+        var baseTexture = utils.BaseTextureCache[canvas._pixiId];
+
+        if (!baseTexture)
+        {
+            baseTexture = new BaseTexture(canvas, scaleMode);
+            utils.BaseTextureCache[canvas._pixiId] = baseTexture;
+        }
+
+        return baseTexture;
+    };
+
+},{"../const":43,"../utils":116,"../utils/determineCrossOrigin":115,"bit-twiddle":1,"eventemitter3":3}],108:[function(require,module,exports){
+    var BaseRenderTexture = require('./BaseRenderTexture'),
+        Texture = require('./Texture');
+
+    /**
+     * A RenderTexture is a special texture that allows any Pixi display object to be rendered to it.
+     *
+     * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded
+     * otherwise black rectangles will be drawn instead.
+     *
+     * A RenderTexture takes a snapshot of any Display Object given to its render method. The position
+     * and rotation of the given Display Objects is ignored. For example:
+     *
+     * ```js
+     * var renderer = PIXI.autoDetectRenderer(1024, 1024, { view: canvas, ratio: 1 });
+     * var renderTexture = PIXI.RenderTexture.create(800, 600);
+     * var sprite = PIXI.Sprite.fromImage("spinObj_01.png");
+     *
+     * sprite.position.x = 800/2;
+     * sprite.position.y = 600/2;
+     * sprite.anchor.x = 0.5;
+     * sprite.anchor.y = 0.5;
+     *
+     * renderer.render(sprite, renderTexture);
+     * ```
+     *
+     * The Sprite in this case will be rendered to a position of 0,0. To render this sprite at its actual
+     * position a Container should be used:
+     *
+     * ```js
+     * var doc = new PIXI.Container();
+     *
+     * doc.addChild(sprite);
+     *
+     * renderer.render(doc, renderTexture);  // Renders to center of renderTexture
+     * ```
+     *
+     * @class
+     * @extends PIXI.Texture
+     * @memberof PIXI
+     * @param baseRenderTexture {PIXI.BaseRenderTexture} The renderer used for this RenderTexture
+     * @param [frame] {PIXI.Rectangle} The rectangle frame of the texture to show
+     */
+    function RenderTexture(baseRenderTexture, frame)
+    {
+        // suport for legacy..
+        this.legacyRenderer = null;
+
+        if( !(baseRenderTexture instanceof BaseRenderTexture) )
+        {
+            var width = arguments[1];
+            var height = arguments[2];
+            var scaleMode = arguments[3] || 0;
+            var resolution = arguments[4] || 1;
+
+            // we have an old render texture..
+            console.warn('v4 RenderTexture now expects a new BaseRenderTexture. Please use RenderTexture.create('+width+', '+height+')');  // jshint ignore:line
+            this.legacyRenderer = arguments[0];
+
+            frame = null;
+            baseRenderTexture = new BaseRenderTexture(width, height, scaleMode, resolution);
+        }
+
+
+        /**
+         * The base texture object that this texture uses
+         *
+         * @member {BaseTexture}
+         */
+        Texture.call(this,
+            baseRenderTexture,
+            frame
+        );
+
+        /**
+         * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered.
+         *
+         * @member {boolean}
+         */
+        this.valid = true;
+
+        this._updateUvs();
+    }
+
+    RenderTexture.prototype = Object.create(Texture.prototype);
+    RenderTexture.prototype.constructor = RenderTexture;
+    module.exports = RenderTexture;
+
+    /**
+     * Resizes the RenderTexture.
+     *
+     * @param width {number} The width to resize to.
+     * @param height {number} The height to resize to.
+     * @param doNotResizeBaseTexture {boolean} Should the baseTexture.width and height values be resized as well?
+     */
+    RenderTexture.prototype.resize = function (width, height, doNotResizeBaseTexture)
+    {
+
+        //TODO - could be not required..
+        this.valid = (width > 0 && height > 0);
+
+        this._frame.width = this.orig.width = width;
+        this._frame.height = this.orig.height = height;
+
+        if (!doNotResizeBaseTexture)
+        {
+            this.baseTexture.resize(width, height);
+        }
+
+        this._updateUvs();
+    };
+
+    /**
+     * A short hand way of creating a render texture..
+     * @param [width=100] {number} The width of the render texture
+     * @param [height=100] {number} The height of the render texture
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @param [resolution=1] {number} The resolution / device pixel ratio of the texture being generated
+     */
+    RenderTexture.create = function(width, height, scaleMode, resolution)
+    {
+        return new RenderTexture(new BaseRenderTexture(width, height, scaleMode, resolution));
+    };
+
+},{"./BaseRenderTexture":106,"./Texture":109}],109:[function(require,module,exports){
+    var BaseTexture = require('./BaseTexture'),
+        VideoBaseTexture = require('./VideoBaseTexture'),
+        TextureUvs = require('./TextureUvs'),
+        EventEmitter = require('eventemitter3'),
+        math = require('../math'),
+        utils = require('../utils');
+
+    /**
+     * A texture stores the information that represents an image or part of an image. It cannot be added
+     * to the display list directly. Instead use it as the texture for a Sprite. If no frame is provided then the whole image is used.
+     *
+     * You can directly create a texture from an image and then reuse it multiple times like this :
+     *
+     * ```js
+     * var texture = PIXI.Texture.fromImage('assets/image.png');
+     * var sprite1 = new PIXI.Sprite(texture);
+     * var sprite2 = new PIXI.Sprite(texture);
+     * ```
+     *
+     * @class
+     * @memberof PIXI
+     * @param baseTexture {PIXI.BaseTexture} The base texture source to create the texture from
+     * @param [frame] {PIXI.Rectangle} The rectangle frame of the texture to show
+     * @param [orig] {PIXI.Rectangle} The area of original texture
+     * @param [trim] {PIXI.Rectangle} Trimmed rectangle of original texture
+     * @param [rotate] {number} indicates how the texture was rotated by texture packer. See {@link PIXI.GroupD8}
+     */
+    function Texture(baseTexture, frame, orig, trim, rotate)
+    {
+        EventEmitter.call(this);
+
+        /**
+         * Does this Texture have any frame data assigned to it?
+         *
+         * @member {boolean}
+         */
+        this.noFrame = false;
+
+        if (!frame)
+        {
+            this.noFrame = true;
+            frame = new math.Rectangle(0, 0, 1, 1);
+        }
+
+        if (baseTexture instanceof Texture)
+        {
+            baseTexture = baseTexture.baseTexture;
+        }
+
+        /**
+         * The base texture that this texture uses.
+         *
+         * @member {PIXI.BaseTexture}
+         */
+        this.baseTexture = baseTexture;
+
+        /**
+         * This is the area of the BaseTexture image to actually copy to the Canvas / WebGL when rendering,
+         * irrespective of the actual frame size or placement (which can be influenced by trimmed texture atlases)
+         *
+         * @member {PIXI.Rectangle}
+         */
+        this._frame = frame;
+
+        /**
+         * This is the trimmed area of original texture, before it was put in atlas
+         *
+         * @member {PIXI.Rectangle}
+         */
+        this.trim = trim;
+
+        /**
+         * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered.
+         *
+         * @member {boolean}
+         */
+        this.valid = false;
+
+        /**
+         * This will let a renderer know that a texture has been updated (used mainly for webGL uv updates)
+         *
+         * @member {boolean}
+         */
+        this.requiresUpdate = false;
+
+        /**
+         * The WebGL UV data cache.
+         *
+         * @member {PIXI.TextureUvs}
+         * @private
+         */
+        this._uvs = null;
+
+        /**
+         * This is the area of original texture, before it was put in atlas
+         *
+         * @member {PIXI.Rectangle}
+         */
+        this.orig = orig || frame;//new math.Rectangle(0, 0, 1, 1);
+
+        this._rotate = +(rotate || 0);
+
+        if (rotate === true) {
+            // this is old texturepacker legacy, some games/libraries are passing "true" for rotated textures
+            this._rotate = 2;
+        } else {
+            if (this._rotate % 2 !== 0) {
+                throw 'attempt to use diamond-shaped UVs. If you are sure, set rotation manually';
+            }
+        }
+
+        if (baseTexture.hasLoaded)
+        {
+            if (this.noFrame)
+            {
+                frame = new math.Rectangle(0, 0, baseTexture.width, baseTexture.height);
+
+                // if there is no frame we should monitor for any base texture changes..
+                baseTexture.on('update', this.onBaseTextureUpdated, this);
+            }
+            this.frame = frame;
+        }
+        else
+        {
+            baseTexture.once('loaded', this.onBaseTextureLoaded, this);
+        }
+
+        /**
+         * Fired when the texture is updated. This happens if the frame or the baseTexture is updated.
+         *
+         * @event update
+         * @memberof PIXI.Texture#
+         * @protected
+         */
+
+
+        this._updateID = 0;
+    }
+
+    Texture.prototype = Object.create(EventEmitter.prototype);
+    Texture.prototype.constructor = Texture;
+    module.exports = Texture;
+
+    Object.defineProperties(Texture.prototype, {
+        /**
+         * The frame specifies the region of the base texture that this texture uses.
+         *
+         * @member {PIXI.Rectangle}
+         * @memberof PIXI.Texture#
+         */
+        frame: {
+            get: function ()
+            {
+                return this._frame;
+            },
+            set: function (frame)
+            {
+                this._frame = frame;
+
+                this.noFrame = false;
+
+                if (frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height)
+                {
+                    throw new Error('Texture Error: frame does not fit inside the base Texture dimensions ' + this);
+                }
+
+                //this.valid = frame && frame.width && frame.height && this.baseTexture.source && this.baseTexture.hasLoaded;
+                this.valid = frame && frame.width && frame.height && this.baseTexture.hasLoaded;
+
+                if (!this.trim && !this.rotate)
+                {
+                    this.orig = frame;
+                }
+
+                if (this.valid)
+                {
+                    this._updateUvs();
+                }
+            }
+        },
+        /**
+         * Indicates whether the texture is rotated inside the atlas
+         * set to 2 to compensate for texture packer rotation
+         * set to 6 to compensate for spine packer rotation
+         * can be used to rotate or mirror sprites
+         * See {@link PIXI.GroupD8} for explanation
+         *
+         * @member {number}
+         */
+        rotate: {
+            get: function ()
+            {
+                return this._rotate;
+            },
+            set: function (rotate)
+            {
+                this._rotate = rotate;
+                if (this.valid)
+                {
+                    this._updateUvs();
+                }
+            }
+        },
+
+        /**
+         * The width of the Texture in pixels.
+         *
+         * @member {number}
+         */
+        width: {
+            get: function() {
+                return this.orig ? this.orig.width : 0;
+            }
+        },
+
+        /**
+         * The height of the Texture in pixels.
+         *
+         * @member {number}
+         */
+        height: {
+            get: function() {
+                return this.orig ? this.orig.height : 0;
+            }
+        }
+    });
+
+    /**
+     * Updates this texture on the gpu.
+     *
+     */
+    Texture.prototype.update = function ()
+    {
+        this.baseTexture.update();
+    };
+
+    /**
+     * Called when the base texture is loaded
+     *
+     * @private
+     */
+    Texture.prototype.onBaseTextureLoaded = function (baseTexture)
+    {
+        this._updateID++;
+
+        // TODO this code looks confusing.. boo to abusing getters and setterss!
+        if (this.noFrame)
+        {
+            this.frame = new math.Rectangle(0, 0, baseTexture.width, baseTexture.height);
+        }
+        else
+        {
+            this.frame = this._frame;
+        }
+
+        this.baseTexture.on('update', this.onBaseTextureUpdated, this);
+        this.emit('update', this);
+
+    };
+
+    /**
+     * Called when the base texture is updated
+     *
+     * @private
+     */
+    Texture.prototype.onBaseTextureUpdated = function (baseTexture)
+    {
+        this._updateID++;
+
+        this._frame.width = baseTexture.width;
+        this._frame.height = baseTexture.height;
+
+        this.emit('update', this);
+    };
+
+    /**
+     * Destroys this texture
+     *
+     * @param [destroyBase=false] {boolean} Whether to destroy the base texture as well
+     */
+    Texture.prototype.destroy = function (destroyBase)
+    {
+        if (this.baseTexture)
+        {
+
+            if (destroyBase)
+            {
+                // delete the texture if it exists in the texture cache..
+                // this only needs to be removed if the base texture is actually destoryed too..
+                if(utils.TextureCache[this.baseTexture.imageUrl])
+                {
+                    delete utils.TextureCache[this.baseTexture.imageUrl];
+                }
+
+                this.baseTexture.destroy();
+            }
+
+            this.baseTexture.off('update', this.onBaseTextureUpdated, this);
+            this.baseTexture.off('loaded', this.onBaseTextureLoaded, this);
+
+            this.baseTexture = null;
+        }
+
+        this._frame = null;
+        this._uvs = null;
+        this.trim = null;
+        this.orig = null;
+
+        this.valid = false;
+
+        this.off('dispose', this.dispose, this);
+        this.off('update', this.update, this);
+    };
+
+    /**
+     * Creates a new texture object that acts the same as this one.
+     *
+     * @return {PIXI.Texture}
+     */
+    Texture.prototype.clone = function ()
+    {
+        return new Texture(this.baseTexture, this.frame, this.orig, this.trim, this.rotate);
+    };
+
+    /**
+     * Updates the internal WebGL UV cache.
+     *
+     * @protected
+     */
+    Texture.prototype._updateUvs = function ()
+    {
+        if (!this._uvs)
+        {
+            this._uvs = new TextureUvs();
+        }
+
+        this._uvs.set(this._frame, this.baseTexture, this.rotate);
+
+        this._updateID++;
+    };
+
+    /**
+     * Helper function that creates a Texture object from the given image url.
+     * If the image is not in the texture cache it will be  created and loaded.
+     *
+     * @static
+     * @param imageUrl {string} The image url of the texture
+     * @param [crossorigin] {boolean} Whether requests should be treated as crossorigin
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @return {PIXI.Texture} The newly created texture
+     */
+    Texture.fromImage = function (imageUrl, crossorigin, scaleMode)
+    {
+        var texture = utils.TextureCache[imageUrl];
+
+        if (!texture)
+        {
+            texture = new Texture(BaseTexture.fromImage(imageUrl, crossorigin, scaleMode));
+            utils.TextureCache[imageUrl] = texture;
+        }
+
+        return texture;
+    };
+
+    /**
+     * Helper function that creates a sprite that will contain a texture from the TextureCache based on the frameId
+     * The frame ids are created when a Texture packer file has been loaded
+     *
+     * @static
+     * @param frameId {string} The frame Id of the texture in the cache
+     * @return {PIXI.Texture} The newly created texture
+     */
+    Texture.fromFrame = function (frameId)
+    {
+        var texture = utils.TextureCache[frameId];
+
+        if (!texture)
+        {
+            throw new Error('The frameId "' + frameId + '" does not exist in the texture cache');
+        }
+
+        return texture;
+    };
+
+    /**
+     * Helper function that creates a new Texture based on the given canvas element.
+     *
+     * @static
+     * @param canvas {HTMLCanvasElement} The canvas element source of the texture
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @return {PIXI.Texture} The newly created texture
+     */
+    Texture.fromCanvas = function (canvas, scaleMode)
+    {
+        return new Texture(BaseTexture.fromCanvas(canvas, scaleMode));
+    };
+
+    /**
+     * Helper function that creates a new Texture based on the given video element.
+     *
+     * @static
+     * @param video {HTMLVideoElement|string} The URL or actual element of the video
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @return {PIXI.Texture} The newly created texture
+     */
+    Texture.fromVideo = function (video, scaleMode)
+    {
+        if (typeof video === 'string')
+        {
+            return Texture.fromVideoUrl(video, scaleMode);
+        }
+        else
+        {
+            return new Texture(VideoBaseTexture.fromVideo(video, scaleMode));
+        }
+    };
+
+    /**
+     * Helper function that creates a new Texture based on the video url.
+     *
+     * @static
+     * @param videoUrl {string} URL of the video
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @return {PIXI.Texture} The newly created texture
+     */
+    Texture.fromVideoUrl = function (videoUrl, scaleMode)
+    {
+        return new Texture(VideoBaseTexture.fromUrl(videoUrl, scaleMode));
+    };
+
+    /**
+     * Helper function that creates a new Texture based on the source you provide.
+     * The soucre can be - frame id, image url, video url, canvae element, video element, base texture
+     *
+     * @static
+     * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from
+     * @return {PIXI.Texture} The newly created texture
+     */
+    Texture.from = function (source)
+    {
+        //TODO auto detect cross origin..
+        //TODO pass in scale mode?
+        if(typeof source === 'string')
+        {
+            var texture = utils.TextureCache[source];
+
+            if (!texture)
+            {
+                // check if its a video..
+                var isVideo = source.match(/\.(mp4|webm|ogg|h264|avi|mov)$/) !== null;
+                if(isVideo)
+                {
+                    return Texture.fromVideoUrl(source);
+                }
+
+                return Texture.fromImage(source);
+            }
+
+            return texture;
+        }
+        else if(source instanceof HTMLCanvasElement)
+        {
+            return Texture.fromCanvas(source);
+        }
+        else if(source instanceof HTMLVideoElement)
+        {
+            return Texture.fromVideo(source);
+        }
+        else if(source instanceof BaseTexture)
+        {
+            return new Texture(BaseTexture);
+        }
+        else
+        {
+            // lets assume its a texture!
+            return source;
+        }
+    };
+
+
+    /**
+     * Adds a texture to the global utils.TextureCache. This cache is shared across the whole PIXI object.
+     *
+     * @static
+     * @param texture {PIXI.Texture} The Texture to add to the cache.
+     * @param id {string} The id that the texture will be stored against.
+     */
+    Texture.addTextureToCache = function (texture, id)
+    {
+        utils.TextureCache[id] = texture;
+    };
+
+    /**
+     * Remove a texture from the global utils.TextureCache.
+     *
+     * @static
+     * @param id {string} The id of the texture to be removed
+     * @return {PIXI.Texture} The texture that was removed
+     */
+    Texture.removeTextureFromCache = function (id)
+    {
+        var texture = utils.TextureCache[id];
+
+        delete utils.TextureCache[id];
+        delete utils.BaseTextureCache[id];
+
+        return texture;
+    };
+
+    /**
+     * An empty texture, used often to not have to create multiple empty textures.
+     * Can not be destroyed.
+     *
+     * @static
+     * @constant
+     */
+    Texture.EMPTY = new Texture(new BaseTexture());
+    Texture.EMPTY.destroy = function() {};
+    Texture.EMPTY.on = function() {};
+    Texture.EMPTY.once = function() {};
+    Texture.EMPTY.emit = function() {};
+
+
+},{"../math":67,"../utils":116,"./BaseTexture":107,"./TextureUvs":110,"./VideoBaseTexture":111,"eventemitter3":3}],110:[function(require,module,exports){
+
+    /**
+     * A standard object to store the Uvs of a texture
+     *
+     * @class
+     * @private
+     * @memberof PIXI
+     */
+    function TextureUvs()
+    {
+        this.x0 = 0;
+        this.y0 = 0;
+
+        this.x1 = 1;
+        this.y1 = 0;
+
+        this.x2 = 1;
+        this.y2 = 1;
+
+        this.x3 = 0;
+        this.y3 = 1;
+
+        this.uvsUint32 = new Uint32Array(4);
+    }
+
+    module.exports = TextureUvs;
+
+    var GroupD8 = require('../math/GroupD8');
+
+    /**
+     * Sets the texture Uvs based on the given frame information
+     * @param frame {PIXI.Rectangle}
+     * @param baseFrame {PIXI.Rectangle}
+     * @param rotate {number} Rotation of frame, see {@link PIXI.GroupD8}
+     * @private
+     */
+    TextureUvs.prototype.set = function (frame, baseFrame, rotate)
+    {
+        var tw = baseFrame.width;
+        var th = baseFrame.height;
+
+        if(rotate)
+        {
+            //width and height div 2 div baseFrame size
+            var w2 = frame.width / 2 / tw;
+            var h2 = frame.height / 2 / th;
+            //coordinates of center
+            var cX = frame.x / tw + w2;
+            var cY = frame.y / th + h2;
+            rotate = GroupD8.add(rotate, GroupD8.NW); //NW is top-left corner
+            this.x0 = cX + w2 * GroupD8.uX(rotate);
+            this.y0 = cY + h2 * GroupD8.uY(rotate);
+            rotate = GroupD8.add(rotate, 2); //rotate 90 degrees clockwise
+            this.x1 = cX + w2 * GroupD8.uX(rotate);
+            this.y1 = cY + h2 * GroupD8.uY(rotate);
+            rotate = GroupD8.add(rotate, 2);
+            this.x2 = cX + w2 * GroupD8.uX(rotate);
+            this.y2 = cY + h2 * GroupD8.uY(rotate);
+            rotate = GroupD8.add(rotate, 2);
+            this.x3 = cX + w2 * GroupD8.uX(rotate);
+            this.y3 = cY + h2 * GroupD8.uY(rotate);
+        }
+        else
+        {
+
+            this.x0 = frame.x / tw;
+            this.y0 = frame.y / th;
+
+            this.x1 = (frame.x + frame.width) / tw;
+            this.y1 = frame.y / th;
+
+            this.x2 = (frame.x + frame.width) / tw;
+            this.y2 = (frame.y + frame.height) / th;
+
+            this.x3 = frame.x / tw;
+            this.y3 = (frame.y + frame.height) / th;
+        }
+
+        this.uvsUint32[0] = (((this.y0 * 65535) & 0xFFFF) << 16) | ((this.x0 * 65535) & 0xFFFF);
+        this.uvsUint32[1] = (((this.y1 * 65535) & 0xFFFF) << 16) | ((this.x1 * 65535) & 0xFFFF);
+        this.uvsUint32[2] = (((this.y2 * 65535) & 0xFFFF) << 16) | ((this.x2 * 65535) & 0xFFFF);
+        this.uvsUint32[3] = (((this.y3 * 65535) & 0xFFFF) << 16) | ((this.x3 * 65535) & 0xFFFF);
+    };
+
+},{"../math/GroupD8":63}],111:[function(require,module,exports){
+    var BaseTexture = require('./BaseTexture'),
+        utils = require('../utils');
+
+    /**
+     * A texture of a [playing] Video.
+     *
+     * Video base textures mimic Pixi BaseTexture.from.... method in their creation process.
+     *
+     * This can be used in several ways, such as:
+     *
+     * ```js
+     * var texture = PIXI.VideoBaseTexture.fromUrl('http://mydomain.com/video.mp4');
+     *
+     * var texture = PIXI.VideoBaseTexture.fromUrl({ src: 'http://mydomain.com/video.mp4', mime: 'video/mp4' });
+     *
+     * var texture = PIXI.VideoBaseTexture.fromUrls(['/video.webm', '/video.mp4']);
+     *
+     * var texture = PIXI.VideoBaseTexture.fromUrls([
+     *     { src: '/video.webm', mime: 'video/webm' },
+     *     { src: '/video.mp4', mime: 'video/mp4' }
+     * ]);
+     * ```
+     *
+     * See the ["deus" demo](http://www.goodboydigital.com/pixijs/examples/deus/).
+     *
+     * @class
+     * @extends PIXI.BaseTexture
+     * @memberof PIXI
+     * @param source {HTMLVideoElement} Video source
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values
+     */
+    function VideoBaseTexture(source, scaleMode)
+    {
+        if (!source)
+        {
+            throw new Error('No video source element specified.');
+        }
+
+        // hook in here to check if video is already available.
+        // BaseTexture looks for a source.complete boolean, plus width & height.
+
+        if ((source.readyState === source.HAVE_ENOUGH_DATA || source.readyState === source.HAVE_FUTURE_DATA) && source.width && source.height)
+        {
+            source.complete = true;
+        }
+
+        BaseTexture.call(this, source, scaleMode);
+
+        /**
+         * Should the base texture automatically update itself, set to true by default
+         *
+         * @member {boolean}
+         * @default true
+         */
+        this.autoUpdate = false;
+
+        this._onUpdate = this._onUpdate.bind(this);
+        this._onCanPlay = this._onCanPlay.bind(this);
+
+        if (!source.complete)
+        {
+            source.addEventListener('canplay', this._onCanPlay);
+            source.addEventListener('canplaythrough', this._onCanPlay);
+
+            // started playing..
+            source.addEventListener('play', this._onPlayStart.bind(this));
+            source.addEventListener('pause', this._onPlayStop.bind(this));
+        }
+
+        this.__loaded = false;
+    }
+
+    VideoBaseTexture.prototype = Object.create(BaseTexture.prototype);
+    VideoBaseTexture.prototype.constructor = VideoBaseTexture;
+    module.exports = VideoBaseTexture;
+
+    /**
+     * The internal update loop of the video base texture, only runs when autoUpdate is set to true
+     *
+     * @private
+     */
+    VideoBaseTexture.prototype._onUpdate = function ()
+    {
+        if (this.autoUpdate)
+        {
+            window.requestAnimationFrame(this._onUpdate);
+            this.update();
+        }
+    };
+
+    /**
+     * Runs the update loop when the video is ready to play
+     *
+     * @private
+     */
+    VideoBaseTexture.prototype._onPlayStart = function ()
+    {
+        // Just in case the video has not recieved its can play even yet..
+        if(!this.hasLoaded)
+        {
+            this._onCanPlay();
+        }
+
+        if (!this.autoUpdate)
+        {
+            window.requestAnimationFrame(this._onUpdate);
+            this.autoUpdate = true;
+        }
+    };
+
+    /**
+     * Fired when a pause event is triggered, stops the update loop
+     *
+     * @private
+     */
+    VideoBaseTexture.prototype._onPlayStop = function ()
+    {
+        this.autoUpdate = false;
+    };
+
+    /**
+     * Fired when the video is loaded and ready to play
+     *
+     * @private
+     */
+    VideoBaseTexture.prototype._onCanPlay = function ()
+    {
+        this.hasLoaded = true;
+
+        if (this.source)
+        {
+            this.source.removeEventListener('canplay', this._onCanPlay);
+            this.source.removeEventListener('canplaythrough', this._onCanPlay);
+
+            this.width = this.source.videoWidth;
+            this.height = this.source.videoHeight;
+
+            this.source.play();
+
+            // prevent multiple loaded dispatches..
+            if (!this.__loaded)
+            {
+                this.__loaded = true;
+                this.emit('loaded', this);
+            }
+        }
+    };
+
+    /**
+     * Destroys this texture
+     *
+     */
+    VideoBaseTexture.prototype.destroy = function ()
+    {
+        if (this.source && this.source._pixiId)
+        {
+            delete utils.BaseTextureCache[ this.source._pixiId ];
+            delete this.source._pixiId;
+        }
+
+        BaseTexture.prototype.destroy.call(this);
+    };
+
+    /**
+     * Mimic Pixi BaseTexture.from.... method.
+     *
+     * @static
+     * @param video {HTMLVideoElement} Video to create texture from
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @return {PIXI.VideoBaseTexture} Newly created VideoBaseTexture
+     */
+    VideoBaseTexture.fromVideo = function (video, scaleMode)
+    {
+        if (!video._pixiId)
+        {
+            video._pixiId = 'video_' + utils.uid();
+        }
+
+        var baseTexture = utils.BaseTextureCache[video._pixiId];
+
+        if (!baseTexture)
+        {
+            baseTexture = new VideoBaseTexture(video, scaleMode);
+            utils.BaseTextureCache[ video._pixiId ] = baseTexture;
+        }
+
+        return baseTexture;
+    };
+
+    /**
+     * Helper function that creates a new BaseTexture based on the given video element.
+     * This BaseTexture can then be used to create a texture
+     *
+     * @static
+     * @param videoSrc {string|object|string[]|object[]} The URL(s) for the video.
+     * @param [videoSrc.src] {string} One of the source urls for the video
+     * @param [videoSrc.mime] {string} The mimetype of the video (e.g. 'video/mp4'). If not specified
+     *  the url's extension will be used as the second part of the mime type.
+     * @param scaleMode {number} See {@link PIXI.SCALE_MODES} for possible values
+     * @return {PIXI.VideoBaseTexture} Newly created VideoBaseTexture
+     */
+    VideoBaseTexture.fromUrl = function (videoSrc, scaleMode)
+    {
+        var video = document.createElement('video');
+
+        // array of objects or strings
+        if (Array.isArray(videoSrc))
+        {
+            for (var i = 0; i < videoSrc.length; ++i)
+            {
+                video.appendChild(createSource(videoSrc[i].src || videoSrc[i], videoSrc[i].mime));
+            }
+        }
+        // single object or string
+        else
+        {
+            video.appendChild(createSource(videoSrc.src || videoSrc, videoSrc.mime));
+        }
+
+        video.load();
+        video.play();
+
+        return VideoBaseTexture.fromVideo(video, scaleMode);
+    };
+
+    VideoBaseTexture.fromUrls = VideoBaseTexture.fromUrl;
+
+    function createSource(path, type)
+    {
+        if (!type)
+        {
+            type = 'video/' + path.substr(path.lastIndexOf('.') + 1);
+        }
+
+        var source = document.createElement('source');
+
+        source.src = path;
+        source.type = type;
+
+        return source;
+    }
+
+},{"../utils":116,"./BaseTexture":107}],112:[function(require,module,exports){
+    var CONST = require('../const'),
+        EventEmitter = require('eventemitter3'),
+    // Internal event used by composed emitter
+        TICK = 'tick';
+
+    /**
+     * A Ticker class that runs an update loop that other objects listen to.
+     * This class is composed around an EventEmitter object to add listeners
+     * meant for execution on the next requested animation frame.
+     * Animation frames are requested only when necessary,
+     * e.g. When the ticker is started and the emitter has listeners.
+     *
+     * @class
+     * @memberof PIXI.ticker
+     */
+    function Ticker()
+    {
+        var _this = this;
+
+        /**
+         * Internal tick method bound to ticker instance.
+         * This is because in early 2015, Function.bind
+         * is still 60% slower in high performance scenarios.
+         * Also separating frame requests from update method
+         * so listeners may be called at any time and with
+         * any animation API, just invoke ticker.update(time).
+         *
+         * @private
+         */
+        this._tick = function _tick(time) {
+
+            _this._requestId = null;
+
+            if (_this.started)
+            {
+                // Invoke listeners now
+                _this.update(time);
+                // Listener side effects may have modified ticker state.
+                if (_this.started && _this._requestId === null && _this._emitter.listeners(TICK, true))
+                {
+                    _this._requestId = requestAnimationFrame(_this._tick);
+                }
+            }
+        };
+
+        /**
+         * Internal emitter used to fire 'tick' event
+         * @private
+         */
+        this._emitter = new EventEmitter();
+
+        /**
+         * Internal current frame request ID
+         * @private
+         */
+        this._requestId = null;
+
+        /**
+         * Internal value managed by minFPS property setter and getter.
+         * This is the maximum allowed milliseconds between updates.
+         * @private
+         */
+        this._maxElapsedMS = 100;
+
+        /**
+         * Whether or not this ticker should invoke the method
+         * {@link PIXI.ticker.Ticker#start} automatically
+         * when a listener is added.
+         *
+         * @member {boolean}
+         * @default false
+         */
+        this.autoStart = false;
+
+        /**
+         * Scalar time value from last frame to this frame.
+         * This value is capped by setting {@link PIXI.ticker.Ticker#minFPS}
+         * and is scaled with {@link PIXI.ticker.Ticker#speed}.
+         * **Note:** The cap may be exceeded by scaling.
+         *
+         * @member {number}
+         * @default 1
+         */
+        this.deltaTime = 1;
+
+        /**
+         * Time elapsed in milliseconds from last frame to this frame.
+         * Opposed to what the scalar {@link PIXI.ticker.Ticker#deltaTime}
+         * is based, this value is neither capped nor scaled.
+         * If the platform supports DOMHighResTimeStamp,
+         * this value will have a precision of 1 µs.
+         *
+         * @member {number}
+         * @default 1 / TARGET_FPMS
+         */
+        this.elapsedMS = 1 / CONST.TARGET_FPMS; // default to target frame time
+
+        /**
+         * The last time {@link PIXI.ticker.Ticker#update} was invoked.
+         * This value is also reset internally outside of invoking
+         * update, but only when a new animation frame is requested.
+         * If the platform supports DOMHighResTimeStamp,
+         * this value will have a precision of 1 µs.
+         *
+         * @member {number}
+         * @default 0
+         */
+        this.lastTime = 0;
+
+        /**
+         * Factor of current {@link PIXI.ticker.Ticker#deltaTime}.
+         * @example
+         * // Scales ticker.deltaTime to what would be
+         * // the equivalent of approximately 120 FPS
+         * ticker.speed = 2;
+         *
+         * @member {number}
+         * @default 1
+         */
+        this.speed = 1;
+
+        /**
+         * Whether or not this ticker has been started.
+         * `true` if {@link PIXI.ticker.Ticker#start} has been called.
+         * `false` if {@link PIXI.ticker.Ticker#stop} has been called.
+         * While `false`, this value may change to `true` in the
+         * event of {@link PIXI.ticker.Ticker#autoStart} being `true`
+         * and a listener is added.
+         *
+         * @member {boolean}
+         * @default false
+         */
+        this.started = false;
+    }
+
+    Object.defineProperties(Ticker.prototype, {
+        /**
+         * The frames per second at which this ticker is running.
+         * The default is approximately 60 in most modern browsers.
+         * **Note:** This does not factor in the value of
+         * {@link PIXI.ticker.Ticker#speed}, which is specific
+         * to scaling {@link PIXI.ticker.Ticker#deltaTime}.
+         *
+         * @memberof PIXI.ticker.Ticker#
+         * @readonly
+         */
+        FPS: {
+            get: function()
+            {
+                return 1000 / this.elapsedMS;
+            }
+        },
+
+        /**
+         * Manages the maximum amount of milliseconds allowed to
+         * elapse between invoking {@link PIXI.ticker.Ticker#update}.
+         * This value is used to cap {@link PIXI.ticker.Ticker#deltaTime},
+         * but does not effect the measured value of {@link PIXI.ticker.Ticker#FPS}.
+         * When setting this property it is clamped to a value between
+         * `0` and `PIXI.TARGET_FPMS * 1000`.
+         *
+         * @memberof PIXI.ticker.Ticker#
+         * @default 10
+         */
+        minFPS: {
+            get: function()
+            {
+                return 1000 / this._maxElapsedMS;
+            },
+            set: function(fps)
+            {
+                // Clamp: 0 to TARGET_FPMS
+                var minFPMS = Math.min(Math.max(0, fps) / 1000, CONST.TARGET_FPMS);
+                this._maxElapsedMS = 1 / minFPMS;
+            }
+        }
+    });
+
+    /**
+     * Conditionally requests a new animation frame.
+     * If a frame has not already been requested, and if the internal
+     * emitter has listeners, a new frame is requested.
+     *
+     * @private
+     */
+    Ticker.prototype._requestIfNeeded = function _requestIfNeeded()
+    {
+        if (this._requestId === null && this._emitter.listeners(TICK, true))
+        {
+            // ensure callbacks get correct delta
+            this.lastTime = performance.now();
+            this._requestId = requestAnimationFrame(this._tick);
+        }
+    };
+
+    /**
+     * Conditionally cancels a pending animation frame.
+     *
+     * @private
+     */
+    Ticker.prototype._cancelIfNeeded = function _cancelIfNeeded()
+    {
+        if (this._requestId !== null)
+        {
+            cancelAnimationFrame(this._requestId);
+            this._requestId = null;
+        }
+    };
+
+    /**
+     * Conditionally requests a new animation frame.
+     * If the ticker has been started it checks if a frame has not already
+     * been requested, and if the internal emitter has listeners. If these
+     * conditions are met, a new frame is requested. If the ticker has not
+     * been started, but autoStart is `true`, then the ticker starts now,
+     * and continues with the previous conditions to request a new frame.
+     *
+     * @private
+     */
+    Ticker.prototype._startIfPossible = function _startIfPossible()
+    {
+        if (this.started)
+        {
+            this._requestIfNeeded();
+        }
+        else if (this.autoStart)
+        {
+            this.start();
+        }
+    };
+
+    /**
+     * Calls {@link module:eventemitter3.EventEmitter#on} internally for the
+     * internal 'tick' event. It checks if the emitter has listeners,
+     * and if so it requests a new animation frame at this point.
+     *
+     * @param fn {Function} The listener function to be added for updates
+     * @param [context] {Function} The listener context
+     * @returns {PIXI.ticker.Ticker} This instance of a ticker
+     */
+    Ticker.prototype.add = function add(fn, context)
+    {
+        this._emitter.on(TICK, fn, context);
+
+        this._startIfPossible();
+
+        return this;
+    };
+
+    /**
+     * Calls {@link module:eventemitter3.EventEmitter#once} internally for the
+     * internal 'tick' event. It checks if the emitter has listeners,
+     * and if so it requests a new animation frame at this point.
+     *
+     * @param fn {Function} The listener function to be added for one update
+     * @param [context] {Function} The listener context
+     * @returns {PIXI.ticker.Ticker} This instance of a ticker
+     */
+    Ticker.prototype.addOnce = function addOnce(fn, context)
+    {
+        this._emitter.once(TICK, fn, context);
+
+        this._startIfPossible();
+
+        return this;
+    };
+
+    /**
+     * Calls {@link module:eventemitter3.EventEmitter#off} internally for 'tick' event.
+     * It checks if the emitter has listeners for 'tick' event.
+     * If it does, then it cancels the animation frame.
+     *
+     * @param [fn] {Function} The listener function to be removed
+     * @param [context] {Function} The listener context to be removed
+     * @returns {PIXI.ticker.Ticker} This instance of a ticker
+     */
+    Ticker.prototype.remove = function remove(fn, context)
+    {
+        this._emitter.off(TICK, fn, context);
+
+        if (!this._emitter.listeners(TICK, true))
+        {
+            this._cancelIfNeeded();
+        }
+
+        return this;
+    };
+
+    /**
+     * Starts the ticker. If the ticker has listeners
+     * a new animation frame is requested at this point.
+     */
+    Ticker.prototype.start = function start()
+    {
+        if (!this.started)
+        {
+            this.started = true;
+            this._requestIfNeeded();
+        }
+    };
+
+    /**
+     * Stops the ticker. If the ticker has requested
+     * an animation frame it is canceled at this point.
+     */
+    Ticker.prototype.stop = function stop()
+    {
+        if (this.started)
+        {
+            this.started = false;
+            this._cancelIfNeeded();
+        }
+    };
+
+    /**
+     * Triggers an update. An update entails setting the
+     * current {@link PIXI.ticker.Ticker#elapsedMS},
+     * the current {@link PIXI.ticker.Ticker#deltaTime},
+     * invoking all listeners with current deltaTime,
+     * and then finally setting {@link PIXI.ticker.Ticker#lastTime}
+     * with the value of currentTime that was provided.
+     * This method will be called automatically by animation
+     * frame callbacks if the ticker instance has been started
+     * and listeners are added.
+     *
+     * @param [currentTime=performance.now()] {number} the current time of execution
+     */
+    Ticker.prototype.update = function update(currentTime)
+    {
+        var elapsedMS;
+
+        // Allow calling update directly with default currentTime.
+        currentTime = currentTime || performance.now();
+
+        // If the difference in time is zero or negative, we ignore most of the work done here.
+        // If there is no valid difference, then should be no reason to let anyone know about it.
+        // A zero delta, is exactly that, nothing should update.
+        //
+        // The difference in time can be negative, and no this does not mean time traveling.
+        // This can be the result of a race condition between when an animation frame is requested
+        // on the current JavaScript engine event loop, and when the ticker's start method is invoked
+        // (which invokes the internal _requestIfNeeded method). If a frame is requested before
+        // _requestIfNeeded is invoked, then the callback for the animation frame the ticker requests,
+        // can receive a time argument that can be less than the lastTime value that was set within
+        // _requestIfNeeded. This difference is in microseconds, but this is enough to cause problems.
+        //
+        // This check covers this browser engine timing issue, as well as if consumers pass an invalid
+        // currentTime value. This may happen if consumers opt-out of the autoStart, and update themselves.
+
+        if (currentTime > this.lastTime)
+        {
+            // Save uncapped elapsedMS for measurement
+            elapsedMS = this.elapsedMS = currentTime - this.lastTime;
+
+            // cap the milliseconds elapsed used for deltaTime
+            if (elapsedMS > this._maxElapsedMS)
+            {
+                elapsedMS = this._maxElapsedMS;
+            }
+
+            this.deltaTime = elapsedMS * CONST.TARGET_FPMS * this.speed;
+
+            // Invoke listeners added to internal emitter
+            this._emitter.emit(TICK, this.deltaTime);
+        }
+        else
+        {
+            this.deltaTime = this.elapsedMS = 0;
+        }
+
+        this.lastTime = currentTime;
+    };
+
+    module.exports = Ticker;
+
+},{"../const":43,"eventemitter3":3}],113:[function(require,module,exports){
+    var Ticker = require('./Ticker');
+
+    /**
+     * The shared ticker instance used by {@link PIXI.extras.MovieClip}.
+     * and by {@link PIXI.interaction.InteractionManager}.
+     * The property {@link PIXI.ticker.Ticker#autoStart} is set to `true`
+     * for this instance. Please follow the examples for usage, including
+     * how to opt-out of auto-starting the shared ticker.
+     *
+     * @example
+     * var ticker = PIXI.ticker.shared;
+     * // Set this to prevent starting this ticker when listeners are added.
+     * // By default this is true only for the PIXI.ticker.shared instance.
+     * ticker.autoStart = false;
+     * // FYI, call this to ensure the ticker is stopped. It should be stopped
+     * // if you have not attempted to render anything yet.
+     * ticker.stop();
+     * // Call this when you are ready for a running shared ticker.
+     * ticker.start();
+     *
+     * @example
+     * // You may use the shared ticker to render...
+     * var renderer = PIXI.autoDetectRenderer(800, 600);
+     * var stage = new PIXI.Container();
+     * var interactionManager = PIXI.interaction.InteractionManager(renderer);
+     * document.body.appendChild(renderer.view);
+     * ticker.add(function (time) {
+ *     renderer.render(stage);
+ * });
+     *
+     * @example
+     * // Or you can just update it manually.
+     * ticker.autoStart = false;
+     * ticker.stop();
+     * function animate(time) {
+ *     ticker.update(time);
+ *     renderer.render(stage);
+ *     requestAnimationFrame(animate);
+ * }
+     * animate(performance.now());
+     *
+     * @type {PIXI.ticker.Ticker}
+     * @memberof PIXI.ticker
+     */
+    var shared = new Ticker();
+    shared.autoStart = true;
+
+    /**
+     * @namespace PIXI.ticker
+     */
+    module.exports = {
+        shared: shared,
+        Ticker: Ticker
+    };
+
+},{"./Ticker":112}],114:[function(require,module,exports){
+    /**
+     * Generic Mask Stack data structure
+     * @class
+     * @memberof PIXI
+     * @param size {number} Number of quads
+     * @return {Uint16Array} indices
+     */
+    var createIndicesForQuads = function (size)
+    {
+        // the total number of indices in our array, there are 6 points per quad.
+
+        var totalIndices = size * 6;
+
+        var indices = new Uint16Array(totalIndices);
+
+        // fill the indices with the quads to draw
+        for (var i=0, j=0; i < totalIndices; i += 6, j += 4)
+        {
+            indices[i + 0] = j + 0;
+            indices[i + 1] = j + 1;
+            indices[i + 2] = j + 2;
+            indices[i + 3] = j + 0;
+            indices[i + 4] = j + 2;
+            indices[i + 5] = j + 3;
+        }
+
+        return indices;
+    };
+
+    module.exports = createIndicesForQuads;
+
+},{}],115:[function(require,module,exports){
+    var tempAnchor;
+    var _url = require('url');
+
+    /**
+     * Sets the `crossOrigin` property for this resource based on if the url
+     * for this resource is cross-origin. If crossOrigin was manually set, this
+     * function does nothing.
+     * Nipped from the resource loader!
+     * @private
+     * @param url {string} The url to test.
+     * @param loc [location=window.location] {object} The location object to test against.
+     * @return {string} The crossOrigin value to use (or empty string for none).
+     */
+    var determineCrossOrigin = function (url, loc) {
+        // data: and javascript: urls are considered same-origin
+        if (url.indexOf('data:') === 0) {
+            return '';
+        }
+
+        // default is window.location
+        loc = loc || window.location;
+
+        if (!tempAnchor) {
+            tempAnchor = document.createElement('a');
+        }
+
+        // let the browser determine the full href for the url of this resource and then
+        // parse with the node url lib, we can't use the properties of the anchor element
+        // because they don't work in IE9 :(
+        tempAnchor.href = url;
+        url = _url.parse(tempAnchor.href);
+
+        var samePort = (!url.port && loc.port === '') || (url.port === loc.port);
+
+        // if cross origin
+        if (url.hostname !== loc.hostname || !samePort || url.protocol !== loc.protocol) {
+            return 'anonymous';
+        }
+
+        return '';
+    };
+
+    module.exports = determineCrossOrigin;
+
+},{"url":28}],116:[function(require,module,exports){
+    var CONST = require('../const');
+
+    /**
+     * @namespace PIXI.utils
+     */
+    var utils = module.exports = {
+        _uid: 0,
+        _saidHello: false,
+
+        EventEmitter:   require('eventemitter3'),
+        pluginTarget:   require('./pluginTarget'),
+
+        /**
+         * Gets the next unique identifier
+         *
+         * @memberof PIXI.utils
+         * @return {number} The next unique identifier to use.
+         */
+        uid: function ()
+        {
+            return ++utils._uid;
+        },
+
+        /**
+         * Converts a hex color number to an [R, G, B] array
+         *
+         * @memberof PIXI.utils
+         * @param hex {number}
+         * @param  {number[]} [out=[]] If supplied, this array will be used rather than returning a new one
+         * @return {number[]} An array representing the [R, G, B] of the color.
+         */
+        hex2rgb: function (hex, out)
+        {
+            out = out || [];
+
+            out[0] = (hex >> 16 & 0xFF) / 255;
+            out[1] = (hex >> 8 & 0xFF) / 255;
+            out[2] = (hex & 0xFF) / 255;
+
+            return out;
+        },
+
+        /**
+         * Converts a hex color number to a string.
+         *
+         * @memberof PIXI.utils
+         * @param hex {number} Number in hex
+         * @return {string} The string color.
+         */
+        hex2string: function (hex)
+        {
+            hex = hex.toString(16);
+            hex = '000000'.substr(0, 6 - hex.length) + hex;
+
+            return '#' + hex;
+        },
+
+        /**
+         * Converts a color as an [R, G, B] array to a hex number
+         *
+         * @memberof PIXI.utils
+         * @param rgb {number[]} rgb array
+         * @return {number} The color number
+         */
+        rgb2hex: function (rgb)
+        {
+            return ((rgb[0]*255 << 16) + (rgb[1]*255 << 8) + rgb[2]*255);
+        },
+
+
+        /**
+         * get the resolution / device pixel ratio of an asset by looking for the prefix
+         * used by spritesheets and image urls
+         *
+         * @memberof PIXI.utils
+         * @param url {string} the image path
+         * @return {number} resolution / device pixel ratio of an asset
+         */
+        getResolutionOfUrl: function (url)
+        {
+            var resolution = CONST.RETINA_PREFIX.exec(url);
+
+            if (resolution)
+            {
+                return parseFloat(resolution[1]);
+            }
+
+            return 1;
+        },
+
+        /**
+         * Logs out the version and renderer information for this running instance of PIXI.
+         * If you don't want to see this message you can set `PIXI.utils._saidHello = true;`
+         * so the library thinks it already said it. Keep in mind that doing that will forever
+         * makes you a jerk face.
+         *
+         * @memberof PIXI.utils
+         * @param {string} type - The string renderer type to log.
+         * @constant
+         * @static
+         */
+        sayHello: function (type)
+        {
+            if (utils._saidHello)
+            {
+                return;
+            }
+
+            if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1)
+            {
+                var args = [
+                    '\n %c %c %c Pixi.js ' + CONST.VERSION + ' - ✰ ' + type + ' ✰  %c ' + ' %c ' + ' http://www.pixijs.com/  %c %c ♥%c♥%c♥ \n\n',
+                    'background: #ff66a5; padding:5px 0;',
+                    'background: #ff66a5; padding:5px 0;',
+                    'color: #ff66a5; background: #030307; padding:5px 0;',
+                    'background: #ff66a5; padding:5px 0;',
+                    'background: #ffc3dc; padding:5px 0;',
+                    'background: #ff66a5; padding:5px 0;',
+                    'color: #ff2424; background: #fff; padding:5px 0;',
+                    'color: #ff2424; background: #fff; padding:5px 0;',
+                    'color: #ff2424; background: #fff; padding:5px 0;'
+                ];
+
+                window.console.log.apply(console, args); //jshint ignore:line
+            }
+            else if (window.console)
+            {
+                window.console.log('Pixi.js ' + CONST.VERSION + ' - ' + type + ' - http://www.pixijs.com/'); //jshint ignore:line
+            }
+
+            utils._saidHello = true;
+        },
+
+        /**
+         * Helper for checking for webgl support
+         *
+         * @memberof PIXI.utils
+         * @return {boolean} is webgl supported
+         */
+        isWebGLSupported: function ()
+        {
+            var contextOptions = { stencil: true, failIfMajorPerformanceCaveat: true };
+            try
+            {
+                if (!window.WebGLRenderingContext)
+                {
+                    return false;
+                }
+
+                var canvas = document.createElement('canvas'),
+                    gl = canvas.getContext('webgl', contextOptions) || canvas.getContext('experimental-webgl', contextOptions);
+
+                var success = !!(gl && gl.getContextAttributes().stencil);
+                if (gl)
+                {
+                    var loseContext = gl.getExtension('WEBGL_lose_context');
+
+                    if(loseContext)
+                    {
+                        loseContext.loseContext();
+                    }
+                }
+                gl = null;
+
+                return success;
+            }
+            catch (e)
+            {
+                return false;
+            }
+        },
+
+        /**
+         * Returns sign of number
+         *
+         * @memberof PIXI.utils
+         * @param n {number}
+         * @returns {number} 0 if n is 0, -1 if n is negative, 1 if n i positive
+         */
+        sign: function (n)
+        {
+            return n ? (n < 0 ? -1 : 1) : 0;
+        },
+
+        /**
+         * Remove a range of items from an array
+         *
+         * @memberof PIXI.utils
+         * @param {Array<*>} arr The target array
+         * @param {number} startIdx The index to begin removing from (inclusive)
+         * @param {number} removeCount How many items to remove
+         */
+        removeItems: function (arr, startIdx, removeCount)
+        {
+            var length = arr.length;
+
+            if (startIdx >= length || removeCount === 0)
+            {
+                return;
+            }
+
+            removeCount = (startIdx+removeCount > length ? length-startIdx : removeCount);
+            for (var i = startIdx, len = length-removeCount; i < len; ++i)
+            {
+                arr[i] = arr[i + removeCount];
+            }
+
+            arr.length = len;
+        },
+
+        /**
+         * @todo Describe property usage
+         *
+         * @memberof PIXI.utils
+         * @private
+         */
+        TextureCache: {},
+
+        /**
+         * @todo Describe property usage
+         *
+         * @memberof PIXI.utils
+         * @private
+         */
+        BaseTextureCache: {}
+    };
+
+},{"../const":43,"./pluginTarget":118,"eventemitter3":3}],117:[function(require,module,exports){
+
+
+    var  Device = require('ismobilejs');
+
+    var maxRecommendedTextures = function(max)
+    {
+
+        if(Device.tablet || Device.phone)
+        {
+            // check if the res is iphone 6 or higher..
+            return 2;
+        }
+        else
+        {
+            // desktop should be ok
+            return max;
+        }
+    };
+
+    module.exports = maxRecommendedTextures;
+},{"ismobilejs":4}],118:[function(require,module,exports){
+    /**
+     * Mixins functionality to make an object have "plugins".
+     *
+     * @mixin
+     * @memberof PIXI.utils
+     * @param obj {object} The object to mix into.
+     * @example
+     *      function MyObject() {}
+     *
+     *      pluginTarget.mixin(MyObject);
+     */
+    function pluginTarget(obj)
+    {
+        obj.__plugins = {};
+
+        /**
+         * Adds a plugin to an object
+         *
+         * @param pluginName {string} The events that should be listed.
+         * @param ctor {Function} The constructor function for the plugin.
+         */
+        obj.registerPlugin = function (pluginName, ctor)
+        {
+            obj.__plugins[pluginName] = ctor;
+        };
+
+        /**
+         * Instantiates all the plugins of this object
+         *
+         */
+        obj.prototype.initPlugins = function ()
+        {
+            this.plugins = this.plugins || {};
+
+            for (var o in obj.__plugins)
+            {
+                this.plugins[o] = new (obj.__plugins[o])(this);
+            }
+        };
+
+        /**
+         * Removes all the plugins of this object
+         *
+         */
+        obj.prototype.destroyPlugins = function ()
+        {
+            for (var o in this.plugins)
+            {
+                this.plugins[o].destroy();
+                this.plugins[o] = null;
+            }
+
+            this.plugins = null;
+        };
+    }
+
+
+    module.exports = {
+        /**
+         * Mixes in the properties of the pluginTarget into another object
+         *
+         * @param obj {object} The obj to mix into
+         */
+        mixin: function mixin(obj)
+        {
+            pluginTarget(obj);
+        }
+    };
+
+},{}],119:[function(require,module,exports){
+    /*global console */
+    var core = require('./core'),
+        mesh = require('./mesh'),
+        particles = require('./particles'),
+        extras = require('./extras'),
+        filters = require('./filters');
+
+// provide method to give a stack track for warnings
+// useful for tracking-down where deprecated methods/properties/classes
+// are being used within the code
+    function warn(msg) {
+        var stack = new Error().stack;
+
+        // Handle IE < 10 and Safari < 6
+        if (typeof stack === 'undefined') {
+            console.warn('Deprecation Warning: ', msg);
+        }
+        else {
+            // chop off the stack trace which includes pixi.js internal calls
+            stack = stack.split('\n').splice(3).join('\n');
+
+            if (console.groupCollapsed) {
+                console.groupCollapsed('%cDeprecation Warning: %c%s', 'color:#614108;background:#fffbe6', 'font-weight:normal;color:#614108;background:#fffbe6', msg);
+                console.warn(stack);
+                console.groupEnd();
+            }
+            else {
+                console.warn('Deprecation Warning: ', msg);
+                console.warn(stack);
+            }
+        }
+    }
+
+    /**
+     * @class
+     * @private
+     * @name SpriteBatch
+     * @memberof PIXI
+     * @see PIXI.ParticleContainer
+     * @throws {ReferenceError} SpriteBatch does not exist any more, please use the new ParticleContainer instead.
+     * @deprecated since version 3.0.0
+     */
+    core.SpriteBatch = function()
+    {
+        throw new ReferenceError('SpriteBatch does not exist any more, please use the new ParticleContainer instead.');
+    };
+
+    /**
+     * @class
+     * @private
+     * @name AssetLoader
+     * @memberof PIXI
+     * @see PIXI.loaders.Loader
+     * @throws {ReferenceError} The loader system was overhauled in pixi v3, please see the new PIXI.loaders.Loader class.
+     * @deprecated since version 3.0.0
+     */
+    core.AssetLoader = function()
+    {
+        throw new ReferenceError('The loader system was overhauled in pixi v3, please see the new PIXI.loaders.Loader class.');
+    };
+
+    Object.defineProperties(core, {
+
+        /**
+         * @class
+         * @private
+         * @name Stage
+         * @memberof PIXI
+         * @see PIXI.Container
+         * @deprecated since version 3.0.0
+         */
+        Stage: {
+            get: function()
+            {
+                warn('You do not need to use a PIXI Stage any more, you can simply render any container.');
+                return core.Container;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name DisplayObjectContainer
+         * @memberof PIXI
+         * @see PIXI.Container
+         * @deprecated since version 3.0.0
+         */
+        DisplayObjectContainer: {
+            get: function()
+            {
+                warn('DisplayObjectContainer has been shortened to Container, please use Container from now on.');
+                return core.Container;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name Strip
+         * @memberof PIXI
+         * @see PIXI.mesh.Mesh
+         * @deprecated since version 3.0.0
+         */
+        Strip: {
+            get: function()
+            {
+                warn('The Strip class has been renamed to Mesh and moved to mesh.Mesh, please use mesh.Mesh from now on.');
+                return mesh.Mesh;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name Rope
+         * @memberof PIXI
+         * @see PIXI.mesh.Rope
+         * @deprecated since version 3.0.0
+         */
+        Rope: {
+            get: function()
+            {
+                warn('The Rope class has been moved to mesh.Rope, please use mesh.Rope from now on.');
+                return mesh.Rope;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name ParticleContainer
+         * @memberof PIXI
+         * @see PIXI.particles.ParticleContainer
+         * @deprecated since version 4.0.0
+         */
+        ParticleContainer: {
+            get: function() {
+                warn('The ParticleContainer class has been moved to particles.ParticleContainer, please use particles.ParticleContainer from now on.');
+                return particles.ParticleContainer;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name MovieClip
+         * @memberof PIXI
+         * @see PIXI.extras.MovieClip
+         * @deprecated since version 3.0.0
+         */
+        MovieClip: {
+            get: function()
+            {
+                warn('The MovieClip class has been moved to extras.MovieClip, please use extras.MovieClip from now on.');
+                return extras.MovieClip;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name TilingSprite
+         * @memberof PIXI
+         * @see PIXI.extras.TilingSprite
+         * @deprecated since version 3.0.0
+         */
+        TilingSprite: {
+            get: function()
+            {
+                warn('The TilingSprite class has been moved to extras.TilingSprite, please use extras.TilingSprite from now on.');
+                return extras.TilingSprite;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name BitmapText
+         * @memberof PIXI
+         * @see PIXI.extras.BitmapText
+         * @deprecated since version 3.0.0
+         */
+        BitmapText: {
+            get: function()
+            {
+                warn('The BitmapText class has been moved to extras.BitmapText, please use extras.BitmapText from now on.');
+                return extras.BitmapText;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name blendModes
+         * @memberof PIXI
+         * @see PIXI.BLEND_MODES
+         * @deprecated since version 3.0.0
+         */
+        blendModes: {
+            get: function()
+            {
+                warn('The blendModes has been moved to BLEND_MODES, please use BLEND_MODES from now on.');
+                return core.BLEND_MODES;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name scaleModes
+         * @memberof PIXI
+         * @see PIXI.SCALE_MODES
+         * @deprecated since version 3.0.0
+         */
+        scaleModes: {
+            get: function()
+            {
+                warn('The scaleModes has been moved to SCALE_MODES, please use SCALE_MODES from now on.');
+                return core.SCALE_MODES;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name BaseTextureCache
+         * @memberof PIXI
+         * @see PIXI.utils.BaseTextureCache
+         * @deprecated since version 3.0.0
+         */
+        BaseTextureCache: {
+            get: function ()
+            {
+                warn('The BaseTextureCache class has been moved to utils.BaseTextureCache, please use utils.BaseTextureCache from now on.');
+                return core.utils.BaseTextureCache;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name TextureCache
+         * @memberof PIXI
+         * @see PIXI.utils.TextureCache
+         * @deprecated since version 3.0.0
+         */
+        TextureCache: {
+            get: function ()
+            {
+                warn('The TextureCache class has been moved to utils.TextureCache, please use utils.TextureCache from now on.');
+                return core.utils.TextureCache;
+            }
+        },
+
+        /**
+         * @namespace
+         * @private
+         * @name math
+         * @memberof PIXI
+         * @see PIXI
+         * @deprecated since version 3.0.6
+         */
+        math: {
+            get: function ()
+            {
+                warn('The math namespace is deprecated, please access members already accessible on PIXI.');
+                return core;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name PIXI.AbstractFilter
+         * @see PIXI.Filter
+         * @deprecated since version 3.0.6
+         */
+        AbstractFilter: {
+            get: function()
+            {
+                warn('AstractFilter has been renamed to Filter, please use PIXI.Filter');
+                return core.Filter;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name PIXI.TransformManual
+         * @see PIXI.TransformBase
+         * @deprecated since version 4.0.0
+         */
+        TransformManual: {
+            get: function()
+            {
+                warn('TransformManual has been renamed to TransformBase, please update your pixi-spine');
+                return core.TransformBase;
+            }
+        }
+    });
+
+    core.DisplayObject.prototype.generateTexture = function(renderer, scaleMode, resolution)
+    {
+        warn('generateTexture has moved to the renderer, please use renderer.generateTexture(displayObject)');
+        return renderer.generateTexture(this, scaleMode, resolution);
+    };
+
+
+    core.Graphics.prototype.generateTexture = function(scaleMode, resolution)
+    {
+        warn('graphics generate texture has moved to the renderer. Or to render a graphics to a texture using canvas please use generateCanvasTexture');
+        return this.generateCanvasTexture(scaleMode, resolution);
+    };
+
+    core.RenderTexture.prototype.render = function(displayObject, matrix, clear, updateTransform)
+    {
+        this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
+        warn('RenderTexture.render is now deprecated, please use renderer.render(displayObject, renderTexture)');
+    };
+
+    core.RenderTexture.prototype.getImage = function(target)
+    {
+        warn('RenderTexture.getImage is now deprecated, please use renderer.extract.image(target)');
+        return this.legacyRenderer.extract.image(target);
+    };
+
+    core.RenderTexture.prototype.getBase64 = function(target)
+    {
+        warn('RenderTexture.getBase64 is now deprecated, please use renderer.extract.base64(target)');
+        return this.legacyRenderer.extract.base64(target);
+    };
+
+    core.RenderTexture.prototype.getCanvas = function(target)
+    {
+        warn('RenderTexture.getCanvas is now deprecated, please use renderer.extract.canvas(target)');
+        return this.legacyRenderer.extract.canvas(target);
+    };
+
+    core.RenderTexture.prototype.getPixels = function(target)
+    {
+        warn('RenderTexture.getPixels is now deprecated, please use renderer.extract.pixels(target)');
+        return this.legacyRenderer.pixels(target);
+    };
+
+
+
+    /**
+     * @method
+     * @private
+     * @name PIXI.Sprite#setTexture
+     * @see PIXI.Sprite#texture
+     * @deprecated since version 3.0.0
+     */
+    core.Sprite.prototype.setTexture = function(texture)
+    {
+        this.texture = texture;
+        warn('setTexture is now deprecated, please use the texture property, e.g : sprite.texture = texture;');
+    };
+
+
+
+    /**
+     * @method
+     * @name PIXI.extras.BitmapText#setText
+     * @see PIXI.extras.BitmapText#text
+     * @deprecated since version 3.0.0
+     */
+    extras.BitmapText.prototype.setText = function(text)
+    {
+        this.text = text;
+        warn('setText is now deprecated, please use the text property, e.g : myBitmapText.text = \'my text\';');
+    };
+
+    /**
+     * @method
+     * @name PIXI.Text#setText
+     * @see PIXI.Text#text
+     * @deprecated since version 3.0.0
+     */
+    core.Text.prototype.setText = function(text)
+    {
+        this.text = text;
+        warn('setText is now deprecated, please use the text property, e.g : myText.text = \'my text\';');
+    };
+
+    /**
+     * @method
+     * @name PIXI.Text#setStyle
+     * @see PIXI.Text#style
+     * @deprecated since version 3.0.0
+     */
+    core.Text.prototype.setStyle = function(style)
+    {
+        this.style = style;
+        warn('setStyle is now deprecated, please use the style property, e.g : myText.style = style;');
+    };
+
+    Object.defineProperties(core.TextStyle.prototype, {
+        /**
+         * Set all properties of a font as a single string
+         *
+         * @name PIXI.TextStyle#font
+         * @deprecated since version 4.0.0
+         */
+        font: {
+            get: function ()
+            {
+                warn('text style property \'font\' is now deprecated, please use the \'fontFamily\',\'fontSize\',fontStyle\',\'fontVariant\' and \'fontWeight\' properties from now on');
+                var fontSizeString = (typeof this._fontSize === 'number') ? this._fontSize + 'px' : this._fontSize;
+                return this._fontStyle + ' ' + this._fontVariant + ' ' + this._fontWeight + ' ' + fontSizeString + ' ' + this._fontFamily;
+            },
+            set: function (font)
+            {
+                warn('text style property \'font\' is now deprecated, please use the \'fontFamily\',\'fontSize\',fontStyle\',\'fontVariant\' and \'fontWeight\' properties from now on');
+
+                // can work out fontStyle from search of whole string
+                if ( font.indexOf('italic') > 1 )
+                {
+                    this._fontStyle = 'italic';
+                }
+                else if ( font.indexOf('oblique') > -1 )
+                {
+                    this._fontStyle = 'oblique';
+                }
+                else
+                {
+                    this._fontStyle = 'normal';
+                }
+
+                // can work out fontVariant from search of whole string
+                if ( font.indexOf('small-caps') > -1 )
+                {
+                    this._fontVariant = 'small-caps';
+                }
+                else
+                {
+                    this._fontVariant = 'normal';
+                }
+
+                // fontWeight and fontFamily are tricker to find, but it's easier to find the fontSize due to it's units
+                var splits = font.split(' ');
+                var i;
+                var fontSizeIndex = -1;
+
+                this._fontSize = 26;
+                for ( i = 0; i < splits.length; ++i )
+                {
+                    if ( splits[i].match( /(px|pt|em|%)/ ) )
+                    {
+                        fontSizeIndex = i;
+                        this._fontSize = splits[i];
+                        break;
+                    }
+                }
+
+                // we can now search for fontWeight as we know it must occur before the fontSize
+                this._fontWeight = 'normal';
+                for ( i = 0; i < fontSizeIndex; ++i )
+                {
+                    if ( splits[i].match( /(bold|bolder|lighter|100|200|300|400|500|600|700|800|900)/ ) )
+                    {
+                        this._fontWeight = splits[i];
+                        break;
+                    }
+                }
+
+                // and finally join everything together after the fontSize in case the font family has multiple words
+                if ( fontSizeIndex > -1 && fontSizeIndex < splits.length-1 )
+                {
+                    this._fontFamily = '';
+                    for ( i = fontSizeIndex + 1; i < splits.length; ++i )
+                    {
+                        this._fontFamily += splits[i] + ' ';
+                    }
+
+                    this._fontFamily = this._fontFamily.slice(0, -1);
+                }
+                else
+                {
+                    this._fontFamily = 'Arial';
+                }
+
+                this.styleID++;
+            }
+        }
+    } );
+
+    /**
+     * @method
+     * @name PIXI.Texture#setFrame
+     * @see PIXI.Texture#setFrame
+     * @deprecated since version 3.0.0
+     */
+    core.Texture.prototype.setFrame = function(frame)
+    {
+        this.frame = frame;
+        warn('setFrame is now deprecated, please use the frame property, e.g : myTexture.frame = frame;');
+    };
+
+    Object.defineProperties(filters, {
+
+        /**
+         * @class
+         * @private
+         * @name PIXI.filters.AbstractFilter
+         * @see PIXI.AbstractFilter
+         * @deprecated since version 3.0.6
+         */
+        AbstractFilter: {
+            get: function()
+            {
+                warn('AstractFilter has been renamed to Filter, please use PIXI.Filter');
+                return core.AbstractFilter;
+            }
+        },
+
+        /**
+         * @class
+         * @private
+         * @name PIXI.filters.SpriteMaskFilter
+         * @see PIXI.SpriteMaskFilter
+         * @deprecated since version 3.0.6
+         */
+        SpriteMaskFilter: {
+            get: function()
+            {
+                warn('filters.SpriteMaskFilter is an undocumented alias, please use SpriteMaskFilter from now on.');
+                return core.SpriteMaskFilter;
+            }
+        }
+    });
+
+    /**
+     * @method
+     * @name PIXI.utils.uuid
+     * @see PIXI.utils.uid
+     * @deprecated since version 3.0.6
+     */
+    core.utils.uuid = function ()
+    {
+        warn('utils.uuid() is deprecated, please use utils.uid() from now on.');
+        return core.utils.uid();
+    };
+
+    /**
+     * @method
+     * @name PIXI.utils.canUseNewCanvasBlendModes
+     * @see PIXI.CanvasTinter
+     * @deprecated
+     */
+    core.utils.canUseNewCanvasBlendModes = function() {
+        warn('utils.canUseNewCanvasBlendModes() is deprecated, please use CanvasTinter.canUseMultiply from now on');
+        return core.CanvasTinter.canUseMultiply;
+    };
+},{"./core":62,"./extras":129,"./filters":140,"./mesh":156,"./particles":159}],120:[function(require,module,exports){
+    var core = require('../../core'),
+        tempRect = new core.Rectangle();
+
+    /**
+     * The extract manager provides functionality to export content from the renderers
+     * @class
+     * @memberof PIXI
+     * @param renderer {PIXI.CanvasRenderer} A reference to the current renderer
+     */
+    function CanvasExtract(renderer)
+    {
+        this.renderer = renderer;
+        renderer.extract = this;
+    }
+
+
+    CanvasExtract.prototype.constructor = CanvasExtract;
+    module.exports = CanvasExtract;
+
+    /**
+     * Will return a HTML Image of the target
+     *
+     * @param target {PIXI.DisplayObject|PIXI.RenderTexture} A displayObject or renderTexture to convert. If left empty will use use the main renderer
+     * @return {HTMLImageElement} HTML Image of the target
+     */
+    CanvasExtract.prototype.image = function ( target )
+    {
+        var image = new Image();
+        image.src = this.base64( target );
+        return image;
+    };
+
+    /**
+     * Will return a a base64 encoded string of this target. It works by calling CanvasExtract.getCanvas and then running toDataURL on that.
+     * @param target {PIXI.DisplayObject|PIXI.RenderTexture} A displayObject or renderTexture to convert. If left empty will use use the main renderer
+     * @return {string} A base64 encoded string of the texture.
+     */
+    CanvasExtract.prototype.base64 = function ( target )
+    {
+        return this.canvas( target ).toDataURL();
+    };
+
+    /**
+     * Creates a Canvas element, renders this target to it and then returns it.
+     * @param target {PIXI.DisplayObject|PIXI.RenderTexture} A displayObject or renderTexture to convert. If left empty will use use the main renderer
+     * @return {HTMLCanvasElement} A Canvas element with the texture rendered on.
+     */
+    CanvasExtract.prototype.canvas = function ( target )
+    {
+        var renderer = this.renderer;
+        var context;
+        var resolution;
+        var frame;
+        var renderTexture;
+
+        if(target)
+        {
+            if(target instanceof core.RenderTexture)
+            {
+                renderTexture = target;
+            }
+            else
+            {
+                renderTexture = renderer.generateTexture(target);
+            }
+        }
+
+        if(renderTexture)
+        {
+            context = renderTexture.baseTexture._canvasRenderTarget.context;
+            resolution = renderTexture.baseTexture._canvasRenderTarget.resolution;
+            frame = renderTexture.frame;
+        }
+        else
+        {
+            context = renderer.rootContext;
+            resolution = renderer.rootResolution;
+
+            frame = tempRect;
+            frame.width = this.renderer.width;
+            frame.height = this.renderer.height;
+        }
+
+        var width = frame.width * resolution;
+        var height = frame.height * resolution;
+
+        var canvasBuffer = new core.CanvasRenderTarget(width, height);
+        var canvasData = context.getImageData(frame.x * resolution, frame.y * resolution, width, height);
+        canvasBuffer.context.putImageData(canvasData, 0, 0);
+
+
+        // send the canvas back..
+        return canvasBuffer.canvas;
+    };
+
+    /**
+     * Will return a one-dimensional array containing the pixel data of the entire texture in RGBA order, with integer values between 0 and 255 (included).
+     * @param target {PIXI.DisplayObject|PIXI.RenderTexture} A displayObject or renderTexture to convert. If left empty will use use the main renderer
+     * @return {Uint8ClampedArray} One-dimensional array containing the pixel data of the entire texture
+     */
+    CanvasExtract.prototype.pixels = function ( target )
+    {
+        var renderer = this.renderer;
+        var context;
+        var resolution;
+        var frame;
+        var renderTexture;
+
+        if(target)
+        {
+            if(target instanceof core.RenderTexture)
+            {
+                renderTexture = target;
+            }
+            else
+            {
+                renderTexture = renderer.generateTexture(target);
+            }
+        }
+
+        if(renderTexture)
+        {
+            context = renderTexture.baseTexture._canvasRenderTarget.context;
+            resolution = renderTexture.baseTexture._canvasRenderTarget.resolution;
+            frame = renderTexture.frame;
+        }
+        else
+        {
+            context = renderer.rootContext;
+            resolution = renderer.rootResolution;
+
+            frame = tempRect;
+            frame.width = renderer.width;
+            frame.height = renderer.height;
+        }
+
+        return context.getImageData(0, 0, frame.width * resolution, frame.height * resolution).data;
+    };
+
+    /**
+     * Destroys the extract
+     *
+     */
+    CanvasExtract.prototype.destroy = function ()
+    {
+        this.renderer.extract = null;
+        this.renderer = null;
+    };
+
+    core.CanvasRenderer.registerPlugin('extract', CanvasExtract);
+
+},{"../../core":62}],121:[function(require,module,exports){
+
+    module.exports = {
+        webGL: require('./webgl/WebGLExtract'),
+        canvas: require('./canvas/CanvasExtract')
+    };
+},{"./canvas/CanvasExtract":120,"./webgl/WebGLExtract":122}],122:[function(require,module,exports){
+    var core = require('../../core'),
+        tempRect = new core.Rectangle();
+
+    /**
+     * The extract manager provides functionality to export content from the renderers
+     * @class
+     * @memberof PIXI
+     * @param renderer {PIXI.WebGLRenderer} A reference to the current renderer
+     */
+    function WebGLExtract(renderer)
+    {
+        this.renderer = renderer;
+        renderer.extract = this;
+    }
+
+
+    WebGLExtract.prototype.constructor = WebGLExtract;
+    module.exports = WebGLExtract;
+
+    /**
+     * Will return a HTML Image of the target
+     *
+     * @param target {PIXI.DisplayObject|PIXI.RenderTexture} A displayObject or renderTexture to convert. If left empty will use use the main renderer
+     * @return {HTMLImageElement} HTML Image of the target
+     */
+    WebGLExtract.prototype.image = function ( target )
+    {
+        var image = new Image();
+        image.src = this.base64( target );
+        return image;
+    };
+
+    /**
+     * Will return a a base64 encoded string of this target. It works by calling WebGLExtract.getCanvas and then running toDataURL on that.
+     * @param target {PIXI.DisplayObject|PIXI.RenderTexture} A displayObject or renderTexture to convert. If left empty will use use the main renderer
+     * @return {string} A base64 encoded string of the texture.
+     */
+    WebGLExtract.prototype.base64 = function ( target )
+    {
+        return this.canvas( target ).toDataURL();
+    };
+
+    /**
+     * Creates a Canvas element, renders this target to it and then returns it.
+     * @param target {PIXI.DisplayObject|PIXI.RenderTexture} A displayObject or renderTexture to convert. If left empty will use use the main renderer
+     * @return {HTMLCanvasElement} A Canvas element with the texture rendered on.
+     */
+    WebGLExtract.prototype.canvas = function ( target )
+    {
+        var renderer = this.renderer;
+        var textureBuffer;
+        var resolution;
+        var frame;
+        var flipY = false;
+        var renderTexture;
+
+        if(target)
+        {
+            if(target instanceof core.RenderTexture)
+            {
+                renderTexture = target;
+            }
+            else
+            {
+                renderTexture = this.renderer.generateTexture(target);
+
+            }
+        }
+
+        if(renderTexture)
+        {
+            textureBuffer = renderTexture.baseTexture._glRenderTargets[this.renderer.CONTEXT_UID];
+            resolution = textureBuffer.resolution;
+            frame = renderTexture.frame;
+            flipY = false;
+        }
+        else
+        {
+            textureBuffer = this.renderer.rootRenderTarget;
+            resolution = textureBuffer.resolution;
+            flipY = true;
+
+            frame = tempRect;
+            frame.width = textureBuffer.size.width;
+            frame.height = textureBuffer.size.height;
+
+        }
+
+
+
+        var width = frame.width * resolution;
+        var height = frame.height * resolution;
+
+        var canvasBuffer = new core.CanvasRenderTarget(width, height);
+
+        if(textureBuffer)
+        {
+            // bind the buffer
+            renderer.bindRenderTarget(textureBuffer);
+
+            // set up an array of pixels
+            var webGLPixels = new Uint8Array(4 * width * height);
+
+            // read pixels to the array
+            var gl = renderer.gl;
+            gl.readPixels(frame.x * resolution, frame.y * resolution, width, height, gl.RGBA, gl.UNSIGNED_BYTE, webGLPixels);
+
+            // add the pixels to the canvas
+            var canvasData = canvasBuffer.context.getImageData(0, 0, width, height);
+            canvasData.data.set(webGLPixels);
+
+            canvasBuffer.context.putImageData(canvasData, 0, 0);
+
+            // pulling pixels
+            if(flipY)
+            {
+                canvasBuffer.context.scale(1, -1);
+                canvasBuffer.context.drawImage(canvasBuffer.canvas, 0,-height);
+            }
+        }
+
+        // send the canvas back..
+        return canvasBuffer.canvas;
+    };
+
+    /**
+     * Will return a one-dimensional array containing the pixel data of the entire texture in RGBA order, with integer values between 0 and 255 (included).
+     * @param target {PIXI.DisplayObject|PIXI.RenderTexture} A displayObject or renderTexture to convert. If left empty will use use the main renderer
+     * @return {Uint8ClampedArray} One-dimensional array containing the pixel data of the entire texture
+     */
+    WebGLExtract.prototype.pixels = function ( target )
+    {
+        var renderer = this.renderer;
+        var textureBuffer;
+        var resolution;
+        var frame;
+        var renderTexture;
+
+        if(target)
+        {
+            if(target instanceof core.RenderTexture)
+            {
+                renderTexture = target;
+            }
+            else
+            {
+                renderTexture = this.renderer.generateTexture(target);
+            }
+        }
+
+        if(renderTexture)
+        {
+            textureBuffer = renderTexture.baseTexture._glRenderTargets[this.renderer.CONTEXT_UID];
+            resolution = textureBuffer.resolution;
+            frame = renderTexture.frame;
+
+        }
+        else
+        {
+            textureBuffer = this.renderer.rootRenderTarget;
+            resolution = textureBuffer.resolution;
+
+            frame = tempRect;
+            frame.width = textureBuffer.size.width;
+            frame.height = textureBuffer.size.height;
+        }
+
+        var width = frame.width * resolution;
+        var height = frame.height * resolution;
+
+        var webGLPixels = new Uint8Array(4 * width * height);
+
+        if(textureBuffer)
+        {
+            // bind the buffer
+            renderer.bindRenderTarget(textureBuffer);
+            // read pixels to the array
+            var gl = renderer.gl;
+            gl.readPixels(frame.x * resolution, frame.y * resolution, width, height, gl.RGBA, gl.UNSIGNED_BYTE, webGLPixels);
+        }
+
+        return webGLPixels;
+    };
+
+    /**
+     * Destroys the extract
+     *
+     */
+    WebGLExtract.prototype.destroy = function ()
+    {
+        this.renderer.extract = null;
+        this.renderer = null;
+    };
+
+    core.WebGLRenderer.registerPlugin('extract', WebGLExtract);
+
+},{"../../core":62}],123:[function(require,module,exports){
+    var core = require('../core'),
+        ObservablePoint = require('../core/math/ObservablePoint');
+
+    /**
+     * A BitmapText object will create a line or multiple lines of text using bitmap font. To
+     * split a line you can use '\n', '\r' or '\r\n' in your string. You can generate the fnt files using:
+     *
+     * A BitmapText can only be created when the font is loaded
+     *
+     * ```js
+     * // in this case the font is in a file called 'desyrel.fnt'
+     * var bitmapText = new PIXI.extras.BitmapText("text using a fancy font!", {font: "35px Desyrel", align: "right"});
+     * ```
+     *
+     * http://www.angelcode.com/products/bmfont/ for windows or
+     * http://www.bmglyph.com/ for mac.
+     *
+     * @class
+     * @extends PIXI.Container
+     * @memberof PIXI.extras
+     * @param text {string} The copy that you would like the text to display
+     * @param style {object} The style parameters
+     * @param style.font {string|object} The font descriptor for the object, can be passed as a string of form
+     *      "24px FontName" or "FontName" or as an object with explicit name/size properties.
+     * @param [style.font.name] {string} The bitmap font id
+     * @param [style.font.size] {number} The size of the font in pixels, e.g. 24
+     * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect
+     *      single line text
+     * @param [style.tint=0xFFFFFF] {number} The tint color
+     */
+    function BitmapText(text, style)
+    {
+        core.Container.call(this);
+
+        style = style || {};
+
+        /**
+         * The width of the overall text, different from fontSize,
+         * which is defined in the style object
+         *
+         * @member {number}
+         * @readonly
+         */
+        this.textWidth = 0;
+
+        /**
+         * The height of the overall text, different from fontSize,
+         * which is defined in the style object
+         *
+         * @member {number}
+         * @readonly
+         */
+        this.textHeight = 0;
+
+        /**
+         * Private tracker for the letter sprite pool.
+         *
+         * @member {PIXI.Sprite[]}
+         * @private
+         */
+        this._glyphs = [];
+
+        /**
+         * Private tracker for the current style.
+         *
+         * @member {object}
+         * @private
+         */
+        this._font = {
+            tint: style.tint !== undefined ? style.tint : 0xFFFFFF,
+            align: style.align || 'left',
+            name: null,
+            size: 0
+        };
+
+        /**
+         * Private tracker for the current font.
+         *
+         * @member {object}
+         * @private
+         */
+        this.font = style.font; // run font setter
+
+        /**
+         * Private tracker for the current text.
+         *
+         * @member {string}
+         * @private
+         */
+        this._text = text;
+
+        /**
+         * The max width of this bitmap text in pixels. If the text provided is longer than the value provided, line breaks will be automatically inserted in the last whitespace.
+         * Disable by setting value to 0
+         *
+         * @member {number}
+         */
+        this.maxWidth = 0;
+
+        /**
+         * The max line height. This is useful when trying to use the total height of the Text, ie: when trying to vertically align.
+         *
+         * @member {number}
+         */
+        this.maxLineHeight = 0;
+
+        /**
+         * Text anchor. read-only
+         *
+         * @member {PIXI.ObservablePoint}
+         * @private
+         */
+        this._anchor = new ObservablePoint(this.makeDirty, this, 0, 0);
+
+        /**
+         * The dirty state of this object.
+         *
+         * @member {boolean}
+         */
+        this.dirty = false;
+
+        this.updateText();
+    }
+
+// constructor
+    BitmapText.prototype = Object.create(core.Container.prototype);
+    BitmapText.prototype.constructor = BitmapText;
+    module.exports = BitmapText;
+
+    Object.defineProperties(BitmapText.prototype, {
+        /**
+         * The tint of the BitmapText object
+         *
+         * @member {number}
+         * @memberof PIXI.extras.BitmapText#
+         */
+        tint: {
+            get: function ()
+            {
+                return this._font.tint;
+            },
+            set: function (value)
+            {
+                this._font.tint = (typeof value === 'number' && value >= 0) ? value : 0xFFFFFF;
+
+                this.dirty = true;
+            }
+        },
+
+        /**
+         * The alignment of the BitmapText object
+         *
+         * @member {string}
+         * @default 'left'
+         * @memberof PIXI.extras.BitmapText#
+         */
+        align: {
+            get: function ()
+            {
+                return this._font.align;
+            },
+            set: function (value)
+            {
+                this._font.align = value || 'left';
+
+                this.dirty = true;
+            }
+        },
+
+        /**
+         * The anchor sets the origin point of the text.
+         * The default is 0,0 this means the text's origin is the top left
+         * Setting the anchor to 0.5,0.5 means the text's origin is centered
+         * Setting the anchor to 1,1 would mean the text's origin point will be the bottom right corner
+         *
+         * @member {PIXI.Point | number}
+         * @memberof PIXI.extras.BitmapText#
+         */
+        anchor: {
+            get : function() {
+                return this._anchor;
+            },
+            set: function(value) {
+                if (typeof value === 'number'){
+                    this._anchor.set(value);
+                }
+                else {
+                    this._anchor.copy(value);
+                }
+            }
+        },
+
+        /**
+         * The font descriptor of the BitmapText object
+         *
+         * @member {string|object}
+         * @memberof PIXI.extras.BitmapText#
+         */
+        font: {
+            get: function ()
+            {
+                return this._font;
+            },
+            set: function (value)
+            {
+                if (!value) {
+                    return;
+                }
+
+                if (typeof value === 'string') {
+                    value = value.split(' ');
+
+                    this._font.name = value.length === 1 ? value[0] : value.slice(1).join(' ');
+                    this._font.size = value.length >= 2 ? parseInt(value[0], 10) : BitmapText.fonts[this._font.name].size;
+                }
+                else {
+                    this._font.name = value.name;
+                    this._font.size = typeof value.size === 'number' ? value.size : parseInt(value.size, 10);
+                }
+
+                this.dirty = true;
+            }
+        },
+
+        /**
+         * The text of the BitmapText object
+         *
+         * @member {string}
+         * @memberof PIXI.extras.BitmapText#
+         */
+        text: {
+            get: function ()
+            {
+                return this._text;
+            },
+            set: function (value)
+            {
+                value = value.toString() || ' ';
+                if (this._text === value)
+                {
+                    return;
+                }
+                this._text = value;
+                this.dirty = true;
+            }
+        }
+    });
+
+    /**
+     * Renders text and updates it when needed
+     *
+     * @private
+     */
+    BitmapText.prototype.updateText = function ()
+    {
+        var data = BitmapText.fonts[this._font.name];
+        var pos = new core.Point();
+        var prevCharCode = null;
+        var chars = [];
+        var lastLineWidth = 0;
+        var maxLineWidth = 0;
+        var lineWidths = [];
+        var line = 0;
+        var scale = this._font.size / data.size;
+        var lastSpace = -1;
+        var lastSpaceWidth = 0;
+        var maxLineHeight = 0;
+
+        for (var i = 0; i < this.text.length; i++)
+        {
+            var charCode = this.text.charCodeAt(i);
+
+            if(/(\s)/.test(this.text.charAt(i))){
+                lastSpace = i;
+                lastSpaceWidth = lastLineWidth;
+            }
+
+            if (/(?:\r\n|\r|\n)/.test(this.text.charAt(i)))
+            {
+                lineWidths.push(lastLineWidth);
+                maxLineWidth = Math.max(maxLineWidth, lastLineWidth);
+                line++;
+
+                pos.x = 0;
+                pos.y += data.lineHeight;
+                prevCharCode = null;
+                continue;
+            }
+
+            if (lastSpace !== -1 && this.maxWidth > 0 && pos.x * scale > this.maxWidth)
+            {
+                core.utils.removeItems(chars, lastSpace, i - lastSpace);
+                i = lastSpace;
+                lastSpace = -1;
+
+                lineWidths.push(lastSpaceWidth);
+                maxLineWidth = Math.max(maxLineWidth, lastSpaceWidth);
+                line++;
+
+                pos.x = 0;
+                pos.y += data.lineHeight;
+                prevCharCode = null;
+                continue;
+            }
+
+            var charData = data.chars[charCode];
+
+            if (!charData)
+            {
+                continue;
+            }
+
+            if (prevCharCode && charData.kerning[prevCharCode])
+            {
+                pos.x += charData.kerning[prevCharCode];
+            }
+
+            chars.push({texture:charData.texture, line: line, charCode: charCode, position: new core.Point(pos.x + charData.xOffset, pos.y + charData.yOffset)});
+            lastLineWidth = pos.x + (charData.texture.width + charData.xOffset);
+            pos.x += charData.xAdvance;
+            maxLineHeight = Math.max(maxLineHeight, (charData.yOffset + charData.texture.height));
+            prevCharCode = charCode;
+        }
+
+        lineWidths.push(lastLineWidth);
+        maxLineWidth = Math.max(maxLineWidth, lastLineWidth);
+
+        var lineAlignOffsets = [];
+
+        for (i = 0; i <= line; i++)
+        {
+            var alignOffset = 0;
+
+            if (this._font.align === 'right')
+            {
+                alignOffset = maxLineWidth - lineWidths[i];
+            }
+            else if (this._font.align === 'center')
+            {
+                alignOffset = (maxLineWidth - lineWidths[i]) / 2;
+            }
+
+            lineAlignOffsets.push(alignOffset);
+        }
+
+        var lenChars = chars.length;
+        var tint = this.tint;
+
+        for (i = 0; i < lenChars; i++)
+        {
+            var c = this._glyphs[i]; // get the next glyph sprite
+
+            if (c)
+            {
+                c.texture = chars[i].texture;
+            }
+            else
+            {
+                c = new core.Sprite(chars[i].texture);
+                this._glyphs.push(c);
+            }
+
+            c.position.x = (chars[i].position.x + lineAlignOffsets[chars[i].line]) * scale;
+            c.position.y = chars[i].position.y * scale;
+            c.scale.x = c.scale.y = scale;
+            c.tint = tint;
+
+            if (!c.parent)
+            {
+                this.addChild(c);
+            }
+        }
+
+        // remove unnecessary children.
+        for (i = lenChars; i < this._glyphs.length; ++i)
+        {
+            this.removeChild(this._glyphs[i]);
+        }
+
+        this.textWidth = maxLineWidth * scale;
+        this.textHeight = (pos.y + data.lineHeight) * scale;
+
+        // apply anchor
+        if (this.anchor.x !== 0 || this.anchor.y !== 0)
+        {
+            for (i = 0; i < lenChars; i++)
+            {
+                this._glyphs[i].x -= this.textWidth * this.anchor.x;
+                this._glyphs[i].y -= this.textHeight * this.anchor.y;
+            }
+        }
+        this.maxLineHeight = maxLineHeight * scale;
+    };
+
+    /**
+     * Updates the transform of this object
+     *
+     * @private
+     */
+    BitmapText.prototype.updateTransform = function ()
+    {
+        this.validate();
+        this.containerUpdateTransform();
+    };
+
+    /**
+     * Validates text before calling parent's getLocalBounds
+     *
+     * @return {PIXI.Rectangle} The rectangular bounding area
+     */
+
+    BitmapText.prototype.getLocalBounds = function()
+    {
+        this.validate();
+        return core.Container.prototype.getLocalBounds.call(this);
+    };
+
+    /**
+     * Updates text when needed
+     *
+     * @private
+     */
+    BitmapText.prototype.validate = function()
+    {
+        if (this.dirty)
+        {
+            this.updateText();
+            this.dirty = false;
+        }
+    };
+
+    BitmapText.prototype.makeDirty = function() {
+        this.dirty = true;
+    };
+
+    BitmapText.fonts = {};
+
+},{"../core":62,"../core/math/ObservablePoint":65}],124:[function(require,module,exports){
+    var core = require('../core');
+
+    /**
+     * @typedef FrameObject
+     * @type {object}
+     * @property texture {PIXI.Texture} The {@link PIXI.Texture} of the frame
+     * @property time {number} the duration of the frame in ms
+     */
+
+    /**
+     * A MovieClip is a simple way to display an animation depicted by a list of textures.
+     *
+     * ```js
+     * var alienImages = ["image_sequence_01.png","image_sequence_02.png","image_sequence_03.png","image_sequence_04.png"];
+     * var textureArray = [];
+     *
+     * for (var i=0; i < 4; i++)
+     * {
+ *      var texture = PIXI.Texture.fromImage(alienImages[i]);
+ *      textureArray.push(texture);
+ * };
+     *
+     * var mc = new PIXI.MovieClip(textureArray);
+     * ```
+     *
+     *
+     * @class
+     * @extends PIXI.Sprite
+     * @memberof PIXI.extras
+     * @param textures {PIXI.Texture[]|FrameObject[]} an array of {@link PIXI.Texture} or frame objects that make up the animation
+     */
+    function MovieClip(textures)
+    {
+        core.Sprite.call(this, textures[0] instanceof core.Texture ? textures[0] : textures[0].texture);
+
+        /**
+         * @private
+         */
+        this._textures = null;
+
+        /**
+         * @private
+         */
+        this._durations = null;
+
+        this.textures = textures;
+
+        /**
+         * The speed that the MovieClip will play at. Higher is faster, lower is slower
+         *
+         * @member {number}
+         * @default 1
+         */
+        this.animationSpeed = 1;
+
+        /**
+         * Whether or not the movie clip repeats after playing.
+         *
+         * @member {boolean}
+         * @default true
+         */
+        this.loop = true;
+
+        /**
+         * Function to call when a MovieClip finishes playing
+         *
+         * @method
+         * @memberof PIXI.extras.MovieClip#
+         */
+        this.onComplete = null;
+
+        /**
+         * Elapsed time since animation has been started, used internally to display current texture
+         *
+         * @member {number}
+         * @private
+         */
+        this._currentTime = 0;
+
+        /**
+         * Indicates if the MovieClip is currently playing
+         *
+         * @member {boolean}
+         * @readonly
+         */
+        this.playing = false;
+    }
+
+// constructor
+    MovieClip.prototype = Object.create(core.Sprite.prototype);
+    MovieClip.prototype.constructor = MovieClip;
+    module.exports = MovieClip;
+
+    Object.defineProperties(MovieClip.prototype, {
+        /**
+         * totalFrames is the total number of frames in the MovieClip. This is the same as number of textures
+         * assigned to the MovieClip.
+         *
+         * @member {number}
+         * @memberof PIXI.extras.MovieClip#
+         * @default 0
+         * @readonly
+         */
+        totalFrames: {
+            get: function()
+            {
+                return this._textures.length;
+            }
+        },
+
+        /**
+         * The array of textures used for this MovieClip
+         *
+         * @member {PIXI.Texture[]}
+         * @memberof PIXI.extras.MovieClip#
+         *
+         */
+        textures: {
+            get: function ()
+            {
+                return this._textures;
+            },
+            set: function (value)
+            {
+                if(value[0] instanceof core.Texture)
+                {
+                    this._textures = value;
+                    this._durations = null;
+                }
+                else
+                {
+                    this._textures = [];
+                    this._durations = [];
+                    for(var i = 0; i < value.length; i++)
+                    {
+                        this._textures.push(value[i].texture);
+                        this._durations.push(value[i].time);
+                    }
+                }
+            }
+        },
+
+        /**
+         * The MovieClips current frame index
+         *
+         * @member {number}
+         * @memberof PIXI.extras.MovieClip#
+         * @readonly
+         */
+        currentFrame: {
+            get: function ()
+            {
+                var currentFrame = Math.floor(this._currentTime) % this._textures.length;
+                if (currentFrame < 0)
+                {
+                    currentFrame += this._textures.length;
+                }
+                return currentFrame;
+            }
+        }
+
+    });
+
+    /**
+     * Stops the MovieClip
+     *
+     */
+    MovieClip.prototype.stop = function ()
+    {
+        if(!this.playing)
+        {
+            return;
+        }
+
+        this.playing = false;
+        core.ticker.shared.remove(this.update, this);
+    };
+
+    /**
+     * Plays the MovieClip
+     *
+     */
+    MovieClip.prototype.play = function ()
+    {
+        if(this.playing)
+        {
+            return;
+        }
+
+        this.playing = true;
+        core.ticker.shared.add(this.update, this);
+    };
+
+    /**
+     * Stops the MovieClip and goes to a specific frame
+     *
+     * @param frameNumber {number} frame index to stop at
+     */
+    MovieClip.prototype.gotoAndStop = function (frameNumber)
+    {
+        this.stop();
+
+        this._currentTime = frameNumber;
+
+        this._texture = this._textures[this.currentFrame];
+        this._textureID = -1;
+    };
+
+    /**
+     * Goes to a specific frame and begins playing the MovieClip
+     *
+     * @param frameNumber {number} frame index to start at
+     */
+    MovieClip.prototype.gotoAndPlay = function (frameNumber)
+    {
+        this._currentTime = frameNumber;
+
+        this.play();
+    };
+
+    /*
+     * Updates the object transform for rendering
+     * @private
+     */
+    MovieClip.prototype.update = function (deltaTime)
+    {
+        var elapsed = this.animationSpeed * deltaTime;
+
+        if (this._durations !== null)
+        {
+            var lag = this._currentTime % 1 * this._durations[this.currentFrame];
+
+            lag += elapsed / 60 * 1000;
+
+            while (lag < 0)
+            {
+                this._currentTime--;
+                lag += this._durations[this.currentFrame];
+            }
+
+            var sign = Math.sign(this.animationSpeed * deltaTime);
+            this._currentTime = Math.floor(this._currentTime);
+
+            while (lag >= this._durations[this.currentFrame])
+            {
+                lag -= this._durations[this.currentFrame] * sign;
+                this._currentTime += sign;
+            }
+
+            this._currentTime += lag / this._durations[this.currentFrame];
+        }
+        else
+        {
+            this._currentTime += elapsed;
+        }
+
+        if (this._currentTime < 0 && !this.loop)
+        {
+            this.gotoAndStop(0);
+
+            if (this.onComplete)
+            {
+                this.onComplete();
+            }
+        }
+        else if (this._currentTime >= this._textures.length && !this.loop)
+        {
+            this.gotoAndStop(this._textures.length - 1);
+
+            if (this.onComplete)
+            {
+                this.onComplete();
+            }
+        }
+        else
+        {
+            this._texture = this._textures[this.currentFrame];
+            this._textureID = -1;
+        }
+
+    };
+
+    /*
+     * Stops the MovieClip and destroys it
+     *
+     */
+    MovieClip.prototype.destroy = function ( )
+    {
+        this.stop();
+        core.Sprite.prototype.destroy.call(this);
+    };
+
+    /**
+     * A short hand way of creating a movieclip from an array of frame ids
+     *
+     * @static
+     * @param frames {string[]} the array of frames ids the movieclip will use as its texture frames
+     */
+    MovieClip.fromFrames = function (frames)
+    {
+        var textures = [];
+
+        for (var i = 0; i < frames.length; ++i)
+        {
+            textures.push(core.Texture.fromFrame(frames[i]));
+        }
+
+        return new MovieClip(textures);
+    };
+
+    /**
+     * A short hand way of creating a movieclip from an array of image ids
+     *
+     * @static
+     * @param images {string[]} the array of image urls the movieclip will use as its texture frames
+     */
+    MovieClip.fromImages = function (images)
+    {
+        var textures = [];
+
+        for (var i = 0; i < images.length; ++i)
+        {
+            textures.push(core.Texture.fromImage(images[i]));
+        }
+
+        return new MovieClip(textures);
+    };
+
+},{"../core":62}],125:[function(require,module,exports){
+    var core = require('../core'),
+        tempPoint = new core.Point(),
+        Texture = require('../core/textures/Texture'),
+        CanvasTinter = require('../core/sprites/canvas/CanvasTinter'),
+        TilingShader = require('./webgl/TilingShader'),
+        tempArray = new Float32Array(4);
+    /**
+     * A tiling sprite is a fast way of rendering a tiling image
+     *
+     * @class
+     * @extends PIXI.Sprite
+     * @memberof PIXI.extras
+     * @param texture {PIXI.Texture} the texture of the tiling sprite
+     * @param width {number}  the width of the tiling sprite
+     * @param height {number} the height of the tiling sprite
+     */
+    function TilingSprite(texture, width, height)
+    {
+        core.Sprite.call(this, texture);
+
+        /**
+         * The scaling of the image that is being tiled
+         *
+         * @member {PIXI.Point}
+         */
+        this.tileScale = new core.Point(1,1);
+
+
+        /**
+         * The offset position of the image that is being tiled
+         *
+         * @member {PIXI.Point}
+         */
+        this.tilePosition = new core.Point(0,0);
+
+        ///// private
+
+        /**
+         * The with of the tiling sprite
+         *
+         * @member {number}
+         * @private
+         */
+        this._width = width || 100;
+
+        /**
+         * The height of the tiling sprite
+         *
+         * @member {number}
+         * @private
+         */
+        this._height = height || 100;
+
+        /**
+         * An internal WebGL UV cache.
+         *
+         * @member {PIXI.TextureUvs}
+         * @private
+         */
+        this._uvs = new core.TextureUvs();
+
+        this._canvasPattern = null;
+
+        this._glDatas = [];
+    }
+
+    TilingSprite.prototype = Object.create(core.Sprite.prototype);
+    TilingSprite.prototype.constructor = TilingSprite;
+    module.exports = TilingSprite;
+
+
+    Object.defineProperties(TilingSprite.prototype, {
+        /**
+         * The width of the sprite, setting this will actually modify the scale to achieve the value set
+         *
+         * @member {number}
+         * @memberof PIXI.extras.TilingSprite#
+         */
+        width: {
+            get: function ()
+            {
+                return this._width;
+            },
+            set: function (value)
+            {
+                this._width = value;
+            }
+        },
+
+        /**
+         * The height of the TilingSprite, setting this will actually modify the scale to achieve the value set
+         *
+         * @member {number}
+         * @memberof PIXI.extras.TilingSprite#
+         */
+        height: {
+            get: function ()
+            {
+                return this._height;
+            },
+            set: function (value)
+            {
+                this._height = value;
+            }
+        }
+    });
+
+    TilingSprite.prototype._onTextureUpdate = function ()
+    {
+        return;
+    };
+
+
+    /**
+     * Renders the object using the WebGL renderer
+     *
+     * @param renderer {PIXI.WebGLRenderer} The renderer
+     * @private
+     */
+    TilingSprite.prototype._renderWebGL = function (renderer)
+    {
+
+        // tweak our texture temporarily..
+        var texture = this._texture;
+
+        if(!texture || !texture._uvs)
+        {
+            return;
+        }
+
+        // get rid of any thing that may be batching.
+        renderer.flush();
+
+        var gl = renderer.gl;
+        var glData = this._glDatas[renderer.CONTEXT_UID];
+
+        if(!glData)
+        {
+            glData = {
+                shader:new TilingShader(gl),
+                quad:new core.Quad(gl)
+            };
+
+            this._glDatas[renderer.CONTEXT_UID] = glData;
+
+            glData.quad.initVao(glData.shader);
+        }
+
+        // if the sprite is trimmed and is not a tilingsprite then we need to add the extra space before transforming the sprite coords..
+        var vertices = glData.quad.vertices;
+
+        vertices[0] = vertices[6] = ( this._width ) * -this.anchor.x;
+        vertices[1] = vertices[3] = this._height * -this.anchor.y;
+
+        vertices[2] = vertices[4] = ( this._width ) * (1-this.anchor.x);
+        vertices[5] = vertices[7] = this._height * (1-this.anchor.y);
+
+        glData.quad.upload();
+
+        renderer.bindShader(glData.shader);
+
+        var textureUvs = texture._uvs,
+            textureWidth = texture._frame.width,
+            textureHeight = texture._frame.height,
+            textureBaseWidth = texture.baseTexture.width,
+            textureBaseHeight = texture.baseTexture.height;
+
+        var uPixelSize = glData.shader.uniforms.uPixelSize;
+        uPixelSize[0] = 1.0/textureBaseWidth;
+        uPixelSize[1] = 1.0/textureBaseHeight;
+        glData.shader.uniforms.uPixelSize = uPixelSize;
+
+        var uFrame = glData.shader.uniforms.uFrame;
+        uFrame[0] = textureUvs.x0;
+        uFrame[1] = textureUvs.y0;
+        uFrame[2] = textureUvs.x1 - textureUvs.x0;
+        uFrame[3] = textureUvs.y2 - textureUvs.y0;
+        glData.shader.uniforms.uFrame = uFrame;
+
+        var uTransform = glData.shader.uniforms.uTransform;
+        uTransform[0] = (this.tilePosition.x % (textureWidth * this.tileScale.x)) / this._width;
+        uTransform[1] = (this.tilePosition.y % (textureHeight * this.tileScale.y)) / this._height;
+        uTransform[2] = ( textureBaseWidth / this._width ) * this.tileScale.x;
+        uTransform[3] = ( textureBaseHeight / this._height ) * this.tileScale.y;
+        glData.shader.uniforms.uTransform = uTransform;
+
+        glData.shader.uniforms.translationMatrix = this.worldTransform.toArray(true);
+
+        var color = tempArray;
+
+        core.utils.hex2rgb(this.tint, color);
+        color[3] = this.worldAlpha;
+
+        glData.shader.uniforms.uColor = color;
+
+        renderer.bindTexture(this._texture, 0);
+
+        renderer.state.setBlendMode( this.blendMode );
+        glData.quad.draw();
+    };
+
+    /**
+     * Renders the object using the Canvas renderer
+     *
+     * @param renderer {PIXI.CanvasRenderer} a reference to the canvas renderer
+     * @private
+     */
+    TilingSprite.prototype._renderCanvas = function (renderer)
+    {
+        var texture = this._texture;
+
+        if (!texture.baseTexture.hasLoaded)
+        {
+            return;
+        }
+
+        var context = renderer.context,
+            transform = this.worldTransform,
+            resolution = renderer.resolution,
+            baseTexture = texture.baseTexture,
+            modX = (this.tilePosition.x / this.tileScale.x) % texture._frame.width,
+            modY = (this.tilePosition.y / this.tileScale.y) % texture._frame.height;
+
+        // create a nice shiny pattern!
+        // TODO this needs to be refreshed if texture changes..
+        if(!this._canvasPattern)
+        {
+            // cut an object from a spritesheet..
+            var tempCanvas = new core.CanvasRenderTarget(texture._frame.width, texture._frame.height);
+
+            // Tint the tiling sprite
+            if (this.tint !== 0xFFFFFF)
+            {
+                if (this.cachedTint !== this.tint)
+                {
+                    this.cachedTint = this.tint;
+
+                    this.tintedTexture = CanvasTinter.getTintedTexture(this, this.tint);
+                }
+                tempCanvas.context.drawImage(this.tintedTexture, 0, 0);
+            }
+            else
+            {
+                tempCanvas.context.drawImage(baseTexture.source, -texture._frame.x, -texture._frame.y);
+            }
+            this._canvasPattern = tempCanvas.context.createPattern( tempCanvas.canvas, 'repeat' );
+        }
+
+        // set context state..
+        context.globalAlpha = this.worldAlpha;
+        context.setTransform(transform.a * resolution,
+            transform.b * resolution,
+            transform.c * resolution,
+            transform.d * resolution,
+            transform.tx * resolution,
+            transform.ty * resolution);
+
+        // TODO - this should be rolled into the setTransform above..
+        context.scale(this.tileScale.x,this.tileScale.y);
+
+        context.translate(modX + (this.anchor.x * -this._width ),
+            modY + (this.anchor.y * -this._height));
+
+        // check blend mode
+        var compositeOperation = renderer.blendModes[this.blendMode];
+        if (compositeOperation !== renderer.context.globalCompositeOperation)
+        {
+            context.globalCompositeOperation = compositeOperation;
+        }
+
+        // fill the pattern!
+        context.fillStyle = this._canvasPattern;
+        context.fillRect(-modX,
+            -modY,
+            this._width / this.tileScale.x,
+            this._height / this.tileScale.y);
+
+
+        //TODO - pretty sure this can be deleted...
+        //context.translate(-this.tilePosition.x + (this.anchor.x * this._width), -this.tilePosition.y + (this.anchor.y * this._height));
+        //context.scale(1 / this.tileScale.x, 1 / this.tileScale.y);
+    };
+
+
+    /**
+     * Returns the framing rectangle of the sprite as a Rectangle object
+     *
+     * @return {PIXI.Rectangle} the framing rectangle
+     */
+    TilingSprite.prototype.getBounds = function ()
+    {
+        var width = this._width;
+        var height = this._height;
+
+        var w0 = width * (1-this.anchor.x);
+        var w1 = width * -this.anchor.x;
+
+        var h0 = height * (1-this.anchor.y);
+        var h1 = height * -this.anchor.y;
+
+        var worldTransform = this.worldTransform;
+
+        var a = worldTransform.a;
+        var b = worldTransform.b;
+        var c = worldTransform.c;
+        var d = worldTransform.d;
+        var tx = worldTransform.tx;
+        var ty = worldTransform.ty;
+
+        var x1 = a * w1 + c * h1 + tx;
+        var y1 = d * h1 + b * w1 + ty;
+
+        var x2 = a * w0 + c * h1 + tx;
+        var y2 = d * h1 + b * w0 + ty;
+
+        var x3 = a * w0 + c * h0 + tx;
+        var y3 = d * h0 + b * w0 + ty;
+
+        var x4 =  a * w1 + c * h0 + tx;
+        var y4 =  d * h0 + b * w1 + ty;
+
+        var minX,
+            maxX,
+            minY,
+            maxY;
+
+        minX = x1;
+        minX = x2 < minX ? x2 : minX;
+        minX = x3 < minX ? x3 : minX;
+        minX = x4 < minX ? x4 : minX;
+
+        minY = y1;
+        minY = y2 < minY ? y2 : minY;
+        minY = y3 < minY ? y3 : minY;
+        minY = y4 < minY ? y4 : minY;
+
+        maxX = x1;
+        maxX = x2 > maxX ? x2 : maxX;
+        maxX = x3 > maxX ? x3 : maxX;
+        maxX = x4 > maxX ? x4 : maxX;
+
+        maxY = y1;
+        maxY = y2 > maxY ? y2 : maxY;
+        maxY = y3 > maxY ? y3 : maxY;
+        maxY = y4 > maxY ? y4 : maxY;
+
+        var bounds = this._bounds;
+
+        bounds.x = minX;
+        bounds.width = maxX - minX;
+
+        bounds.y = minY;
+        bounds.height = maxY - minY;
+
+        // store a reference so that if this function gets called again in the render cycle we do not have to recalculate
+        this._currentBounds = bounds;
+
+        return bounds;
+    };
+
+    /**
+     * Checks if a point is inside this tiling sprite
+     * @param point {PIXI.Point} the point to check
+     */
+    TilingSprite.prototype.containsPoint = function( point )
+    {
+        this.worldTransform.applyInverse(point,  tempPoint);
+
+        var width = this._width;
+        var height = this._height;
+        var x1 = -width * this.anchor.x;
+        var y1;
+
+        if ( tempPoint.x > x1 && tempPoint.x < x1 + width )
+        {
+            y1 = -height * this.anchor.y;
+
+            if ( tempPoint.y > y1 && tempPoint.y < y1 + height )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    };
+
+    /**
+     * Destroys this tiling sprite
+     *
+     */
+    TilingSprite.prototype.destroy = function () {
+        core.Sprite.prototype.destroy.call(this);
+
+        this.tileScale = null;
+        this._tileScaleOffset = null;
+        this.tilePosition = null;
+
+        this._uvs = null;
+    };
+
+    /**
+     * Helper function that creates a new tiling sprite based on the source you provide.
+     * The source can be - frame id, image url, video url, canvas element, video element, base texture
+     *
+     * @static
+     * @param {number|string|PIXI.BaseTexture|HTMLCanvasElement|HTMLVideoElement} source Source to create texture from
+     * @param width {number}  the width of the tiling sprite
+     * @param height {number} the height of the tiling sprite
+     * @return {PIXI.Texture} The newly created texture
+     */
+    TilingSprite.from = function (source,width,height)
+    {
+        return new TilingSprite(Texture.from(source),width,height);
+    };
+
+
+
+    /**
+     * Helper function that creates a tiling sprite that will use a texture from the TextureCache based on the frameId
+     * The frame ids are created when a Texture packer file has been loaded
+     *
+     * @static
+     * @param frameId {string} The frame Id of the texture in the cache
+     * @return {PIXI.extras.TilingSprite} A new TilingSprite using a texture from the texture cache matching the frameId
+     * @param width {number}  the width of the tiling sprite
+     * @param height {number} the height of the tiling sprite
+     * @return {PIXI.extras.TilingSprite} A new TilingSprite
+     */
+    TilingSprite.fromFrame = function (frameId,width,height)
+    {
+        var texture = core.utils.TextureCache[frameId];
+
+        if (!texture)
+        {
+            throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ' + this);
+        }
+
+        return new TilingSprite(texture,width,height);
+    };
+
+    /**
+     * Helper function that creates a sprite that will contain a texture based on an image url
+     * If the image is not in the texture cache it will be loaded
+     *
+     * @static
+     * @param imageId {string} The image url of the texture
+     * @param width {number}  the width of the tiling sprite
+     * @param height {number} the height of the tiling sprite
+     * @param [crossorigin=(auto)] {boolean} if you want to specify the cross-origin parameter
+     * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} if you want to specify the scale mode, see {@link PIXI.SCALE_MODES} for possible values
+     * @return {PIXI.extras.TilingSprite} A new TilingSprite using a texture from the texture cache matching the image id
+     */
+    TilingSprite.fromImage = function (imageId, width, height, crossorigin, scaleMode)
+    {
+        return new TilingSprite(core.Texture.fromImage(imageId, crossorigin, scaleMode),width,height);
+    };
+
+},{"../core":62,"../core/sprites/canvas/CanvasTinter":100,"../core/textures/Texture":109,"./webgl/TilingShader":130}],126:[function(require,module,exports){
+    var core = require('../core'),
+        DisplayObject = core.DisplayObject,
+        _tempMatrix = new core.Matrix();
+
+    DisplayObject.prototype._cacheAsBitmap = false;
+    DisplayObject.prototype._cacheData = false;
+
+// figured theres no point adding ALL the extra variables to prototype.
+// this model can hold the information needed. This can also be generated on demand as
+// most objects are not cached as bitmaps.
+    var CacheData = function(){
+
+        this.originalRenderWebGL = null;
+        this.originalRenderCanvas = null;
+        this.originalCalculateBounds = null;
+        this.originalGetLocalBounds = null;
+
+        this.originalUpdateTransform = null;
+        this.originalHitTest = null;
+        this.originalDestroy = null;
+        this.originalMask = null;
+        this.originalFilterArea = null;
+        this.sprite = null;
+    };
+
+
+    Object.defineProperties(DisplayObject.prototype, {
+
+        /**
+         * Set this to true if you want this display object to be cached as a bitmap.
+         * This basically takes a snap shot of the display object as it is at that moment. It can provide a performance benefit for complex static displayObjects.
+         * To remove simply set this property to 'false'
+         *
+         * @member {boolean}
+         * @memberof PIXI.DisplayObject#
+         */
+        cacheAsBitmap: {
+            get: function ()
+            {
+                return this._cacheAsBitmap;
+            },
+            set: function (value)
+            {
+                if (this._cacheAsBitmap === value)
+                {
+                    return;
+                }
+
+                this._cacheAsBitmap = value;
+
+                var data;
+
+                if (value)
+                {
+
+                    if(!this._cacheData)
+                    {
+                        this._cacheData = new CacheData();
+                    }
+
+                    data = this._cacheData;
+
+                    data.originalRenderWebGL = this.renderWebGL;
+                    data.originalRenderCanvas = this.renderCanvas;
+
+                    data.originalUpdateTransform = this.updateTransform;
+                    data.originalCalculateBounds = this._calculateBounds;
+                    data.originalGetLocalBounds = this.getLocalBounds;
+
+                    data.originalDestroy = this.destroy;
+
+                    data.originalContainsPoint = this.containsPoint;
+
+                    data.originalMask = this._mask;
+                    data.originalFilterArea = this.filterArea;
+
+
+
+                    this.renderWebGL = this._renderCachedWebGL;
+                    this.renderCanvas = this._renderCachedCanvas;
+
+                    this.destroy = this._cacheAsBitmapDestroy;
+
+                }
+                else
+                {
+                    data = this._cacheData;
+
+                    if (data.sprite)
+                    {
+                        this._destroyCachedDisplayObject();
+                    }
+
+
+                    this.renderWebGL = data.originalRenderWebGL;
+                    this.renderCanvas = data.originalRenderCanvas;
+                    this._calculateBounds = data.originalCalculateBounds;
+                    this.getLocalBounds = data.originalGetLocalBounds;
+
+                    this.destroy = data.originalDestroy;
+
+                    this.updateTransform = data.originalUpdateTransform;
+                    this.containsPoint = data.originalContainsPoint;
+
+                    this._mask = data.originalMask;
+                    this.filterArea = data.originalFilterArea;
+                }
+            }
+        }
+    });
+    /**
+     * Renders a cached version of the sprite with WebGL
+     *
+     * @param renderer {PIXI.WebGLRenderer} the WebGL renderer
+     * @private
+     */
+    DisplayObject.prototype._renderCachedWebGL = function (renderer)
+    {
+        if (!this.visible || this.worldAlpha <= 0 || !this.renderable)
+        {
+            return;
+        }
+
+        this._initCachedDisplayObject( renderer );
+
+        this._cacheData.sprite._transformID = -1;
+        this._cacheData.sprite.worldAlpha = this.worldAlpha;
+        this._cacheData.sprite._renderWebGL(renderer);
+    };
+
+    /**
+     * Prepares the WebGL renderer to cache the sprite
+     *
+     * @param renderer {PIXI.WebGLRenderer} the WebGL renderer
+     * @private
+     */
+    DisplayObject.prototype._initCachedDisplayObject = function (renderer)
+    {
+        if(this._cacheData && this._cacheData.sprite)
+        {
+            return;
+        }
+
+        // make sure alpha is set to 1 otherwise it will get rendered as invisible!
+        var cacheAlpha = this.alpha;
+        this.alpha = 1;
+
+        // first we flush anything left in the renderer (otherwise it would get rendered to the cached texture)
+        renderer.currentRenderer.flush();
+        //this.filters= [];
+        // next we find the dimensions of the untransformed object
+        // this function also calls updatetransform on all its children as part of the measuring. This means we don't need to update the transform again in this function
+        // TODO pass an object to clone too? saves having to create a new one each time!
+        var bounds = this.getLocalBounds().clone();
+
+        // add some padding!
+        if(this._filters)
+        {
+            var padding = this._filters[0].padding;
+
+            bounds.pad(padding);
+        }
+
+        // for now we cache the current renderTarget that the webGL renderer is currently using.
+        // this could be more elegent..
+        var cachedRenderTarget = renderer._activeRenderTarget;
+        // We also store the filter stack - I will definitely look to change how this works a little later down the line.
+        var stack = renderer.filterManager.filterStack;
+
+        // this renderTexture will be used to store the cached DisplayObject
+
+        var renderTexture = core.RenderTexture.create(bounds.width | 0, bounds.height | 0);
+
+        // need to set //
+        var m = _tempMatrix;
+        m.tx = -bounds.x;
+        m.ty = -bounds.y;
+
+        // reset
+        this.transform.worldTransform.identity();
+
+        // set all properties to there original so we can render to a texture
+        this.renderWebGL = this._cacheData.originalRenderWebGL;
+
+
+        renderer.render(this, renderTexture, true, m, true);
+        // now restore the state be setting the new properties
+
+        renderer.bindRenderTarget(cachedRenderTarget);
+
+        renderer.filterManager.filterStack = stack;
+
+        this.renderWebGL     = this._renderCachedWebGL;
+        this.updateTransform = this.displayObjectUpdateTransform;
+
+        this._mask = null;
+        this.filterArea = null;
+
+        // create our cached sprite
+        var cachedSprite = new core.Sprite(renderTexture);
+        cachedSprite.transform.worldTransform = this.transform.worldTransform;
+        cachedSprite.anchor.x = -( bounds.x / bounds.width );
+        cachedSprite.anchor.y = -( bounds.y / bounds.height );
+        cachedSprite.alpha = cacheAlpha;
+        cachedSprite._bounds =  this._bounds;
+
+        //easy bounds..
+        this._calculateBounds  = this._calculateCachedBounds;
+        this.getLocalBounds  = this._getCachedLocalBounds;
+
+        this._cacheData.sprite = cachedSprite;
+
+        this.transform._parentID = -1;
+        // restore the transform of the cached sprite to avoid the nasty flicker..
+        this.updateTransform();
+
+        // map the hit test..
+        this.containsPoint = cachedSprite.containsPoint.bind(cachedSprite);
+    };
+
+    /**
+     * Renders a cached version of the sprite with canvas
+     *
+     * @param renderer {PIXI.CanvasRenderer} the Canvas renderer
+     * @private
+     */
+    DisplayObject.prototype._renderCachedCanvas = function (renderer)
+    {
+        if (!this.visible || this.worldAlpha <= 0 || !this.renderable)
+        {
+            return;
+        }
+
+        this._initCachedDisplayObjectCanvas( renderer );
+
+        this._cacheData.sprite.worldAlpha = this.worldAlpha;
+
+        this._cacheData.sprite.renderCanvas(renderer);
+    };
+
+//TODO this can be the same as the webGL verison.. will need to do a little tweaking first though..
+    /**
+     * Prepares the Canvas renderer to cache the sprite
+     *
+     * @param renderer {PIXI.CanvasRenderer} the Canvas renderer
+     * @private
+     */
+    DisplayObject.prototype._initCachedDisplayObjectCanvas = function (renderer)
+    {
+        if(this._cacheData && this._cacheData.sprite)
+        {
+            return;
+        }
+
+        //get bounds actually transforms the object for us already!
+        var bounds = this.getLocalBounds();
+
+        var cacheAlpha = this.alpha;
+        this.alpha = 1;
+
+        var cachedRenderTarget = renderer.context;
+
+        var renderTexture = new core.RenderTexture.create(bounds.width | 0, bounds.height | 0);
+
+        // need to set //
+        var m = _tempMatrix;
+        this.transform.worldTransform.copy(m);
+        m.invert();
+
+        m.tx -= bounds.x;
+        m.ty -= bounds.y;
+
+        //m.append(this.transform.worldTransform.)
+        // set all properties to there original so we can render to a texture
+        this.renderCanvas = this._cacheData.originalRenderCanvas;
+
+        //renderTexture.render(this, m, true);
+        renderer.render(this, renderTexture, true, m, false);
+
+        // now restore the state be setting the new properties
+        renderer.context = cachedRenderTarget;
+
+        this.renderCanvas = this._renderCachedCanvas;
+        this._calculateBounds  = this._calculateCachedBounds;
+
+        this._mask = null;
+        this.filterArea = null;
+
+        // create our cached sprite
+        var cachedSprite = new core.Sprite(renderTexture);
+        cachedSprite.transform.worldTransform = this.transform.worldTransform;
+        cachedSprite.anchor.x = -( bounds.x / bounds.width );
+        cachedSprite.anchor.y = -( bounds.y / bounds.height );
+        cachedSprite._bounds =  this._bounds;
+        cachedSprite.alpha = cacheAlpha;
+
+        this.updateTransform();
+        this.updateTransform = this.displayObjectUpdateTransform;
+
+        this._cacheData.sprite = cachedSprite;
+
+        this.containsPoint = cachedSprite.containsPoint.bind(cachedSprite);
+
+
+    };
+
+    /**
+     * Calculates the bounds of the cached sprite
+     *
+     * @private
+     */
+    DisplayObject.prototype._calculateCachedBounds = function ()
+    {
+        return this._cacheData.sprite._calculateBounds();
+    };
+
+    DisplayObject.prototype._getCachedLocalBounds = function ()
+    {
+        return this._cacheData.sprite.getLocalBounds();
+    };
+
+    /**
+     * Destroys the cached sprite.
+     *
+     * @private
+     */
+    DisplayObject.prototype._destroyCachedDisplayObject = function ()
+    {
+        this._cacheData.sprite._texture.destroy(true);
+        this._cacheData.sprite = null;
+    };
+
+    DisplayObject.prototype._cacheAsBitmapDestroy = function ()
+    {
+        this.cacheAsBitmap = false;
+        this.destroy();
+    };
+
+},{"../core":62}],127:[function(require,module,exports){
+    var core = require('../core');
+
+    /**
+     * The instance name of the object.
+     *
+     * @memberof PIXI.DisplayObject#
+     * @member {string}
+     */
+    core.DisplayObject.prototype.name = null;
+
+    /**
+     * Returns the display object in the container
+     *
+     * @memberof PIXI.Container#
+     * @param name {string} instance name
+     * @return {PIXI.DisplayObject}
+     */
+    core.Container.prototype.getChildByName = function (name)
+    {
+        for (var i = 0; i < this.children.length; i++)
+        {
+            if (this.children[i].name === name)
+            {
+                return this.children[i];
+            }
+        }
+        return null;
+    };
+
+},{"../core":62}],128:[function(require,module,exports){
+    var core = require('../core');
+
+    /**
+     * Returns the global position of the displayObject
+     *
+     * @memberof PIXI.DisplayObject#
+     * @param point {Point} the point to write the global value to. If null a new point will be returned
+     * @return {Point}
+     */
+    core.DisplayObject.prototype.getGlobalPosition = function (point)
+    {
+        point = point || new core.Point();
+
+        if(this.parent)
+        {
+            this.displayObjectUpdateTransform();
+
+            point.x = this.worldTransform.tx;
+            point.y = this.worldTransform.ty;
+        }
+        else
+        {
+            point.x = this.position.x;
+            point.y = this.position.y;
+        }
+
+        return point;
+    };
+
+},{"../core":62}],129:[function(require,module,exports){
+    /**
+     * @file        Main export of the PIXI extras library
+     * @author      Mat Groves <mat@goodboydigital.com>
+     * @copyright   2013-2015 GoodBoyDigital
+     * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}
+     */
+
+    require('./cacheAsBitmap');
+    require('./getChildByName');
+    require('./getGlobalPosition');
+
+    /**
+     * @namespace PIXI.extras
+     */
+    module.exports = {
+        MovieClip:      require('./MovieClip'),
+        TilingSprite:   require('./TilingSprite'),
+        BitmapText:     require('./BitmapText')
+    };
+
+},{"./BitmapText":123,"./MovieClip":124,"./TilingSprite":125,"./cacheAsBitmap":126,"./getChildByName":127,"./getGlobalPosition":128}],130:[function(require,module,exports){
+    var Shader = require('../../core/Shader');
+
+
+    /**
+     * @class
+     * @extends PIXI.Shader
+     * @memberof PIXI.mesh
+     * @param gl {PIXI.Shader} The WebGL shader manager this shader works for.
+     */
+    function TilingShader(gl)
+    {
+        Shader.call(this,
+            gl,
+            "#define GLSLIFY 1\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\nuniform mat3 translationMatrix;\n\nuniform vec4 uFrame;\nuniform vec4 uTransform;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n\n    vec2 coord = aTextureCoord;\n    coord -= uTransform.xy;\n    coord /= uTransform.zw;\n    vTextureCoord = coord;\n}\n",
+            "#define GLSLIFY 1\nvarying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\nuniform vec4 uColor;\nuniform vec4 uFrame;\nuniform vec2 uPixelSize;\n\nvoid main(void)\n{\n\n   \tvec2 coord = mod(vTextureCoord, uFrame.zw);\n   \tcoord = clamp(coord, uPixelSize, uFrame.zw - uPixelSize);\n   \tcoord += uFrame.xy;\n\n   \tvec4 sample = texture2D(uSampler, coord);\n  \tvec4 color = vec4(uColor.rgb * uColor.a, uColor.a);\n\n   \tgl_FragColor = sample * color ;\n}\n"
+        );
+    }
+
+    TilingShader.prototype = Object.create(Shader.prototype);
+    TilingShader.prototype.constructor = TilingShader;
+    module.exports = TilingShader;
+
+
+},{"../../core/Shader":42}],131:[function(require,module,exports){
+    var core = require('../../core'),
+        BlurXFilter = require('./BlurXFilter'),
+        BlurYFilter = require('./BlurYFilter');
+
+    /**
+     * The BlurFilter applies a Gaussian blur to an object.
+     * The strength of the blur can be set for x- and y-axis separately.
+     *
+     * @class
+     * @extends PIXI.Filter
+     * @memberof PIXI.filters
+     */
+    function BlurFilter(strength, quality, resolution)
+    {
+        core.Filter.call(this);
+
+        this.blurXFilter = new BlurXFilter();
+        this.blurYFilter = new BlurYFilter();
+        this.resolution = 1;
+
+        this.padding = 0;
+        this.resolution = resolution || 1;
+        this.quality = quality || 4;
+        this.blur = strength || 8;
+    }
+
+    BlurFilter.prototype = Object.create(core.Filter.prototype);
+    BlurFilter.prototype.constructor = BlurFilter;
+    module.exports = BlurFilter;
+
+    BlurFilter.prototype.apply = function (filterManager, input, output)
+    {
+
+        var renderTarget = filterManager.getRenderTarget(true);
+
+        this.blurXFilter.apply(filterManager, input, renderTarget, true);
+        this.blurYFilter.apply(filterManager, renderTarget, output, false);
+
+        filterManager.returnRenderTarget(renderTarget);
+    };
+
+    Object.defineProperties(BlurFilter.prototype, {
+        /**
+         * Sets the strength of both the blurX and blurY properties simultaneously
+         *
+         * @member {number}
+         * @memberOf PIXI.filters.BlurFilter#
+         * @default 2
+         */
+        blur: {
+            get: function ()
+            {
+                return this.blurXFilter.blur;
+            },
+            set: function (value)
+            {
+                this.blurXFilter.blur = this.blurYFilter.blur = value;
+                this.padding = Math.max( Math.abs(this.blurYFilter.strength),  Math.abs(this.blurYFilter.strength)) * 2;
+            }
+        },
+
+        /**
+         * Sets the number of passes for blur. More passes means higher quaility bluring.
+         *
+         * @member {number}
+         * @memberof PIXI.filters.BlurYFilter#
+         * @default 1
+         */
+        quality: {
+            get: function ()
+            {
+                return  this.blurXFilter.quality;
+            },
+            set: function (value)
+            {
+
+                this.blurXFilter.quality = this.blurYFilter.quality = value;
+            }
+        },
+
+        /**
+         * Sets the strength of the blurX property
+         *
+         * @member {number}
+         * @memberOf PIXI.filters.BlurFilter#
+         * @default 2
+         */
+        blurX: {
+            get: function ()
+            {
+                return this.blurXFilter.blur;
+            },
+            set: function (value)
+            {
+                this.blurXFilter.blur = value;
+                this.padding = Math.max( Math.abs(this.blurYFilter.strength),  Math.abs(this.blurYFilter.strength)) * 2;
+            }
+        },
+
+        /**
+         * Sets the strength of the blurY property
+         *
+         * @member {number}
+         * @memberOf PIXI.filters.BlurFilter#
+         * @default 2
+         */
+        blurY: {
+            get: function ()
+            {
+                return this.blurYFilter.blur;
+            },
+            set: function (value)
+            {
+                this.blurYFilter.blur = value;
+                this.padding = Math.max( Math.abs(this.blurYFilter.strength),  Math.abs(this.blurYFilter.strength)) * 2;
+            }
+        }
+    });
+
+},{"../../core":62,"./BlurXFilter":132,"./BlurYFilter":133}],132:[function(require,module,exports){
+    var core = require('../../core');
+    var generateBlurVertSource  = require('./generateBlurVertSource');
+    var generateBlurFragSource  = require('./generateBlurFragSource');
+    var getMaxBlurKernelSize    = require('./getMaxBlurKernelSize');
+
+    /**
+     * The BlurXFilter applies a horizontal Gaussian blur to an object.
+     *
+     * @class
+     * @extends PIXI.Filter
+     * @memberof PIXI.filters
+     */
+    function BlurXFilter(strength, quality, resolution)
+    {
+        var vertSrc = generateBlurVertSource(5, true);
+        var fragSrc = generateBlurFragSource(5);
+
+        core.Filter.call(this,
+            // vertex shader
+            vertSrc,
+            // fragment shader
+            fragSrc
+        );
+
+        this.resolution = resolution || 1;
+
+        this._quality = 0;
+
+        this.quality = quality || 4;
+        this.strength = strength || 8;
+
+        this.firstRun = true;
+
+    }
+
+    BlurXFilter.prototype = Object.create(core.Filter.prototype);
+    BlurXFilter.prototype.constructor = BlurXFilter;
+    module.exports = BlurXFilter;
+
+    BlurXFilter.prototype.apply = function (filterManager, input, output, clear)
+    {
+        if(this.firstRun)
+        {
+            var gl = filterManager.renderer.gl;
+            var kernelSize = getMaxBlurKernelSize(gl);
+
+            this.vertexSrc = generateBlurVertSource(kernelSize, true);
+            this.fragmentSrc = generateBlurFragSource(kernelSize);
+
+            this.firstRun = false;
+        }
+
+        this.uniforms.strength = (1/output.size.width) * (output.size.width/input.size.width); /// // *  2 //4//this.strength / 4 / this.passes * (input.frame.width / input.size.width);
+
+        // screen space!
+        this.uniforms.strength *= this.strength;
+        this.uniforms.strength /= this.passes;// / this.passes//Math.pow(1, this.passes);
+
+        if(this.passes === 1)
+        {
+            filterManager.applyFilter(this, input, output, clear);
+        }
+        else
+        {
+            var renderTarget = filterManager.getRenderTarget(true);
+            var flip = input;
+            var flop = renderTarget;
+
+            for(var i = 0; i < this.passes-1; i++)
+            {
+                filterManager.applyFilter(this, flip, flop, true);
+
+                var temp = flop;
+                flop = flip;
+                flip = temp;
+            }
+
+            filterManager.applyFilter(this, flip, output, clear);
+
+            filterManager.returnRenderTarget(renderTarget);
+        }
+    };
+
+
+    Object.defineProperties(BlurXFilter.prototype, {
+        /**
+         * Sets the strength of both the blur.
+         *
+         * @member {number}
+         * @memberof PIXI.filters.BlurXFilter#
+         * @default 16
+         */
+        blur: {
+            get: function ()
+            {
+                return  this.strength;
+            },
+            set: function (value)
+            {
+                this.padding =  Math.abs(value) * 2;
+                this.strength = value;
+            }
+        },
+
+        /**
+         * Sets the quality of the blur by modifying the number of passes. More passes means higher quaility bluring but the lower the performance.
+         *
+         * @member {number}
+         * @memberof PIXI.filters.BlurXFilter#
+         * @default 4
+         */
+        quality: {
+            get: function ()
+            {
+                return  this._quality;
+            },
+            set: function (value)
+            {
+                this._quality = value;
+                this.passes = value;
+            }
+        }
+    });
+
+},{"../../core":62,"./generateBlurFragSource":134,"./generateBlurVertSource":135,"./getMaxBlurKernelSize":136}],133:[function(require,module,exports){
+    var core = require('../../core');
+    var generateBlurVertSource  = require('./generateBlurVertSource');
+    var generateBlurFragSource  = require('./generateBlurFragSource');
+    var getMaxBlurKernelSize    = require('./getMaxBlurKernelSize');
+
+    /**
+     * The BlurYFilter applies a horizontal Gaussian blur to an object.
+     *
+     * @class
+     * @extends PIXI.Filter
+     * @memberof PIXI.filters
+     */
+    function BlurYFilter(strength, quality, resolution)
+    {
+        var vertSrc = generateBlurVertSource(5, false);
+        var fragSrc = generateBlurFragSource(5);
+
+        core.Filter.call(this,
+            // vertex shader
+            vertSrc,
+            // fragment shader
+            fragSrc
+        );
+
+        this.resolution = resolution || 1;
+
+        this._quality = 0;
+
+        this.quality = quality || 4;
+        this.strength = strength || 8;
+
+        this.firstRun = true;
+    }
+
+    BlurYFilter.prototype = Object.create(core.Filter.prototype);
+    BlurYFilter.prototype.constructor = BlurYFilter;
+    module.exports = BlurYFilter;
+
+    BlurYFilter.prototype.apply = function (filterManager, input, output, clear)
+    {
+        if(this.firstRun)
+        {
+            var gl = filterManager.renderer.gl;
+            var kernelSize = getMaxBlurKernelSize(gl);
+
+            this.vertexSrc = generateBlurVertSource(kernelSize, false);
+            this.fragmentSrc = generateBlurFragSource(kernelSize);
+
+            this.firstRun = false;
+        }
+
+        this.uniforms.strength = (1/output.size.height) * (output.size.height/input.size.height); /// // *  2 //4//this.strength / 4 / this.passes * (input.frame.width / input.size.width);
+
+        this.uniforms.strength *= this.strength;
+        this.uniforms.strength /= this.passes;
+
+        if(this.passes === 1)
+        {
+            filterManager.applyFilter(this, input, output, clear);
+        }
+        else
+        {
+            var renderTarget = filterManager.getRenderTarget(true);
+            var flip = input;
+            var flop = renderTarget;
+
+            for(var i = 0; i < this.passes-1; i++)
+            {
+                filterManager.applyFilter(this, flip, flop, true);
+
+                var temp = flop;
+                flop = flip;
+                flip = temp;
+            }
+
+            filterManager.applyFilter(this, flip, output, clear);
+
+            filterManager.returnRenderTarget(renderTarget);
+        }
+    };
+
+
+    Object.defineProperties(BlurYFilter.prototype, {
+        /**
+         * Sets the strength of both the blur.
+         *
+         * @member {number}
+         * @memberof PIXI.filters.BlurYFilter#
+         * @default 2
+         */
+        blur: {
+            get: function ()
+            {
+                return  this.strength;
+            },
+            set: function (value)
+            {
+                this.padding = Math.abs(value) * 2;
+                this.strength = value;
+            }
+        },
+
+        /**
+         * Sets the quality of the blur by modifying the number of passes. More passes means higher quaility bluring but the lower the performance.
+         *
+         * @member {number}
+         * @memberof PIXI.filters.BlurXFilter#
+         * @default 4
+         */
+        quality: {
+            get: function ()
+            {
+                return  this._quality;
+            },
+            set: function (value)
+            {
+                this._quality = value;
+                this.passes = value;
+            }
+        }
+    });
+
+},{"../../core":62,"./generateBlurFragSource":134,"./generateBlurVertSource":135,"./getMaxBlurKernelSize":136}],134:[function(require,module,exports){
+    var GAUSSIAN_VALUES = {
+        5:[0.153388, 0.221461, 0.250301],
+        7:[0.071303, 0.131514, 0.189879, 0.214607],
+        9:[0.028532, 0.067234, 0.124009, 0.179044, 0.20236],
+        11:[0.0093, 0.028002, 0.065984, 0.121703, 0.175713, 0.198596],
+        13:[0.002406, 0.009255, 0.027867, 0.065666, 0.121117, 0.174868, 0.197641],
+        15:[0.000489, 0.002403, 0.009246, 0.02784, 0.065602, 0.120999, 0.174697, 0.197448]
+    };
+
+    var fragTemplate = [
+        'varying vec2 vBlurTexCoords[%size%];',
+        'uniform sampler2D uSampler;',
+
+        'void main(void)',
+        '{',
+        '	gl_FragColor = vec4(0.0);',
+        '	%blur%',
+        '}'
+
+    ].join('\n');
+
+    var generateFragBlurSource = function(kernelSize)
+    {
+        var kernel = GAUSSIAN_VALUES[kernelSize];
+        var halfLength = kernel.length;
+
+        var fragSource = fragTemplate;
+
+        var blurLoop = '';
+        var template = 'gl_FragColor += texture2D(uSampler, vBlurTexCoords[%index%]) * %value%;';
+        var value;
+
+        for (var i = 0; i < kernelSize; i++)
+        {
+            var blur = template.replace('%index%', i);
+
+            value = i;
+
+            if(i >= halfLength)
+            {
+                value = kernelSize - i - 1;
+            }
+
+
+            blur = blur.replace('%value%', kernel[value]);
+
+            blurLoop += blur;
+            blurLoop += '\n';
+        }
+
+        fragSource = fragSource.replace('%blur%', blurLoop);
+        fragSource = fragSource.replace('%size%', kernelSize);
+
+
+        return fragSource;
+    };
+
+
+
+    module.exports = generateFragBlurSource;
+
+},{}],135:[function(require,module,exports){
+
+    var vertTemplate = [
+        'attribute vec2 aVertexPosition;',
+        'attribute vec2 aTextureCoord;',
+
+        'uniform float strength;',
+        'uniform mat3 projectionMatrix;',
+
+        'varying vec2 vBlurTexCoords[%size%];',
+
+        'void main(void)',
+        '{',
+        'gl_Position = vec4((projectionMatrix * vec3((aVertexPosition), 1.0)).xy, 0.0, 1.0);',
+        '%blur%',
+        '}'
+    ].join('\n');
+
+    var generateVertBlurSource = function(kernelSize, x)
+    {
+        var halfLength = Math.ceil(kernelSize/2);
+
+        var vertSource = vertTemplate;
+
+        var blurLoop = '';
+        var template;
+        var value;
+
+        if(x)
+        {
+            template = 'vBlurTexCoords[%index%] = aTextureCoord + vec2(%sampleIndex% * strength, 0.0);';
+        }
+        else
+        {
+            template = 'vBlurTexCoords[%index%] = aTextureCoord + vec2(0.0, %sampleIndex% * strength);';
+
+        }
+
+
+        for (var i = 0; i < kernelSize; i++)
+        {
+            var blur = template.replace('%index%', i);
+
+            value = i;
+
+            if(i >= halfLength)
+            {
+                value = kernelSize - i - 1;
+            }
+
+            blur = blur.replace('%sampleIndex%', (i - (halfLength-1)) + '.0');
+
+            blurLoop += blur;
+            blurLoop += '\n';
+        }
+
+        vertSource = vertSource.replace('%blur%', blurLoop);
+        vertSource = vertSource.replace('%size%', kernelSize);
+
+        return vertSource;
+    };
+
+
+
+    module.exports = generateVertBlurSource;
+
+},{}],136:[function(require,module,exports){
+
+
+    var getMaxKernelSize = function(gl)
+    {
+        var maxVaryings = ( gl.getParameter(gl.MAX_VARYING_VECTORS) );
+        var kernelSize = 15;
+
+        while(kernelSize > maxVaryings)
+        {
+            kernelSize -= 2;
+        }
+
+        return kernelSize;
+    };
+
+    module.exports = getMaxKernelSize;
+
+},{}],137:[function(require,module,exports){
+    var core = require('../../core');
+// @see https://github.com/substack/brfs/issues/25
+
+
+    /**
+     * The ColorMatrixFilter class lets you apply a 5x4 matrix transformation on the RGBA
+     * color and alpha values of every pixel on your displayObject to produce a result
+     * with a new set of RGBA color and alpha values. It's pretty powerful!
+     *
+     * ```js
+     *  var colorMatrix = new PIXI.ColorMatrixFilter();
+     *  container.filters = [colorMatrix];
+     *  colorMatrix.contrast(2);
+     * ```
+     * @author Clément Chenebault <clement@goodboydigital.com>
+     * @class
+     * @extends PIXI.Filter
+     * @memberof PIXI.filters
+     */
+    function ColorMatrixFilter()
+    {
+        core.Filter.call(this,
+            // vertex shader
+            "#define GLSLIFY 1\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n    vTextureCoord = aTextureCoord;\n}",
+            // fragment shader
+            "#define GLSLIFY 1\nvarying vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform float m[20];\n\nvoid main(void)\n{\n\n    vec4 c = texture2D(uSampler, vTextureCoord);\n\n    gl_FragColor.r = (m[0] * c.r);\n        gl_FragColor.r += (m[1] * c.g);\n        gl_FragColor.r += (m[2] * c.b);\n        gl_FragColor.r += (m[3] * c.a);\n        gl_FragColor.r += m[4] * c.a;\n\n    gl_FragColor.g = (m[5] * c.r);\n        gl_FragColor.g += (m[6] * c.g);\n        gl_FragColor.g += (m[7] * c.b);\n        gl_FragColor.g += (m[8] * c.a);\n        gl_FragColor.g += m[9] * c.a;\n\n     gl_FragColor.b = (m[10] * c.r);\n        gl_FragColor.b += (m[11] * c.g);\n        gl_FragColor.b += (m[12] * c.b);\n        gl_FragColor.b += (m[13] * c.a);\n        gl_FragColor.b += m[14] * c.a;\n\n     gl_FragColor.a = (m[15] * c.r);\n        gl_FragColor.a += (m[16] * c.g);\n        gl_FragColor.a += (m[17] * c.b);\n        gl_FragColor.a += (m[18] * c.a);\n        gl_FragColor.a += m[19] * c.a;\n\n//    gl_FragColor = vec4(m[0]);\n}\n"
+        );
+
+        this.uniforms.m = [
+            1, 0, 0, 0, 0,
+            0, 1, 0, 0, 0,
+            0, 0, 1, 0, 0,
+            0, 0, 0, 1, 0];
+
+
+    }
+
+    ColorMatrixFilter.prototype = Object.create(core.Filter.prototype);
+    ColorMatrixFilter.prototype.constructor = ColorMatrixFilter;
+    module.exports = ColorMatrixFilter;
+
+
+    /**
+     * Transforms current matrix and set the new one
+     *
+     * @param matrix {number[]} (mat 5x4)
+     * @param multiply {boolean} if true, current matrix and matrix are multiplied. If false, just set the current matrix with @param matrix
+     */
+    ColorMatrixFilter.prototype._loadMatrix = function (matrix, multiply)
+    {
+        multiply = !!multiply;
+
+        var newMatrix = matrix;
+
+        if (multiply) {
+            this._multiply(newMatrix, this.uniforms.m, matrix);
+            newMatrix = this._colorMatrix(newMatrix);
+        }
+
+        // set the new matrix
+        this.uniforms.m = newMatrix;
+    };
+
+    /**
+     * Multiplies two mat5's
+     *
+     * @param out {number[]} (mat 5x4) the receiving matrix
+     * @param a {number[]} (mat 5x4) the first operand
+     * @param b {number[]} (mat 5x4) the second operand
+     * @returns out {number[]} (mat 5x4)
+     */
+    ColorMatrixFilter.prototype._multiply = function (out, a, b)
+    {
+
+        // Red Channel
+        out[0] = (a[0] * b[0]) + (a[1] * b[5]) + (a[2] * b[10]) + (a[3] * b[15]);
+        out[1] = (a[0] * b[1]) + (a[1] * b[6]) + (a[2] * b[11]) + (a[3] * b[16]);
+        out[2] = (a[0] * b[2]) + (a[1] * b[7]) + (a[2] * b[12]) + (a[3] * b[17]);
+        out[3] = (a[0] * b[3]) + (a[1] * b[8]) + (a[2] * b[13]) + (a[3] * b[18]);
+        out[4] = (a[0] * b[4]) + (a[1] * b[9]) + (a[2] * b[14]) + (a[3] * b[19]);
+
+        // Green Channel
+        out[5] = (a[5] * b[0]) + (a[6] * b[5]) + (a[7] * b[10]) + (a[8] * b[15]);
+        out[6] = (a[5] * b[1]) + (a[6] * b[6]) + (a[7] * b[11]) + (a[8] * b[16]);
+        out[7] = (a[5] * b[2]) + (a[6] * b[7]) + (a[7] * b[12]) + (a[8] * b[17]);
+        out[8] = (a[5] * b[3]) + (a[6] * b[8]) + (a[7] * b[13]) + (a[8] * b[18]);
+        out[9] = (a[5] * b[4]) + (a[6] * b[9]) + (a[7] * b[14]) + (a[8] * b[19]);
+
+        // Blue Channel
+        out[10] = (a[10] * b[0]) + (a[11] * b[5]) + (a[12] * b[10]) + (a[13] * b[15]);
+        out[11] = (a[10] * b[1]) + (a[11] * b[6]) + (a[12] * b[11]) + (a[13] * b[16]);
+        out[12] = (a[10] * b[2]) + (a[11] * b[7]) + (a[12] * b[12]) + (a[13] * b[17]);
+        out[13] = (a[10] * b[3]) + (a[11] * b[8]) + (a[12] * b[13]) + (a[13] * b[18]);
+        out[14] = (a[10] * b[4]) + (a[11] * b[9]) + (a[12] * b[14]) + (a[13] * b[19]);
+
+        // Alpha Channel
+        out[15] = (a[15] * b[0]) + (a[16] * b[5]) + (a[17] * b[10]) + (a[18] * b[15]);
+        out[16] = (a[15] * b[1]) + (a[16] * b[6]) + (a[17] * b[11]) + (a[18] * b[16]);
+        out[17] = (a[15] * b[2]) + (a[16] * b[7]) + (a[17] * b[12]) + (a[18] * b[17]);
+        out[18] = (a[15] * b[3]) + (a[16] * b[8]) + (a[17] * b[13]) + (a[18] * b[18]);
+        out[19] = (a[15] * b[4]) + (a[16] * b[9]) + (a[17] * b[14]) + (a[18] * b[19]);
+
+        return out;
+    };
+
+    /**
+     * Create a Float32 Array and normalize the offset component to 0-1
+     *
+     * @param matrix {number[]} (mat 5x4)
+     * @return m {number[]} (mat 5x4) with all values between 0-1
+     */
+    ColorMatrixFilter.prototype._colorMatrix = function (matrix)
+    {
+        // Create a Float32 Array and normalize the offset component to 0-1
+        var m = new Float32Array(matrix);
+        m[4] /= 255;
+        m[9] /= 255;
+        m[14] /= 255;
+        m[19] /= 255;
+
+        return m;
+    };
+
+    /**
+     * Adjusts brightness
+     *
+     * @param b {number} value of the brigthness (0 is black)
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.brightness = function (b, multiply)
+    {
+        var matrix = [
+            b, 0, 0, 0, 0,
+            0, b, 0, 0, 0,
+            0, 0, b, 0, 0,
+            0, 0, 0, 1, 0
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /**
+     * Set the matrices in grey scales
+     *
+     * @param scale {number} value of the grey (0 is black)
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.greyscale = function (scale, multiply)
+    {
+        var matrix = [
+            scale, scale, scale, 0, 0,
+            scale, scale, scale, 0, 0,
+            scale, scale, scale, 0, 0,
+            0, 0, 0, 1, 0
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+//Americanized alias
+    ColorMatrixFilter.prototype.grayscale = ColorMatrixFilter.prototype.greyscale;
+
+    /**
+     * Set the black and white matrice
+     * Multiply the current matrix
+     *
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.blackAndWhite = function (multiply)
+    {
+        var matrix = [
+            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
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /**
+     * Set the hue property of the color
+     *
+     * @param rotation {number} in degrees
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.hue = function (rotation, multiply)
+    {
+        rotation = (rotation || 0) / 180 * Math.PI;
+
+        var cosR = Math.cos(rotation),
+            sinR = Math.sin(rotation),
+            sqrt = Math.sqrt;
+
+        /*a good approximation for hue rotation
+         This matrix is far better than the versions with magic luminance constants
+         formerly used here, but also used in the starling framework (flash) and known from this
+         old part of the internet: quasimondo.com/archives/000565.php
+
+         This new matrix is based on rgb cube rotation in space. Look here for a more descriptive
+         implementation as a shader not a general matrix:
+         https://github.com/evanw/glfx.js/blob/58841c23919bd59787effc0333a4897b43835412/src/filters/adjust/huesaturation.js
+
+         This is the source for the code:
+         see http://stackoverflow.com/questions/8507885/shift-hue-of-an-rgb-color/8510751#8510751
+         */
+
+        var w = 1/3, sqrW = sqrt(w);//weight is
+
+        var a00 = cosR + (1.0 - cosR) * w;
+        var a01 = w * (1.0 - cosR) - sqrW * sinR;
+        var a02 = w * (1.0 - cosR) + sqrW * sinR;
+
+        var a10 = w * (1.0 - cosR) + sqrW * sinR;
+        var a11 = cosR + w*(1.0 - cosR);
+        var a12 = w * (1.0 - cosR) - sqrW * sinR;
+
+        var a20 = w * (1.0 - cosR) - sqrW * sinR;
+        var a21 = w * (1.0 - cosR) + sqrW * sinR;
+        var a22 = cosR + w * (1.0 - cosR);
+
+
+        var matrix = [
+            a00, a01, a02, 0, 0,
+            a10, a11, a12, 0, 0,
+            a20, a21, a22, 0, 0,
+            0, 0, 0, 1, 0,
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+
+    /**
+     * Set the contrast matrix, increase the separation between dark and bright
+     * Increase contrast : shadows darker and highlights brighter
+     * Decrease contrast : bring the shadows up and the highlights down
+     *
+     * @param amount {number} value of the contrast
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.contrast = function (amount, multiply)
+    {
+        var v = (amount || 0) + 1;
+        var o = -128 * (v - 1);
+
+        var matrix = [
+            v, 0, 0, 0, o,
+            0, v, 0, 0, o,
+            0, 0, v, 0, o,
+            0, 0, 0, 1, 0
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /**
+     * Set the saturation matrix, increase the separation between colors
+     * Increase saturation : increase contrast, brightness, and sharpness
+     *
+     * @param [amount=0] {number}
+     * @param [multiply] {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.saturate = function (amount, multiply)
+    {
+        var x = (amount || 0) * 2 / 3 + 1;
+        var y = ((x - 1) * -0.5);
+
+        var matrix = [
+            x, y, y, 0, 0,
+            y, x, y, 0, 0,
+            y, y, x, 0, 0,
+            0, 0, 0, 1, 0
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /**
+     * Desaturate image (remove color)
+     *
+     * Call the saturate function
+     *
+     */
+    ColorMatrixFilter.prototype.desaturate = function () // jshint unused:false
+    {
+        this.saturate(-1);
+    };
+
+    /**
+     * Negative image (inverse of classic rgb matrix)
+     *
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.negative = function (multiply)
+    {
+        var matrix = [
+            0, 1, 1, 0, 0,
+            1, 0, 1, 0, 0,
+            1, 1, 0, 0, 0,
+            0, 0, 0, 1, 0
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /**
+     * Sepia image
+     *
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.sepia = function (multiply)
+    {
+        var matrix = [
+            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
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /**
+     * Color motion picture process invented in 1916 (thanks Dominic Szablewski)
+     *
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.technicolor = function (multiply)
+    {
+        var matrix = [
+            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
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /**
+     * Polaroid filter
+     *
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.polaroid = function (multiply)
+    {
+        var matrix = [
+            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
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /**
+     * Filter who transforms : Red -> Blue and Blue -> Red
+     *
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.toBGR = function (multiply)
+    {
+        var matrix = [
+            0, 0, 1, 0, 0,
+            0, 1, 0, 0, 0,
+            1, 0, 0, 0, 0,
+            0, 0, 0, 1, 0
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /**
+     * Color reversal film introduced by Eastman Kodak in 1935. (thanks Dominic Szablewski)
+     *
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.kodachrome = function (multiply)
+    {
+        var matrix = [
+            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
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /**
+     * Brown delicious browni filter (thanks Dominic Szablewski)
+     *
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.browni = function (multiply)
+    {
+        var matrix = [
+            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
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /*
+     * Vintage filter (thanks Dominic Szablewski)
+     *
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.vintage = function (multiply)
+    {
+        var matrix = [
+            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
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /*
+     * We don't know exactly what it does, kind of gradient map, but funny to play with!
+     *
+     * @param desaturation {number}
+     * @param toned {number}
+     * @param lightColor {string} (example : "0xFFE580")
+     * @param darkColor {string}  (example : "0xFFE580")
+     *
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.colorTone = function (desaturation, toned, lightColor, darkColor, multiply)
+    {
+        desaturation = desaturation || 0.2;
+        toned = toned || 0.15;
+        lightColor = lightColor || 0xFFE580;
+        darkColor = darkColor || 0x338000;
+
+        var lR = ((lightColor >> 16) & 0xFF) / 255;
+        var lG = ((lightColor >> 8) & 0xFF) / 255;
+        var lB = (lightColor & 0xFF) / 255;
+
+        var dR = ((darkColor >> 16) & 0xFF) / 255;
+        var dG = ((darkColor >> 8) & 0xFF) / 255;
+        var dB = (darkColor & 0xFF) / 255;
+
+        var matrix = [
+            0.3, 0.59, 0.11, 0, 0,
+            lR, lG, lB, desaturation, 0,
+            dR, dG, dB, toned, 0,
+            lR - dR, lG - dG, lB - dB, 0, 0
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /*
+     * Night effect
+     *
+     * @param intensity {number}
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.night = function (intensity, multiply)
+    {
+        intensity = intensity || 0.1;
+        var matrix = [
+            intensity * ( -2.0), -intensity, 0, 0, 0,
+            -intensity, 0, intensity, 0, 0,
+            0, intensity, intensity * 2.0, 0, 0,
+            0, 0, 0, 1, 0
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+
+    /*
+     * Predator effect
+     *
+     * Erase the current matrix by setting a new indepent one
+     *
+     * @param amount {number} how much the predator feels his future victim
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.predator = function (amount, multiply)
+    {
+        var matrix = [
+            11.224130630493164 * amount, -4.794486999511719 * amount, -2.8746118545532227 * amount, 0 * amount, 0.40342438220977783 * amount,
+            -3.6330697536468506 * amount, 9.193157196044922 * amount, -2.951810836791992 * amount, 0 * amount, -1.316135048866272 * amount,
+            -3.2184197902679443 * amount, -4.2375030517578125 * amount, 7.476448059082031 * amount, 0 * amount, 0.8044459223747253 * amount,
+            0, 0, 0, 1, 0
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /*
+     * LSD effect
+     *
+     * Multiply the current matrix
+     *
+     * @param amount {number} How crazy is your effect
+     * @param multiply {boolean} refer to ._loadMatrix() method
+     */
+    ColorMatrixFilter.prototype.lsd = function (multiply)
+    {
+        var matrix = [
+            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
+        ];
+
+        this._loadMatrix(matrix, multiply);
+    };
+
+    /*
+     * Erase the current matrix by setting the default one
+     *
+     */
+    ColorMatrixFilter.prototype.reset = function ()
+    {
+        var matrix = [
+            1, 0, 0, 0, 0,
+            0, 1, 0, 0, 0,
+            0, 0, 1, 0, 0,
+            0, 0, 0, 1, 0
+        ];
+
+        this._loadMatrix(matrix, false);
+    };
+
+
+    Object.defineProperties(ColorMatrixFilter.prototype, {
+        /**
+         * Sets the matrix of the color matrix filter
+         *
+         * @member {number[]}
+         * @memberof PIXI.filters.ColorMatrixFilter#
+         * @default [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0]
+         */
+        matrix: {
+            get: function ()
+            {
+                return this.uniforms.m;
+            },
+            set: function (value)
+            {
+                this.uniforms.m = value;
+            }
+        }
+    });
+
+},{"../../core":62}],138:[function(require,module,exports){
+    var core = require('../../core');
+
+
+    /**
+     * The DisplacementFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object.
+     * You can use this filter to apply all manor of crazy warping effects
+     * Currently the r property of the texture is used to offset the x and the g property of the texture is used to offset the y.
+     *
+     * @class
+     * @extends PIXI.Filter
+     * @memberof PIXI.filters
+     * @param sprite {PIXI.Sprite} The sprite used for the displacement map. (make sure its added to the scene!)
+     * @param scale {number} The scale of the displacement
+     */
+    function DisplacementFilter(sprite, scale)
+    {
+        var maskMatrix = new core.Matrix();
+        sprite.renderable = false;
+
+        core.Filter.call(this,
+            // vertex shader
+//        glslify('./displacement.vert'),
+            "#define GLSLIFY 1\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\nuniform mat3 filterMatrix;\n\nvarying vec2 vTextureCoord;\nvarying vec2 vFilterCoord;\n\nvoid main(void)\n{\n   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n   vFilterCoord = ( filterMatrix * vec3( aTextureCoord, 1.0)  ).xy;\n   vTextureCoord = aTextureCoord;\n}",
+            // fragment shader
+            "#define GLSLIFY 1\nvarying vec2 vFilterCoord;\nvarying vec2 vTextureCoord;\n\nuniform vec2 scale;\n\nuniform sampler2D uSampler;\nuniform sampler2D mapSampler;\n\nuniform vec4 filterClamp;\n\nvoid main(void)\n{\n   vec4 map =  texture2D(mapSampler, vFilterCoord);\n\n   map -= 0.5;\n   map.xy *= scale;\n\n   gl_FragColor = texture2D(uSampler, clamp(vec2(vTextureCoord.x + map.x, vTextureCoord.y + map.y), filterClamp.xy, filterClamp.zw));\n}\n"
+
+        );
+
+        this.maskSprite = sprite;
+        this.maskMatrix = maskMatrix;
+
+        this.uniforms.mapSampler = sprite.texture;
+        this.uniforms.filterMatrix = maskMatrix.toArray(true);
+        this.uniforms.scale = { x: 1, y: 1 };
+
+        if (scale === null || scale === undefined)
+        {
+            scale = 20;
+        }
+
+        this.scale = new core.Point(scale, scale);
+    }
+
+    DisplacementFilter.prototype = Object.create(core.Filter.prototype);
+    DisplacementFilter.prototype.constructor = DisplacementFilter;
+    module.exports = DisplacementFilter;
+
+    DisplacementFilter.prototype.apply = function (filterManager, input, output)
+    {
+        var ratio =  (1/output.destinationFrame.width) * (output.size.width/input.size.width); /// // *  2 //4//this.strength / 4 / this.passes * (input.frame.width / input.size.width);
+
+        this.uniforms.filterMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, this.maskSprite);
+        this.uniforms.scale.x = this.scale.x * ratio;
+        this.uniforms.scale.y = this.scale.y * ratio;
+
+        // draw the filter...
+        filterManager.applyFilter(this, input, output);
+    };
+
+
+    Object.defineProperties(DisplacementFilter.prototype, {
+        /**
+         * The texture used for the displacement map. Must be power of 2 sized texture.
+         *
+         * @member {PIXI.Texture}
+         * @memberof PIXI.filters.DisplacementFilter#
+         */
+        map: {
+            get: function ()
+            {
+                return this.uniforms.mapSampler;
+            },
+            set: function (value)
+            {
+                this.uniforms.mapSampler = value;
+
+            }
+        }
+    });
+
+},{"../../core":62}],139:[function(require,module,exports){
+    var core = require('../../core');
+
+
+    /**
+     *
+     * Basic FXAA implementation based on the code on geeks3d.com with the
+     * modification that the texture2DLod stuff was removed since it's
+     * unsupported by WebGL.
+     *
+     * @see https://github.com/mitsuhiko/webgl-meincraft
+     *
+     * @class
+     * @extends PIXI.Filter
+     * @memberof PIXI
+     *
+     */
+    function FXAAFilter()
+    {
+        //TODO - needs work
+        core.Filter.call(this,
+
+            // vertex shader
+            "#define GLSLIFY 1\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 v_rgbNW;\nvarying vec2 v_rgbNE;\nvarying vec2 v_rgbSW;\nvarying vec2 v_rgbSE;\nvarying vec2 v_rgbM;\n\nuniform vec4 filterArea;\n\nvarying vec2 vTextureCoord;\n\nvec2 mapCoord( vec2 coord )\n{\n    coord *= filterArea.xy;\n    coord += filterArea.zw;\n\n    return coord;\n}\n\nvec2 unmapCoord( vec2 coord )\n{\n    coord -= filterArea.zw;\n    coord /= filterArea.xy;\n\n    return coord;\n}\n\nvoid texcoords(vec2 fragCoord, vec2 resolution,\n               out vec2 v_rgbNW, out vec2 v_rgbNE,\n               out vec2 v_rgbSW, out vec2 v_rgbSE,\n               out vec2 v_rgbM) {\n    vec2 inverseVP = 1.0 / resolution.xy;\n    v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\n    v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\n    v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\n    v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\n    v_rgbM = vec2(fragCoord * inverseVP);\n}\n\nvoid main(void) {\n\n   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n\n   vTextureCoord = aTextureCoord;\n\n   vec2 fragCoord = vTextureCoord * filterArea.xy;\n\n   texcoords(fragCoord, filterArea.xy, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n}",
+            // fragment shader
+            "#define GLSLIFY 1\nvarying vec2 v_rgbNW;\nvarying vec2 v_rgbNE;\nvarying vec2 v_rgbSW;\nvarying vec2 v_rgbSE;\nvarying vec2 v_rgbM;\n\nvarying vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform vec4 filterArea;\n\n/**\n Basic FXAA implementation based on the code on geeks3d.com with the\n modification that the texture2DLod stuff was removed since it's\n unsupported by WebGL.\n \n --\n \n From:\n https://github.com/mitsuhiko/webgl-meincraft\n \n Copyright (c) 2011 by Armin Ronacher.\n \n Some rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are\n met:\n \n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n \n * Redistributions in binary form must reproduce the above\n copyright notice, this list of conditions and the following\n disclaimer in the documentation and/or other materials provided\n with the distribution.\n \n * The names of the contributors may not be used to endorse or\n promote products derived from this software without specific\n prior written permission.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef FXAA_REDUCE_MIN\n#define FXAA_REDUCE_MIN   (1.0/ 128.0)\n#endif\n#ifndef FXAA_REDUCE_MUL\n#define FXAA_REDUCE_MUL   (1.0 / 8.0)\n#endif\n#ifndef FXAA_SPAN_MAX\n#define FXAA_SPAN_MAX     8.0\n#endif\n\n//optimized version for mobile, where dependent\n//texture reads can be a bottleneck\nvec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution,\n          vec2 v_rgbNW, vec2 v_rgbNE,\n          vec2 v_rgbSW, vec2 v_rgbSE,\n          vec2 v_rgbM) {\n    vec4 color;\n    mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y);\n    vec3 rgbNW = texture2D(tex, v_rgbNW).xyz;\n    vec3 rgbNE = texture2D(tex, v_rgbNE).xyz;\n    vec3 rgbSW = texture2D(tex, v_rgbSW).xyz;\n    vec3 rgbSE = texture2D(tex, v_rgbSE).xyz;\n    vec4 texColor = texture2D(tex, v_rgbM);\n    vec3 rgbM  = texColor.xyz;\n    vec3 luma = vec3(0.299, 0.587, 0.114);\n    float lumaNW = dot(rgbNW, luma);\n    float lumaNE = dot(rgbNE, luma);\n    float lumaSW = dot(rgbSW, luma);\n    float lumaSE = dot(rgbSE, luma);\n    float lumaM  = dot(rgbM,  luma);\n    float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\n    float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\n    \n    mediump vec2 dir;\n    dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n    dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n    \n    float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\n                          (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);\n    \n    float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\n    dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),\n              max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\n                  dir * rcpDirMin)) * inverseVP;\n    \n    vec3 rgbA = 0.5 * (\n                       texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\n                       texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\n    vec3 rgbB = rgbA * 0.5 + 0.25 * (\n                                     texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz +\n                                     texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);\n    \n    float lumaB = dot(rgbB, luma);\n    if ((lumaB < lumaMin) || (lumaB > lumaMax))\n        color = vec4(rgbA, texColor.a);\n    else\n        color = vec4(rgbB, texColor.a);\n    return color;\n}\n\nvoid main() {\n\n  \tvec2 fragCoord = vTextureCoord * filterArea.xy;\n\n  \tvec4 color;\n\n    color = fxaa(uSampler, fragCoord, filterArea.xy, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n\n  \tgl_FragColor = color;\n}\n"
+        );
+
+    }
+
+    FXAAFilter.prototype = Object.create(core.Filter.prototype);
+    FXAAFilter.prototype.constructor = FXAAFilter;
+
+    module.exports = FXAAFilter;
+
+},{"../../core":62}],140:[function(require,module,exports){
+    /**
+     * @file        Main export of the PIXI filters library
+     * @author      Mat Groves <mat@goodboydigital.com>
+     * @copyright   2013-2015 GoodBoyDigital
+     * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}
+     */
+
+    /**
+     * @namespace PIXI.filters
+     */
+    module.exports = {
+        FXAAFilter:          require('./fxaa/FXAAFilter'),
+        NoiseFilter:        require('./noise/NoiseFilter'),
+        DisplacementFilter: require('./displacement/DisplacementFilter'),
+        BlurFilter:         require('./blur/BlurFilter'),
+        BlurXFilter:        require('./blur/BlurXFilter'),
+        BlurYFilter:        require('./blur/BlurYFilter'),
+        ColorMatrixFilter:  require('./colormatrix/ColorMatrixFilter'),
+        VoidFilter:         require('./void/VoidFilter')
+    };
+
+},{"./blur/BlurFilter":131,"./blur/BlurXFilter":132,"./blur/BlurYFilter":133,"./colormatrix/ColorMatrixFilter":137,"./displacement/DisplacementFilter":138,"./fxaa/FXAAFilter":139,"./noise/NoiseFilter":141,"./void/VoidFilter":142}],141:[function(require,module,exports){
+    var core = require('../../core');
+
+
+    /**
+     * @author Vico @vicocotea
+     * original filter: https://github.com/evanw/glfx.js/blob/master/src/filters/adjust/noise.js
+     */
+
+    /**
+     * A Noise effect filter.
+     *
+     * @class
+     * @extends PIXI.Filter
+     * @memberof PIXI.filters
+     */
+    function NoiseFilter()
+    {
+        core.Filter.call(this,
+            // vertex shader
+            "#define GLSLIFY 1\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n    vTextureCoord = aTextureCoord;\n}",
+            // fragment shader
+            "precision highp float;\n#define GLSLIFY 1\n\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\n\nuniform float noise;\nuniform sampler2D uSampler;\n\nfloat rand(vec2 co)\n{\n    return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main()\n{\n    vec4 color = texture2D(uSampler, vTextureCoord);\n\n    float diff = (rand(gl_FragCoord.xy) - 0.5) * noise;\n\n    color.r += diff;\n    color.g += diff;\n    color.b += diff;\n\n    gl_FragColor = color;\n}\n"
+        );
+
+        this.noise = 0.5;
+    }
+
+    NoiseFilter.prototype = Object.create(core.Filter.prototype);
+    NoiseFilter.prototype.constructor = NoiseFilter;
+    module.exports = NoiseFilter;
+
+    Object.defineProperties(NoiseFilter.prototype, {
+        /**
+         * The amount of noise to apply.
+         *
+         * @member {number}
+         * @memberof PIXI.filters.NoiseFilter#
+         * @default 0.5
+         */
+        noise: {
+            get: function ()
+            {
+                return this.uniforms.noise;
+            },
+            set: function (value)
+            {
+                this.uniforms.noise = value;
+            }
+        }
+    });
+
+},{"../../core":62}],142:[function(require,module,exports){
+    var core = require('../../core');
+// @see https://github.com/substack/brfs/issues/25
+
+
+    /**
+     * Does nothing. Very handy.
+     *
+     * @class
+     * @extends PIXI.Filter
+     * @memberof PIXI.filters
+     */
+    function VoidFilter()
+    {
+        core.Filter.call(this,
+            // vertex shader
+            "#define GLSLIFY 1\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n    vTextureCoord = aTextureCoord;\n}",
+            // fragment shader
+            "#define GLSLIFY 1\nvarying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\n\nvoid main(void)\n{\n   gl_FragColor = texture2D(uSampler, vTextureCoord);\n}\n"
+        );
+
+        this.glShaderKey = 'void';
+    }
+
+    VoidFilter.prototype = Object.create(core.Filter.prototype);
+    VoidFilter.prototype.constructor = VoidFilter;
+    module.exports = VoidFilter;
+
+},{"../../core":62}],143:[function(require,module,exports){
+    var core = require('../core');
+
+    /**
+     * Holds all information related to an Interaction event
+     *
+     * @class
+     * @memberof PIXI.interaction
+     */
+    function InteractionData()
+    {
+        /**
+         * This point stores the global coords of where the touch/mouse event happened
+         *
+         * @member {PIXI.Point}
+         */
+        this.global = new core.Point();
+
+        /**
+         * The target Sprite that was interacted with
+         *
+         * @member {PIXI.Sprite}
+         */
+        this.target = null;
+
+        /**
+         * When passed to an event handler, this will be the original DOM Event that was captured
+         *
+         * @member {Event}
+         */
+        this.originalEvent = null;
+    }
+
+    InteractionData.prototype.constructor = InteractionData;
+    module.exports = InteractionData;
+
+    /**
+     * This will return the local coordinates of the specified displayObject for this InteractionData
+     *
+     * @param displayObject {PIXI.DisplayObject} The DisplayObject that you would like the local coords off
+     * @param [point] {PIXI.Point} A Point object in which to store the value, optional (otherwise will create a new point)
+     * @param [globalPos] {PIXI.Point} A Point object containing your custom global coords, optional (otherwise will use the current global coords)
+     * @return {PIXI.Point} A point containing the coordinates of the InteractionData position relative to the DisplayObject
+     */
+    InteractionData.prototype.getLocalPosition = function (displayObject, point, globalPos)
+    {
+        return displayObject.worldTransform.applyInverse(globalPos || this.global, point);
+    };
+
+},{"../core":62}],144:[function(require,module,exports){
+    var core = require('../core'),
+        InteractionData = require('./InteractionData'),
+        EventEmitter = require('eventemitter3');
+
+// Mix interactiveTarget into core.DisplayObject.prototype
+    Object.assign(
+        core.DisplayObject.prototype,
+        require('./interactiveTarget')
+    );
+
+    /**
+     * The interaction manager deals with mouse and touch events. Any DisplayObject can be interactive
+     * if its interactive parameter is set to true
+     * This manager also supports multitouch.
+     *
+     * @class
+     * @extends EventEmitter
+     * @memberof PIXI.interaction
+     * @param renderer {PIXI.CanvasRenderer|PIXI.WebGLRenderer} A reference to the current renderer
+     * @param [options] {object}
+     * @param [options.autoPreventDefault=true] {boolean} Should the manager automatically prevent default browser actions.
+     * @param [options.interactionFrequency=10] {number} Frequency increases the interaction events will be checked.
+     */
+    function InteractionManager(renderer, options)
+    {
+        EventEmitter.call(this);
+
+        options = options || {};
+
+        /**
+         * The renderer this interaction manager works for.
+         *
+         * @member {PIXI.SystemRenderer}
+         */
+        this.renderer = renderer;
+
+        /**
+         * Should default browser actions automatically be prevented.
+         *
+         * @member {boolean}
+         * @default true
+         */
+        this.autoPreventDefault = options.autoPreventDefault !== undefined ? options.autoPreventDefault : true;
+
+        /**
+         * As this frequency increases the interaction events will be checked more often.
+         *
+         * @member {number}
+         * @default 10
+         */
+        this.interactionFrequency = options.interactionFrequency || 10;
+
+        /**
+         * The mouse data
+         *
+         * @member {PIXI.interaction.InteractionData}
+         */
+        this.mouse = new InteractionData();
+
+        // setting the pointer to start off far off screen will mean that mouse over does
+        //  not get called before we even move the mouse.
+        this.mouse.global.set(-999999);
+
+        /**
+         * An event data object to handle all the event tracking/dispatching
+         *
+         * @member {object}
+         */
+        this.eventData = {
+            stopped: false,
+            target: null,
+            type: null,
+            data: this.mouse,
+            stopPropagation:function(){
+                this.stopped = true;
+            }
+        };
+
+        /**
+         * Tiny little interactiveData pool !
+         *
+         * @member {PIXI.interaction.InteractionData[]}
+         */
+        this.interactiveDataPool = [];
+
+        /**
+         * The DOM element to bind to.
+         *
+         * @member {HTMLElement}
+         * @private
+         */
+        this.interactionDOMElement = null;
+
+        /**
+         * This property determins if mousemove and touchmove events are fired only when the cursror is over the object
+         * Setting to true will make things work more in line with how the DOM verison works.
+         * Setting to false can make things easier for things like dragging
+         * It is currently set to false as this is how pixi used to work. This will be set to true in future versions of pixi.
+         * @member {boolean}
+         * @private
+         */
+        this.moveWhenInside = false;
+
+        /**
+         * Have events been attached to the dom element?
+         *
+         * @member {boolean}
+         * @private
+         */
+        this.eventsAdded = false;
+
+        //this will make it so that you don't have to call bind all the time
+
+        /**
+         * @member {Function}
+         * @private
+         */
+        this.onMouseUp = this.onMouseUp.bind(this);
+        this.processMouseUp = this.processMouseUp.bind( this );
+
+
+        /**
+         * @member {Function}
+         *  @private
+         */
+        this.onMouseDown = this.onMouseDown.bind(this);
+        this.processMouseDown = this.processMouseDown.bind( this );
+
+        /**
+         * @member {Function}
+         * @private
+         */
+        this.onMouseMove = this.onMouseMove.bind( this );
+        this.processMouseMove = this.processMouseMove.bind( this );
+
+        /**
+         * @member {Function}
+         * @private
+         */
+        this.onMouseOut = this.onMouseOut.bind(this);
+        this.processMouseOverOut = this.processMouseOverOut.bind( this );
+
+        /**
+         * @member {Function}
+         * @private
+         */
+        this.onMouseOver = this.onMouseOver.bind(this);
+
+
+        /**
+         * @member {Function}
+         * @private
+         */
+        this.onTouchStart = this.onTouchStart.bind(this);
+        this.processTouchStart = this.processTouchStart.bind(this);
+
+        /**
+         * @member {Function}
+         * @private
+         */
+        this.onTouchEnd = this.onTouchEnd.bind(this);
+        this.processTouchEnd = this.processTouchEnd.bind(this);
+
+        /**
+         * @member {Function}
+         * @private
+         */
+        this.onTouchMove = this.onTouchMove.bind(this);
+        this.processTouchMove = this.processTouchMove.bind(this);
+
+        /**
+         * Every update cursor will be reset to this value, if some element wont override it in its hitTest
+         * @member {string}
+         * @default 'inherit'
+         */
+        this.defaultCursorStyle = 'inherit';
+
+        /**
+         * The css style of the cursor that is being used
+         * @member {string}
+         */
+        this.currentCursorStyle = 'inherit';
+
+        /**
+         * Internal cached var
+         * @member {PIXI.Point}
+         * @private
+         */
+        this._tempPoint = new core.Point();
+
+
+        /**
+         * The current resolution / device pixel ratio.
+         * @member {number}
+         * @default 1
+         */
+        this.resolution = 1;
+
+        this.setTargetElement(this.renderer.view, this.renderer.resolution);
+
+        /**
+         * Fired when a pointing device button (usually a mouse button) is pressed on the display object.
+         *
+         * @memberof PIXI.interaction.InteractionManager#
+         * @event mousedown
+         */
+
+        /**
+         * Fired when a pointing device secondary button (usually a mouse right-button) is pressed on the display object.
+         *
+         * @memberof PIXI.interaction.InteractionManager#
+         * @event rightdown
+         */
+
+        /**
+         * Fired when a pointing device button (usually a mouse button) is released over the display object.
+         *
+         * @memberof PIXI.interaction.InteractionManager#
+         * @event mouseup
+         */
+
+        /**
+         * Fired when a pointing device secondary button (usually a mouse right-button) is released over the display object.
+         *
+         * @memberof PIXI.interaction.InteractionManager#
+         * @event rightup
+         */
+
+        /**
+         * Fired when a pointing device button (usually a mouse button) is pressed and released on the display object.
+         *
+         * @event click
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+
+        /**
+         * Fired when a pointing device secondary button (usually a mouse right-button) is pressed and released on the display object.
+         *
+         * @event rightclick
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+
+        /**
+         * Fired when a pointing device button (usually a mouse button) is released outside the display object that initially registered a [mousedown]{@link PIXI.interaction.InteractionManager#event:mousedown}.
+         *
+         * @event mouseupoutside
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+
+        /**
+         * Fired when a pointing device secondary button (usually a mouse right-button) is released outside the display object that initially
+         * registered a [rightdown]{@link PIXI.interaction.InteractionManager#event:rightdown}.
+         *
+         * @event rightupoutside
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+
+        /**
+         * Fired when a pointing device (usually a mouse) is moved while over the display object
+         *
+         * @event mousemove
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+
+        /**
+         * Fired when a pointing device (usually a mouse) is moved onto the display object
+         *
+         * @event mouseover
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+
+        /**
+         * Fired when a pointing device (usually a mouse) is moved off the display object
+         *
+         * @event mouseout
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+
+        /**
+         * Fired when a touch point is placed on the display object.
+         *
+         * @event touchstart
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+
+        /**
+         * Fired when a touch point is removed from the display object.
+         *
+         * @event touchend
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+
+        /**
+         * Fired when a touch point is placed and removed from the display object.
+         *
+         * @event tap
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+
+        /**
+         * Fired when a touch point is removed outside of the display object that initially registered a [touchstart]{@link PIXI.interaction.InteractionManager#event:touchstart}.
+         *
+         * @event touchendoutside
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+
+        /**
+         * Fired when a touch point is moved along the display object.
+         *
+         * @event touchmove
+         * @memberof PIXI.interaction.InteractionManager#
+         */
+    }
+
+    InteractionManager.prototype = Object.create(EventEmitter.prototype);
+    InteractionManager.prototype.constructor = InteractionManager;
+    module.exports = InteractionManager;
+
+    /**
+     * Sets the DOM element which will receive mouse/touch events. This is useful for when you have
+     * other DOM elements on top of the renderers Canvas element. With this you'll be bale to deletegate
+     * another DOM element to receive those events.
+     *
+     * @param element {HTMLElement} the DOM element which will receive mouse and touch events.
+     * @param [resolution=1] {number} The resolution / device pixel ratio of the new element (relative to the canvas).
+     * @private
+     */
+    InteractionManager.prototype.setTargetElement = function (element, resolution)
+    {
+        this.removeEvents();
+
+        this.interactionDOMElement = element;
+
+        this.resolution = resolution || 1;
+
+        this.addEvents();
+    };
+
+    /**
+     * Registers all the DOM events
+     *
+     * @private
+     */
+    InteractionManager.prototype.addEvents = function ()
+    {
+        if (!this.interactionDOMElement)
+        {
+            return;
+        }
+
+        core.ticker.shared.add(this.update, this);
+
+        if (window.navigator.msPointerEnabled)
+        {
+            this.interactionDOMElement.style['-ms-content-zooming'] = 'none';
+            this.interactionDOMElement.style['-ms-touch-action'] = 'none';
+        }
+
+        window.document.addEventListener('mousemove',    this.onMouseMove, true);
+        this.interactionDOMElement.addEventListener('mousedown',    this.onMouseDown, true);
+        this.interactionDOMElement.addEventListener('mouseout',     this.onMouseOut, true);
+        this.interactionDOMElement.addEventListener('mouseover',    this.onMouseOver, true);
+
+        this.interactionDOMElement.addEventListener('touchstart',   this.onTouchStart, true);
+        this.interactionDOMElement.addEventListener('touchend',     this.onTouchEnd, true);
+        this.interactionDOMElement.addEventListener('touchmove',    this.onTouchMove, true);
+
+        window.addEventListener('mouseup',  this.onMouseUp, true);
+
+        this.eventsAdded = true;
+    };
+
+    /**
+     * Removes all the DOM events that were previously registered
+     *
+     * @private
+     */
+    InteractionManager.prototype.removeEvents = function ()
+    {
+        if (!this.interactionDOMElement)
+        {
+            return;
+        }
+
+        core.ticker.shared.remove(this.update);
+
+        if (window.navigator.msPointerEnabled)
+        {
+            this.interactionDOMElement.style['-ms-content-zooming'] = '';
+            this.interactionDOMElement.style['-ms-touch-action'] = '';
+        }
+
+        window.document.removeEventListener('mousemove', this.onMouseMove, true);
+        this.interactionDOMElement.removeEventListener('mousedown', this.onMouseDown, true);
+        this.interactionDOMElement.removeEventListener('mouseout',  this.onMouseOut, true);
+        this.interactionDOMElement.removeEventListener('mouseover', this.onMouseOver, true);
+
+        this.interactionDOMElement.removeEventListener('touchstart', this.onTouchStart, true);
+        this.interactionDOMElement.removeEventListener('touchend',  this.onTouchEnd, true);
+        this.interactionDOMElement.removeEventListener('touchmove', this.onTouchMove, true);
+
+        this.interactionDOMElement = null;
+
+        window.removeEventListener('mouseup',  this.onMouseUp, true);
+
+        this.eventsAdded = false;
+    };
+
+    /**
+     * Updates the state of interactive objects.
+     * Invoked by a throttled ticker update from
+     * {@link PIXI.ticker.shared}.
+     *
+     * @param deltaTime {number} time delta since last tick
+     */
+    InteractionManager.prototype.update = function (deltaTime)
+    {
+        this._deltaTime += deltaTime;
+
+        if (this._deltaTime < this.interactionFrequency)
+        {
+            return;
+        }
+
+        this._deltaTime = 0;
+
+        if (!this.interactionDOMElement)
+        {
+            return;
+        }
+
+        // if the user move the mouse this check has already been dfone using the mouse move!
+        if(this.didMove)
+        {
+            this.didMove = false;
+            return;
+        }
+
+        this.cursor = this.defaultCursorStyle;
+
+        this.processInteractive(this.mouse.global, this.renderer._lastObjectRendered, this.processMouseOverOut, true );
+
+        if (this.currentCursorStyle !== this.cursor)
+        {
+            this.currentCursorStyle = this.cursor;
+            this.interactionDOMElement.style.cursor = this.cursor;
+        }
+
+        //TODO
+    };
+
+    /**
+     * Dispatches an event on the display object that was interacted with
+     *
+     * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} the display object in question
+     * @param eventString {string} the name of the event (e.g, mousedown)
+     * @param eventData {object} the event data object
+     * @private
+     */
+    InteractionManager.prototype.dispatchEvent = function ( displayObject, eventString, eventData )
+    {
+        if(!eventData.stopped)
+        {
+            eventData.target = displayObject;
+            eventData.type = eventString;
+
+            displayObject.emit( eventString, eventData );
+
+            if( displayObject[eventString] )
+            {
+                displayObject[eventString]( eventData );
+            }
+        }
+    };
+
+    /**
+     * Maps x and y coords from a DOM object and maps them correctly to the pixi view. The resulting value is stored in the point.
+     * This takes into account the fact that the DOM element could be scaled and positioned anywhere on the screen.
+     *
+     * @param  {PIXI.Point} point the point that the result will be stored in
+     * @param  {number} x     the x coord of the position to map
+     * @param  {number} y     the y coord of the position to map
+     */
+    InteractionManager.prototype.mapPositionToPoint = function ( point, x, y )
+    {
+        var rect;
+        // IE 11 fix
+        if(!this.interactionDOMElement.parentElement)
+        {
+            rect = { x: 0, y: 0, width: 0, height: 0 };
+        } else {
+            rect = this.interactionDOMElement.getBoundingClientRect();
+        }
+
+        point.x = ( ( x - rect.left ) * (this.interactionDOMElement.width  / rect.width  ) ) / this.resolution;
+        point.y = ( ( y - rect.top  ) * (this.interactionDOMElement.height / rect.height ) ) / this.resolution;
+    };
+
+    /**
+     * This function is provides a neat way of crawling through the scene graph and running a specified function on all interactive objects it finds.
+     * It will also take care of hit testing the interactive objects and passes the hit across in the function.
+     *
+     * @param point {PIXI.Point} the point that is tested for collision
+     * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} the displayObject that will be hit test (recurcsivly crawls its children)
+     * @param [func] {Function} the function that will be called on each interactive object. The displayObject and hit will be passed to the function
+     * @param [hitTest] {boolean} this indicates if the objects inside should be hit test against the point
+     * @param [interactive] {boolean} Whether the displayObject is interactive
+     * @return {boolean} returns true if the displayObject hit the point
+     */
+    InteractionManager.prototype.processInteractive = function (point, displayObject, func, hitTest, interactive)
+    {
+        if(!displayObject || !displayObject.visible)
+        {
+            return false;
+        }
+
+        // Took a little while to rework this function correctly! But now it is done and nice and optimised. ^_^
+        //
+        // This function will now loop through all objects and then only hit test the objects it HAS to, not all of them. MUCH faster..
+        // An object will be hit test if the following is true:
+        //
+        // 1: It is interactive.
+        // 2: It belongs to a parent that is interactive AND one of the parents children have not already been hit.
+        //
+        // As another little optimisation once an interactive object has been hit we can carry on through the scenegraph, but we know that there will be no more hits! So we can avoid extra hit tests
+        // A final optimisation is that an object is not hit test directly if a child has already been hit.
+
+        var hit = false,
+            interactiveParent = interactive = displayObject.interactive || interactive;
+
+
+
+
+        // if the displayobject has a hitArea, then it does not need to hitTest children.
+        if(displayObject.hitArea)
+        {
+            interactiveParent = false;
+        }
+
+        // it has a mask! Then lets hit test that before continuing..
+        if(hitTest && displayObject._mask)
+        {
+            if(!displayObject._mask.containsPoint(point))
+            {
+                hitTest = false;
+            }
+        }
+
+        // it has a filterArea! Same as mask but easier, its a rectangle
+        if(hitTest && displayObject.filterArea)
+        {
+            if(!displayObject.filterArea.contains(point.x, point.y))
+            {
+                hitTest = false;
+            }
+        }
+
+        // ** FREE TIP **! If an object is not interactive or has no buttons in it (such as a game scene!) set interactiveChildren to false for that displayObject.
+        // This will allow pixi to completly ignore and bypass checking the displayObjects children.
+        if(displayObject.interactiveChildren)
+        {
+            var children = displayObject.children;
+
+            for (var i = children.length-1; i >= 0; i--)
+            {
+                var child = children[i];
+
+                // time to get recursive.. if this function will return if somthing is hit..
+                if(this.processInteractive(point, child, func, hitTest, interactiveParent))
+                {
+                    // its a good idea to check if a child has lost its parent.
+                    // this means it has been removed whilst looping so its best
+                    if(!child.parent)
+                    {
+                        continue;
+                    }
+
+                    hit = true;
+
+                    // we no longer need to hit test any more objects in this container as we we now know the parent has been hit
+                    interactiveParent = false;
+
+                    // If the child is interactive , that means that the object hit was actually interactive and not just the child of an interactive object.
+                    // This means we no longer need to hit test anything else. We still need to run through all objects, but we don't need to perform any hit tests.
+
+                    //{
+                    hitTest = false;
+                    //}
+
+                    // we can break now as we have hit an object.
+                }
+            }
+        }
+
+
+
+        // no point running this if the item is not interactive or does not have an interactive parent.
+        if(interactive)
+        {
+            // if we are hit testing (as in we have no hit any objects yet)
+            // We also don't need to worry about hit testing if once of the displayObjects children has already been hit!
+            if(hitTest && !hit)
+            {
+
+                if(displayObject.hitArea)
+                {
+                    displayObject.worldTransform.applyInverse(point,  this._tempPoint);
+                    hit = displayObject.hitArea.contains( this._tempPoint.x, this._tempPoint.y );
+                }
+                else if(displayObject.containsPoint)
+                {
+                    hit = displayObject.containsPoint(point);
+                }
+
+
+            }
+
+            if(displayObject.interactive)
+            {
+                func(displayObject, hit);
+            }
+        }
+
+        return hit;
+
+    };
+
+
+    /**
+     * Is called when the mouse button is pressed down on the renderer element
+     *
+     * @param event {Event} The DOM event of a mouse button being pressed down
+     * @private
+     */
+    InteractionManager.prototype.onMouseDown = function (event)
+    {
+        this.mouse.originalEvent = event;
+        this.eventData.data = this.mouse;
+        this.eventData.stopped = false;
+
+        // Update internal mouse reference
+        this.mapPositionToPoint( this.mouse.global, event.clientX, event.clientY);
+
+        if (this.autoPreventDefault)
+        {
+            this.mouse.originalEvent.preventDefault();
+        }
+
+        this.processInteractive(this.mouse.global, this.renderer._lastObjectRendered, this.processMouseDown, true );
+
+        var isRightButton = event.button === 2 || event.which === 3;
+        this.emit(isRightButton ? 'rightdown' : 'mousedown', this.eventData);
+    };
+
+    /**
+     * Processes the result of the mouse down check and dispatches the event if need be
+     *
+     * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested
+     * @param hit {boolean} the result of the hit test on the dispay object
+     * @private
+     */
+    InteractionManager.prototype.processMouseDown = function ( displayObject, hit )
+    {
+        var e = this.mouse.originalEvent;
+
+        var isRightButton = e.button === 2 || e.which === 3;
+
+        if(hit)
+        {
+            displayObject[ isRightButton ? '_isRightDown' : '_isLeftDown' ] = true;
+            this.dispatchEvent( displayObject, isRightButton ? 'rightdown' : 'mousedown', this.eventData );
+        }
+    };
+
+    /**
+     * Is called when the mouse button is released on the renderer element
+     *
+     * @param event {Event} The DOM event of a mouse button being released
+     * @private
+     */
+    InteractionManager.prototype.onMouseUp = function (event)
+    {
+        this.mouse.originalEvent = event;
+        this.eventData.data = this.mouse;
+        this.eventData.stopped = false;
+
+        // Update internal mouse reference
+        this.mapPositionToPoint( this.mouse.global, event.clientX, event.clientY);
+
+        this.processInteractive(this.mouse.global, this.renderer._lastObjectRendered, this.processMouseUp, true );
+
+        var isRightButton = event.button === 2 || event.which === 3;
+        this.emit(isRightButton ? 'rightup' : 'mouseup', this.eventData);
+    };
+
+    /**
+     * Processes the result of the mouse up check and dispatches the event if need be
+     *
+     * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested
+     * @param hit {boolean} the result of the hit test on the display object
+     * @private
+     */
+    InteractionManager.prototype.processMouseUp = function ( displayObject, hit )
+    {
+        var e = this.mouse.originalEvent;
+
+        var isRightButton = e.button === 2 || e.which === 3;
+        var isDown =  isRightButton ? '_isRightDown' : '_isLeftDown';
+
+        if(hit)
+        {
+            this.dispatchEvent( displayObject, isRightButton ? 'rightup' : 'mouseup', this.eventData );
+
+            if( displayObject[ isDown ] )
+            {
+                displayObject[ isDown ] = false;
+                this.dispatchEvent( displayObject, isRightButton ? 'rightclick' : 'click', this.eventData );
+            }
+        }
+        else
+        {
+            if( displayObject[ isDown ] )
+            {
+                displayObject[ isDown ] = false;
+                this.dispatchEvent( displayObject, isRightButton ? 'rightupoutside' : 'mouseupoutside', this.eventData );
+            }
+        }
+    };
+
+
+    /**
+     * Is called when the mouse moves across the renderer element
+     *
+     * @param event {Event} The DOM event of the mouse moving
+     * @private
+     */
+    InteractionManager.prototype.onMouseMove = function (event)
+    {
+        this.mouse.originalEvent = event;
+        this.eventData.data = this.mouse;
+        this.eventData.stopped = false;
+
+        this.mapPositionToPoint( this.mouse.global, event.clientX, event.clientY);
+
+        this.didMove = true;
+
+        this.cursor = this.defaultCursorStyle;
+
+        this.processInteractive(this.mouse.global, this.renderer._lastObjectRendered, this.processMouseMove, true );
+
+        this.emit('mousemove', this.eventData);
+
+        if (this.currentCursorStyle !== this.cursor)
+        {
+            this.currentCursorStyle = this.cursor;
+            this.interactionDOMElement.style.cursor = this.cursor;
+        }
+
+        //TODO BUG for parents ineractive object (border order issue)
+    };
+
+    /**
+     * Processes the result of the mouse move check and dispatches the event if need be
+     *
+     * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested
+     * @param hit {boolean} the result of the hit test on the display object
+     * @private
+     */
+    InteractionManager.prototype.processMouseMove = function ( displayObject, hit )
+    {
+        this.processMouseOverOut(displayObject, hit);
+
+        // only display on mouse over
+        if(!this.moveWhenInside || hit)
+        {
+            this.dispatchEvent( displayObject, 'mousemove', this.eventData);
+        }
+    };
+
+
+    /**
+     * Is called when the mouse is moved out of the renderer element
+     *
+     * @param event {Event} The DOM event of a mouse being moved out
+     * @private
+     */
+    InteractionManager.prototype.onMouseOut = function (event)
+    {
+        this.mouse.originalEvent = event;
+        this.eventData.data = this.mouse;
+        this.eventData.stopped = false;
+
+        // Update internal mouse reference
+        this.mapPositionToPoint( this.mouse.global, event.clientX, event.clientY);
+
+        this.interactionDOMElement.style.cursor = this.defaultCursorStyle;
+
+        // TODO optimize by not check EVERY TIME! maybe half as often? //
+        this.mapPositionToPoint( this.mouse.global, event.clientX, event.clientY );
+
+        this.processInteractive( this.mouse.global, this.renderer._lastObjectRendered, this.processMouseOverOut, false );
+
+        this.emit('mouseout', this.eventData);
+    };
+
+    /**
+     * Processes the result of the mouse over/out check and dispatches the event if need be
+     *
+     * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested
+     * @param hit {boolean} the result of the hit test on the display object
+     * @private
+     */
+    InteractionManager.prototype.processMouseOverOut = function ( displayObject, hit )
+    {
+        if(hit)
+        {
+            if(!displayObject._over)
+            {
+                displayObject._over = true;
+                this.dispatchEvent( displayObject, 'mouseover', this.eventData );
+            }
+
+            if (displayObject.buttonMode)
+            {
+                this.cursor = displayObject.defaultCursor;
+            }
+        }
+        else
+        {
+            if(displayObject._over)
+            {
+                displayObject._over = false;
+                this.dispatchEvent( displayObject, 'mouseout', this.eventData);
+            }
+        }
+    };
+
+    /**
+     * Is called when the mouse enters the renderer element area
+     *
+     * @param event {Event} The DOM event of the mouse moving into the renderer view
+     * @private
+     */
+    InteractionManager.prototype.onMouseOver = function(event)
+    {
+        this.mouse.originalEvent = event;
+        this.eventData.data = this.mouse;
+        this.eventData.stopped = false;
+
+        this.emit('mouseover', this.eventData);
+    };
+
+
+    /**
+     * Is called when a touch is started on the renderer element
+     *
+     * @param event {Event} The DOM event of a touch starting on the renderer view
+     * @private
+     */
+    InteractionManager.prototype.onTouchStart = function (event)
+    {
+        if (this.autoPreventDefault)
+        {
+            event.preventDefault();
+        }
+
+        var changedTouches = event.changedTouches;
+        var cLength = changedTouches.length;
+
+        for (var i=0; i < cLength; i++)
+        {
+            var touchEvent = changedTouches[i];
+            //TODO POOL
+            var touchData = this.getTouchData( touchEvent );
+
+            touchData.originalEvent = event;
+
+            this.eventData.data = touchData;
+            this.eventData.stopped = false;
+
+            this.processInteractive( touchData.global, this.renderer._lastObjectRendered, this.processTouchStart, true );
+
+            this.emit('touchstart', this.eventData);
+
+            this.returnTouchData( touchData );
+        }
+    };
+
+    /**
+     * Processes the result of a touch check and dispatches the event if need be
+     *
+     * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested
+     * @param hit {boolean} the result of the hit test on the display object
+     * @private
+     */
+    InteractionManager.prototype.processTouchStart = function ( displayObject, hit )
+    {
+        if(hit)
+        {
+            displayObject._touchDown = true;
+            this.dispatchEvent( displayObject, 'touchstart', this.eventData );
+        }
+    };
+
+
+    /**
+     * Is called when a touch ends on the renderer element
+     *
+     * @param event {Event} The DOM event of a touch ending on the renderer view
+     * @private
+     */
+    InteractionManager.prototype.onTouchEnd = function (event)
+    {
+        if (this.autoPreventDefault)
+        {
+            event.preventDefault();
+        }
+
+        var changedTouches = event.changedTouches;
+        var cLength = changedTouches.length;
+
+        for (var i=0; i < cLength; i++)
+        {
+            var touchEvent = changedTouches[i];
+
+            var touchData = this.getTouchData( touchEvent );
+
+            touchData.originalEvent = event;
+
+            //TODO this should be passed along.. no set
+            this.eventData.data = touchData;
+            this.eventData.stopped = false;
+
+
+            this.processInteractive( touchData.global, this.renderer._lastObjectRendered, this.processTouchEnd, true );
+
+            this.emit('touchend', this.eventData);
+
+            this.returnTouchData( touchData );
+        }
+    };
+
+    /**
+     * Processes the result of the end of a touch and dispatches the event if need be
+     *
+     * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested
+     * @param hit {boolean} the result of the hit test on the display object
+     * @private
+     */
+    InteractionManager.prototype.processTouchEnd = function ( displayObject, hit )
+    {
+        if(hit)
+        {
+            this.dispatchEvent( displayObject, 'touchend', this.eventData );
+
+            if( displayObject._touchDown )
+            {
+                displayObject._touchDown = false;
+                this.dispatchEvent( displayObject, 'tap', this.eventData );
+            }
+        }
+        else
+        {
+            if( displayObject._touchDown )
+            {
+                displayObject._touchDown = false;
+                this.dispatchEvent( displayObject, 'touchendoutside', this.eventData );
+            }
+        }
+    };
+
+    /**
+     * Is called when a touch is moved across the renderer element
+     *
+     * @param event {Event} The DOM event of a touch moving across the renderer view
+     * @private
+     */
+    InteractionManager.prototype.onTouchMove = function (event)
+    {
+        if (this.autoPreventDefault)
+        {
+            event.preventDefault();
+        }
+
+        var changedTouches = event.changedTouches;
+        var cLength = changedTouches.length;
+
+        for (var i=0; i < cLength; i++)
+        {
+            var touchEvent = changedTouches[i];
+
+            var touchData = this.getTouchData( touchEvent );
+
+            touchData.originalEvent = event;
+
+            this.eventData.data = touchData;
+            this.eventData.stopped = false;
+
+            this.processInteractive( touchData.global, this.renderer._lastObjectRendered, this.processTouchMove, this.moveWhenInside );
+
+            this.emit('touchmove', this.eventData);
+
+            this.returnTouchData( touchData );
+        }
+    };
+
+    /**
+     * Processes the result of a touch move check and dispatches the event if need be
+     *
+     * @param displayObject {PIXI.Container|PIXI.Sprite|PIXI.extras.TilingSprite} The display object that was tested
+     * @param hit {boolean} the result of the hit test on the display object
+     * @private
+     */
+    InteractionManager.prototype.processTouchMove = function ( displayObject, hit )
+    {
+        if(!this.moveWhenInside || hit)
+        {
+            this.dispatchEvent( displayObject, 'touchmove', this.eventData);
+        }
+    };
+
+    /**
+     * Grabs an interaction data object from the internal pool
+     *
+     * @param touchEvent {object} The touch event we need to pair with an interactionData object
+     *
+     * @private
+     */
+    InteractionManager.prototype.getTouchData = function (touchEvent)
+    {
+        var touchData = this.interactiveDataPool.pop();
+
+        if(!touchData)
+        {
+            touchData = new InteractionData();
+        }
+
+        touchData.identifier = touchEvent.identifier;
+        this.mapPositionToPoint( touchData.global, touchEvent.clientX, touchEvent.clientY );
+
+        if(navigator.isCocoonJS)
+        {
+            touchData.global.x = touchData.global.x / this.resolution;
+            touchData.global.y = touchData.global.y / this.resolution;
+        }
+
+        touchEvent.globalX = touchData.global.x;
+        touchEvent.globalY = touchData.global.y;
+
+        return touchData;
+    };
+
+    /**
+     * Returns an interaction data object to the internal pool
+     *
+     * @param touchData {PIXI.interaction.InteractionData} The touch data object we want to return to the pool
+     *
+     * @private
+     */
+    InteractionManager.prototype.returnTouchData = function ( touchData )
+    {
+        this.interactiveDataPool.push( touchData );
+    };
+
+    /**
+     * Destroys the interaction manager
+     *
+     */
+    InteractionManager.prototype.destroy = function () {
+        this.removeEvents();
+
+        this.removeAllListeners();
+
+        this.renderer = null;
+
+        this.mouse = null;
+
+        this.eventData = null;
+
+        this.interactiveDataPool = null;
+
+        this.interactionDOMElement = null;
+
+        this.onMouseUp = null;
+        this.processMouseUp = null;
+
+
+        this.onMouseDown = null;
+        this.processMouseDown = null;
+
+        this.onMouseMove = null;
+        this.processMouseMove = null;
+
+        this.onMouseOut = null;
+        this.processMouseOverOut = null;
+
+        this.onMouseOver = null;
+
+        this.onTouchStart = null;
+        this.processTouchStart = null;
+
+        this.onTouchEnd = null;
+        this.processTouchEnd = null;
+
+        this.onTouchMove = null;
+        this.processTouchMove = null;
+
+        this._tempPoint = null;
+    };
+
+    core.WebGLRenderer.registerPlugin('interaction', InteractionManager);
+    core.CanvasRenderer.registerPlugin('interaction', InteractionManager);
+
+},{"../core":62,"./InteractionData":143,"./interactiveTarget":146,"eventemitter3":3}],145:[function(require,module,exports){
+    /**
+     * @file        Main export of the PIXI interactions library
+     * @author      Mat Groves <mat@goodboydigital.com>
+     * @copyright   2013-2015 GoodBoyDigital
+     * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}
+     */
+
+    /**
+     * @namespace PIXI.interaction
+     */
+    module.exports = {
+        InteractionData:    require('./InteractionData'),
+        InteractionManager: require('./InteractionManager'),
+        interactiveTarget:  require('./interactiveTarget')
+    };
+
+},{"./InteractionData":143,"./InteractionManager":144,"./interactiveTarget":146}],146:[function(require,module,exports){
+    /**
+     * Default property values of interactive objects
+     * Used by {@link PIXI.interaction.InteractionManager} to automatically give all DisplayObjects these properties
+     *
+     * @mixin
+     * @memberof PIXI.interaction
+     * @example
+     *      function MyObject() {}
+     *
+     *      Object.assign(
+     *          MyObject.prototype,
+     *          PIXI.interaction.interactiveTarget
+     *      );
+     */
+    var interactiveTarget = {
+        /**
+         * Determines if the displayObject be clicked/touched
+         *
+         * @inner {boolean}
+         */
+        interactive: false,
+
+        /**
+         * Determines if the children to the displayObject can be clicked/touched
+         * Setting this to false allows pixi to bypass a recursive hitTest function
+         *
+         * @inner {boolean}
+         */
+        interactiveChildren: true,
+
+        /**
+         * Interaction shape. Children will be hit first, then this shape will be checked.
+         * Setting this will cause this shape to be checked in hit tests rather than the displayObject's bounds.
+         *
+         * @inner {PIXI.Rectangle|PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.RoundedRectangle}
+         */
+        hitArea: null,
+
+        /**
+         * If enabled, the mouse cursor will change when hovered over the displayObject if it is interactive
+         *
+         * @inner {boolean}
+         */
+        buttonMode: false,
+
+        /**
+         * If buttonMode is enabled, this defines what CSS cursor property is used when the mouse cursor is hovered over the displayObject
+         * https://developer.mozilla.org/en/docs/Web/CSS/cursor
+         *
+         * @inner {string}
+         */
+        defaultCursor: 'pointer',
+
+        // some internal checks..
+        /**
+         * Internal check to detect if the mouse cursor is hovered over the displayObject
+         *
+         * @inner {boolean}
+         * @private
+         */
+        _over: false,
+
+        /**
+         * Internal check to detect if the left mouse button is pressed on the displayObject
+         *
+         * @inner {boolean}
+         * @private
+         */
+        _isLeftDown: false,
+
+        /**
+         * Internal check to detect if the right mouse button is pressed on the displayObject
+         *
+         * @inner {boolean}
+         * @private
+         */
+        _isRightDown: false,
+
+        /**
+         * Internal check to detect if a user has touched the displayObject
+         *
+         * @inner {boolean}
+         * @private
+         */
+        _touchDown: false
+    };
+
+    module.exports = interactiveTarget;
+
+},{}],147:[function(require,module,exports){
+    var Resource = require('resource-loader').Resource,
+        core = require('../core'),
+        extras = require('../extras'),
+        path = require('path');
+
+
+    function parse(resource, texture) {
+        var data = {};
+        var info = resource.data.getElementsByTagName('info')[0];
+        var common = resource.data.getElementsByTagName('common')[0];
+
+        data.font = info.getAttribute('face');
+        data.size = parseInt(info.getAttribute('size'), 10);
+        data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10);
+        data.chars = {};
+
+        //parse letters
+        var letters = resource.data.getElementsByTagName('char');
+
+        for (var i = 0; i < letters.length; i++)
+        {
+            var charCode = parseInt(letters[i].getAttribute('id'), 10);
+
+            var textureRect = new core.Rectangle(
+                parseInt(letters[i].getAttribute('x'), 10) + texture.frame.x,
+                parseInt(letters[i].getAttribute('y'), 10) + texture.frame.y,
+                parseInt(letters[i].getAttribute('width'), 10),
+                parseInt(letters[i].getAttribute('height'), 10)
+            );
+
+            data.chars[charCode] = {
+                xOffset: parseInt(letters[i].getAttribute('xoffset'), 10),
+                yOffset: parseInt(letters[i].getAttribute('yoffset'), 10),
+                xAdvance: parseInt(letters[i].getAttribute('xadvance'), 10),
+                kerning: {},
+                texture: new core.Texture(texture.baseTexture, textureRect)
+
+            };
+        }
+
+        //parse kernings
+        var kernings = resource.data.getElementsByTagName('kerning');
+        for (i = 0; i < kernings.length; i++)
+        {
+            var first = parseInt(kernings[i].getAttribute('first'), 10);
+            var second = parseInt(kernings[i].getAttribute('second'), 10);
+            var amount = parseInt(kernings[i].getAttribute('amount'), 10);
+
+            if(data.chars[second])
+            {
+                data.chars[second].kerning[first] = amount;
+            }
+        }
+
+        resource.bitmapFont = data;
+
+        // I'm leaving this as a temporary fix so we can test the bitmap fonts in v3
+        // but it's very likely to change
+        extras.BitmapText.fonts[data.font] = data;
+    }
+
+
+    module.exports = function ()
+    {
+        return function (resource, next)
+        {
+            // skip if no data or not xml data
+            if (!resource.data || !resource.isXml)
+            {
+                return next();
+            }
+
+            // skip if not bitmap font data, using some silly duck-typing
+            if (
+                resource.data.getElementsByTagName('page').length === 0 ||
+                resource.data.getElementsByTagName('info').length === 0 ||
+                resource.data.getElementsByTagName('info')[0].getAttribute('face') === null
+            )
+            {
+                return next();
+            }
+
+            var xmlUrl = !resource.isDataUrl ? path.dirname(resource.url) : '';
+
+            if (resource.isDataUrl) {
+                if (xmlUrl === '.') {
+                    xmlUrl = '';
+                }
+
+                if (this.baseUrl && xmlUrl) {
+                    // if baseurl has a trailing slash then add one to xmlUrl so the replace works below
+                    if (this.baseUrl.charAt(this.baseUrl.length - 1) === '/') {
+                        xmlUrl += '/';
+                    }
+
+                    // remove baseUrl from xmlUrl
+                    xmlUrl = xmlUrl.replace(this.baseUrl, '');
+                }
+            }
+
+            // if there is an xmlUrl now, it needs a trailing slash. Ensure that it does if the string isn't empty.
+            if (xmlUrl && xmlUrl.charAt(xmlUrl.length - 1) !== '/') {
+                xmlUrl += '/';
+            }
+
+            var textureUrl = xmlUrl + resource.data.getElementsByTagName('page')[0].getAttribute('file');
+            if (core.utils.TextureCache[textureUrl]) {
+                //reuse existing texture
+                parse(resource, core.utils.TextureCache[textureUrl]);
+                next();
+            }
+            else {
+                var loadOptions = {
+                    crossOrigin: resource.crossOrigin,
+                    loadType: Resource.LOAD_TYPE.IMAGE,
+                    metadata: resource.metadata.imageMetadata
+                };
+                // load the texture for the font
+                this.add(resource.name + '_image', textureUrl, loadOptions, function (res) {
+                    parse(resource, res.texture);
+                    next();
+                });
+            }
+        };
+    };
+
+},{"../core":62,"../extras":129,"path":22,"resource-loader":36}],148:[function(require,module,exports){
+    /**
+     * @file        Main export of the PIXI loaders library
+     * @author      Mat Groves <mat@goodboydigital.com>
+     * @copyright   2013-2015 GoodBoyDigital
+     * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}
+     */
+
+    /**
+     * @namespace PIXI.loaders
+     */
+    module.exports = {
+        Loader:             require('./loader'),
+
+        // parsers
+        bitmapFontParser:   require('./bitmapFontParser'),
+        spritesheetParser:  require('./spritesheetParser'),
+        textureParser:      require('./textureParser'),
+        Resource:           require('resource-loader').Resource
+    };
+
+},{"./bitmapFontParser":147,"./loader":149,"./spritesheetParser":150,"./textureParser":151,"resource-loader":36}],149:[function(require,module,exports){
+    var ResourceLoader = require('resource-loader'),
+        textureParser = require('./textureParser'),
+        spritesheetParser = require('./spritesheetParser'),
+        bitmapFontParser = require('./bitmapFontParser');
+
+    /**
+     *
+     * The new loader, extends Resource Loader by Chad Engler : https://github.com/englercj/resource-loader
+     *
+     * ```js
+     * var loader = PIXI.loader; // pixi exposes a premade instance for you to use.
+     * //or
+     * var loader = new PIXI.loaders.Loader(); // you can also create your own if you want
+     *
+     * loader.add('bunny',"data/bunny.png");
+     *
+     * loader.once('complete',onAssetsLoaded);
+     *
+     * loader.load();
+     * ```
+     *
+     * @class
+     * @extends module:resource-loader.ResourceLoader
+     * @memberof PIXI.loaders
+     * @param [baseUrl=''] {string} The base url for all resources loaded by this loader.
+     * @param [concurrency=10] {number} The number of resources to load concurrently.
+     * @see https://github.com/englercj/resource-loader
+     */
+    function Loader(baseUrl, concurrency)
+    {
+        ResourceLoader.call(this, baseUrl, concurrency);
+
+        for (var i = 0; i < Loader._pixiMiddleware.length; ++i) {
+            this.use(Loader._pixiMiddleware[i]());
+        }
+    }
+
+    Loader.prototype = Object.create(ResourceLoader.prototype);
+    Loader.prototype.constructor = Loader;
+
+    module.exports = Loader;
+
+    Loader._pixiMiddleware = [
+        // parse any blob into more usable objects (e.g. Image)
+        ResourceLoader.middleware.parsing.blob,
+        // parse any Image objects into textures
+        textureParser,
+        // parse any spritesheet data into multiple textures
+        spritesheetParser,
+        // parse any spritesheet data into multiple textures
+        bitmapFontParser
+    ];
+
+    Loader.addPixiMiddleware = function (fn) {
+        Loader._pixiMiddleware.push(fn);
+    };
+
+// Add custom extentions
+    var Resource = ResourceLoader.Resource;
+
+    Resource.setExtensionXhrType('fnt', Resource.XHR_RESPONSE_TYPE.DOCUMENT);
+
+},{"./bitmapFontParser":147,"./spritesheetParser":150,"./textureParser":151,"resource-loader":36}],150:[function(require,module,exports){
+    var Resource = require('resource-loader').Resource,
+        path = require('path'),
+        core = require('../core');
+
+    var BATCH_SIZE = 1000;
+
+    module.exports = function ()
+    {
+        return function (resource, next)
+        {
+            var resourcePath;
+            var imageResourceName = resource.name + '_image';
+
+            // skip if no data, its not json, it isn't spritesheet data, or the image resource already exists
+            if (!resource.data || !resource.isJson || !resource.data.frames || this.resources[imageResourceName])
+            {
+                return next();
+            }
+
+            var loadOptions = {
+                crossOrigin: resource.crossOrigin,
+                loadType: Resource.LOAD_TYPE.IMAGE,
+                metadata: resource.metadata.imageMetadata
+            };
+
+            // Prepend url path unless the resource image is a data url
+            if (resource.isDataUrl)
+            {
+                resourcePath = resource.data.meta.image;
+            }
+            else
+            {
+                resourcePath = path.dirname(resource.url.replace(this.baseUrl, '')) + '/' + resource.data.meta.image;
+            }
+
+            // load the image for this sheet
+            this.add(imageResourceName, resourcePath, loadOptions, function (res)
+            {
+                resource.textures = {};
+
+                var frames = resource.data.frames;
+                var frameKeys = Object.keys(frames);
+                var resolution = core.utils.getResolutionOfUrl(resource.url);
+                var batchIndex = 0;
+
+                function processFrames(initialFrameIndex, maxFrames)
+                {
+                    var frameIndex = initialFrameIndex;
+
+                    while (frameIndex - initialFrameIndex < maxFrames && frameIndex < frameKeys.length)
+                    {
+                        var i = frameKeys[frameIndex];
+                        var rect = frames[i].frame;
+
+                        if (rect)
+                        {
+
+                            var frame = null;
+                            var trim = null;
+                            var orig = new core.Rectangle(0, 0, frames[i].sourceSize.w / resolution, frames[i].sourceSize.h / resolution);
+
+                            if (frames[i].rotated) {
+                                frame = new core.Rectangle(rect.x / resolution, rect.y / resolution, rect.h / resolution, rect.w / resolution);
+                            }
+                            else {
+                                frame = new core.Rectangle(rect.x / resolution, rect.y / resolution, rect.w / resolution, rect.h / resolution);
+                            }
+
+                            //  Check to see if the sprite is trimmed
+                            if (frames[i].trimmed)
+                            {
+                                trim = new core.Rectangle(
+                                    frames[i].spriteSourceSize.x / resolution,
+                                    frames[i].spriteSourceSize.y / resolution,
+                                    frames[i].spriteSourceSize.w / resolution,
+                                    frames[i].spriteSourceSize.h / resolution
+                                );
+                            }
+
+                            resource.textures[i] = new core.Texture(res.texture.baseTexture, frame, orig, trim, frames[i].rotated ? 2 : 0);
+
+                            // lets also add the frame to pixi's global cache for fromFrame and fromImage functions
+                            core.utils.TextureCache[i] = resource.textures[i];
+
+                        }
+
+                        frameIndex++;
+                    }
+                }
+
+                function shouldProcessNextBatch()
+                {
+                    return batchIndex * BATCH_SIZE < frameKeys.length;
+                }
+
+                function processNextBatch(done)
+                {
+                    processFrames(batchIndex * BATCH_SIZE, BATCH_SIZE);
+                    batchIndex++;
+                    setTimeout(done, 0);
+                }
+
+                function iteration() {
+                    processNextBatch(function() {
+                        if (shouldProcessNextBatch()) {
+                            iteration();
+                        } else {
+                            next();
+                        }
+                    });
+                }
+
+                if (frameKeys.length <= BATCH_SIZE)
+                {
+                    processFrames(0, BATCH_SIZE);
+                    next();
+                }
+                else
+                {
+                    iteration();
+                }
+            });
+        };
+    };
+
+},{"../core":62,"path":22,"resource-loader":36}],151:[function(require,module,exports){
+    var core = require('../core');
+
+    module.exports = function ()
+    {
+        return function (resource, next)
+        {
+            // create a new texture if the data is an Image object
+            if (resource.data && resource.isImage)
+            {
+                var baseTexture = new core.BaseTexture(resource.data, null, core.utils.getResolutionOfUrl(resource.url));
+                baseTexture.imageUrl = resource.url;
+                resource.texture = new core.Texture(baseTexture);
+                // lets also add the frame to pixi's global cache for fromFrame and fromImage fucntions
+                core.utils.BaseTextureCache[resource.url] = baseTexture;
+                core.utils.TextureCache[resource.url] = resource.texture;
+            }
+
+            next();
+        };
+    };
+
+},{"../core":62}],152:[function(require,module,exports){
+    var core = require('../core'),
+        glCore = require('pixi-gl-core'),
+        Shader = require('./webgl/MeshShader'),
+        tempPoint = new core.Point(),
+        tempPolygon = new core.Polygon();
+
+    /**
+     * Base mesh class
+     * @class
+     * @extends PIXI.Container
+     * @memberof PIXI.mesh
+     * @param texture {PIXI.Texture} The texture to use
+     * @param [vertices] {Float32Array} if you want to specify the vertices
+     * @param [uvs] {Float32Array} if you want to specify the uvs
+     * @param [indices] {Uint16Array} if you want to specify the indices
+     * @param [drawMode] {number} the drawMode, can be any of the Mesh.DRAW_MODES consts
+     */
+    function Mesh(texture, vertices, uvs, indices, drawMode)
+    {
+        core.Container.call(this);
+
+        /**
+         * The texture of the Mesh
+         *
+         * @member {PIXI.Texture}
+         * @private
+         */
+        this._texture = null;
+
+        /**
+         * The Uvs of the Mesh
+         *
+         * @member {Float32Array}
+         */
+        this.uvs = uvs || new Float32Array([0, 0,
+            1, 0,
+            1, 1,
+            0, 1]);
+
+        /**
+         * An array of vertices
+         *
+         * @member {Float32Array}
+         */
+        this.vertices = vertices || new Float32Array([0, 0,
+            100, 0,
+            100, 100,
+            0, 100]);
+
+        /*
+         * @member {Uint16Array} An array containing the indices of the vertices
+         */
+        //  TODO auto generate this based on draw mode!
+        this.indices = indices || new Uint16Array([0, 1, 3, 2]);
+
+        /**
+         * Whether the Mesh is dirty or not
+         *
+         * @member {number}
+         */
+        this.dirty = 0;
+        this.indexDirty = 0;
+
+        /**
+         * The blend mode to be applied to the sprite. Set to `PIXI.BLEND_MODES.NORMAL` to remove any blend mode.
+         *
+         * @member {number}
+         * @default PIXI.BLEND_MODES.NORMAL
+         * @see PIXI.BLEND_MODES
+         */
+        this.blendMode = core.BLEND_MODES.NORMAL;
+
+        /**
+         * Triangles in canvas mode are automatically antialiased, use this value to force triangles to overlap a bit with each other.
+         *
+         * @member {number}
+         */
+        this.canvasPadding = 0;
+
+        /**
+         * The way the Mesh should be drawn, can be any of the {@link PIXI.mesh.Mesh.DRAW_MODES} consts
+         *
+         * @member {number}
+         * @see PIXI.mesh.Mesh.DRAW_MODES
+         */
+        this.drawMode = drawMode || Mesh.DRAW_MODES.TRIANGLE_MESH;
+
+        // run texture setter;
+        this.texture = texture;
+
+        /**
+         * The default shader that is used if a mesh doesn't have a more specific one.
+         *
+         * @member {PIXI.Shader}
+         */
+        this.shader = null;
+
+
+        /**
+         * The tint applied to the mesh. This is a [r,g,b] value. A value of [1,1,1] will remove any tint effect.
+         *
+         * @member {number}
+         * @memberof PIXI.mesh.Mesh#
+         */
+        this.tintRgb = new Float32Array([1, 1, 1]);
+
+        this._glDatas = [];
+    }
+
+// constructor
+    Mesh.prototype = Object.create(core.Container.prototype);
+    Mesh.prototype.constructor = Mesh;
+    module.exports = Mesh;
+
+    Object.defineProperties(Mesh.prototype, {
+        /**
+         * The texture that the sprite is using
+         *
+         * @member {PIXI.Texture}
+         * @memberof PIXI.mesh.Mesh#
+         */
+        texture: {
+            get: function ()
+            {
+                return  this._texture;
+            },
+            set: function (value)
+            {
+                if (this._texture === value)
+                {
+                    return;
+                }
+
+                this._texture = value;
+
+                if (value)
+                {
+                    // wait for the texture to load
+                    if (value.baseTexture.hasLoaded)
+                    {
+                        this._onTextureUpdate();
+                    }
+                    else
+                    {
+                        value.once('update', this._onTextureUpdate, this);
+                    }
+                }
+            }
+        },
+        /**
+         * The tint applied to the mesh. This is a hex value. A value of 0xFFFFFF will remove any tint effect.
+         *
+         * @member {number}
+         * @memberof PIXI.mesh.Mesh#
+         * @default 0xFFFFFF
+         */
+        tint: {
+            get: function() {
+                return core.utils.rgb2hex(this.tintRgb);
+            },
+            set: function(value) {
+                this.tintRgb = core.utils.hex2rgb(value, this.tintRgb);
+            }
+        }
+    });
+
+    /**
+     * Renders the object using the WebGL renderer
+     *
+     * @param renderer {PIXI.WebGLRenderer} a reference to the WebGL renderer
+     * @private
+     */
+    Mesh.prototype._renderWebGL = function (renderer)
+    {
+        // get rid of any thing that may be batching.
+        renderer.flush();
+
+        //  renderer.plugins.mesh.render(this);
+        var gl = renderer.gl;
+        var glData = this._glDatas[renderer.CONTEXT_UID];
+
+        if(!glData)
+        {
+            glData = {
+                shader:new Shader(gl),
+                vertexBuffer:glCore.GLBuffer.createVertexBuffer(gl, this.vertices, gl.STREAM_DRAW),
+                uvBuffer:glCore.GLBuffer.createVertexBuffer(gl, this.uvs, gl.STREAM_DRAW),
+                indexBuffer:glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW),
+                // build the vao object that will render..
+                vao:new glCore.VertexArrayObject(gl),
+                dirty:this.dirty,
+                indexDirty:this.indexDirty
+            };
+
+            // build the vao object that will render..
+            glData.vao = new glCore.VertexArrayObject(gl)
+                .addIndex(glData.indexBuffer)
+                .addAttribute(glData.vertexBuffer, glData.shader.attributes.aVertexPosition, gl.FLOAT, false, 2 * 4, 0)
+                .addAttribute(glData.uvBuffer, glData.shader.attributes.aTextureCoord, gl.FLOAT, false, 2 * 4, 0);
+
+            this._glDatas[renderer.CONTEXT_UID] = glData;
+
+
+        }
+
+        if(this.dirty !== glData.dirty)
+        {
+            glData.dirty = this.dirty;
+            glData.uvBuffer.upload();
+
+        }
+
+        if(this.indexDirty !== glData.indexDirty)
+        {
+            glData.indexDirty = this.indexDirty;
+            glData.indexBuffer.upload();
+        }
+
+        glData.vertexBuffer.upload();
+
+        renderer.bindShader(glData.shader);
+        renderer.bindTexture(this._texture, 0);
+        renderer.state.setBlendMode(this.blendMode);
+
+        glData.shader.uniforms.translationMatrix = this.worldTransform.toArray(true);
+        glData.shader.uniforms.alpha = this.worldAlpha;
+        glData.shader.uniforms.tint = this.tintRgb;
+
+        var drawMode = this.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH ? gl.TRIANGLE_STRIP : gl.TRIANGLES;
+
+        glData.vao.bind()
+            .draw(drawMode, this.indices.length)
+            .unbind();
+    };
+
+    /**
+     * Renders the object using the Canvas renderer
+     *
+     * @param renderer {PIXI.CanvasRenderer}
+     * @private
+     */
+    Mesh.prototype._renderCanvas = function (renderer)
+    {
+        var context = renderer.context;
+
+        var transform = this.worldTransform;
+        var res = renderer.resolution;
+
+        if (renderer.roundPixels)
+        {
+            context.setTransform(transform.a * res, transform.b * res, transform.c * res, transform.d * res, (transform.tx * res) | 0, (transform.ty * res) | 0);
+        }
+        else
+        {
+            context.setTransform(transform.a * res, transform.b * res, transform.c * res, transform.d * res, transform.tx * res, transform.ty * res);
+        }
+
+        if (this.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH)
+        {
+            this._renderCanvasTriangleMesh(context);
+        }
+        else
+        {
+            this._renderCanvasTriangles(context);
+        }
+    };
+
+    /**
+     * Draws the object in Triangle Mesh mode using canvas
+     *
+     * @param context {CanvasRenderingContext2D} the current drawing context
+     * @private
+     */
+    Mesh.prototype._renderCanvasTriangleMesh = function (context)
+    {
+        // draw triangles!!
+        var vertices = this.vertices;
+        var uvs = this.uvs;
+
+        var length = vertices.length / 2;
+        // this.count++;
+
+        for (var i = 0; i < length - 2; i++)
+        {
+            // draw some triangles!
+            var index = i * 2;
+            this._renderCanvasDrawTriangle(context, vertices, uvs, index, (index + 2), (index + 4));
+        }
+    };
+
+    /**
+     * Draws the object in triangle mode using canvas
+     *
+     * @param context {CanvasRenderingContext2D} the current drawing context
+     * @private
+     */
+    Mesh.prototype._renderCanvasTriangles = function (context)
+    {
+        // draw triangles!!
+        var vertices = this.vertices;
+        var uvs = this.uvs;
+        var indices = this.indices;
+
+        var length = indices.length;
+        // this.count++;
+
+        for (var i = 0; i < length; i += 3)
+        {
+            // draw some triangles!
+            var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2;
+            this._renderCanvasDrawTriangle(context, vertices, uvs, index0, index1, index2);
+        }
+    };
+
+    /**
+     * Draws one of the triangles that form this Mesh
+     *
+     * @param context {CanvasRenderingContext2D} the current drawing context
+     * @param vertices {Float32Array} a reference to the vertices of the Mesh
+     * @param uvs {Float32Array} a reference to the uvs of the Mesh
+     * @param index0 {number} the index of the first vertex
+     * @param index1 {number} the index of the second vertex
+     * @param index2 {number} the index of the third vertex
+     * @private
+     */
+    Mesh.prototype._renderCanvasDrawTriangle = function (context, vertices, uvs, index0, index1, index2)
+    {
+        var base = this._texture.baseTexture;
+        var textureSource = base.source;
+        var textureWidth = base.width;
+        var textureHeight = base.height;
+
+        var x0 = vertices[index0], x1 = vertices[index1], x2 = vertices[index2];
+        var y0 = vertices[index0 + 1], y1 = vertices[index1 + 1], y2 = vertices[index2 + 1];
+
+        var u0 = uvs[index0] * base.width, u1 = uvs[index1] * base.width, u2 = uvs[index2] * base.width;
+        var v0 = uvs[index0 + 1] * base.height, v1 = uvs[index1 + 1] * base.height, v2 = uvs[index2 + 1] * base.height;
+
+        if (this.canvasPadding > 0)
+        {
+            var paddingX = this.canvasPadding / this.worldTransform.a;
+            var paddingY = this.canvasPadding / this.worldTransform.d;
+            var centerX = (x0 + x1 + x2) / 3;
+            var centerY = (y0 + y1 + y2) / 3;
+
+            var normX = x0 - centerX;
+            var normY = y0 - centerY;
+
+            var dist = Math.sqrt(normX * normX + normY * normY);
+            x0 = centerX + (normX / dist) * (dist + paddingX);
+            y0 = centerY + (normY / dist) * (dist + paddingY);
+
+            //
+
+            normX = x1 - centerX;
+            normY = y1 - centerY;
+
+            dist = Math.sqrt(normX * normX + normY * normY);
+            x1 = centerX + (normX / dist) * (dist + paddingX);
+            y1 = centerY + (normY / dist) * (dist + paddingY);
+
+            normX = x2 - centerX;
+            normY = y2 - centerY;
+
+            dist = Math.sqrt(normX * normX + normY * normY);
+            x2 = centerX + (normX / dist) * (dist + paddingX);
+            y2 = centerY + (normY / dist) * (dist + paddingY);
+        }
+
+        context.save();
+        context.beginPath();
+
+
+        context.moveTo(x0, y0);
+        context.lineTo(x1, y1);
+        context.lineTo(x2, y2);
+
+        context.closePath();
+
+        context.clip();
+
+        // Compute matrix transform
+        var delta =  (u0 * v1)      + (v0 * u2)      + (u1 * v2)      - (v1 * u2)      - (v0 * u1)      - (u0 * v2);
+        var deltaA = (x0 * v1)      + (v0 * x2)      + (x1 * v2)      - (v1 * x2)      - (v0 * x1)      - (x0 * v2);
+        var deltaB = (u0 * x1)      + (x0 * u2)      + (u1 * x2)      - (x1 * u2)      - (x0 * u1)      - (u0 * x2);
+        var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2);
+        var deltaD = (y0 * v1)      + (v0 * y2)      + (y1 * v2)      - (v1 * y2)      - (v0 * y1)      - (y0 * v2);
+        var deltaE = (u0 * y1)      + (y0 * u2)      + (u1 * y2)      - (y1 * u2)      - (y0 * u1)      - (u0 * y2);
+        var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2);
+
+        context.transform(deltaA / delta, deltaD / delta,
+            deltaB / delta, deltaE / delta,
+            deltaC / delta, deltaF / delta);
+
+        context.drawImage(textureSource, 0, 0, textureWidth * base.resolution, textureHeight * base.resolution, 0, 0, textureWidth, textureHeight);
+        context.restore();
+    };
+
+
+
+    /**
+     * Renders a flat Mesh
+     *
+     * @param Mesh {PIXI.mesh.Mesh} The Mesh to render
+     * @private
+     */
+    Mesh.prototype.renderMeshFlat = function (Mesh)
+    {
+        var context = this.context;
+        var vertices = Mesh.vertices;
+
+        var length = vertices.length/2;
+        // this.count++;
+
+        context.beginPath();
+        for (var i=1; i < length-2; i++)
+        {
+            // draw some triangles!
+            var index = i*2;
+
+            var x0 = vertices[index],   x1 = vertices[index+2], x2 = vertices[index+4];
+            var y0 = vertices[index+1], y1 = vertices[index+3], y2 = vertices[index+5];
+
+            context.moveTo(x0, y0);
+            context.lineTo(x1, y1);
+            context.lineTo(x2, y2);
+        }
+
+        context.fillStyle = '#FF0000';
+        context.fill();
+        context.closePath();
+    };
+
+    /**
+     * When the texture is updated, this event will fire to update the scale and frame
+     *
+     * @private
+     */
+    Mesh.prototype._onTextureUpdate = function ()
+    {
+
+    };
+
+    /**
+     * Returns the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account.
+     *
+     * @param [matrix=this.worldTransform] {PIXI.Matrix} the transformation matrix of the sprite
+     * @return {PIXI.Rectangle} the framing rectangle
+     */
+    Mesh.prototype._calculateBounds = function ()
+    {
+        //TODO - we can cache local bounds and use them if they are dirty (like graphics)
+        this._bounds.addVertices(this.transform, this.vertices, 0, this.vertices.length);
+    };
+
+    /**
+     * Tests if a point is inside this mesh. Works only for TRIANGLE_MESH
+     *
+     * @param point {PIXI.Point} the point to test
+     * @return {boolean} the result of the test
+     */
+    Mesh.prototype.containsPoint = function( point ) {
+        if (!this.getBounds().contains(point.x, point.y)) {
+            return false;
+        }
+        this.worldTransform.applyInverse(point,  tempPoint);
+
+        var vertices = this.vertices;
+        var points = tempPolygon.points;
+
+        var indices = this.indices;
+        var len = this.indices.length;
+        var step = this.drawMode === Mesh.DRAW_MODES.TRIANGLES ? 3 : 1;
+        for (var i=0;i+2<len;i+=step) {
+            var ind0 = indices[i]*2, ind1 = indices[i+1]*2, ind2 = indices[i+2]*2;
+            points[0] = vertices[ind0];
+            points[1] = vertices[ind0+1];
+            points[2] = vertices[ind1];
+            points[3] = vertices[ind1+1];
+            points[4] = vertices[ind2];
+            points[5] = vertices[ind2+1];
+            if (tempPolygon.contains(tempPoint.x, tempPoint.y)) {
+                return true;
+            }
+        }
+        return false;
+    };
+
+    /**
+     * Different drawing buffer modes supported
+     *
+     * @static
+     * @constant
+     * @property {object} DRAW_MODES
+     * @property {number} DRAW_MODES.TRIANGLE_MESH
+     * @property {number} DRAW_MODES.TRIANGLES
+     */
+    Mesh.DRAW_MODES = {
+        TRIANGLE_MESH: 0,
+        TRIANGLES: 1
+    };
+
+},{"../core":62,"./webgl/MeshShader":157,"pixi-gl-core":12}],153:[function(require,module,exports){
+    var DEFAULT_BORDER_SIZE= 10;
+
+    var Plane = require('./Plane');
+
+    /**
+     * The NineSlicePlane allows you to stretch a texture using 9-slice scaling. The corners will remain unscaled (useful
+     * for buttons with rounded corners for example) and the other areas will be scaled horizontally and or vertically
+     *
+     *```js
+     * var Plane9 = new PIXI.NineSlicePlane(PIXI.Texture.fromImage('BoxWithRoundedCorners.png'), 15, 15, 15, 15);
+     *  ```
+     * <pre>
+     *      A                          B
+     *    +---+----------------------+---+
+     *  C | 1 |          2           | 3 |
+     *    +---+----------------------+---+
+     *    |   |                      |   |
+     *    | 4 |          5           | 6 |
+     *    |   |                      |   |
+     *    +---+----------------------+---+
+     *  D | 7 |          8           | 9 |
+     *    +---+----------------------+---+
+
+     *  When changing this objects width and/or height:
+     *     areas 1 3 7 and 9 will remain unscaled.
+     *     areas 2 and 8 will be stretched horizontally
+     *     areas 4 and 6 will be stretched vertically
+     *     area 5 will be stretched both horizontally and vertically
+     * </pre>
+     *
+     * @class
+     * @extends PIXI.mesh.Plane
+     * @memberof PIXI.mesh
+     * @param {PIXI.Texture} texture - The texture to use on the NineSlicePlane.
+     * @param {int} [leftWidth=10] size of the left vertical bar (A)
+     * @param {int} [topHeight=10] size of the top horizontal bar (C)
+     * @param {int} [rightWidth=10] size of the right vertical bar (B)
+     * @param {int} [bottomHeight=10] size of the bottom horizontal bar (D)
+     *
+     */
+    function NineSlicePlane(texture, leftWidth, topHeight, rightWidth, bottomHeight)
+    {
+        Plane.call(this, texture, 4, 4);
+
+        var uvs = this.uvs;
+        // right and bottom uv's are always 1
+        uvs[6] = uvs[14] = uvs[22] = uvs[30] = 1;
+        uvs[25] = uvs[27] = uvs[29] = uvs[31] = 1;
+
+        this._origWidth = texture.width;
+        this._origHeight = texture.height;
+        this._uvw = 1 / this._origWidth;
+        this._uvh = 1 / this._origHeight;
+        /**
+         * The width of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane
+         *
+         * @member {number}
+         * @memberof PIXI.NineSlicePlane#
+         * @override
+         */
+        this.width = texture.width;
+        /**
+         * The height of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane
+         *
+         * @member {number}
+         * @memberof PIXI.NineSlicePlane#
+         * @override
+         */
+        this.height = texture.height;
+
+        uvs[2] = uvs[10] = uvs[18] = uvs[26] = this._uvw * leftWidth;
+        uvs[4] = uvs[12] = uvs[20] = uvs[28] = 1 - this._uvw * rightWidth;
+        uvs[9] = uvs[11] = uvs[13] = uvs[15] = this._uvh * topHeight;
+        uvs[17] = uvs[19] = uvs[21] = uvs[23] = 1 - this._uvh * bottomHeight;
+
+        /**
+         * The width of the left column (a)
+         *
+         * @member {number}
+         */
+        this.leftWidth = typeof leftWidth !== 'undefined' ? leftWidth : DEFAULT_BORDER_SIZE;
+        /**
+         * The width of the right column (b)
+         *
+         * @member {number}
+         */
+        this.rightWidth = typeof rightWidth !== 'undefined' ? rightWidth : DEFAULT_BORDER_SIZE;
+        /**
+         * The height of the top row (c)
+         *
+         * @member {number}
+         */
+        this.topHeight = typeof topHeight !== 'undefined' ? topHeight : DEFAULT_BORDER_SIZE;
+        /**
+         * The height of the bottom row (d)
+         *
+         * @member {number}
+         */
+        this.bottomHeight = typeof bottomHeight !== 'undefined' ? bottomHeight : DEFAULT_BORDER_SIZE;
+    }
+
+
+// constructor
+    NineSlicePlane.prototype = Object.create( Plane.prototype );
+    NineSlicePlane.prototype.constructor = NineSlicePlane;
+    module.exports = NineSlicePlane;
+
+    Object.defineProperties(NineSlicePlane.prototype, {
+        /**
+         * The width of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane
+         *
+         * @member {number}
+         * @memberof PIXI.NineSlicePlane#
+         * @override
+         */
+        width: {
+            get: function ()
+            {
+                return this._width;
+            },
+            set: function (value)
+            {
+                this._width = value;
+                this.updateVerticalVertices();
+            }
+        },
+
+        /**
+         * The height of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane
+         *
+         * @member {number}
+         * @memberof PIXI.NineSlicePlane#
+         * @override
+         */
+        height: {
+            get: function ()
+            {
+                return  this._height;
+            },
+            set: function (value)
+            {
+                this._height = value;
+                this.updateHorizontalVertices();
+            }
+        },
+
+        /**
+         * The width of the left column
+         *
+         * @member {number}
+         */
+        leftWidth: {
+            get: function()
+            {
+                return this._leftWidth;
+            },
+            set: function (value)
+            {
+                this._leftWidth = value;
+                var uvs = this.uvs;
+                var vertices = this.vertices;
+                uvs[2] = uvs[10] = uvs[18] = uvs[26] = this._uvw * value;
+                vertices[2] = vertices[10] = vertices[18] = vertices[26] = value;
+                this.dirty=true;
+            }
+        },
+        /**
+         * The width of the right column
+         *
+         * @member {number}
+         */
+        rightWidth: {
+            get: function()
+            {
+                return this._rightWidth;
+            },
+            set: function (value)
+            {
+                this._rightWidth = value;
+                var uvs = this.uvs;
+                var vertices = this.vertices;
+                uvs[4] = uvs[12] = uvs[20] = uvs[28] = 1 - this._uvw * value;
+                vertices[4] = vertices[12] = vertices[20] = vertices[28] = this._width - value;
+                this.dirty=true;
+            }
+        },
+        /**
+         * The height of the top row
+         *
+         * @member {number}
+         */
+        topHeight: {
+            get: function()
+            {
+                return this._topHeight;
+            },
+            set: function (value)
+            {
+                this._topHeight = value;
+                var uvs = this.uvs;
+                var vertices = this.vertices;
+                uvs[9] = uvs[11] = uvs[13] = uvs[15] = this._uvh * value;
+                vertices[9] = vertices[11] = vertices[13] = vertices[15] = value;
+                this.dirty=true;
+            }
+        },
+        /**
+         * The height of the bottom row
+         *
+         * @member {number}
+         */
+        bottomHeight: {
+            get: function()
+            {
+                return this._bottomHeight;
+            },
+            set: function (value)
+            {
+                this._bottomHeight = value;
+                var uvs = this.uvs;
+                var vertices = this.vertices;
+                uvs[17] = uvs[19] = uvs[21] = uvs[23] = 1 - this._uvh * value;
+                vertices[17] = vertices[19] = vertices[21] = vertices[23] = this._height - value;
+                this.dirty=true;
+            }
+        }
+    });
+
+    NineSlicePlane.prototype.updateHorizontalVertices = function() {
+        var vertices = this.vertices;
+        vertices[9] = vertices[11] = vertices[13] = vertices[15] = this._topHeight;
+        vertices[17] = vertices[19] = vertices[21] = vertices[23] = this._height - this._bottomHeight;
+        vertices[25] = vertices[27] = vertices[29] = vertices[31] = this._height;
+    };
+
+    NineSlicePlane.prototype.updateVerticalVertices = function() {
+        var vertices = this.vertices;
+        vertices[2] = vertices[10] = vertices[18] = vertices[26] = this._leftWidth;
+        vertices[4] = vertices[12] = vertices[20] = vertices[28] = this._width - this._rightWidth;
+        vertices[6] = vertices[14] = vertices[22] = vertices[30] = this._width ;
+    };
+
+    /**
+     * Renders the object using the Canvas renderer
+     *
+     * @param renderer {PIXI.CanvasRenderer}
+     * @private
+     */
+    NineSlicePlane.prototype._renderCanvas= function (renderer)
+    {
+        var context = renderer.context;
+        context.globalAlpha = this.worldAlpha;
+
+        var transform = this.worldTransform;
+        var res = renderer.resolution;
+
+        if (renderer.roundPixels)
+        {
+            context.setTransform(transform.a * res, transform.b * res, transform.c * res, transform.d * res, (transform.tx * res) | 0, (transform.ty * res) | 0);
+        }
+        else
+        {
+            context.setTransform(transform.a * res, transform.b * res, transform.c * res, transform.d * res, transform.tx * res, transform.ty * res);
+        }
+
+        var base = this._texture.baseTexture;
+        var textureSource = base.source;
+        var w = base.width;
+        var h = base.height;
+
+        this.drawSegment(context, textureSource, w, h, 0, 1, 10, 11);
+        this.drawSegment(context, textureSource, w, h, 2, 3, 12, 13);
+        this.drawSegment(context, textureSource, w, h, 4, 5, 14, 15);
+        this.drawSegment(context, textureSource, w, h, 8, 9, 18, 19);
+        this.drawSegment(context, textureSource, w, h, 10, 11, 20, 21);
+        this.drawSegment(context, textureSource, w, h, 12, 13, 22, 23);
+        this.drawSegment(context, textureSource, w, h, 16, 17, 26, 27);
+        this.drawSegment(context, textureSource, w, h, 18, 19, 28, 29);
+        this.drawSegment(context, textureSource, w, h, 20, 21, 30, 31);
+    };
+
+    /**
+     * Renders one segment of the plane.
+     * to mimic the exact drawing behavior of stretching the image like WebGL does, we need to make sure
+     * that the source area is at least 1 pixel in size, otherwise nothing gets drawn when a slice size of 0 is used.
+     *
+     * @param context
+     * @param textureSource
+     * @param w	width of the texture
+     * @param h height of the texture
+     * @param x1
+     * @param y1
+     * @param x2
+     * @param y2
+     * @private
+     */
+    NineSlicePlane.prototype.drawSegment= function (context, textureSource, w, h, x1, y1, x2, y2)
+    {
+        // otherwise you get weird results when using slices of that are 0 wide or high.
+        var uvs = this.uvs;
+        var vertices = this.vertices;
+
+        var sw = (uvs[x2]-uvs[x1]) * w;
+        var sh = (uvs[y2]-uvs[y1]) * h;
+        var dw = vertices[x2] - vertices[x1];
+        var dh = vertices[y2] - vertices[y1];
+
+        // make sure the source is at least 1 pixel wide and high, otherwise nothing will be drawn.
+        if (sw<1) {
+            sw=1;
+        }
+        if (sh<1) {
+            sh=1;
+        }
+        // make sure destination is at least 1 pixel wide and high, otherwise you get lines when rendering close to original size.
+        if (dw<1) {
+            dw=1;
+        }
+        if (dh<1) {
+            dh=1;
+        }
+        context.drawImage(textureSource, uvs[x1] * w, uvs[y1] * h, sw, sh, vertices[x1], vertices[y1], dw, dh);
+    };
+
+},{"./Plane":154}],154:[function(require,module,exports){
+    var Mesh = require('./Mesh');
+
+    /**
+     * The Plane allows you to draw a texture across several points and them manipulate these points
+     *
+     *```js
+     * for (var i = 0; i < 20; i++) {
+ *     points.push(new PIXI.Point(i * 50, 0));
+ * };
+     * var Plane = new PIXI.Plane(PIXI.Texture.fromImage("snake.png"), points);
+     *  ```
+     *
+     * @class
+     * @extends PIXI.mesh.Mesh
+     * @memberof PIXI.mesh
+     * @param {PIXI.Texture} texture - The texture to use on the Plane.
+     * @param {number} verticesX - The number of vertices in the x-axis
+     * @param {number} verticesY - The number of vertices in the y-axis
+     *
+     */
+    function Plane(texture, verticesX, verticesY)
+    {
+        Mesh.call(this, texture);
+
+        /**
+         * Tracker for if the Plane is ready to be drawn. Needed because Mesh ctor can
+         * call _onTextureUpdated which could call refresh too early.
+         *
+         * @member {boolean}
+         * @private
+         */
+        this._ready = true;
+
+        this.verticesX = verticesX || 10;
+        this.verticesY = verticesY || 10;
+
+        this.drawMode = Mesh.DRAW_MODES.TRIANGLES;
+        this.refresh();
+
+    }
+
+
+// constructor
+    Plane.prototype = Object.create( Mesh.prototype );
+    Plane.prototype.constructor = Plane;
+    module.exports = Plane;
+
+    /**
+     * Refreshes
+     *
+     */
+    Plane.prototype.refresh = function()
+    {
+        var total = this.verticesX * this.verticesY;
+        var verts = [];
+        var colors = [];
+        var uvs = [];
+        var indices = [];
+        var texture = this.texture;
+
+        var segmentsX = this.verticesX - 1;
+        var segmentsY = this.verticesY - 1;
+        var i = 0;
+
+        var sizeX = texture.width / segmentsX;
+        var sizeY = texture.height / segmentsY;
+
+        for (i = 0; i < total; i++) {
+
+            var x = (i % this.verticesX);
+            var y = ( (i / this.verticesX ) | 0 );
+
+
+            verts.push((x * sizeX),
+                (y * sizeY));
+
+            // this works for rectangular textures.
+            uvs.push(texture._uvs.x0 + (texture._uvs.x1 - texture._uvs.x0) * (x / (this.verticesX-1)), texture._uvs.y0 + (texture._uvs.y3-texture._uvs.y0) * (y/ (this.verticesY-1)));
+        }
+
+        //  cons
+
+        var totalSub = segmentsX * segmentsY;
+
+        for (i = 0; i < totalSub; i++) {
+
+            var xpos = i % segmentsX;
+            var ypos = (i / segmentsX ) | 0;
+
+
+            var  value = (ypos * this.verticesX) + xpos;
+            var  value2 = (ypos * this.verticesX) + xpos + 1;
+            var  value3 = ((ypos+1) * this.verticesX) + xpos;
+            var  value4 = ((ypos+1) * this.verticesX) + xpos + 1;
+
+            indices.push(value, value2, value3);
+            indices.push(value2, value4, value3);
+        }
+
+
+        //console.log(indices)
+        this.vertices = new Float32Array(verts);
+        this.uvs = new Float32Array(uvs);
+        this.colors = new Float32Array(colors);
+        this.indices = new Uint16Array(indices);
+
+        this.indexDirty = true;
+    };
+
+    /**
+     * Clear texture UVs when new texture is set
+     *
+     * @private
+     */
+    Plane.prototype._onTextureUpdate = function ()
+    {
+        Mesh.prototype._onTextureUpdate.call(this);
+
+        // wait for the Plane ctor to finish before calling refresh
+        if (this._ready) {
+            this.refresh();
+        }
+    };
+
+},{"./Mesh":152}],155:[function(require,module,exports){
+    var Mesh = require('./Mesh');
+    var core = require('../core');
+
+    /**
+     * The rope allows you to draw a texture across several points and them manipulate these points
+     *
+     *```js
+     * for (var i = 0; i < 20; i++) {
+ *     points.push(new PIXI.Point(i * 50, 0));
+ * };
+     * var rope = new PIXI.Rope(PIXI.Texture.fromImage("snake.png"), points);
+     *  ```
+     *
+     * @class
+     * @extends PIXI.mesh.Mesh
+     * @memberof PIXI.mesh
+     * @param {PIXI.Texture} texture - The texture to use on the rope.
+     * @param {PIXI.Point[]} points - An array of {@link PIXI.Point} objects to construct this rope.
+     *
+     */
+    function Rope(texture, points)
+    {
+        Mesh.call(this, texture);
+
+        /*
+         * @member {PIXI.Point[]} An array of points that determine the rope
+         */
+        this.points = points;
+
+        /*
+         * @member {Float32Array} An array of vertices used to construct this rope.
+         */
+        this.vertices = new Float32Array(points.length * 4);
+
+        /*
+         * @member {Float32Array} The WebGL Uvs of the rope.
+         */
+        this.uvs = new Float32Array(points.length * 4);
+
+        /*
+         * @member {Float32Array} An array containing the color components
+         */
+        this.colors = new Float32Array(points.length * 2);
+
+        /*
+         * @member {Uint16Array} An array containing the indices of the vertices
+         */
+        this.indices = new Uint16Array(points.length * 2);
+
+        /**
+         * Tracker for if the rope is ready to be drawn. Needed because Mesh ctor can
+         * call _onTextureUpdated which could call refresh too early.
+         *
+         * @member {boolean}
+         * @private
+         */
+        this._ready = true;
+
+        this.refresh();
+    }
+
+
+// constructor
+    Rope.prototype = Object.create(Mesh.prototype);
+    Rope.prototype.constructor = Rope;
+    module.exports = Rope;
+
+    /**
+     * Refreshes
+     *
+     */
+    Rope.prototype.refresh = function ()
+    {
+        var points = this.points;
+
+        // if too little points, or texture hasn't got UVs set yet just move on.
+        if (points.length < 1 || !this._texture._uvs)
+        {
+            return;
+        }
+
+        var uvs = this.uvs;
+
+        var indices = this.indices;
+        var colors = this.colors;
+
+        var textureUvs = this._texture._uvs;
+        var offset = new core.Point(textureUvs.x0, textureUvs.y0);
+        var factor = new core.Point(textureUvs.x2 - textureUvs.x0, textureUvs.y2 - textureUvs.y0);
+
+        uvs[0] = 0 + offset.x;
+        uvs[1] = 0 + offset.y;
+        uvs[2] = 0 + offset.x;
+        uvs[3] = 1 * factor.y + offset.y;
+
+        colors[0] = 1;
+        colors[1] = 1;
+
+        indices[0] = 0;
+        indices[1] = 1;
+
+        var total = points.length,
+            point, index, amount;
+
+        for (var i = 1; i < total; i++)
+        {
+            point = points[i];
+            index = i * 4;
+            // time to do some smart drawing!
+            amount = i / (total-1);
+
+            uvs[index] = amount * factor.x + offset.x;
+            uvs[index+1] = 0 + offset.y;
+
+            uvs[index+2] = amount * factor.x + offset.x;
+            uvs[index+3] = 1 * factor.y + offset.y;
+
+            index = i * 2;
+            colors[index] = 1;
+            colors[index+1] = 1;
+
+            index = i * 2;
+            indices[index] = index;
+            indices[index + 1] = index + 1;
+        }
+
+        this.dirty = true;
+        this.indexDirty = true;
+    };
+
+    /**
+     * Clear texture UVs when new texture is set
+     *
+     * @private
+     */
+    Rope.prototype._onTextureUpdate = function ()
+    {
+
+        Mesh.prototype._onTextureUpdate.call(this);
+
+        // wait for the Rope ctor to finish before calling refresh
+        if (this._ready) {
+            this.refresh();
+        }
+    };
+
+    /**
+     * Updates the object transform for rendering
+     *
+     * @private
+     */
+    Rope.prototype.updateTransform = function ()
+    {
+        var points = this.points;
+
+        if (points.length < 1)
+        {
+            return;
+        }
+
+        var lastPoint = points[0];
+        var nextPoint;
+        var perpX = 0;
+        var perpY = 0;
+
+        // this.count -= 0.2;
+
+        var vertices = this.vertices;
+        var total = points.length,
+            point, index, ratio, perpLength, num;
+
+        for (var i = 0; i < total; i++)
+        {
+            point = points[i];
+            index = i * 4;
+
+            if (i < points.length-1)
+            {
+                nextPoint = points[i+1];
+            }
+            else
+            {
+                nextPoint = point;
+            }
+
+            perpY = -(nextPoint.x - lastPoint.x);
+            perpX = nextPoint.y - lastPoint.y;
+
+            ratio = (1 - (i / (total-1))) * 10;
+
+            if (ratio > 1)
+            {
+                ratio = 1;
+            }
+
+            perpLength = Math.sqrt(perpX * perpX + perpY * perpY);
+            num = this._texture.height / 2; //(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio;
+            perpX /= perpLength;
+            perpY /= perpLength;
+
+            perpX *= num;
+            perpY *= num;
+
+            vertices[index] = point.x + perpX;
+            vertices[index+1] = point.y + perpY;
+            vertices[index+2] = point.x - perpX;
+            vertices[index+3] = point.y - perpY;
+
+            lastPoint = point;
+        }
+
+        this.containerUpdateTransform();
+    };
+
+},{"../core":62,"./Mesh":152}],156:[function(require,module,exports){
+    /**
+     * @file        Main export of the PIXI extras library
+     * @author      Mat Groves <mat@goodboydigital.com>
+     * @copyright   2013-2015 GoodBoyDigital
+     * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}
+     */
+
+    /**
+     * @namespace PIXI.mesh
+     */
+    module.exports = {
+        Mesh:           require('./Mesh'),
+        Plane:           require('./Plane'),
+        NineSlicePlane: require('./NineSlicePlane'),
+        Rope:           require('./Rope'),
+        MeshShader:     require('./webgl/MeshShader')
+    };
+
+},{"./Mesh":152,"./NineSlicePlane":153,"./Plane":154,"./Rope":155,"./webgl/MeshShader":157}],157:[function(require,module,exports){
+    var Shader = require('../../core/Shader');
+
+    /**
+     * @class
+     * @extends PIXI.Shader
+     * @memberof PIXI.mesh
+     * @param gl {PIXI.Shader} TODO: Find a good explanation for this.
+     */
+    function MeshShader(gl)
+    {
+        Shader.call(this,
+            gl,
+            // vertex shader
+            [
+                'attribute vec2 aVertexPosition;',
+                'attribute vec2 aTextureCoord;',
+
+                'uniform mat3 translationMatrix;',
+                'uniform mat3 projectionMatrix;',
+
+                'varying vec2 vTextureCoord;',
+
+                'void main(void){',
+                '   gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',
+                '   vTextureCoord = aTextureCoord;',
+                '}'
+            ].join('\n'),
+            [
+                'varying vec2 vTextureCoord;',
+                'uniform float alpha;',
+                'uniform vec3 tint;',
+
+                'uniform sampler2D uSampler;',
+
+                'void main(void){',
+                '   gl_FragColor = texture2D(uSampler, vTextureCoord) * vec4(tint * alpha, alpha);',
+                // '   gl_FragColor = vec4(1.0);',
+                '}'
+            ].join('\n')
+        );
+    }
+
+    MeshShader.prototype = Object.create(Shader.prototype);
+    MeshShader.prototype.constructor = MeshShader;
+    module.exports = MeshShader;
+
+
+},{"../../core/Shader":42}],158:[function(require,module,exports){
+    var core = require('../core');
+
+    /**
+     * The ParticleContainer class is a really fast version of the Container built solely for speed,
+     * so use when you need a lot of sprites or particles. The tradeoff of the ParticleContainer is that advanced
+     * functionality will not work. ParticleContainer implements only the basic object transform (position, scale, rotation).
+     * Any other functionality like tinting, masking, etc will not work on sprites in this batch.
+     *
+     * It's extremely easy to use :
+     *
+     * ```js
+     * var container = new ParticleContainer();
+     *
+     * for (var i = 0; i < 100; ++i)
+     * {
+ *     var sprite = new PIXI.Sprite.fromImage("myImage.png");
+ *     container.addChild(sprite);
+ * }
+     * ```
+     *
+     * And here you have a hundred sprites that will be renderer at the speed of light.
+     *
+     * @class
+     * @extends PIXI.Container
+     * @memberof PIXI.particles
+     * @param [maxSize=15000] {number} The maximum number of particles that can be renderer by the container.
+     * @param [properties] {object} The properties of children that should be uploaded to the gpu and applied.
+     * @param [properties.scale=false] {boolean} When true, scale be uploaded and applied.
+     * @param [properties.position=true] {boolean} When true, position be uploaded and applied.
+     * @param [properties.rotation=false] {boolean} When true, rotation be uploaded and applied.
+     * @param [properties.uvs=false] {boolean} When true, uvs be uploaded and applied.
+     * @param [properties.alpha=false] {boolean} When true, alpha be uploaded and applied.
+     * @param [batchSize=15000] {number} Number of particles per batch.
+     */
+    function ParticleContainer(maxSize, properties, batchSize)
+    {
+        core.Container.call(this);
+
+        batchSize = batchSize || 15000; //CONST.SPRITE_BATCH_SIZE; // 2000 is a nice balance between mobile / desktop
+        maxSize = maxSize || 15000;
+
+        // Making sure the batch size is valid
+        // 65535 is max vertex index in the index buffer (see ParticleRenderer)
+        // so max number of particles is 65536 / 4 = 16384
+        var maxBatchSize = 16384;
+        if (batchSize > maxBatchSize) {
+            batchSize = maxBatchSize;
+        }
+
+        if (batchSize > maxSize) {
+            batchSize = maxSize;
+        }
+
+        /**
+         * Set properties to be dynamic (true) / static (false)
+         *
+         * @member {boolean[]}
+         * @private
+         */
+        this._properties = [false, true, false, false, false];
+
+        /**
+         * @member {number}
+         * @private
+         */
+        this._maxSize = maxSize;
+
+        /**
+         * @member {number}
+         * @private
+         */
+        this._batchSize = batchSize;
+
+        /**
+         * @member {WebGLBuffer}
+         * @private
+         */
+        this._glBuffers = [];
+
+        /**
+         * @member {number}
+         * @private
+         */
+        this._bufferToUpdate = 0;
+
+        /**
+         * @member {boolean}
+         *
+         */
+        this.interactiveChildren = false;
+
+        /**
+         * The blend mode to be applied to the sprite. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.
+         *
+         * @member {number}
+         * @default PIXI.BLEND_MODES.NORMAL
+         * @see PIXI.BLEND_MODES
+         */
+        this.blendMode = core.BLEND_MODES.NORMAL;
+
+        /**
+         * Used for canvas renderering. If true then the elements will be positioned at the nearest pixel. This provides a nice speed boost.
+         *
+         * @member {boolean}
+         * @default true;
+         */
+        this.roundPixels = true;
+
+        this.baseTexture = null;
+
+        this.setProperties(properties);
+    }
+
+    ParticleContainer.prototype = Object.create(core.Container.prototype);
+    ParticleContainer.prototype.constructor = ParticleContainer;
+    module.exports = ParticleContainer;
+
+    /**
+     * Sets the private properties array to dynamic / static based on the passed properties object
+     *
+     * @param properties {object} The properties to be uploaded
+     */
+    ParticleContainer.prototype.setProperties = function(properties)
+    {
+        if ( properties ) {
+            this._properties[0] = 'scale' in properties ? !!properties.scale : this._properties[0];
+            this._properties[1] = 'position' in properties ? !!properties.position : this._properties[1];
+            this._properties[2] = 'rotation' in properties ? !!properties.rotation : this._properties[2];
+            this._properties[3] = 'uvs' in properties ? !!properties.uvs : this._properties[3];
+            this._properties[4] = 'alpha' in properties ? !!properties.alpha : this._properties[4];
+        }
+    };
+
+    /**
+     * Updates the object transform for rendering
+     *
+     * @private
+     */
+    ParticleContainer.prototype.updateTransform = function ()
+    {
+
+        // TODO don't need to!
+        this.displayObjectUpdateTransform();
+        //  PIXI.Container.prototype.updateTransform.call( this );
+    };
+
+    /**
+     * Renders the container using the WebGL renderer
+     *
+     * @param renderer {PIXI.WebGLRenderer} The webgl renderer
+     * @private
+     */
+    ParticleContainer.prototype.renderWebGL = function (renderer)
+    {
+        if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable)
+        {
+            return;
+        }
+
+
+        if(!this.baseTexture)
+        {
+            this.baseTexture = this.children[0]._texture.baseTexture;
+            if(!this.baseTexture.hasLoaded)
+            {
+                this.baseTexture.once('update', function(){
+                    this.onChildrenChange(0);
+                }, this);
+            }
+        }
+
+
+        renderer.setObjectRenderer( renderer.plugins.particle );
+        renderer.plugins.particle.render( this );
+    };
+
+    /**
+     * Set the flag that static data should be updated to true
+     *
+     * @private
+     */
+    ParticleContainer.prototype.onChildrenChange = function (smallestChildIndex)
+    {
+        var bufferIndex = Math.floor(smallestChildIndex / this._batchSize);
+        if (bufferIndex < this._bufferToUpdate) {
+            this._bufferToUpdate = bufferIndex;
+        }
+    };
+
+    /**
+     * Renders the object using the Canvas renderer
+     *
+     * @param renderer {PIXI.CanvasRenderer} The canvas renderer
+     * @private
+     */
+    ParticleContainer.prototype.renderCanvas = function (renderer)
+    {
+        if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable)
+        {
+            return;
+        }
+
+        var context = renderer.context;
+        var transform = this.worldTransform;
+        var isRotated = true;
+
+        var positionX = 0;
+        var positionY = 0;
+
+        var finalWidth = 0;
+        var finalHeight = 0;
+
+        var compositeOperation = renderer.blendModes[this.blendMode];
+        if (compositeOperation !== context.globalCompositeOperation)
+        {
+            context.globalCompositeOperation = compositeOperation;
+        }
+
+        context.globalAlpha = this.worldAlpha;
+
+        this.displayObjectUpdateTransform();
+
+        for (var i = 0; i < this.children.length; ++i)
+        {
+            var child = this.children[i];
+
+            if (!child.visible)
+            {
+                continue;
+            }
+
+            var frame = child.texture.frame;
+
+            context.globalAlpha = this.worldAlpha * child.alpha;
+
+            if (child.rotation % (Math.PI * 2) === 0)
+            {
+                // this is the fastest  way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call
+                if (isRotated)
+                {
+                    context.setTransform(
+                        transform.a,
+                        transform.b,
+                        transform.c,
+                        transform.d,
+                        transform.tx * renderer.resolution,
+                        transform.ty * renderer.resolution
+                    );
+
+                    isRotated = false;
+                }
+
+                positionX = ((child.anchor.x) * (-frame.width * child.scale.x) + child.position.x  + 0.5);
+                positionY = ((child.anchor.y) * (-frame.height * child.scale.y) + child.position.y  + 0.5);
+
+                finalWidth = frame.width * child.scale.x;
+                finalHeight = frame.height * child.scale.y;
+
+            }
+            else
+            {
+                if (!isRotated)
+                {
+                    isRotated = true;
+                }
+
+                child.displayObjectUpdateTransform();
+
+                var childTransform = child.worldTransform;
+
+                if (renderer.roundPixels)
+                {
+                    context.setTransform(
+                        childTransform.a,
+                        childTransform.b,
+                        childTransform.c,
+                        childTransform.d,
+                        (childTransform.tx * renderer.resolution) | 0,
+                        (childTransform.ty * renderer.resolution) | 0
+                    );
+                }
+                else
+                {
+                    context.setTransform(
+                        childTransform.a,
+                        childTransform.b,
+                        childTransform.c,
+                        childTransform.d,
+                        childTransform.tx * renderer.resolution,
+                        childTransform.ty * renderer.resolution
+                    );
+                }
+
+                positionX = ((child.anchor.x) * (-frame.width) + 0.5);
+                positionY = ((child.anchor.y) * (-frame.height) + 0.5);
+
+                finalWidth = frame.width;
+                finalHeight = frame.height;
+            }
+
+            var resolution = child.texture.baseTexture.resolution;
+
+            context.drawImage(
+                child.texture.baseTexture.source,
+                frame.x * resolution,
+                frame.y * resolution,
+                frame.width * resolution,
+                frame.height * resolution,
+                positionX * resolution,
+                positionY * resolution,
+                finalWidth * resolution,
+                finalHeight * resolution
+            );
+        }
+    };
+
+    /**
+     * Destroys the container
+     *
+     */
+    ParticleContainer.prototype.destroy = function () {
+        core.Container.prototype.destroy.apply(this, arguments);
+
+        if (this._buffers) {
+            for (var i = 0; i < this._buffers.length; ++i) {
+                this._buffers[i].destroy();
+            }
+        }
+
+        this._properties = null;
+        this._buffers = null;
+    };
+
+},{"../core":62}],159:[function(require,module,exports){
+    /**
+     * @file        Main export of the PIXI extras library
+     * @author      Mat Groves <mat@goodboydigital.com>
+     * @copyright   2013-2015 GoodBoyDigital
+     * @license     {@link https://github.com/pixijs/pixi.js/blob/master/LICENSE|MIT License}
+     */
+
+    /**
+     * @namespace PIXI.particles
+     */
+    module.exports = {
+        ParticleContainer:           require('./ParticleContainer'),
+        ParticleRenderer: 			 require('./webgl/ParticleRenderer')
+    };
+
+},{"./ParticleContainer":158,"./webgl/ParticleRenderer":161}],160:[function(require,module,exports){
+    var glCore = require('pixi-gl-core'),
+        createIndicesForQuads = require('../../core/utils/createIndicesForQuads');
+
+    /**
+     * @author Mat Groves
+     *
+     * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/
+     * for creating the original pixi version!
+     * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer
+     *
+     * Heavily inspired by LibGDX's ParticleBuffer:
+     * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/ParticleBuffer.java
+     */
+
+    /**
+     * The particle buffer manages the static and dynamic buffers for a particle container.
+     *
+     * @class
+     * @private
+     * @memberof PIXI
+     */
+    function ParticleBuffer(gl, properties, dynamicPropertyFlags, size)
+    {
+        /**
+         * The current WebGL drawing context.
+         *
+         * @member {WebGLRenderingContext}
+         */
+        this.gl = gl;
+
+        /**
+         * Size of a single vertex.
+         *
+         * @member {number}
+         */
+        this.vertSize = 2;
+
+        /**
+         * Size of a single vertex in bytes.
+         *
+         * @member {number}
+         */
+        this.vertByteSize = this.vertSize * 4;
+
+        /**
+         * The number of particles the buffer can hold
+         *
+         * @member {number}
+         */
+        this.size = size;
+
+        /**
+         * A list of the properties that are dynamic.
+         *
+         * @member {object[]}
+         */
+        this.dynamicProperties = [];
+
+        /**
+         * A list of the properties that are static.
+         *
+         * @member {object[]}
+         */
+        this.staticProperties = [];
+
+        for (var i = 0; i < properties.length; i++)
+        {
+            var property = properties[i];
+
+            // Make copy of properties object so that when we edit the offset it doesn't
+            // change all other instances of the object literal
+            property =
+            {
+                attribute:property.attribute,
+                size:property.size,
+                uploadFunction:property.uploadFunction,
+                offset:property.offset
+            };
+
+            if(dynamicPropertyFlags[i])
+            {
+                this.dynamicProperties.push(property);
+            }
+            else
+            {
+                this.staticProperties.push(property);
+            }
+        }
+
+        this.staticStride = 0;
+        this.staticBuffer = null;
+        this.staticData = null;
+
+        this.dynamicStride = 0;
+        this.dynamicBuffer = null;
+        this.dynamicData = null;
+
+        this.initBuffers();
+
+    }
+
+    ParticleBuffer.prototype.constructor = ParticleBuffer;
+    module.exports = ParticleBuffer;
+
+    /**
+     * Sets up the renderer context and necessary buffers.
+     *
+     * @private
+     */
+    ParticleBuffer.prototype.initBuffers = function ()
+    {
+        var gl = this.gl;
+        var i;
+        var property;
+
+        var dynamicOffset = 0;
+
+
+        /**
+         * Holds the indices of the geometry (quads) to draw
+         *
+         * @member {Uint16Array}
+         */
+        this.indices = createIndicesForQuads(this.size);
+        this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW);
+
+
+        this.dynamicStride = 0;
+
+        for (i = 0; i < this.dynamicProperties.length; i++)
+        {
+            property = this.dynamicProperties[i];
+
+            property.offset = dynamicOffset;
+            dynamicOffset += property.size;
+            this.dynamicStride += property.size;
+        }
+
+        this.dynamicData = new Float32Array( this.size * this.dynamicStride * 4);
+        this.dynamicBuffer = glCore.GLBuffer.createVertexBuffer(gl, this.dynamicData, gl.STREAM_DRAW);
+
+        // static //
+        var staticOffset = 0;
+        this.staticStride = 0;
+
+        for (i = 0; i < this.staticProperties.length; i++)
+        {
+            property = this.staticProperties[i];
+
+            property.offset = staticOffset;
+            staticOffset += property.size;
+            this.staticStride += property.size;
+
+
+        }
+
+        this.staticData = new Float32Array( this.size * this.staticStride * 4);
+        this.staticBuffer = glCore.GLBuffer.createVertexBuffer(gl, this.staticData, gl.STATIC_DRAW);
+
+
+        this.vao = new glCore.VertexArrayObject(gl)
+            .addIndex(this.indexBuffer);
+
+        for (i = 0; i < this.dynamicProperties.length; i++)
+        {
+            property = this.dynamicProperties[i];
+            this.vao.addAttribute(this.dynamicBuffer, property.attribute, gl.FLOAT, false, this.dynamicStride * 4, property.offset * 4);
+        }
+
+        for (i = 0; i < this.staticProperties.length; i++)
+        {
+            property = this.staticProperties[i];
+            this.vao.addAttribute(this.staticBuffer, property.attribute, gl.FLOAT, false, this.staticStride * 4, property.offset * 4);
+        }
+    };
+
+    /**
+     * Uploads the dynamic properties.
+     *
+     */
+    ParticleBuffer.prototype.uploadDynamic = function(children, startIndex, amount)
+    {
+        for (var i = 0; i < this.dynamicProperties.length; i++)
+        {
+            var property = this.dynamicProperties[i];
+            property.uploadFunction(children, startIndex, amount, this.dynamicData, this.dynamicStride, property.offset);
+        }
+
+        this.dynamicBuffer.upload();
+    };
+
+    /**
+     * Uploads the static properties.
+     *
+     */
+    ParticleBuffer.prototype.uploadStatic = function(children, startIndex, amount)
+    {
+        for (var i = 0; i < this.staticProperties.length; i++)
+        {
+            var property = this.staticProperties[i];
+            property.uploadFunction(children, startIndex, amount, this.staticData, this.staticStride, property.offset);
+        }
+
+        this.staticBuffer.upload();
+    };
+
+    /**
+     * Binds the buffers to the GPU
+     *
+     */
+    ParticleBuffer.prototype.bind = function ()
+    {
+        this.vao.bind();
+    };
+
+    /**
+     * Destroys the ParticleBuffer.
+     *
+     */
+    ParticleBuffer.prototype.destroy = function ()
+    {
+        this.dynamicProperties = null;
+        this.dynamicData = null;
+        this.dynamicBuffer.destroy();
+
+        this.staticProperties = null;
+        this.staticData = null;
+        this.staticBuffer.destroy();
+    };
+
+},{"../../core/utils/createIndicesForQuads":114,"pixi-gl-core":12}],161:[function(require,module,exports){
+    var core = require('../../core'),
+        ParticleShader = require('./ParticleShader'),
+        ParticleBuffer = require('./ParticleBuffer');
+
+    /**
+     * @author Mat Groves
+     *
+     * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/
+     * for creating the original pixi version!
+     * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer
+     *
+     * Heavily inspired by LibGDX's ParticleRenderer:
+     * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/ParticleRenderer.java
+     */
+
+    /**
+     *
+     * @class
+     * @private
+     * @memberof PIXI
+     * @param renderer {PIXI.WebGLRenderer} The renderer this sprite batch works for.
+     */
+    function ParticleRenderer(renderer)
+    {
+        core.ObjectRenderer.call(this, renderer);
+
+        // 65535 is max vertex index in the index buffer (see ParticleRenderer)
+        // so max number of particles is 65536 / 4 = 16384
+        // and max number of element in the index buffer is 16384 * 6 = 98304
+        // Creating a full index buffer, overhead is 98304 * 2 = 196Ko
+        // var numIndices = 98304;
+
+        /**
+         * The default shader that is used if a sprite doesn't have a more specific one.
+         *
+         * @member {PIXI.Shader}
+         */
+        this.shader = null;
+
+        this.indexBuffer = null;
+
+        this.properties = null;
+
+        this.tempMatrix = new core.Matrix();
+
+        this.CONTEXT_UID = 0;
+    }
+
+    ParticleRenderer.prototype = Object.create(core.ObjectRenderer.prototype);
+    ParticleRenderer.prototype.constructor = ParticleRenderer;
+    module.exports = ParticleRenderer;
+
+    core.WebGLRenderer.registerPlugin('particle', ParticleRenderer);
+
+    /**
+     * When there is a WebGL context change
+     *
+     * @private
+     */
+    ParticleRenderer.prototype.onContextChange = function ()
+    {
+        var gl = this.renderer.gl;
+
+        this.CONTEXT_UID = this.renderer.CONTEXT_UID;
+
+        // setup default shader
+        this.shader = new ParticleShader(gl);
+
+        this.properties = [
+            // verticesData
+            {
+                attribute:this.shader.attributes.aVertexPosition,
+                size:2,
+                uploadFunction:this.uploadVertices,
+                offset:0
+            },
+            // positionData
+            {
+                attribute:this.shader.attributes.aPositionCoord,
+                size:2,
+                uploadFunction:this.uploadPosition,
+                offset:0
+            },
+            // rotationData
+            {
+                attribute:this.shader.attributes.aRotation,
+                size:1,
+                uploadFunction:this.uploadRotation,
+                offset:0
+            },
+            // uvsData
+            {
+                attribute:this.shader.attributes.aTextureCoord,
+                size:2,
+                uploadFunction:this.uploadUvs,
+                offset:0
+            },
+            // alphaData
+            {
+                attribute:this.shader.attributes.aColor,
+                size:1,
+                uploadFunction:this.uploadAlpha,
+                offset:0
+            }
+        ];
+
+    };
+
+    /**
+     * Starts a new particle batch.
+     *
+     */
+    ParticleRenderer.prototype.start = function ()
+    {
+        this.renderer.bindShader(this.shader);
+    };
+
+
+    /**
+     * Renders the particle container object.
+     *
+     * @param container {PIXI.ParticleContainer} The container to render using this ParticleRenderer
+     */
+    ParticleRenderer.prototype.render = function (container)
+    {
+        var children = container.children,
+            totalChildren = children.length,
+            maxSize = container._maxSize,
+            batchSize = container._batchSize;
+
+        if(totalChildren === 0)
+        {
+            return;
+        }
+        else if(totalChildren > maxSize)
+        {
+            totalChildren = maxSize;
+        }
+
+        var buffers = container._glBuffers[this.renderer.CONTEXT_UID];
+
+        if(!buffers)
+        {
+            buffers = container._glBuffers[this.renderer.CONTEXT_UID] = this.generateBuffers( container );
+        }
+
+        // if the uvs have not updated then no point rendering just yet!
+        this.renderer.setBlendMode(container.blendMode);
+
+        var gl = this.renderer.gl;
+
+        var m = container.worldTransform.copy( this.tempMatrix );
+        m.prepend( this.renderer._activeRenderTarget.projectionMatrix );
+        this.shader.uniforms.projectionMatrix = m.toArray(true);
+        this.shader.uniforms.uAlpha = container.worldAlpha;
+
+
+        // make sure the texture is bound..
+        var baseTexture = children[0]._texture.baseTexture;
+
+        this.renderer.bindTexture(baseTexture);
+
+        // now lets upload and render the buffers..
+        for (var i = 0, j = 0; i < totalChildren; i += batchSize, j += 1)
+        {
+            var amount = ( totalChildren - i);
+            if(amount > batchSize)
+            {
+                amount = batchSize;
+            }
+
+            var buffer = buffers[j];
+
+            // we always upload the dynamic
+            buffer.uploadDynamic(children, i, amount);
+
+            // we only upload the static content when we have to!
+            if(container._bufferToUpdate === j)
+            {
+                buffer.uploadStatic(children, i, amount);
+                container._bufferToUpdate = j + 1;
+            }
+
+            // bind the buffer
+            buffer.vao.bind()
+                .draw(gl.TRIANGLES, amount * 6)
+                .unbind();
+
+            // now draw those suckas!
+            // gl.drawElements(gl.TRIANGLES, amount * 6, gl.UNSIGNED_SHORT, 0);
+            //  this.renderer.drawCount++;
+        }
+    };
+
+    /**
+     * Creates one particle buffer for each child in the container we want to render and updates internal properties
+     *
+     * @param container {PIXI.ParticleContainer} The container to render using this ParticleRenderer
+     */
+    ParticleRenderer.prototype.generateBuffers = function (container)
+    {
+        var gl = this.renderer.gl,
+            buffers = [],
+            size = container._maxSize,
+            batchSize = container._batchSize,
+            dynamicPropertyFlags = container._properties,
+            i;
+
+        for (i = 0; i < size; i += batchSize)
+        {
+            buffers.push(new ParticleBuffer(gl, this.properties, dynamicPropertyFlags, batchSize));
+        }
+
+        return buffers;
+    };
+
+    /**
+     * Uploads the verticies.
+     *
+     * @param children {PIXI.DisplayObject[]} the array of display objects to render
+     * @param startIndex {number} the index to start from in the children array
+     * @param amount {number} the amount of children that will have their vertices uploaded
+     * @param array {number[]}
+     * @param stride {number}
+     * @param offset {number}
+     */
+    ParticleRenderer.prototype.uploadVertices = function (children, startIndex, amount, array, stride, offset)
+    {
+        var sprite,
+            texture,
+            trim,
+            orig,
+            sx,
+            sy,
+            w0, w1, h0, h1;
+
+        for (var i = 0; i < amount; i++) {
+
+            sprite = children[startIndex + i];
+            texture = sprite._texture;
+            sx = sprite.scale.x;
+            sy = sprite.scale.y;
+            trim = texture.trim;
+            orig = texture.orig;
+
+            if (trim)
+            {
+                // if the sprite is trimmed and is not a tilingsprite then we need to add the extra space before transforming the sprite coords..
+                w1 = trim.x - sprite.anchor.x * orig.width;
+                w0 = w1 + trim.width;
+
+                h1 = trim.y - sprite.anchor.y * orig.height;
+                h0 = h1 + trim.height;
+
+            }
+            else
+            {
+                w0 = (orig.width ) * (1-sprite.anchor.x);
+                w1 = (orig.width ) * -sprite.anchor.x;
+
+                h0 = orig.height * (1-sprite.anchor.y);
+                h1 = orig.height * -sprite.anchor.y;
+            }
+
+            array[offset] = w1 * sx;
+            array[offset + 1] = h1 * sy;
+
+            array[offset + stride] = w0 * sx;
+            array[offset + stride + 1] = h1 * sy;
+
+            array[offset + stride * 2] = w0 * sx;
+            array[offset + stride * 2 + 1] = h0 * sy;
+
+            array[offset + stride * 3] = w1 * sx;
+            array[offset + stride * 3 + 1] = h0 * sy;
+
+            offset += stride * 4;
+        }
+
+    };
+
+    /**
+     *
+     * @param children {PIXI.DisplayObject[]} the array of display objects to render
+     * @param startIndex {number} the index to start from in the children array
+     * @param amount {number} the amount of children that will have their positions uploaded
+     * @param array {number[]}
+     * @param stride {number}
+     * @param offset {number}
+     */
+    ParticleRenderer.prototype.uploadPosition = function (children,startIndex, amount, array, stride, offset)
+    {
+        for (var i = 0; i < amount; i++)
+        {
+            var spritePosition = children[startIndex + i].position;
+
+            array[offset] = spritePosition.x;
+            array[offset + 1] = spritePosition.y;
+
+            array[offset + stride] = spritePosition.x;
+            array[offset + stride + 1] = spritePosition.y;
+
+            array[offset + stride * 2] = spritePosition.x;
+            array[offset + stride * 2 + 1] = spritePosition.y;
+
+            array[offset + stride * 3] = spritePosition.x;
+            array[offset + stride * 3 + 1] = spritePosition.y;
+
+            offset += stride * 4;
+        }
+
+    };
+
+    /**
+     *
+     * @param children {PIXI.DisplayObject[]} the array of display objects to render
+     * @param startIndex {number} the index to start from in the children array
+     * @param amount {number} the amount of children that will have their rotation uploaded
+     * @param array {number[]}
+     * @param stride {number}
+     * @param offset {number}
+     */
+    ParticleRenderer.prototype.uploadRotation = function (children,startIndex, amount, array, stride, offset)
+    {
+        for (var i = 0; i < amount; i++)
+        {
+            var spriteRotation = children[startIndex + i].rotation;
+
+
+            array[offset] = spriteRotation;
+            array[offset + stride] = spriteRotation;
+            array[offset + stride * 2] = spriteRotation;
+            array[offset + stride * 3] = spriteRotation;
+
+            offset += stride * 4;
+        }
+    };
+
+    /**
+     *
+     * @param children {PIXI.DisplayObject[]} the array of display objects to render
+     * @param startIndex {number} the index to start from in the children array
+     * @param amount {number} the amount of children that will have their Uvs uploaded
+     * @param array {number[]}
+     * @param stride {number}
+     * @param offset {number}
+     */
+    ParticleRenderer.prototype.uploadUvs = function (children,startIndex, amount, array, stride, offset)
+    {
+        for (var i = 0; i < amount; i++)
+        {
+            var textureUvs = children[startIndex + i]._texture._uvs;
+
+            if (textureUvs)
+            {
+                array[offset] = textureUvs.x0;
+                array[offset + 1] = textureUvs.y0;
+
+                array[offset + stride] = textureUvs.x1;
+                array[offset + stride + 1] = textureUvs.y1;
+
+                array[offset + stride * 2] = textureUvs.x2;
+                array[offset + stride * 2 + 1] = textureUvs.y2;
+
+                array[offset + stride * 3] = textureUvs.x3;
+                array[offset + stride * 3 + 1] = textureUvs.y3;
+
+                offset += stride * 4;
+            }
+            else
+            {
+                //TODO you know this can be easier!
+                array[offset] = 0;
+                array[offset + 1] = 0;
+
+                array[offset + stride] = 0;
+                array[offset + stride + 1] = 0;
+
+                array[offset + stride * 2] = 0;
+                array[offset + stride * 2 + 1] = 0;
+
+                array[offset + stride * 3] = 0;
+                array[offset + stride * 3 + 1] = 0;
+
+                offset += stride * 4;
+            }
+        }
+    };
+
+    /**
+     *
+     * @param children {PIXI.DisplayObject[]} the array of display objects to render
+     * @param startIndex {number} the index to start from in the children array
+     * @param amount {number} the amount of children that will have their alpha uploaded
+     * @param array {number[]}
+     * @param stride {number}
+     * @param offset {number}
+     */
+    ParticleRenderer.prototype.uploadAlpha = function (children,startIndex, amount, array, stride, offset)
+    {
+        for (var i = 0; i < amount; i++)
+        {
+            var spriteAlpha = children[startIndex + i].alpha;
+
+            array[offset] = spriteAlpha;
+            array[offset + stride] = spriteAlpha;
+            array[offset + stride * 2] = spriteAlpha;
+            array[offset + stride * 3] = spriteAlpha;
+
+            offset += stride * 4;
+        }
+    };
+
+
+    /**
+     * Destroys the ParticleRenderer.
+     *
+     */
+    ParticleRenderer.prototype.destroy = function ()
+    {
+        if (this.renderer.gl) {
+            this.renderer.gl.deleteBuffer(this.indexBuffer);
+        }
+        core.ObjectRenderer.prototype.destroy.apply(this, arguments);
+
+        this.shader.destroy();
+
+        this.indices = null;
+        this.tempMatrix = null;
+    };
+
+},{"../../core":62,"./ParticleBuffer":160,"./ParticleShader":162}],162:[function(require,module,exports){
+    var Shader = require('../../core/Shader');
+
+    /**
+     * @class
+     * @extends PIXI.Shader
+     * @memberof PIXI
+     * @param gl {PIXI.Shader} The webgl shader manager this shader works for.
+     */
+    function ParticleShader(gl)
+    {
+        Shader.call(this,
+            gl,
+            // vertex shader
+            [
+                'attribute vec2 aVertexPosition;',
+                'attribute vec2 aTextureCoord;',
+                'attribute float aColor;',
+
+                'attribute vec2 aPositionCoord;',
+                'attribute vec2 aScale;',
+                'attribute float aRotation;',
+
+                'uniform mat3 projectionMatrix;',
+
+                'varying vec2 vTextureCoord;',
+                'varying float vColor;',
+
+                'void main(void){',
+                '   vec2 v = aVertexPosition;',
+
+                '   v.x = (aVertexPosition.x) * cos(aRotation) - (aVertexPosition.y) * sin(aRotation);',
+                '   v.y = (aVertexPosition.x) * sin(aRotation) + (aVertexPosition.y) * cos(aRotation);',
+                '   v = v + aPositionCoord;',
+
+                '   gl_Position = vec4((projectionMatrix * vec3(v, 1.0)).xy, 0.0, 1.0);',
+
+                '   vTextureCoord = aTextureCoord;',
+                '   vColor = aColor;',
+                '}'
+            ].join('\n'),
+            // hello
+            [
+                'varying vec2 vTextureCoord;',
+                'varying float vColor;',
+
+                'uniform sampler2D uSampler;',
+                'uniform float uAlpha;',
+
+                'void main(void){',
+                '  vec4 color = texture2D(uSampler, vTextureCoord) * vColor * uAlpha;',
+                '  if (color.a == 0.0) discard;',
+                '  gl_FragColor = color;',
+                '}'
+            ].join('\n')
+        );
+
+        // TEMP HACK
+
+    }
+
+    ParticleShader.prototype = Object.create(Shader.prototype);
+    ParticleShader.prototype.constructor = ParticleShader;
+
+    module.exports = ParticleShader;
+
+},{"../../core/Shader":42}],163:[function(require,module,exports){
+// References:
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign
+
+    if (!Math.sign)
+    {
+        Math.sign = function (x) {
+            x = +x;
+            if (x === 0 || isNaN(x))
+            {
+                return x;
+            }
+            return x > 0 ? 1 : -1;
+        };
+    }
+
+},{}],164:[function(require,module,exports){
+// References:
+// https://github.com/sindresorhus/object-assign
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
+
+    if (!Object.assign)
+    {
+        Object.assign = require('object-assign');
+    }
+
+},{"object-assign":5}],165:[function(require,module,exports){
+    require('./Object.assign');
+    require('./requestAnimationFrame');
+    require('./Math.sign');
+
+    if(!window.ArrayBuffer){
+        window.ArrayBuffer = Array;
+    }
+    if(!window.Float32Array) {
+        window.Float32Array = Array;
+    }
+    if(!window.Uint32Array){
+        window.Uint32Array = Array;
+    }
+    if(!window.Uint16Array){
+        window.Uint16Array = Array;
+    }
+
+},{"./Math.sign":163,"./Object.assign":164,"./requestAnimationFrame":166}],166:[function(require,module,exports){
+    (function (global){
+// References:
+// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
+// https://gist.github.com/1579671
+// http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision
+// https://gist.github.com/timhall/4078614
+// https://github.com/Financial-Times/polyfill-service/tree/master/polyfills/requestAnimationFrame
+
+// Expected to be used with Browserfiy
+// Browserify automatically detects the use of `global` and passes the
+// correct reference of `global`, `self`, and finally `window`
+
+// Date.now
+        if (!(Date.now && Date.prototype.getTime)) {
+            Date.now = function now() {
+                return new Date().getTime();
+            };
+        }
+
+// performance.now
+        if (!(global.performance && global.performance.now)) {
+            var startTime = Date.now();
+            if (!global.performance) {
+                global.performance = {};
+            }
+            global.performance.now = function () {
+                return Date.now() - startTime;
+            };
+        }
+
+// requestAnimationFrame
+        var lastTime = Date.now();
+        var vendors = ['ms', 'moz', 'webkit', 'o'];
+
+        for(var x = 0; x < vendors.length && !global.requestAnimationFrame; ++x) {
+            global.requestAnimationFrame = global[vendors[x] + 'RequestAnimationFrame'];
+            global.cancelAnimationFrame = global[vendors[x] + 'CancelAnimationFrame'] ||
+            global[vendors[x] + 'CancelRequestAnimationFrame'];
+        }
+
+        if (!global.requestAnimationFrame) {
+            global.requestAnimationFrame = function (callback) {
+                if (typeof callback !== 'function') {
+                    throw new TypeError(callback + 'is not a function');
+                }
+
+                var currentTime = Date.now(),
+                    delay = 16 + lastTime - currentTime;
+
+                if (delay < 0) {
+                    delay = 0;
+                }
+
+                lastTime = currentTime;
+
+                return setTimeout(function () {
+                    lastTime = Date.now();
+                    callback(performance.now());
+                }, delay);
+            };
+        }
+
+        if (!global.cancelAnimationFrame) {
+            global.cancelAnimationFrame = function(id) {
+                clearTimeout(id);
+            };
+        }
+
+    }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{}],167:[function(require,module,exports){
+    var core = require('../../core');
+
+    /**
+     * Prepare uploads elements to the GPU. The CanvasRenderer version of prepare
+     * provides the same APIs as the WebGL version, but doesn't do anything.
+     * @class
+     * @memberof PIXI
+     * @param renderer {PIXI.CanvasRenderer} A reference to the current renderer
+     */
+    function CanvasPrepare()
+    {
+    }
+
+    CanvasPrepare.prototype.constructor = CanvasPrepare;
+    module.exports = CanvasPrepare;
+
+    /**
+     * Stub method for upload.
+     * @param {Function|PIXI.DisplayObject|PIXI.Container} item Either
+     *        the container or display object to search for items to upload or
+     *        the callback function, if items have been added using `prepare.add`.
+     * @param {Function} done When completed
+     */
+    CanvasPrepare.prototype.upload = function(displayObject, done)
+    {
+        if (typeof displayObject === 'function')
+        {
+            done = displayObject;
+            displayObject = null;
+        }
+        done();
+    };
+
+    /**
+     * Stub method for registering hooks.
+     * @return {PIXI.CanvasPrepare} Instance of plugin for chaining.
+     */
+    CanvasPrepare.prototype.register = function()
+    {
+        return this;
+    };
+
+    /**
+     * Stub method for adding items.
+     * @return {PIXI.CanvasPrepare} Instance of plugin for chaining.
+     */
+    CanvasPrepare.prototype.add = function()
+    {
+        return this;
+    };
+
+    /**
+     * Stub method for destroying plugin.
+     */
+    CanvasPrepare.prototype.destroy = function()
+    {
+    };
+
+    core.CanvasRenderer.registerPlugin('prepare', CanvasPrepare);
+},{"../../core":62}],168:[function(require,module,exports){
+
+    module.exports = {
+        webGL: require('./webgl/WebGLPrepare'),
+        canvas: require('./canvas/CanvasPrepare')
+    };
+},{"./canvas/CanvasPrepare":167,"./webgl/WebGLPrepare":169}],169:[function(require,module,exports){
+    var core = require('../../core'),
+        SharedTicker = core.ticker.shared;
+
+    /**
+     * The prepare manager provides functionality to upload content to the GPU
+     * @class
+     * @memberof PIXI
+     * @param renderer {PIXI.WebGLRenderer} A reference to the current renderer
+     */
+    function WebGLPrepare(renderer)
+    {
+        /**
+         * Reference to the renderer.
+         * @type {PIXI.WebGLRenderer}
+         * @private
+         */
+        this.renderer = renderer;
+
+        /**
+         * Collection of items to uploads at once.
+         * @type {Array<*>}
+         * @private
+         */
+        this.queue = [];
+
+        /**
+         * Collection of additional hooks for finding assets.
+         * @type {Array<Function>}
+         * @private
+         */
+        this.addHooks = [];
+
+        /**
+         * Collection of additional hooks for processing assets.
+         * @type {Array<Function>}
+         * @private
+         */
+        this.uploadHooks = [];
+
+        /**
+         * Callback to call after completed.
+         * @type {Array<Function>}
+         * @private
+         */
+        this.completes = [];
+
+        /**
+         * If prepare is ticking (running).
+         * @type {boolean}
+         * @private
+         */
+        this.ticking = false;
+
+        // Add textures and graphics to upload
+        this.register(findBaseTextures, uploadBaseTextures)
+            .register(findGraphics, uploadGraphics);
+    }
+
+    /**
+     * The number of graphics or textures to upload to the GPU
+     * @property {number} UPLOADS_PER_FRAME
+     * @static
+     * @default 4
+     */
+    WebGLPrepare.UPLOADS_PER_FRAME = 4;
+
+    WebGLPrepare.prototype.constructor = WebGLPrepare;
+    module.exports = WebGLPrepare;
+
+    /**
+     * Upload all the textures and graphics to the GPU.
+     * @param {Function|PIXI.DisplayObject|PIXI.Container} item Either
+     *        the container or display object to search for items to upload or
+     *        the callback function, if items have been added using `prepare.add`.
+     * @param {Function} done When completed
+     */
+    WebGLPrepare.prototype.upload = function(item, done)
+    {
+        if (typeof item === 'function')
+        {
+            done = item;
+            item = null;
+        }
+
+        // If a display object, search for items
+        // that we could upload
+        if (item)
+        {
+            this.add(item);
+        }
+
+        // Get the items for upload from the display
+        if (this.queue.length)
+        {
+            this.numLeft = WebGLPrepare.UPLOADS_PER_FRAME;
+            this.completes.push(done);
+            if (!this.ticking)
+            {
+                this.ticking = true;
+                SharedTicker.add(this.tick, this);
+            }
+        }
+        else
+        {
+            done();
+        }
+    };
+
+    /**
+     * Handle tick update
+     * @private
+     */
+    WebGLPrepare.prototype.tick = function()
+    {
+        var i, len;
+
+        // Upload the graphics
+        while(this.queue.length && this.numLeft > 0)
+        {
+            var item = this.queue[0];
+            var uploaded = false;
+            for (i = 0, len = this.uploadHooks.length; i < len; i++)
+            {
+                if (this.uploadHooks[i](this.renderer, item))
+                {
+                    this.numLeft--;
+                    this.queue.shift();
+                    uploaded = true;
+                    break;
+                }
+            }
+            if (!uploaded)
+            {
+                this.queue.shift();
+            }
+        }
+
+        // We're finished
+        if (this.queue.length)
+        {
+            this.numLeft = WebGLPrepare.UPLOADS_PER_FRAME;
+        }
+        else
+        {
+            this.ticking = false;
+            SharedTicker.remove(this.tick, this);
+            var completes = this.completes.slice(0);
+            this.completes.length = 0;
+            for (i = 0, len = completes.length; i < len; i++)
+            {
+                completes[i]();
+            }
+        }
+    };
+
+    /**
+     * Adds hooks for finding and uploading items.
+     * @param {Function} [addHook] Function call that takes two parameters: `item:*, queue:Array`
+     function must return `true` if it was able to add item to the queue.
+     * @param {Function} [uploadHook] Function call that takes two parameters: `renderer:WebGLRenderer, item:*` and
+     *        function must return `true` if it was able to handle upload of item.
+     * @return {PIXI.WebGLPrepare} Instance of plugin for chaining.
+     */
+    WebGLPrepare.prototype.register = function(addHook, uploadHook)
+    {
+        if (addHook)
+        {
+            this.addHooks.push(addHook);
+        }
+        if (uploadHook)
+        {
+            this.uploadHooks.push(uploadHook);
+        }
+        return this;
+    };
+
+    /**
+     * Manually add an item to the uploading queue.
+     * @param {PIXI.DisplayObject|PIXI.Container|*} item Object to add to the queue
+     * @return {PIXI.WebGLPrepare} Instance of plugin for chaining.
+     */
+    WebGLPrepare.prototype.add = function(item)
+    {
+        var i, len;
+
+        // Add additional hooks for finding elements on special
+        // types of objects that
+        for (i = 0, len = this.addHooks.length; i < len; i++)
+        {
+            if (this.addHooks[i](item, this.queue))
+            {
+                break;
+            }
+        }
+
+        // Get childen recursively
+        if (item instanceof core.Container)
+        {
+            for (i = item.children.length - 1; i >= 0; i--)
+            {
+                this.add(item.children[i]);
+            }
+        }
+        return this;
+    };
+
+    /**
+     * Destroys the plugin, don't use after this.
+     */
+    WebGLPrepare.prototype.destroy = function()
+    {
+        if (this.ticking)
+        {
+            SharedTicker.remove(this.tick, this);
+        }
+        this.ticking = false;
+        this.addHooks = null;
+        this.uploadHooks = null;
+        this.renderer = null;
+        this.completes = null;
+        this.queue = null;
+    };
+
+    /**
+     * Built-in hook to upload PIXI.Texture objects to the GPU
+     * @private
+     * @param {*} item Item to check
+     * @return {boolean} If item was uploaded.
+     */
+    function uploadBaseTextures(renderer, item)
+    {
+        if (item instanceof core.BaseTexture)
+        {
+            renderer.textureManager.updateTexture(item);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Built-in hook to upload PIXI.Graphics to the GPU
+     * @private
+     * @param {*} item Item to check
+     * @return {boolean} If item was uploaded.
+     */
+    function uploadGraphics(renderer, item)
+    {
+        if (item instanceof core.Graphics)
+        {
+            renderer.plugins.graphics.updateGraphics(item);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Built-in hook to find textures from Sprites
+     * @private
+     * @param {PIXI.DisplayObject} item Display object to check
+     * @param {Array<*>} queue Collection of items to upload
+     * @return {boolean} if a PIXI.Texture object was found.
+     */
+    function findBaseTextures(item, queue)
+    {
+        // Objects with textures, like Sprites/Text
+        if (item instanceof core.BaseTexture)
+        {
+            if (queue.indexOf(item) === -1)
+            {
+                queue.push(item);
+            }
+            return true;
+        }
+        else if (item._texture && item._texture instanceof core.Texture)
+        {
+            var texture = item._texture.baseTexture;
+            if (queue.indexOf(texture) === -1)
+            {
+                queue.push(texture);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Built-in hook to find graphics
+     * @private
+     * @param {PIXI.DisplayObject} item Display object to check
+     * @param {Array<*>} queue Collection of items to upload
+     * @return {boolean} if a PIXI.Graphics object was found.
+     */
+    function findGraphics(item, queue)
+    {
+        if (item instanceof core.Graphics)
+        {
+            queue.push(item);
+            return true;
+        }
+        return false;
+    }
+
+    core.WebGLRenderer.registerPlugin('prepare', WebGLPrepare);
+},{"../../core":62}],170:[function(require,module,exports){
+    (function (global){
+// run the polyfills
+        require('./polyfill');
+
+        var core = module.exports = require('./core');
+
+// add core plugins.
+        core.extras         = require('./extras');
+        core.filters        = require('./filters');
+        core.interaction    = require('./interaction');
+        core.loaders        = require('./loaders');
+        core.mesh           = require('./mesh');
+        core.particles      = require('./particles');
+        core.accessibility  = require('./accessibility');
+        core.extract        = require('./extract');
+        core.prepare        = require('./prepare');
+
+// export a premade loader instance
+        /**
+         * A premade instance of the loader that can be used to loader resources.
+         *
+         * @name loader
+         * @memberof PIXI
+         * @property {PIXI.loaders.Loader}
+         */
+        core.loader = new core.loaders.Loader();
+
+// mixin the deprecation features.
+        Object.assign(core, require('./deprecation'));
+
+// Always export pixi globally.
+        global.PIXI = core;
+
+    }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"./accessibility":41,"./core":62,"./deprecation":119,"./extract":121,"./extras":129,"./filters":140,"./interaction":145,"./loaders":148,"./mesh":156,"./particles":159,"./polyfill":165,"./prepare":168}]},{},[170])(170)
+});
+
+
+//# sourceMappingURL=pixi.js.map
\ No newline at end of file
diff --git a/player/js/3rd_party/PIXI_4_4_3.js b/player/js/3rd_party/PIXI_4_4_3.js
new file mode 100644
index 0000000..81f24a3
--- /dev/null
+++ b/player/js/3rd_party/PIXI_4_4_3.js
@@ -0,0 +1,21 @@
+/*!
+ * pixi.js - v4.4.3
+ * Compiled Thu, 23 Mar 2017 12:28:18 UTC
+ *
+ * pixi.js is licensed under the MIT License.
+ * http://www.opensource.org/licenses/mit-license
+ */
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.PIXI=t()}}(function(){var t;return function t(e,r,n){function i(s,a){if(!r[s]){if(!e[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var l=r[s]={exports:{}};e[s][0].call(l.exports,function(t){var r=e[s][1][t];return i(r?r:t)},l,l.exports,t,e,r,n)}return r[s].exports}for(var o="function"==typeof require&&require,s=0;s<n.length;s++)i(n[s]);return i}({1:[function(t,e,r){"use strict";"use restrict";function n(t){var e=32;return t&=-t,t&&e--,65535&t&&(e-=16),16711935&t&&(e-=8),252645135&t&&(e-=4),858993459&t&&(e-=2),1431655765&t&&(e-=1),e}r.INT_BITS=32,r.INT_MAX=2147483647,r.INT_MIN=-1<<31,r.sign=function(t){return(t>0)-(t<0)},r.abs=function(t){var e=t>>31;return(t^e)-e},r.min=function(t,e){return e^(t^e)&-(t<e)},r.max=function(t,e){return t^(t^e)&-(t<e)},r.isPow2=function(t){return!(t&t-1||!t)},r.log2=function(t){var e,r;return e=(t>65535)<<4,t>>>=e,r=(t>255)<<3,t>>>=r,e|=r,r=(t>15)<<2,t>>>=r,e|=r,r=(t>3)<<1,t>>>=r,(e|=r)|t>>1},r.log10=function(t){return t>=1e9?9:t>=1e8?8:t>=1e7?7:t>=1e6?6:t>=1e5?5:t>=1e4?4:t>=1e3?3:t>=100?2:t>=10?1:0},r.popCount=function(t){return t-=t>>>1&1431655765,16843009*((t=(858993459&t)+(t>>>2&858993459))+(t>>>4)&252645135)>>>24},r.countTrailingZeros=n,r.nextPow2=function(t){return t+=0===t,--t,t|=t>>>1,t|=t>>>2,t|=t>>>4,t|=t>>>8,(t|=t>>>16)+1},r.prevPow2=function(t){return t|=t>>>1,t|=t>>>2,t|=t>>>4,t|=t>>>8,(t|=t>>>16)-(t>>>1)},r.parity=function(t){return t^=t>>>16,t^=t>>>8,t^=t>>>4,27030>>>(t&=15)&1};var i=new Array(256);!function(t){for(var e=0;e<256;++e){var r=e,n=e,i=7;for(r>>>=1;r;r>>>=1)n<<=1,n|=1&r,--i;t[e]=n<<i&255}}(i),r.reverse=function(t){return i[255&t]<<24|i[t>>>8&255]<<16|i[t>>>16&255]<<8|i[t>>>24&255]},r.interleave2=function(t,e){return t&=65535,t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e&=65535,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t|e<<1},r.deinterleave2=function(t,e){return t=t>>>e&1431655765,t=858993459&(t|t>>>1),t=252645135&(t|t>>>2),t=16711935&(t|t>>>4),(t=65535&(t|t>>>16))<<16>>16},r.interleave3=function(t,e,r){return t&=1023,t=4278190335&(t|t<<16),t=251719695&(t|t<<8),t=3272356035&(t|t<<4),t=1227133513&(t|t<<2),e&=1023,e=4278190335&(e|e<<16),e=251719695&(e|e<<8),e=3272356035&(e|e<<4),e=1227133513&(e|e<<2),t|=e<<1,r&=1023,r=4278190335&(r|r<<16),r=251719695&(r|r<<8),r=3272356035&(r|r<<4),r=1227133513&(r|r<<2),t|r<<2},r.deinterleave3=function(t,e){return t=t>>>e&1227133513,t=3272356035&(t|t>>>2),t=251719695&(t|t>>>4),t=4278190335&(t|t>>>8),(t=1023&(t|t>>>16))<<22>>22},r.nextCombination=function(t){var e=t|t-1;return e+1|(~e&-~e)-1>>>n(t)+1}},{}],2:[function(t,e,r){"use strict";function n(t,e,r){r=r||2;var n=e&&e.length,o=n?e[0]*r:t.length,a=i(t,0,o,r,!0),u=[];if(!a)return u;var h,l,f,d,p,v,y;if(n&&(a=c(t,e,a,r)),t.length>80*r){h=f=t[0],l=d=t[1];for(var g=r;g<o;g+=r)p=t[g],v=t[g+1],p<h&&(h=p),v<l&&(l=v),p>f&&(f=p),v>d&&(d=v);y=Math.max(f-h,d-l)}return s(a,u,r,h,l,y),u}function i(t,e,r,n,i){var o,s;if(i===A(t,e,r,n)>0)for(o=e;o<r;o+=n)s=P(o,t[o],t[o+1],s);else for(o=r-n;o>=e;o-=n)s=P(o,t[o],t[o+1],s);return s&&T(s,s.next)&&(C(s),s=s.next),s}function o(t,e){if(!t)return t;e||(e=t);var r,n=t;do{if(r=!1,n.steiner||!T(n,n.next)&&0!==x(n.prev,n,n.next))n=n.next;else{if(C(n),(n=e=n.prev)===n.next)return null;r=!0}}while(r||n!==e);return e}function s(t,e,r,n,i,c,f){if(t){!f&&c&&v(t,n,i,c);for(var d,p,y=t;t.prev!==t.next;)if(d=t.prev,p=t.next,c?u(t,n,i,c):a(t))e.push(d.i/r),e.push(t.i/r),e.push(p.i/r),C(t),t=p.next,y=p.next;else if((t=p)===y){f?1===f?(t=h(t,e,r),s(t,e,r,n,i,c,2)):2===f&&l(t,e,r,n,i,c):s(o(t),e,r,n,i,c,1);break}}}function a(t){var e=t.prev,r=t,n=t.next;if(x(e,r,n)>=0)return!1;for(var i=t.next.next;i!==t.prev;){if(_(e.x,e.y,r.x,r.y,n.x,n.y,i.x,i.y)&&x(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function u(t,e,r,n){var i=t.prev,o=t,s=t.next;if(x(i,o,s)>=0)return!1;for(var a=i.x<o.x?i.x<s.x?i.x:s.x:o.x<s.x?o.x:s.x,u=i.y<o.y?i.y<s.y?i.y:s.y:o.y<s.y?o.y:s.y,h=i.x>o.x?i.x>s.x?i.x:s.x:o.x>s.x?o.x:s.x,l=i.y>o.y?i.y>s.y?i.y:s.y:o.y>s.y?o.y:s.y,c=g(a,u,e,r,n),f=g(h,l,e,r,n),d=t.nextZ;d&&d.z<=f;){if(d!==t.prev&&d!==t.next&&_(i.x,i.y,o.x,o.y,s.x,s.y,d.x,d.y)&&x(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=t.prevZ;d&&d.z>=c;){if(d!==t.prev&&d!==t.next&&_(i.x,i.y,o.x,o.y,s.x,s.y,d.x,d.y)&&x(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function h(t,e,r){var n=t;do{var i=n.prev,o=n.next.next;!T(i,o)&&w(i,n,n.next,o)&&S(i,o)&&S(o,i)&&(e.push(i.i/r),e.push(n.i/r),e.push(o.i/r),C(n),C(n.next),n=t=o),n=n.next}while(n!==t);return n}function l(t,e,r,n,i,a){var u=t;do{for(var h=u.next.next;h!==u.prev;){if(u.i!==h.i&&b(u,h)){var l=M(u,h);return u=o(u,u.next),l=o(l,l.next),s(u,e,r,n,i,a),void s(l,e,r,n,i,a)}h=h.next}u=u.next}while(u!==t)}function c(t,e,r,n){var s,a,u,h,l,c=[];for(s=0,a=e.length;s<a;s++)u=e[s]*n,h=s<a-1?e[s+1]*n:t.length,l=i(t,u,h,n,!1),l===l.next&&(l.steiner=!0),c.push(m(l));for(c.sort(f),s=0;s<c.length;s++)d(c[s],r),r=o(r,r.next);return r}function f(t,e){return t.x-e.x}function d(t,e){if(e=p(t,e)){var r=M(e,t);o(r,r.next)}}function p(t,e){var r,n=e,i=t.x,o=t.y,s=-(1/0);do{if(o<=n.y&&o>=n.next.y){var a=n.x+(o-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(a<=i&&a>s){if(s=a,a===i){if(o===n.y)return n;if(o===n.next.y)return n.next}r=n.x<n.next.x?n:n.next}}n=n.next}while(n!==e);if(!r)return null;if(i===s)return r.prev;var u,h=r,l=r.x,c=r.y,f=1/0;for(n=r.next;n!==h;)i>=n.x&&n.x>=l&&_(o<c?i:s,o,l,c,o<c?s:i,o,n.x,n.y)&&((u=Math.abs(o-n.y)/(i-n.x))<f||u===f&&n.x>r.x)&&S(n,t)&&(r=n,f=u),n=n.next;return r}function v(t,e,r,n){var i=t;do{null===i.z&&(i.z=g(i.x,i.y,e,r,n)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==t);i.prevZ.nextZ=null,i.prevZ=null,y(i)}function y(t){var e,r,n,i,o,s,a,u,h=1;do{for(r=t,t=null,o=null,s=0;r;){for(s++,n=r,a=0,e=0;e<h&&(a++,n=n.nextZ);e++);for(u=h;a>0||u>0&&n;)0===a?(i=n,n=n.nextZ,u--):0!==u&&n?r.z<=n.z?(i=r,r=r.nextZ,a--):(i=n,n=n.nextZ,u--):(i=r,r=r.nextZ,a--),o?o.nextZ=i:t=i,i.prevZ=o,o=i;r=n}o.nextZ=null,h*=2}while(s>1);return t}function g(t,e,r,n,i){return t=32767*(t-r)/i,e=32767*(e-n)/i,t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t|e<<1}function m(t){var e=t,r=t;do{e.x<r.x&&(r=e),e=e.next}while(e!==t);return r}function _(t,e,r,n,i,o,s,a){return(i-s)*(e-a)-(t-s)*(o-a)>=0&&(t-s)*(n-a)-(r-s)*(e-a)>=0&&(r-s)*(o-a)-(i-s)*(n-a)>=0}function b(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!E(t,e)&&S(t,e)&&S(e,t)&&O(t,e)}function x(t,e,r){return(e.y-t.y)*(r.x-e.x)-(e.x-t.x)*(r.y-e.y)}function T(t,e){return t.x===e.x&&t.y===e.y}function w(t,e,r,n){return!!(T(t,e)&&T(r,n)||T(t,n)&&T(r,e))||x(t,e,r)>0!=x(t,e,n)>0&&x(r,n,t)>0!=x(r,n,e)>0}function E(t,e){var r=t;do{if(r.i!==t.i&&r.next.i!==t.i&&r.i!==e.i&&r.next.i!==e.i&&w(r,r.next,t,e))return!0;r=r.next}while(r!==t);return!1}function S(t,e){return x(t.prev,t,t.next)<0?x(t,e,t.next)>=0&&x(t,t.prev,e)>=0:x(t,e,t.prev)<0||x(t,t.next,e)<0}function O(t,e){var r=t,n=!1,i=(t.x+e.x)/2,o=(t.y+e.y)/2;do{r.y>o!=r.next.y>o&&i<(r.next.x-r.x)*(o-r.y)/(r.next.y-r.y)+r.x&&(n=!n),r=r.next}while(r!==t);return n}function M(t,e){var r=new R(t.i,t.x,t.y),n=new R(e.i,e.x,e.y),i=t.next,o=e.prev;return t.next=e,e.prev=t,r.next=i,i.prev=r,n.next=r,r.prev=n,o.next=n,n.prev=o,n}function P(t,e,r,n){var i=new R(t,e,r);return n?(i.next=n.next,i.prev=n,n.next.prev=i,n.next=i):(i.prev=i,i.next=i),i}function C(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}function R(t,e,r){this.i=t,this.x=e,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function A(t,e,r,n){for(var i=0,o=e,s=r-n;o<r;o+=n)i+=(t[s]-t[o])*(t[o+1]+t[s+1]),s=o;return i}e.exports=n,n.deviation=function(t,e,r,n){var i=e&&e.length,o=i?e[0]*r:t.length,s=Math.abs(A(t,0,o,r));if(i)for(var a=0,u=e.length;a<u;a++){var h=e[a]*r,l=a<u-1?e[a+1]*r:t.length;s-=Math.abs(A(t,h,l,r))}var c=0;for(a=0;a<n.length;a+=3){var f=n[a]*r,d=n[a+1]*r,p=n[a+2]*r;c+=Math.abs((t[f]-t[p])*(t[d+1]-t[f+1])-(t[f]-t[d])*(t[p+1]-t[f+1]))}return 0===s&&0===c?0:Math.abs((c-s)/s)},n.flatten=function(t){for(var e=t[0][0].length,r={vertices:[],holes:[],dimensions:e},n=0,i=0;i<t.length;i++){for(var o=0;o<t[i].length;o++)for(var s=0;s<e;s++)r.vertices.push(t[i][o][s]);i>0&&(n+=t[i-1].length,r.holes.push(n))}return r}},{}],3:[function(t,e,r){"use strict";function n(){}function i(t,e,r){this.fn=t,this.context=e,this.once=r||!1}function o(){this._events=new n,this._eventsCount=0}var s=Object.prototype.hasOwnProperty,a="~";Object.create&&(n.prototype=Object.create(null),(new n).__proto__||(a=!1)),o.prototype.eventNames=function(){var t,e,r=[];if(0===this._eventsCount)return r;for(e in t=this._events)s.call(t,e)&&r.push(a?e.slice(1):e);return Object.getOwnPropertySymbols?r.concat(Object.getOwnPropertySymbols(t)):r},o.prototype.listeners=function(t,e){var r=a?a+t:t,n=this._events[r];if(e)return!!n;if(!n)return[];if(n.fn)return[n.fn];for(var i=0,o=n.length,s=new Array(o);i<o;i++)s[i]=n[i].fn;return s},o.prototype.emit=function(t,e,r,n,i,o){var s=a?a+t:t;if(!this._events[s])return!1;var u,h,l=this._events[s],c=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),c){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,r),!0;case 4:return l.fn.call(l.context,e,r,n),!0;case 5:return l.fn.call(l.context,e,r,n,i),!0;case 6:return l.fn.call(l.context,e,r,n,i,o),!0}for(h=1,u=new Array(c-1);h<c;h++)u[h-1]=arguments[h];l.fn.apply(l.context,u)}else{var f,d=l.length;for(h=0;h<d;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),c){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,r);break;case 4:l[h].fn.call(l[h].context,e,r,n);break;default:if(!u)for(f=1,u=new Array(c-1);f<c;f++)u[f-1]=arguments[f];l[h].fn.apply(l[h].context,u)}}return!0},o.prototype.on=function(t,e,r){var n=new i(e,r||this),o=a?a+t:t;return this._events[o]?this._events[o].fn?this._events[o]=[this._events[o],n]:this._events[o].push(n):(this._events[o]=n,this._eventsCount++),this},o.prototype.once=function(t,e,r){var n=new i(e,r||this,!0),o=a?a+t:t;return this._events[o]?this._events[o].fn?this._events[o]=[this._events[o],n]:this._events[o].push(n):(this._events[o]=n,this._eventsCount++),this},o.prototype.removeListener=function(t,e,r,i){var o=a?a+t:t;if(!this._events[o])return this;if(!e)return 0==--this._eventsCount?this._events=new n:delete this._events[o],this;var s=this._events[o];if(s.fn)s.fn!==e||i&&!s.once||r&&s.context!==r||(0==--this._eventsCount?this._events=new n:delete this._events[o]);else{for(var u=0,h=[],l=s.length;u<l;u++)(s[u].fn!==e||i&&!s[u].once||r&&s[u].context!==r)&&h.push(s[u]);h.length?this._events[o]=1===h.length?h[0]:h:0==--this._eventsCount?this._events=new n:delete this._events[o]}return this},o.prototype.removeAllListeners=function(t){var e;return t?(e=a?a+t:t,this._events[e]&&(0==--this._eventsCount?this._events=new n:delete this._events[e])):(this._events=new n,this._eventsCount=0),this},o.prototype.off=o.prototype.removeListener,o.prototype.addListener=o.prototype.on,o.prototype.setMaxListeners=function(){return this},o.prefixed=a,o.EventEmitter=o,void 0!==e&&(e.exports=o)},{}],4:[function(e,r,n){!function(e){var n=/(?=.*\bAndroid\b)(?=.*\bMobile\b)/i,i=/(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i,o=/(?=.*\bAndroid\b)(?=.*\b(?:KFOT|KFTT|KFJWI|KFJWA|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFSAWI|KFSAWA)\b)/i,s=new RegExp("(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)","i"),a=function(t,e){return t.test(e)},u=function(t){var e=t||navigator.userAgent,r=e.split("[FBAN");if(void 0!==r[1]&&(e=r[0]),r=e.split("Twitter"),void 0!==r[1]&&(e=r[0]),this.apple={phone:a(/iPhone/i,e),ipod:a(/iPod/i,e),tablet:!a(/iPhone/i,e)&&a(/iPad/i,e),device:a(/iPhone/i,e)||a(/iPod/i,e)||a(/iPad/i,e)},this.amazon={phone:a(i,e),tablet:!a(i,e)&&a(o,e),device:a(i,e)||a(o,e)},this.android={phone:a(i,e)||a(n,e),tablet:!a(i,e)&&!a(n,e)&&(a(o,e)||a(/Android/i,e)),device:a(i,e)||a(o,e)||a(n,e)||a(/Android/i,e)},this.windows={phone:a(/Windows Phone/i,e),tablet:a(/(?=.*\bWindows\b)(?=.*\bARM\b)/i,e),device:a(/Windows Phone/i,e)||a(/(?=.*\bWindows\b)(?=.*\bARM\b)/i,e)},this.other={blackberry:a(/BlackBerry/i,e),blackberry10:a(/BB10/i,e),opera:a(/Opera Mini/i,e),firefox:a(/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,e),chrome:a(/(CriOS|Chrome)(?=.*\bMobile\b)/i,e),device:a(/BlackBerry/i,e)||a(/BB10/i,e)||a(/Opera Mini/i,e)||a(/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,e)||a(/(CriOS|Chrome)(?=.*\bMobile\b)/i,e)},this.seven_inch=a(s,e),this.any=this.apple.device||this.android.device||this.windows.device||this.other.device||this.seven_inch,this.phone=this.apple.phone||this.android.phone||this.windows.phone,this.tablet=this.apple.tablet||this.android.tablet||this.windows.tablet,"undefined"==typeof window)return this},h=function(){var t=new u;return t.Class=u,t};void 0!==r&&r.exports&&"undefined"==typeof window?r.exports=u:void 0!==r&&r.exports&&"undefined"!=typeof window?r.exports=h():"function"==typeof t&&t.amd?t("isMobile",[],e.isMobile=h()):e.isMobile=h()}(this)},{}],5:[function(t,e,r){"use strict";function n(t){if(null===t||void 0===t)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(t)}var i=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,s=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var t=new String("abc");if(t[5]="de","5"===Object.getOwnPropertyNames(t)[0])return!1;for(var e={},r=0;r<10;r++)e["_"+String.fromCharCode(r)]=r;if("0123456789"!==Object.getOwnPropertyNames(e).map(function(t){return e[t]}).join(""))return!1;var n={};return"abcdefghijklmnopqrst".split("").forEach(function(t){n[t]=t}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},n)).join("")}catch(t){return!1}}()?Object.assign:function(t,e){for(var r,a,u=n(t),h=1;h<arguments.length;h++){r=Object(arguments[h]);for(var l in r)o.call(r,l)&&(u[l]=r[l]);if(i){a=i(r);for(var c=0;c<a.length;c++)s.call(r,a[c])&&(u[a[c]]=r[a[c]])}}return u}},{}],6:[function(t,e,r){var n=new ArrayBuffer(0),i=function(t,e,r,i){this.gl=t,this.buffer=t.createBuffer(),this.type=e||t.ARRAY_BUFFER,this.drawType=i||t.STATIC_DRAW,this.data=n,r&&this.upload(r),this._updateID=0};i.prototype.upload=function(t,e,r){r||this.bind();var n=this.gl;t=t||this.data,e=e||0,this.data.byteLength>=t.byteLength?n.bufferSubData(this.type,e,t):n.bufferData(this.type,t,this.drawType),this.data=t},i.prototype.bind=function(){this.gl.bindBuffer(this.type,this.buffer)},i.createVertexBuffer=function(t,e,r){return new i(t,t.ARRAY_BUFFER,e,r)},i.createIndexBuffer=function(t,e,r){return new i(t,t.ELEMENT_ARRAY_BUFFER,e,r)},i.create=function(t,e,r,n){return new i(t,e,r,n)},i.prototype.destroy=function(){this.gl.deleteBuffer(this.buffer)},e.exports=i},{}],7:[function(t,e,r){var n=t("./GLTexture"),i=function(t,e,r){this.gl=t,this.framebuffer=t.createFramebuffer(),this.stencil=null,this.texture=null,this.width=e||100,this.height=r||100};i.prototype.enableTexture=function(t){var e=this.gl;this.texture=t||new n(e),this.texture.bind(),this.bind(),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture.texture,0)},i.prototype.enableStencil=function(){if(!this.stencil){var t=this.gl;this.stencil=t.createRenderbuffer(),t.bindRenderbuffer(t.RENDERBUFFER,this.stencil),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.RENDERBUFFER,this.stencil),t.renderbufferStorage(t.RENDERBUFFER,t.DEPTH_STENCIL,this.width,this.height)}},i.prototype.clear=function(t,e,r,n){this.bind();var i=this.gl;i.clearColor(t,e,r,n),i.clear(i.COLOR_BUFFER_BIT|i.DEPTH_BUFFER_BIT)},i.prototype.bind=function(){var t=this.gl;t.bindFramebuffer(t.FRAMEBUFFER,this.framebuffer)},i.prototype.unbind=function(){var t=this.gl;t.bindFramebuffer(t.FRAMEBUFFER,null)},i.prototype.resize=function(t,e){var r=this.gl;this.width=t,this.height=e,this.texture&&this.texture.uploadData(null,t,e),this.stencil&&(r.bindRenderbuffer(r.RENDERBUFFER,this.stencil),r.renderbufferStorage(r.RENDERBUFFER,r.DEPTH_STENCIL,t,e))},i.prototype.destroy=function(){var t=this.gl;this.texture&&this.texture.destroy(),t.deleteFramebuffer(this.framebuffer),this.gl=null,this.stencil=null,this.texture=null},i.createRGBA=function(t,e,r,o){var s=n.fromData(t,null,e,r);s.enableNearestScaling(),s.enableWrapClamp();var a=new i(t,e,r);return a.enableTexture(s),a.unbind(),a},i.createFloat32=function(t,e,r,o){var s=new n.fromData(t,o,e,r);s.enableNearestScaling(),s.enableWrapClamp();var a=new i(t,e,r);return a.enableTexture(s),a.unbind(),a},e.exports=i},{"./GLTexture":9}],8:[function(t,e,r){var n=t("./shader/compileProgram"),i=t("./shader/extractAttributes"),o=t("./shader/extractUniforms"),s=t("./shader/setPrecision"),a=t("./shader/generateUniformAccessObject"),u=function(t,e,r,u,h){this.gl=t,u&&(e=s(e,u),r=s(r,u)),this.program=n(t,e,r,h),this.attributes=i(t,this.program),this.uniformData=o(t,this.program),this.uniforms=a(t,this.uniformData)};u.prototype.bind=function(){this.gl.useProgram(this.program)},u.prototype.destroy=function(){this.attributes=null,this.uniformData=null,this.uniforms=null,this.gl.deleteProgram(this.program)},e.exports=u},{"./shader/compileProgram":14,"./shader/extractAttributes":16,"./shader/extractUniforms":17,"./shader/generateUniformAccessObject":18,"./shader/setPrecision":22}],9:[function(t,e,r){var n=function(t,e,r,n,i){this.gl=t,this.texture=t.createTexture(),this.mipmap=!1,this.premultiplyAlpha=!1,this.width=e||-1,this.height=r||-1,this.format=n||t.RGBA,this.type=i||t.UNSIGNED_BYTE};n.prototype.upload=function(t){this.bind();var e=this.gl;e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this.premultiplyAlpha);var r=t.videoWidth||t.width,n=t.videoHeight||t.height;n!==this.height||r!==this.width?e.texImage2D(e.TEXTURE_2D,0,this.format,this.format,this.type,t):e.texSubImage2D(e.TEXTURE_2D,0,0,0,this.format,this.type,t),this.width=r,this.height=n};var i=!1;n.prototype.uploadData=function(t,e,r){this.bind();var n=this.gl;if(t instanceof Float32Array){if(!i){if(!n.getExtension("OES_texture_float"))throw new Error("floating point textures not available");i=!0}this.type=n.FLOAT}else this.type=this.type||n.UNSIGNED_BYTE;n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this.premultiplyAlpha),e!==this.width||r!==this.height?n.texImage2D(n.TEXTURE_2D,0,this.format,e,r,0,this.format,this.type,t||null):n.texSubImage2D(n.TEXTURE_2D,0,0,0,e,r,this.format,this.type,t||null),this.width=e,this.height=r},n.prototype.bind=function(t){var e=this.gl;void 0!==t&&e.activeTexture(e.TEXTURE0+t),e.bindTexture(e.TEXTURE_2D,this.texture)},n.prototype.unbind=function(){var t=this.gl;t.bindTexture(t.TEXTURE_2D,null)},n.prototype.minFilter=function(t){var e=this.gl;this.bind(),this.mipmap?e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,t?e.LINEAR_MIPMAP_LINEAR:e.NEAREST_MIPMAP_NEAREST):e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,t?e.LINEAR:e.NEAREST)},n.prototype.magFilter=function(t){var e=this.gl;this.bind(),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,t?e.LINEAR:e.NEAREST)},n.prototype.enableMipmap=function(){var t=this.gl;this.bind(),this.mipmap=!0,t.generateMipmap(t.TEXTURE_2D)},n.prototype.enableLinearScaling=function(){this.minFilter(!0),this.magFilter(!0)},n.prototype.enableNearestScaling=function(){this.minFilter(!1),this.magFilter(!1)},n.prototype.enableWrapClamp=function(){var t=this.gl;this.bind(),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE)},n.prototype.enableWrapRepeat=function(){var t=this.gl;this.bind(),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.REPEAT)},n.prototype.enableWrapMirrorRepeat=function(){var t=this.gl;this.bind(),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.MIRRORED_REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.MIRRORED_REPEAT)},n.prototype.destroy=function(){this.gl.deleteTexture(this.texture)},n.fromSource=function(t,e,r){var i=new n(t);return i.premultiplyAlpha=r||!1,i.upload(e),i},n.fromData=function(t,e,r,i){var o=new n(t);return o.uploadData(e,r,i),o},e.exports=n},{}],10:[function(t,e,r){function n(t,e){if(this.nativeVaoExtension=null,n.FORCE_NATIVE||(this.nativeVaoExtension=t.getExtension("OES_vertex_array_object")||t.getExtension("MOZ_OES_vertex_array_object")||t.getExtension("WEBKIT_OES_vertex_array_object")),this.nativeState=e,this.nativeVaoExtension){this.nativeVao=this.nativeVaoExtension.createVertexArrayOES();var r=t.getParameter(t.MAX_VERTEX_ATTRIBS);this.nativeState={tempAttribState:new Array(r),attribState:new Array(r)}}this.gl=t,this.attributes=[],this.indexBuffer=null,this.dirty=!1}var i=t("./setVertexAttribArrays");n.prototype.constructor=n,e.exports=n,n.FORCE_NATIVE=!1,n.prototype.bind=function(){return this.nativeVao?(this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao),this.dirty&&(this.dirty=!1,this.activate())):this.activate(),this},n.prototype.unbind=function(){return this.nativeVao&&this.nativeVaoExtension.bindVertexArrayOES(null),this},n.prototype.activate=function(){for(var t=this.gl,e=null,r=0;r<this.attributes.length;r++){var n=this.attributes[r];e!==n.buffer&&(n.buffer.bind(),e=n.buffer),t.vertexAttribPointer(n.attribute.location,n.attribute.size,n.type||t.FLOAT,n.normalized||!1,n.stride||0,n.start||0)}return i(t,this.attributes,this.nativeState),this.indexBuffer&&this.indexBuffer.bind(),this},n.prototype.addAttribute=function(t,e,r,n,i,o){return this.attributes.push({buffer:t,attribute:e,location:e.location,type:r||this.gl.FLOAT,normalized:n||!1,stride:i||0,start:o||0}),this.dirty=!0,this},n.prototype.addIndex=function(t){return this.indexBuffer=t,this.dirty=!0,this},n.prototype.clear=function(){return this.nativeVao&&this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao),this.attributes.length=0,this.indexBuffer=null,this},n.prototype.draw=function(t,e,r){var n=this.gl;return this.indexBuffer?n.drawElements(t,e||this.indexBuffer.data.length,n.UNSIGNED_SHORT,2*(r||0)):n.drawArrays(t,r,e||this.getSize()),this},n.prototype.destroy=function(){this.gl=null,this.indexBuffer=null,this.attributes=null,this.nativeState=null,this.nativeVao&&this.nativeVaoExtension.deleteVertexArrayOES(this.nativeVao),this.nativeVaoExtension=null,this.nativeVao=null},n.prototype.getSize=function(){var t=this.attributes[0];return t.buffer.data.length/(t.stride/4||t.attribute.size)}},{"./setVertexAttribArrays":13}],11:[function(t,e,r){var n=function(t,e){var r=t.getContext("webgl",e)||t.getContext("experimental-webgl",e);if(!r)throw new Error("This browser does not support webGL. Try using the canvas renderer");return r};e.exports=n},{}],12:[function(t,e,r){var n={createContext:t("./createContext"),setVertexAttribArrays:t("./setVertexAttribArrays"),GLBuffer:t("./GLBuffer"),GLFramebuffer:t("./GLFramebuffer"),GLShader:t("./GLShader"),GLTexture:t("./GLTexture"),VertexArrayObject:t("./VertexArrayObject"),shader:t("./shader")};void 0!==e&&e.exports&&(e.exports=n),"undefined"!=typeof window&&(window.PIXI=window.PIXI||{},window.PIXI.glCore=n)},{"./GLBuffer":6,"./GLFramebuffer":7,"./GLShader":8,"./GLTexture":9,"./VertexArrayObject":10,"./createContext":11,"./setVertexAttribArrays":13,"./shader":19}],13:[function(t,e,r){var n=function(t,e,r){var n;if(r){var i=r.tempAttribState,o=r.attribState;for(n=0;n<i.length;n++)i[n]=!1;for(n=0;n<e.length;n++)i[e[n].attribute.location]=!0;for(n=0;n<o.length;n++)o[n]!==i[n]&&(o[n]=i[n],r.attribState[n]?t.enableVertexAttribArray(n):t.disableVertexAttribArray(n))}else for(n=0;n<e.length;n++){var s=e[n];t.enableVertexAttribArray(s.attribute.location)}};e.exports=n},{}],14:[function(t,e,r){var n=function(t,e,r,n){var o=i(t,t.VERTEX_SHADER,e),s=i(t,t.FRAGMENT_SHADER,r),a=t.createProgram();if(t.attachShader(a,o),t.attachShader(a,s),n)for(var u in n)t.bindAttribLocation(a,n[u],u);return t.linkProgram(a),t.getProgramParameter(a,t.LINK_STATUS)||(console.error("Pixi.js Error: Could not initialize shader."),console.error("gl.VALIDATE_STATUS",t.getProgramParameter(a,t.VALIDATE_STATUS)),console.error("gl.getError()",t.getError()),""!==t.getProgramInfoLog(a)&&console.warn("Pixi.js Warning: gl.getProgramInfoLog()",t.getProgramInfoLog(a)),t.deleteProgram(a),a=null),t.deleteShader(o),t.deleteShader(s),a},i=function(t,e,r){var n=t.createShader(e);return t.shaderSource(n,r),t.compileShader(n),t.getShaderParameter(n,t.COMPILE_STATUS)?n:(console.log(t.getShaderInfoLog(n)),null)};e.exports=n},{}],15:[function(t,e,r){var n=function(t,e){switch(t){case"float":return 0;case"vec2":return new Float32Array(2*e);case"vec3":return new Float32Array(3*e);case"vec4":return new Float32Array(4*e);case"int":case"sampler2D":return 0;case"ivec2":return new Int32Array(2*e);case"ivec3":return new Int32Array(3*e);case"ivec4":return new Int32Array(4*e);case"bool":return!1;case"bvec2":return i(2*e);case"bvec3":return i(3*e);case"bvec4":return i(4*e);case"mat2":return new Float32Array([1,0,0,1]);case"mat3":return new Float32Array([1,0,0,0,1,0,0,0,1]);case"mat4":return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])}},i=function(t){for(var e=new Array(t),r=0;r<e.length;r++)e[r]=!1;return e};e.exports=n},{}],16:[function(t,e,r){var n=t("./mapType"),i=t("./mapSize"),o=function(t,e){for(var r={},o=t.getProgramParameter(e,t.ACTIVE_ATTRIBUTES),a=0;a<o;a++){var u=t.getActiveAttrib(e,a),h=n(t,u.type);r[u.name]={type:h,size:i(h),location:t.getAttribLocation(e,u.name),pointer:s}}return r},s=function(t,e,r,n){gl.vertexAttribPointer(this.location,this.size,t||gl.FLOAT,e||!1,r||0,n||0)};e.exports=o},{"./mapSize":20,"./mapType":21}],17:[function(t,e,r){var n=t("./mapType"),i=t("./defaultValue"),o=function(t,e){for(var r={},o=t.getProgramParameter(e,t.ACTIVE_UNIFORMS),s=0;s<o;s++){var a=t.getActiveUniform(e,s),u=a.name.replace(/\[.*?\]/,""),h=n(t,a.type);r[u]={type:h,size:a.size,location:t.getUniformLocation(e,u),value:i(h,a.size)}}return r};e.exports=o},{"./defaultValue":15,"./mapType":21}],18:[function(t,e,r){var n=function(t,e){var r={data:{}};r.gl=t;for(var n=Object.keys(e),a=0;a<n.length;a++){var u=n[a],h=u.split("."),l=h[h.length-1],c=s(h,r),f=e[u];c.data[l]=f,c.gl=t,Object.defineProperty(c,l,{get:i(l),set:o(l,f)})}return r},i=function(t){var e=a.replace("%%",t);return new Function(e)},o=function(t,e){var r,n=u.replace(/%%/g,t);return r=1===e.size?h[e.type]:l[e.type],r&&(n+="\nthis.gl."+r+";"),new Function("value",n)},s=function(t,e){for(var r=e,n=0;n<t.length-1;n++){var i=r[t[n]]||{data:{}};r[t[n]]=i,r=i}return r},a=["return this.data.%%.value;"].join("\n"),u=["this.data.%%.value = value;","var location = this.data.%%.location;"].join("\n"),h={float:"uniform1f(location, value)",vec2:"uniform2f(location, value[0], value[1])",vec3:"uniform3f(location, value[0], value[1], value[2])",vec4:"uniform4f(location, value[0], value[1], value[2], value[3])",int:"uniform1i(location, value)",ivec2:"uniform2i(location, value[0], value[1])",ivec3:"uniform3i(location, value[0], value[1], value[2])",ivec4:"uniform4i(location, value[0], value[1], value[2], value[3])",bool:"uniform1i(location, value)",bvec2:"uniform2i(location, value[0], value[1])",bvec3:"uniform3i(location, value[0], value[1], value[2])",bvec4:"uniform4i(location, value[0], value[1], value[2], value[3])",mat2:"uniformMatrix2fv(location, false, value)",mat3:"uniformMatrix3fv(location, false, value)",mat4:"uniformMatrix4fv(location, false, value)",sampler2D:"uniform1i(location, value)"},l={float:"uniform1fv(location, value)",vec2:"uniform2fv(location, value)",vec3:"uniform3fv(location, value)",vec4:"uniform4fv(location, value)",int:"uniform1iv(location, value)",ivec2:"uniform2iv(location, value)",ivec3:"uniform3iv(location, value)",ivec4:"uniform4iv(location, value)",bool:"uniform1iv(location, value)",bvec2:"uniform2iv(location, value)",bvec3:"uniform3iv(location, value)",bvec4:"uniform4iv(location, value)",sampler2D:"uniform1iv(location, value)"};e.exports=n},{}],19:[function(t,e,r){e.exports={compileProgram:t("./compileProgram"),defaultValue:t("./defaultValue"),extractAttributes:t("./extractAttributes"),extractUniforms:t("./extractUniforms"),generateUniformAccessObject:t("./generateUniformAccessObject"),setPrecision:t("./setPrecision"),mapSize:t("./mapSize"),mapType:t("./mapType")}},{"./compileProgram":14,"./defaultValue":15,"./extractAttributes":16,"./extractUniforms":17,"./generateUniformAccessObject":18,"./mapSize":20,"./mapType":21,"./setPrecision":22}],20:[function(t,e,r){var n=function(t){return i[t]},i={float:1,vec2:2,vec3:3,vec4:4,int:1,ivec2:2,ivec3:3,ivec4:4,bool:1,bvec2:2,bvec3:3,bvec4:4,mat2:4,mat3:9,mat4:16,sampler2D:1};e.exports=n},{}],21:[function(t,e,r){var n=function(t,e){if(!i){var r=Object.keys(o);i={};for(var n=0;n<r.length;++n){var s=r[n];i[t[s]]=o[s]}}return i[e]},i=null,o={FLOAT:"float",FLOAT_VEC2:"vec2",FLOAT_VEC3:"vec3",FLOAT_VEC4:"vec4",INT:"int",INT_VEC2:"ivec2",INT_VEC3:"ivec3",INT_VEC4:"ivec4",BOOL:"bool",BOOL_VEC2:"bvec2",BOOL_VEC3:"bvec3",BOOL_VEC4:"bvec4",FLOAT_MAT2:"mat2",FLOAT_MAT3:"mat3",FLOAT_MAT4:"mat4",SAMPLER_2D:"sampler2D"};e.exports=n},{}],22:[function(t,e,r){var n=function(t,e){return"precision"!==t.substring(0,9)?"precision "+e+" float;\n"+t:t};e.exports=n},{}],23:[function(t,e,r){(function(t){function e(t,e){for(var r=0,n=t.length-1;n>=0;n--){var i=t[n];"."===i?t.splice(n,1):".."===i?(t.splice(n,1),r++):r&&(t.splice(n,1),r--)}if(e)for(;r--;r)t.unshift("..");return t}function n(t,e){if(t.filter)return t.filter(e);for(var r=[],n=0;n<t.length;n++)e(t[n],n,t)&&r.push(t[n]);return r}var i=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,o=function(t){return i.exec(t).slice(1)};r.resolve=function(){for(var r="",i=!1,o=arguments.length-1;o>=-1&&!i;o--){var s=o>=0?arguments[o]:t.cwd();if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(r=s+"/"+r,i="/"===s.charAt(0))}return r=e(n(r.split("/"),function(t){return!!t}),!i).join("/"),(i?"/":"")+r||"."},r.normalize=function(t){var i=r.isAbsolute(t),o="/"===s(t,-1);return t=e(n(t.split("/"),function(t){return!!t}),!i).join("/"),t||i||(t="."),t&&o&&(t+="/"),(i?"/":"")+t},r.isAbsolute=function(t){return"/"===t.charAt(0)},r.join=function(){var t=Array.prototype.slice.call(arguments,0);return r.normalize(n(t,function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t}).join("/"))},r.relative=function(t,e){function n(t){for(var e=0;e<t.length&&""===t[e];e++);for(var r=t.length-1;r>=0&&""===t[r];r--);return e>r?[]:t.slice(e,r-e+1)}t=r.resolve(t).substr(1),e=r.resolve(e).substr(1);for(var i=n(t.split("/")),o=n(e.split("/")),s=Math.min(i.length,o.length),a=s,u=0;u<s;u++)if(i[u]!==o[u]){a=u;break}for(var h=[],u=a;u<i.length;u++)h.push("..");return h=h.concat(o.slice(a)),h.join("/")},r.sep="/",r.delimiter=":",r.dirname=function(t){var e=o(t),r=e[0],n=e[1];return r||n?(n&&(n=n.substr(0,n.length-1)),r+n):"."},r.basename=function(t,e){var r=o(t)[2];return e&&r.substr(-1*e.length)===e&&(r=r.substr(0,r.length-e.length)),r},r.extname=function(t){return o(t)[3]};var s="b"==="ab".substr(-1)?function(t,e,r){return t.substr(e,r)}:function(t,e,r){return e<0&&(e=t.length+e),t.substr(e,r)}}).call(this,t("_process"))},{_process:24}],24:[function(t,e,r){function n(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function o(t){if(c===setTimeout)return setTimeout(t,0)
+;if((c===n||!c)&&setTimeout)return c=setTimeout,setTimeout(t,0);try{return c(t,0)}catch(e){try{return c.call(null,t,0)}catch(e){return c.call(this,t,0)}}}function s(t){if(f===clearTimeout)return clearTimeout(t);if((f===i||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(t);try{return f(t)}catch(e){try{return f.call(null,t)}catch(e){return f.call(this,t)}}}function a(){y&&p&&(y=!1,p.length?v=p.concat(v):g=-1,v.length&&u())}function u(){if(!y){var t=o(a);y=!0;for(var e=v.length;e;){for(p=v,v=[];++g<e;)p&&p[g].run();g=-1,e=v.length}p=null,y=!1,s(t)}}function h(t,e){this.fun=t,this.array=e}function l(){}var c,f,d=e.exports={};!function(){try{c="function"==typeof setTimeout?setTimeout:n}catch(t){c=n}try{f="function"==typeof clearTimeout?clearTimeout:i}catch(t){f=i}}();var p,v=[],y=!1,g=-1;d.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)e[r-1]=arguments[r];v.push(new h(t,e)),1!==v.length||y||o(u)},h.prototype.run=function(){this.fun.apply(null,this.array)},d.title="browser",d.browser=!0,d.env={},d.argv=[],d.version="",d.versions={},d.on=l,d.addListener=l,d.once=l,d.off=l,d.removeListener=l,d.removeAllListeners=l,d.emit=l,d.binding=function(t){throw new Error("process.binding is not supported")},d.cwd=function(){return"/"},d.chdir=function(t){throw new Error("process.chdir is not supported")},d.umask=function(){return 0}},{}],25:[function(e,r,n){(function(e){!function(i){function o(t){throw new RangeError(L[t])}function s(t,e){for(var r=t.length,n=[];r--;)n[r]=e(t[r]);return n}function a(t,e){var r=t.split("@"),n="";return r.length>1&&(n=r[0]+"@",t=r[1]),t=t.replace(I,"."),n+s(t.split("."),e).join(".")}function u(t){for(var e,r,n=[],i=0,o=t.length;i<o;)e=t.charCodeAt(i++),e>=55296&&e<=56319&&i<o?(r=t.charCodeAt(i++),56320==(64512&r)?n.push(((1023&e)<<10)+(1023&r)+65536):(n.push(e),i--)):n.push(e);return n}function h(t){return s(t,function(t){var e="";return t>65535&&(t-=65536,e+=B(t>>>10&1023|55296),t=56320|1023&t),e+=B(t)}).join("")}function l(t){return t-48<10?t-22:t-65<26?t-65:t-97<26?t-97:w}function c(t,e){return t+22+75*(t<26)-((0!=e)<<5)}function f(t,e,r){var n=0;for(t=r?j(t/M):t>>1,t+=j(t/e);t>N*S>>1;n+=w)t=j(t/N);return j(n+(N+1)*t/(t+O))}function d(t){var e,r,n,i,s,a,u,c,d,p,v=[],y=t.length,g=0,m=C,_=P;for(r=t.lastIndexOf(R),r<0&&(r=0),n=0;n<r;++n)t.charCodeAt(n)>=128&&o("not-basic"),v.push(t.charCodeAt(n));for(i=r>0?r+1:0;i<y;){for(s=g,a=1,u=w;i>=y&&o("invalid-input"),c=l(t.charCodeAt(i++)),(c>=w||c>j((T-g)/a))&&o("overflow"),g+=c*a,d=u<=_?E:u>=_+S?S:u-_,!(c<d);u+=w)p=w-d,a>j(T/p)&&o("overflow"),a*=p;e=v.length+1,_=f(g-s,e,0==s),j(g/e)>T-m&&o("overflow"),m+=j(g/e),g%=e,v.splice(g++,0,m)}return h(v)}function p(t){var e,r,n,i,s,a,h,l,d,p,v,y,g,m,_,b=[];for(t=u(t),y=t.length,e=C,r=0,s=P,a=0;a<y;++a)(v=t[a])<128&&b.push(B(v));for(n=i=b.length,i&&b.push(R);n<y;){for(h=T,a=0;a<y;++a)(v=t[a])>=e&&v<h&&(h=v);for(g=n+1,h-e>j((T-r)/g)&&o("overflow"),r+=(h-e)*g,e=h,a=0;a<y;++a)if(v=t[a],v<e&&++r>T&&o("overflow"),v==e){for(l=r,d=w;p=d<=s?E:d>=s+S?S:d-s,!(l<p);d+=w)_=l-p,m=w-p,b.push(B(c(p+_%m,0))),l=j(_/m);b.push(B(c(l,0))),s=f(r,g,n==i),r=0,++n}++r,++e}return b.join("")}function v(t){return a(t,function(t){return A.test(t)?d(t.slice(4).toLowerCase()):t})}function y(t){return a(t,function(t){return D.test(t)?"xn--"+p(t):t})}var g="object"==typeof n&&n&&!n.nodeType&&n,m="object"==typeof r&&r&&!r.nodeType&&r,_="object"==typeof e&&e;_.global!==_&&_.window!==_&&_.self!==_||(i=_);var b,x,T=2147483647,w=36,E=1,S=26,O=38,M=700,P=72,C=128,R="-",A=/^xn--/,D=/[^\x20-\x7E]/,I=/[\x2E\u3002\uFF0E\uFF61]/g,L={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},N=w-E,j=Math.floor,B=String.fromCharCode;if(b={version:"1.4.1",ucs2:{decode:u,encode:h},decode:d,encode:p,toASCII:y,toUnicode:v},"function"==typeof t&&"object"==typeof t.amd&&t.amd)t("punycode",function(){return b});else if(g&&m)if(r.exports==g)m.exports=b;else for(x in b)b.hasOwnProperty(x)&&(g[x]=b[x]);else i.punycode=b}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],26:[function(t,e,r){"use strict";function n(t,e){return Object.prototype.hasOwnProperty.call(t,e)}e.exports=function(t,e,r,o){e=e||"&",r=r||"=";var s={};if("string"!=typeof t||0===t.length)return s;t=t.split(e);var a=1e3;o&&"number"==typeof o.maxKeys&&(a=o.maxKeys);var u=t.length;a>0&&u>a&&(u=a);for(var h=0;h<u;++h){var l,c,f,d,p=t[h].replace(/\+/g,"%20"),v=p.indexOf(r);v>=0?(l=p.substr(0,v),c=p.substr(v+1)):(l=p,c=""),f=decodeURIComponent(l),d=decodeURIComponent(c),n(s,f)?i(s[f])?s[f].push(d):s[f]=[s[f],d]:s[f]=d}return s};var i=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)}},{}],27:[function(t,e,r){"use strict";function n(t,e){if(t.map)return t.map(e);for(var r=[],n=0;n<t.length;n++)r.push(e(t[n],n));return r}var i=function(t){switch(typeof t){case"string":return t;case"boolean":return t?"true":"false";case"number":return isFinite(t)?t:"";default:return""}};e.exports=function(t,e,r,a){return e=e||"&",r=r||"=",null===t&&(t=void 0),"object"==typeof t?n(s(t),function(s){var a=encodeURIComponent(i(s))+r;return o(t[s])?n(t[s],function(t){return a+encodeURIComponent(i(t))}).join(e):a+encodeURIComponent(i(t[s]))}).join(e):a?encodeURIComponent(i(a))+r+encodeURIComponent(i(t)):""};var o=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)},s=Object.keys||function(t){var e=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.push(r);return e}},{}],28:[function(t,e,r){"use strict";r.decode=r.parse=t("./decode"),r.encode=r.stringify=t("./encode")},{"./decode":26,"./encode":27}],29:[function(t,e,r){"use strict";function n(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}function i(t,e,r){if(t&&h.isObject(t)&&t instanceof n)return t;var i=new n;return i.parse(t,e,r),i}function o(t){return h.isString(t)&&(t=i(t)),t instanceof n?t.format():n.prototype.format.call(t)}function s(t,e){return i(t,!1,!0).resolve(e)}function a(t,e){return t?i(t,!1,!0).resolveObject(e):e}var u=t("punycode"),h=t("./util");r.parse=i,r.resolve=s,r.resolveObject=a,r.format=o,r.Url=n;var l=/^([a-z0-9.+-]+:)/i,c=/:[0-9]*$/,f=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,d=["<",">",'"',"`"," ","\r","\n","\t"],p=["{","}","|","\\","^","`"].concat(d),v=["'"].concat(p),y=["%","/","?",";","#"].concat(v),g=["/","?","#"],m={javascript:!0,"javascript:":!0},_={javascript:!0,"javascript:":!0},b={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},x=t("querystring");n.prototype.parse=function(t,e,r){if(!h.isString(t))throw new TypeError("Parameter 'url' must be a string, not "+typeof t);var n=t.indexOf("?"),i=n!==-1&&n<t.indexOf("#")?"?":"#",o=t.split(i);o[0]=o[0].replace(/\\/g,"/"),t=o.join(i);var s=t;if(s=s.trim(),!r&&1===t.split("#").length){var a=f.exec(s);if(a)return this.path=s,this.href=s,this.pathname=a[1],a[2]?(this.search=a[2],this.query=e?x.parse(this.search.substr(1)):this.search.substr(1)):e&&(this.search="",this.query={}),this}var c=l.exec(s);if(c){c=c[0];var d=c.toLowerCase();this.protocol=d,s=s.substr(c.length)}if(r||c||s.match(/^\/\/[^@\/]+@[^@\/]+/)){var p="//"===s.substr(0,2);!p||c&&_[c]||(s=s.substr(2),this.slashes=!0)}if(!_[c]&&(p||c&&!b[c])){for(var T=-1,w=0;w<g.length;w++){var E=s.indexOf(g[w]);E!==-1&&(T===-1||E<T)&&(T=E)}var S,O;O=T===-1?s.lastIndexOf("@"):s.lastIndexOf("@",T),O!==-1&&(S=s.slice(0,O),s=s.slice(O+1),this.auth=decodeURIComponent(S)),T=-1;for(var w=0;w<y.length;w++){var E=s.indexOf(y[w]);E!==-1&&(T===-1||E<T)&&(T=E)}T===-1&&(T=s.length),this.host=s.slice(0,T),s=s.slice(T),this.parseHost(),this.hostname=this.hostname||"";var M="["===this.hostname[0]&&"]"===this.hostname[this.hostname.length-1];if(!M)for(var P=this.hostname.split(/\./),w=0,C=P.length;w<C;w++){var R=P[w];if(R&&!R.match(/^[+a-z0-9A-Z_-]{0,63}$/)){for(var A="",D=0,I=R.length;D<I;D++)A+=R.charCodeAt(D)>127?"x":R[D];if(!A.match(/^[+a-z0-9A-Z_-]{0,63}$/)){var L=P.slice(0,w),N=P.slice(w+1),j=R.match(/^([+a-z0-9A-Z_-]{0,63})(.*)$/);j&&(L.push(j[1]),N.unshift(j[2])),N.length&&(s="/"+N.join(".")+s),this.hostname=L.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),M||(this.hostname=u.toASCII(this.hostname));var B=this.port?":"+this.port:"",k=this.hostname||"";this.host=k+B,this.href+=this.host,M&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==s[0]&&(s="/"+s))}if(!m[d])for(var w=0,C=v.length;w<C;w++){var F=v[w];if(s.indexOf(F)!==-1){var U=encodeURIComponent(F);U===F&&(U=escape(F)),s=s.split(F).join(U)}}var X=s.indexOf("#");X!==-1&&(this.hash=s.substr(X),s=s.slice(0,X));var G=s.indexOf("?");if(G!==-1?(this.search=s.substr(G),this.query=s.substr(G+1),e&&(this.query=x.parse(this.query)),s=s.slice(0,G)):e&&(this.search="",this.query={}),s&&(this.pathname=s),b[d]&&this.hostname&&!this.pathname&&(this.pathname="/"),this.pathname||this.search){var B=this.pathname||"",W=this.search||"";this.path=B+W}return this.href=this.format(),this},n.prototype.format=function(){var t=this.auth||"";t&&(t=encodeURIComponent(t),t=t.replace(/%3A/i,":"),t+="@");var e=this.protocol||"",r=this.pathname||"",n=this.hash||"",i=!1,o="";this.host?i=t+this.host:this.hostname&&(i=t+(this.hostname.indexOf(":")===-1?this.hostname:"["+this.hostname+"]"),this.port&&(i+=":"+this.port)),this.query&&h.isObject(this.query)&&Object.keys(this.query).length&&(o=x.stringify(this.query));var s=this.search||o&&"?"+o||"";return e&&":"!==e.substr(-1)&&(e+=":"),this.slashes||(!e||b[e])&&i!==!1?(i="//"+(i||""),r&&"/"!==r.charAt(0)&&(r="/"+r)):i||(i=""),n&&"#"!==n.charAt(0)&&(n="#"+n),s&&"?"!==s.charAt(0)&&(s="?"+s),r=r.replace(/[?#]/g,function(t){return encodeURIComponent(t)}),s=s.replace("#","%23"),e+i+r+s+n},n.prototype.resolve=function(t){return this.resolveObject(i(t,!1,!0)).format()},n.prototype.resolveObject=function(t){if(h.isString(t)){var e=new n;e.parse(t,!1,!0),t=e}for(var r=new n,i=Object.keys(this),o=0;o<i.length;o++){var s=i[o];r[s]=this[s]}if(r.hash=t.hash,""===t.href)return r.href=r.format(),r;if(t.slashes&&!t.protocol){for(var a=Object.keys(t),u=0;u<a.length;u++){var l=a[u];"protocol"!==l&&(r[l]=t[l])}return b[r.protocol]&&r.hostname&&!r.pathname&&(r.path=r.pathname="/"),r.href=r.format(),r}if(t.protocol&&t.protocol!==r.protocol){if(!b[t.protocol]){for(var c=Object.keys(t),f=0;f<c.length;f++){var d=c[f];r[d]=t[d]}return r.href=r.format(),r}if(r.protocol=t.protocol,t.host||_[t.protocol])r.pathname=t.pathname;else{for(var p=(t.pathname||"").split("/");p.length&&!(t.host=p.shift()););t.host||(t.host=""),t.hostname||(t.hostname=""),""!==p[0]&&p.unshift(""),p.length<2&&p.unshift(""),r.pathname=p.join("/")}if(r.search=t.search,r.query=t.query,r.host=t.host||"",r.auth=t.auth,r.hostname=t.hostname||t.host,r.port=t.port,r.pathname||r.search){var v=r.pathname||"",y=r.search||"";r.path=v+y}return r.slashes=r.slashes||t.slashes,r.href=r.format(),r}var g=r.pathname&&"/"===r.pathname.charAt(0),m=t.host||t.pathname&&"/"===t.pathname.charAt(0),x=m||g||r.host&&t.pathname,T=x,w=r.pathname&&r.pathname.split("/")||[],p=t.pathname&&t.pathname.split("/")||[],E=r.protocol&&!b[r.protocol];if(E&&(r.hostname="",r.port=null,r.host&&(""===w[0]?w[0]=r.host:w.unshift(r.host)),r.host="",t.protocol&&(t.hostname=null,t.port=null,t.host&&(""===p[0]?p[0]=t.host:p.unshift(t.host)),t.host=null),x=x&&(""===p[0]||""===w[0])),m)r.host=t.host||""===t.host?t.host:r.host,r.hostname=t.hostname||""===t.hostname?t.hostname:r.hostname,r.search=t.search,r.query=t.query,w=p;else if(p.length)w||(w=[]),w.pop(),w=w.concat(p),r.search=t.search,r.query=t.query;else if(!h.isNullOrUndefined(t.search)){if(E){r.hostname=r.host=w.shift();var S=!!(r.host&&r.host.indexOf("@")>0)&&r.host.split("@");S&&(r.auth=S.shift(),r.host=r.hostname=S.shift())}return r.search=t.search,r.query=t.query,h.isNull(r.pathname)&&h.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.href=r.format(),r}if(!w.length)return r.pathname=null,r.search?r.path="/"+r.search:r.path=null,r.href=r.format(),r;for(var O=w.slice(-1)[0],M=(r.host||t.host||w.length>1)&&("."===O||".."===O)||""===O,P=0,C=w.length;C>=0;C--)O=w[C],"."===O?w.splice(C,1):".."===O?(w.splice(C,1),P++):P&&(w.splice(C,1),P--);if(!x&&!T)for(;P--;P)w.unshift("..");!x||""===w[0]||w[0]&&"/"===w[0].charAt(0)||w.unshift(""),M&&"/"!==w.join("/").substr(-1)&&w.push("");var R=""===w[0]||w[0]&&"/"===w[0].charAt(0);if(E){r.hostname=r.host=R?"":w.length?w.shift():"";var S=!!(r.host&&r.host.indexOf("@")>0)&&r.host.split("@");S&&(r.auth=S.shift(),r.host=r.hostname=S.shift())}return x=x||r.host&&w.length,x&&!R&&w.unshift(""),w.length?r.pathname=w.join("/"):(r.pathname=null,r.path=null),h.isNull(r.pathname)&&h.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.auth=t.auth||r.auth,r.slashes=r.slashes||t.slashes,r.href=r.format(),r},n.prototype.parseHost=function(){var t=this.host,e=c.exec(t);e&&(e=e[0],":"!==e&&(this.port=e.substr(1)),t=t.substr(0,t.length-e.length)),t&&(this.hostname=t)}},{"./util":30,punycode:25,querystring:28}],30:[function(t,e,r){"use strict";e.exports={isString:function(t){return"string"==typeof t},isObject:function(t){return"object"==typeof t&&null!==t},isNull:function(t){return null===t},isNullOrUndefined:function(t){return null==t}}},{}],31:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},s=t("mini-signals"),a=n(s),u=t("parse-uri"),h=n(u),l=t("./async"),c=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(l),f=t("./Resource"),d=n(f),p=/(#[\w-]+)?$/,v=function(){function t(){var e=this,r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:10;i(this,t),this.baseUrl=r,this.progress=0,this.loading=!1,this.defaultQueryString="",this._beforeMiddleware=[],this._afterMiddleware=[],this._resourcesParsing=[],this._boundLoadResource=function(t,r){return e._loadResource(t,r)},this._queue=c.queue(this._boundLoadResource,n),this._queue.pause(),this.resources={},this.onProgress=new a.default,this.onError=new a.default,this.onLoad=new a.default,this.onStart=new a.default,this.onComplete=new a.default}return t.prototype.add=function(t,e,r,n){if(Array.isArray(t)){for(var i=0;i<t.length;++i)this.add(t[i]);return this}if("object"===(void 0===t?"undefined":o(t))&&(n=e||t.callback||t.onComplete,r=t,e=t.url,t=t.name||t.key||t.url),"string"!=typeof e&&(n=r,r=e,e=t),"string"!=typeof e)throw new Error("No url passed to add resource to loader.");if("function"==typeof r&&(n=r,r=null),this.loading&&(!r||!r.parentResource))throw new Error("Cannot add resources while the loader is running.");if(this.resources[t])throw new Error('Resource named "'+t+'" already exists.');if(e=this._prepareUrl(e),this.resources[t]=new d.default(t,e,r),"function"==typeof n&&this.resources[t].onAfterMiddleware.once(n),this.loading){for(var s=r.parentResource,a=[],u=0;u<s.children.length;++u)s.children[u].isComplete||a.push(s.children[u]);var h=s.progressChunk*(a.length+1),l=h/(a.length+2);s.children.push(this.resources[t]),s.progressChunk=l;for(var c=0;c<a.length;++c)a[c].progressChunk=l;this.resources[t].progressChunk=l}return this._queue.push(this.resources[t]),this},t.prototype.pre=function(t){return this._beforeMiddleware.push(t),this},t.prototype.use=function(t){return this._afterMiddleware.push(t),this},t.prototype.reset=function(){this.progress=0,this.loading=!1,this._queue.kill(),this._queue.pause();for(var t in this.resources){var e=this.resources[t];e._onLoadBinding&&e._onLoadBinding.detach(),e.isLoading&&e.abort()}return this.resources={},this},t.prototype.load=function(t){if("function"==typeof t&&this.onComplete.once(t),this.loading)return this;for(var e=100/this._queue._tasks.length,r=0;r<this._queue._tasks.length;++r)this._queue._tasks[r].data.progressChunk=e;return this.loading=!0,this.onStart.dispatch(this),this._queue.resume(),this},t.prototype._prepareUrl=function(t){var e=(0,h.default)(t,{strictMode:!0}),r=void 0;if(r=e.protocol||!e.path||0===t.indexOf("//")?t:this.baseUrl.length&&this.baseUrl.lastIndexOf("/")!==this.baseUrl.length-1&&"/"!==t.charAt(0)?this.baseUrl+"/"+t:this.baseUrl+t,this.defaultQueryString){var n=p.exec(r)[0];r=r.substr(0,r.length-n.length),r+=r.indexOf("?")!==-1?"&"+this.defaultQueryString:"?"+this.defaultQueryString,r+=n}return r},t.prototype._loadResource=function(t,e){var r=this;t._dequeue=e,c.eachSeries(this._beforeMiddleware,function(e,n){e.call(r,t,function(){n(t.isComplete?{}:null)})},function(){t.isComplete?r._onLoad(t):(t._onLoadBinding=t.onComplete.once(r._onLoad,r),t.load())})},t.prototype._onComplete=function(){this.loading=!1,this.onComplete.dispatch(this,this.resources)},t.prototype._onLoad=function(t){var e=this;t._onLoadBinding=null,t._dequeue(),this._resourcesParsing.push(t),c.eachSeries(this._afterMiddleware,function(r,n){r.call(e,t,n)},function(){t.onAfterMiddleware.dispatch(t),e.progress+=t.progressChunk,e.onProgress.dispatch(e,t),t.error?e.onError.dispatch(t.error,e,t):e.onLoad.dispatch(e,t),e._resourcesParsing.splice(e._resourcesParsing.indexOf(t),1),e._queue.idle()&&0===e._resourcesParsing.length&&(e.progress=100,e._onComplete())})},t}();r.default=v},{"./Resource":32,"./async":33,"mini-signals":37,"parse-uri":38}],32:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(){}function s(t,e,r){e&&0===e.indexOf(".")&&(e=e.substring(1)),e&&(t[e]=r)}function a(t){return t.toString().replace("object ","")}r.__esModule=!0;var u=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),h=t("parse-uri"),l=n(h),c=t("mini-signals"),f=n(c),d=!(!window.XDomainRequest||"withCredentials"in new XMLHttpRequest),p=null,v=function(){function t(e,r,n){if(i(this,t),"string"!=typeof e||"string"!=typeof r)throw new Error("Both name and url are required for constructing a resource.");n=n||{},this._flags=0,this._setFlag(t.STATUS_FLAGS.DATA_URL,0===r.indexOf("data:")),this.name=e,this.url=r,this.extension=this._getExtension(),this.data=null,this.crossOrigin=n.crossOrigin===!0?"anonymous":n.crossOrigin,this.loadType=n.loadType||this._determineLoadType(),this.xhrType=n.xhrType,this.metadata=n.metadata||{},this.error=null,this.xhr=null,this.children=[],this.type=t.TYPE.UNKNOWN,this.progressChunk=0,this._dequeue=o,this._onLoadBinding=null,this._boundComplete=this.complete.bind(this),this._boundOnError=this._onError.bind(this),this._boundOnProgress=this._onProgress.bind(this),this._boundXhrOnError=this._xhrOnError.bind(this),this._boundXhrOnAbort=this._xhrOnAbort.bind(this),this._boundXhrOnLoad=this._xhrOnLoad.bind(this),this._boundXdrOnTimeout=this._xdrOnTimeout.bind(this),this.onStart=new f.default,this.onProgress=new f.default,this.onComplete=new f.default,this.onAfterMiddleware=new f.default}return t.setExtensionLoadType=function(e,r){s(t._loadTypeMap,e,r)},t.setExtensionXhrType=function(e,r){s(t._xhrTypeMap,e,r)},t.prototype.complete=function(){if(this.data&&this.data.removeEventListener&&(this.data.removeEventListener("error",this._boundOnError,!1),this.data.removeEventListener("load",this._boundComplete,!1),this.data.removeEventListener("progress",this._boundOnProgress,!1),this.data.removeEventListener("canplaythrough",this._boundComplete,!1)),this.xhr&&(this.xhr.removeEventListener?(this.xhr.removeEventListener("error",this._boundXhrOnError,!1),this.xhr.removeEventListener("abort",this._boundXhrOnAbort,!1),this.xhr.removeEventListener("progress",this._boundOnProgress,!1),this.xhr.removeEventListener("load",this._boundXhrOnLoad,!1)):(this.xhr.onerror=null,this.xhr.ontimeout=null,this.xhr.onprogress=null,this.xhr.onload=null)),this.isComplete)throw new Error("Complete called again for an already completed resource.");this._setFlag(t.STATUS_FLAGS.COMPLETE,!0),this._setFlag(t.STATUS_FLAGS.LOADING,!1),this.onComplete.dispatch(this)},t.prototype.abort=function(e){if(!this.error){if(this.error=new Error(e),this.xhr)this.xhr.abort();else if(this.xdr)this.xdr.abort();else if(this.data)if(this.data.src)this.data.src=t.EMPTY_GIF;else for(;this.data.firstChild;)this.data.removeChild(this.data.firstChild);this.complete()}},t.prototype.load=function(e){var r=this;if(!this.isLoading){if(this.isComplete)return void(e&&setTimeout(function(){return e(r)},1));switch(e&&this.onComplete.once(e),this._setFlag(t.STATUS_FLAGS.LOADING,!0),this.onStart.dispatch(this),this.crossOrigin!==!1&&"string"==typeof this.crossOrigin||(this.crossOrigin=this._determineCrossOrigin(this.url)),this.loadType){case t.LOAD_TYPE.IMAGE:this.type=t.TYPE.IMAGE,this._loadElement("image");break;case t.LOAD_TYPE.AUDIO:this.type=t.TYPE.AUDIO,this._loadSourceElement("audio");break;case t.LOAD_TYPE.VIDEO:this.type=t.TYPE.VIDEO,this._loadSourceElement("video");break;case t.LOAD_TYPE.XHR:default:d&&this.crossOrigin?this._loadXdr():this._loadXhr()}}},t.prototype._hasFlag=function(t){return!!(this._flags&t)},t.prototype._setFlag=function(t,e){this._flags=e?this._flags|t:this._flags&~t},t.prototype._loadElement=function(t){this.metadata.loadElement?this.data=this.metadata.loadElement:"image"===t&&void 0!==window.Image?this.data=new Image:this.data=document.createElement(t),this.crossOrigin&&(this.data.crossOrigin=this.crossOrigin),this.metadata.skipSource||(this.data.src=this.url),this.data.addEventListener("error",this._boundOnError,!1),this.data.addEventListener("load",this._boundComplete,!1),this.data.addEventListener("progress",this._boundOnProgress,!1)},t.prototype._loadSourceElement=function(t){if(this.metadata.loadElement?this.data=this.metadata.loadElement:"audio"===t&&void 0!==window.Audio?this.data=new Audio:this.data=document.createElement(t),null===this.data)return void this.abort("Unsupported element: "+t);if(!this.metadata.skipSource)if(navigator.isCocoonJS)this.data.src=Array.isArray(this.url)?this.url[0]:this.url;else if(Array.isArray(this.url))for(var e=0;e<this.url.length;++e)this.data.appendChild(this._createSource(t,this.url[e]));else this.data.appendChild(this._createSource(t,this.url));this.data.addEventListener("error",this._boundOnError,!1),this.data.addEventListener("load",this._boundComplete,!1),this.data.addEventListener("progress",this._boundOnProgress,!1),this.data.addEventListener("canplaythrough",this._boundComplete,!1),this.data.load()},t.prototype._loadXhr=function(){"string"!=typeof this.xhrType&&(this.xhrType=this._determineXhrType());var e=this.xhr=new XMLHttpRequest;e.open("GET",this.url,!0),this.xhrType===t.XHR_RESPONSE_TYPE.JSON||this.xhrType===t.XHR_RESPONSE_TYPE.DOCUMENT?e.responseType=t.XHR_RESPONSE_TYPE.TEXT:e.responseType=this.xhrType,e.addEventListener("error",this._boundXhrOnError,!1),e.addEventListener("abort",this._boundXhrOnAbort,!1),e.addEventListener("progress",this._boundOnProgress,!1),e.addEventListener("load",this._boundXhrOnLoad,!1),e.send()},t.prototype._loadXdr=function(){"string"!=typeof this.xhrType&&(this.xhrType=this._determineXhrType());var t=this.xhr=new XDomainRequest;t.timeout=5e3,t.onerror=this._boundXhrOnError,t.ontimeout=this._boundXdrOnTimeout,t.onprogress=this._boundOnProgress,t.onload=this._boundXhrOnLoad,t.open("GET",this.url,!0),setTimeout(function(){return t.send()},1)},t.prototype._createSource=function(t,e,r){r||(r=t+"/"+e.substr(e.lastIndexOf(".")+1));var n=document.createElement("source");return n.src=e,n.type=r,n},t.prototype._onError=function(t){this.abort("Failed to load element using: "+t.target.nodeName)},t.prototype._onProgress=function(t){t&&t.lengthComputable&&this.onProgress.dispatch(this,t.loaded/t.total)},t.prototype._xhrOnError=function(){var t=this.xhr;this.abort(a(t)+" Request failed. Status: "+t.status+', text: "'+t.statusText+'"')},t.prototype._xhrOnAbort=function(){this.abort(a(this.xhr)+" Request was aborted by the user.")},t.prototype._xdrOnTimeout=function(){this.abort(a(this.xhr)+" Request timed out.")},t.prototype._xhrOnLoad=function(){var e=this.xhr,r="",n=void 0===e.status?200:e.status;if(""!==e.responseType&&"text"!==e.responseType&&void 0!==e.responseType||(r=e.responseText),0===n&&r.length>0?n=200:1223===n&&(n=204),2!=(n/100|0))return void this.abort("["+e.status+"] "+e.statusText+": "+e.responseURL);if(this.xhrType===t.XHR_RESPONSE_TYPE.TEXT)this.data=r,this.type=t.TYPE.TEXT;else if(this.xhrType===t.XHR_RESPONSE_TYPE.JSON)try{this.data=JSON.parse(r),this.type=t.TYPE.JSON}catch(t){return void this.abort("Error trying to parse loaded json: "+t)}else if(this.xhrType===t.XHR_RESPONSE_TYPE.DOCUMENT)try{if(window.DOMParser){var i=new DOMParser;this.data=i.parseFromString(r,"text/xml")}else{var o=document.createElement("div");o.innerHTML=r,this.data=o}this.type=t.TYPE.XML}catch(t){return void this.abort("Error trying to parse loaded xml: "+t)}else this.data=e.response||r;this.complete()},t.prototype._determineCrossOrigin=function(t,e){if(0===t.indexOf("data:"))return"";e=e||window.location,p||(p=document.createElement("a")),p.href=t,t=(0,l.default)(p.href,{strictMode:!0});var r=!t.port&&""===e.port||t.port===e.port,n=t.protocol?t.protocol+":":"";return t.host===e.hostname&&r&&n===e.protocol?"":"anonymous"},t.prototype._determineXhrType=function(){return t._xhrTypeMap[this.extension]||t.XHR_RESPONSE_TYPE.TEXT},t.prototype._determineLoadType=function(){return t._loadTypeMap[this.extension]||t.LOAD_TYPE.XHR},t.prototype._getExtension=function(){var t=this.url,e="";if(this.isDataUrl){var r=t.indexOf("/");e=t.substring(r+1,t.indexOf(";",r))}else{var n=t.indexOf("?");n!==-1&&(t=t.substring(0,n)),e=t.substring(t.lastIndexOf(".")+1)}return e.toLowerCase()},t.prototype._getMimeFromXhrType=function(e){switch(e){case t.XHR_RESPONSE_TYPE.BUFFER:return"application/octet-binary";case t.XHR_RESPONSE_TYPE.BLOB:return"application/blob";case t.XHR_RESPONSE_TYPE.DOCUMENT:return"application/xml";case t.XHR_RESPONSE_TYPE.JSON:return"application/json";case t.XHR_RESPONSE_TYPE.DEFAULT:case t.XHR_RESPONSE_TYPE.TEXT:default:return"text/plain"}},u(t,[{key:"isDataUrl",get:function(){return this._hasFlag(t.STATUS_FLAGS.DATA_URL)}},{key:"isComplete",get:function(){return this._hasFlag(t.STATUS_FLAGS.COMPLETE)}},{key:"isLoading",get:function(){return this._hasFlag(t.STATUS_FLAGS.LOADING)}}]),t}();r.default=v,v.STATUS_FLAGS={NONE:0,DATA_URL:1,COMPLETE:2,LOADING:4},v.TYPE={UNKNOWN:0,JSON:1,XML:2,IMAGE:3,AUDIO:4,VIDEO:5,TEXT:6},v.LOAD_TYPE={XHR:1,IMAGE:2,AUDIO:3,VIDEO:4},v.XHR_RESPONSE_TYPE={DEFAULT:"text",BUFFER:"arraybuffer",BLOB:"blob",DOCUMENT:"document",JSON:"json",TEXT:"text"},v._loadTypeMap={gif:v.LOAD_TYPE.IMAGE,png:v.LOAD_TYPE.IMAGE,bmp:v.LOAD_TYPE.IMAGE,jpg:v.LOAD_TYPE.IMAGE,jpeg:v.LOAD_TYPE.IMAGE,tif:v.LOAD_TYPE.IMAGE,tiff:v.LOAD_TYPE.IMAGE,webp:v.LOAD_TYPE.IMAGE,tga:v.LOAD_TYPE.IMAGE,svg:v.LOAD_TYPE.IMAGE,"svg+xml":v.LOAD_TYPE.IMAGE,mp3:v.LOAD_TYPE.AUDIO,ogg:v.LOAD_TYPE.AUDIO,wav:v.LOAD_TYPE.AUDIO,mp4:v.LOAD_TYPE.VIDEO,webm:v.LOAD_TYPE.VIDEO},v._xhrTypeMap={xhtml:v.XHR_RESPONSE_TYPE.DOCUMENT,html:v.XHR_RESPONSE_TYPE.DOCUMENT,htm:v.XHR_RESPONSE_TYPE.DOCUMENT,xml:v.XHR_RESPONSE_TYPE.DOCUMENT,tmx:v.XHR_RESPONSE_TYPE.DOCUMENT,svg:v.XHR_RESPONSE_TYPE.DOCUMENT,tsx:v.XHR_RESPONSE_TYPE.DOCUMENT,gif:v.XHR_RESPONSE_TYPE.BLOB,png:v.XHR_RESPONSE_TYPE.BLOB,bmp:v.XHR_RESPONSE_TYPE.BLOB,jpg:v.XHR_RESPONSE_TYPE.BLOB,jpeg:v.XHR_RESPONSE_TYPE.BLOB,tif:v.XHR_RESPONSE_TYPE.BLOB,tiff:v.XHR_RESPONSE_TYPE.BLOB,webp:v.XHR_RESPONSE_TYPE.BLOB,tga:v.XHR_RESPONSE_TYPE.BLOB,json:v.XHR_RESPONSE_TYPE.JSON,text:v.XHR_RESPONSE_TYPE.TEXT,txt:v.XHR_RESPONSE_TYPE.TEXT,ttf:v.XHR_RESPONSE_TYPE.BUFFER,otf:v.XHR_RESPONSE_TYPE.BUFFER},v.EMPTY_GIF="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="},{"mini-signals":37,"parse-uri":38}],33:[function(t,e,r){"use strict";function n(){}function i(t,e,r){var n=0,i=t.length;!function o(s){if(s||n===i)return void(r&&r(s));e(t[n++],o)}()}function o(t){return function(){if(null===t)throw new Error("Callback was already called.");var e=t;t=null,e.apply(this,arguments)}}function s(t,e){function r(t,e,r){if(null!=r&&"function"!=typeof r)throw new Error("task callback must be a function");if(a.started=!0,null==t&&a.idle())return void setTimeout(function(){return a.drain()},1);var i={data:t,callback:"function"==typeof r?r:n};e?a._tasks.unshift(i):a._tasks.push(i),setTimeout(function(){return a.process()},1)}function i(t){return function(){s-=1,t.callback.apply(t,arguments),null!=arguments[0]&&a.error(arguments[0],t.data),s<=a.concurrency-a.buffer&&a.unsaturated(),a.idle()&&a.drain(),a.process()}}if(null==e)e=1;else if(0===e)throw new Error("Concurrency must not be zero");var s=0,a={_tasks:[],concurrency:e,saturated:n,unsaturated:n,buffer:e/4,empty:n,drain:n,error:n,started:!1,paused:!1,push:function(t,e){r(t,!1,e)},kill:function(){s=0,a.drain=n,a.started=!1,a._tasks=[]},unshift:function(t,e){r(t,!0,e)},process:function(){for(;!a.paused&&s<a.concurrency&&a._tasks.length;){var e=a._tasks.shift();0===a._tasks.length&&a.empty(),s+=1,s===a.concurrency&&a.saturated(),t(e.data,o(i(e)))}},length:function(){return a._tasks.length},running:function(){return s},idle:function(){return a._tasks.length+s===0},pause:function(){a.paused!==!0&&(a.paused=!0)},resume:function(){if(a.paused!==!1){a.paused=!1;for(var t=1;t<=a.concurrency;t++)a.process()}}};return a}r.__esModule=!0,r.eachSeries=i,r.queue=s},{}],34:[function(t,e,r){"use strict";function n(t){for(var e="",r=0;r<t.length;){for(var n=[0,0,0],o=[0,0,0,0],s=0;s<n.length;++s)r<t.length?n[s]=255&t.charCodeAt(r++):n[s]=0;o[0]=n[0]>>2,o[1]=(3&n[0])<<4|n[1]>>4,o[2]=(15&n[1])<<2|n[2]>>6,o[3]=63&n[2];switch(r-(t.length-1)){case 2:o[3]=64,o[2]=64;break;case 1:o[3]=64}for(var a=0;a<o.length;++a)e+=i.charAt(o[a])}return e}r.__esModule=!0,r.encodeBinary=n;var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},{}],35:[function(t,e,r){"use strict";function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}function i(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0;var o=t("./Loader"),s=i(o),a=t("./Resource"),u=i(a),h=t("./async"),l=n(h),c=t("./b64"),f=n(c);s.default.Resource=u.default,s.default.async=l,s.default.base64=f,e.exports=s.default,r.default=s.default},{"./Loader":31,"./Resource":32,"./async":33,"./b64":34}],36:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(){return function(t,e){if(!t.data)return void e();if(t.xhr&&t.xhrType===a.default.XHR_RESPONSE_TYPE.BLOB)if(window.Blob&&"string"!=typeof t.data){if(0===t.data.type.indexOf("image")){var r=function(){var r=l.createObjectURL(t.data);return t.blob=t.data,t.data=new Image,t.data.src=r,t.type=a.default.TYPE.IMAGE,t.data.onload=function(){l.revokeObjectURL(r),t.data.onload=null,e()},{v:void 0}}();if("object"===(void 0===r?"undefined":o(r)))return r.v}}else{var n=t.xhr.getResponseHeader("content-type");if(n&&0===n.indexOf("image"))return t.data=new Image,t.data.src="data:"+n+";base64,"+h.default.encodeBinary(t.xhr.responseText),t.type=a.default.TYPE.IMAGE,
+void(t.data.onload=function(){t.data.onload=null,e()})}e()}}r.__esModule=!0;var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};r.blobMiddlewareFactory=i;var s=t("../../Resource"),a=n(s),u=t("../../b64"),h=n(u),l=window.URL||window.webkitURL},{"../../Resource":32,"../../b64":34}],37:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){return t._head?(t._tail._next=e,e._prev=t._tail,t._tail=e):(t._head=e,t._tail=e),e._owner=t,e}Object.defineProperty(r,"__esModule",{value:!0});var o=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),s=function(){function t(e,r,i){void 0===r&&(r=!1),n(this,t),this._fn=e,this._once=r,this._thisArg=i,this._next=this._prev=this._owner=null}return o(t,[{key:"detach",value:function(){return null!==this._owner&&(this._owner.detach(this),!0)}}]),t}(),a=function(){function t(){n(this,t),this._head=this._tail=void 0}return o(t,[{key:"handlers",value:function(){var t=!(arguments.length<=0||void 0===arguments[0])&&arguments[0],e=this._head;if(t)return!!e;for(var r=[];e;)r.push(e),e=e._next;return r}},{key:"has",value:function(t){if(!(t instanceof s))throw new Error("MiniSignal#has(): First arg must be a MiniSignalBinding object.");return t._owner===this}},{key:"dispatch",value:function(){var t=this._head;if(!t)return!1;for(;t;)t._once&&this.detach(t),t._fn.apply(t._thisArg,arguments),t=t._next;return!0}},{key:"add",value:function(t){var e=arguments.length<=1||void 0===arguments[1]?null:arguments[1];if("function"!=typeof t)throw new Error("MiniSignal#add(): First arg must be a Function.");return i(this,new s(t,!1,e))}},{key:"once",value:function(t){var e=arguments.length<=1||void 0===arguments[1]?null:arguments[1];if("function"!=typeof t)throw new Error("MiniSignal#once(): First arg must be a Function.");return i(this,new s(t,!0,e))}},{key:"detach",value:function(t){if(!(t instanceof s))throw new Error("MiniSignal#detach(): First arg must be a MiniSignalBinding object.");return t._owner!==this?this:(t._prev&&(t._prev._next=t._next),t._next&&(t._next._prev=t._prev),t===this._head?(this._head=t._next,null===t._next&&(this._tail=null)):t===this._tail&&(this._tail=t._prev,this._tail._next=null),t._owner=null,this)}},{key:"detachAll",value:function(){var t=this._head;if(!t)return this;for(this._head=this._tail=null;t;)t._owner=null,t=t._next;return this}}]),t}();a.MiniSignalBinding=s,r.default=a,e.exports=r.default},{}],38:[function(t,e,r){"use strict";e.exports=function(t,e){e=e||{};for(var r={key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}},n=r.parser[e.strictMode?"strict":"loose"].exec(t),i={},o=14;o--;)i[r.key[o]]=n[o]||"";return i[r.q.name]={},i[r.key[12]].replace(r.q.parser,function(t,e,n){e&&(i[r.q.name][e]=n)}),i}},{}],39:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var o=t("../core"),s=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(o),a=t("ismobilejs"),u=n(a),h=t("./accessibleTarget"),l=n(h);s.utils.mixins.delayMixin(s.DisplayObject.prototype,l.default);var c=100,f=0,d=0,p=2,v=function(){function t(e){i(this,t),!u.default.tablet&&!u.default.phone||navigator.isCocoonJS||this.createTouchHook();var r=document.createElement("div");r.style.width=c+"px",r.style.height=c+"px",r.style.position="absolute",r.style.top=f+"px",r.style.left=d+"px",r.style.zIndex=p,this.div=r,this.pool=[],this.renderId=0,this.debug=!1,this.renderer=e,this.children=[],this._onKeyDown=this._onKeyDown.bind(this),this._onMouseMove=this._onMouseMove.bind(this),this.isActive=!1,this.isMobileAccessabillity=!1,window.addEventListener("keydown",this._onKeyDown,!1)}return t.prototype.createTouchHook=function(){var t=this,e=document.createElement("button");e.style.width="1px",e.style.height="1px",e.style.position="absolute",e.style.top="-1000px",e.style.left="-1000px",e.style.zIndex=2,e.style.backgroundColor="#FF0000",e.title="HOOK DIV",e.addEventListener("focus",function(){t.isMobileAccessabillity=!0,t.activate(),document.body.removeChild(e)}),document.body.appendChild(e)},t.prototype.activate=function(){this.isActive||(this.isActive=!0,window.document.addEventListener("mousemove",this._onMouseMove,!0),window.removeEventListener("keydown",this._onKeyDown,!1),this.renderer.on("postrender",this.update,this),this.renderer.view.parentNode&&this.renderer.view.parentNode.appendChild(this.div))},t.prototype.deactivate=function(){this.isActive&&!this.isMobileAccessabillity&&(this.isActive=!1,window.document.removeEventListener("mousemove",this._onMouseMove),window.addEventListener("keydown",this._onKeyDown,!1),this.renderer.off("postrender",this.update),this.div.parentNode&&this.div.parentNode.removeChild(this.div))},t.prototype.updateAccessibleObjects=function(t){if(t.visible){t.accessible&&t.interactive&&(t._accessibleActive||this.addChild(t),t.renderId=this.renderId);for(var e=t.children,r=e.length-1;r>=0;r--)this.updateAccessibleObjects(e[r])}},t.prototype.update=function(){if(this.renderer.renderingToScreen){this.updateAccessibleObjects(this.renderer._lastObjectRendered);var t=this.renderer.view.getBoundingClientRect(),e=t.width/this.renderer.width,r=t.height/this.renderer.height,n=this.div;n.style.left=t.left+"px",n.style.top=t.top+"px",n.style.width=this.renderer.width+"px",n.style.height=this.renderer.height+"px";for(var i=0;i<this.children.length;i++){var o=this.children[i];if(o.renderId!==this.renderId)o._accessibleActive=!1,s.utils.removeItems(this.children,i,1),this.div.removeChild(o._accessibleDiv),this.pool.push(o._accessibleDiv),o._accessibleDiv=null,i--,0===this.children.length&&this.deactivate();else{n=o._accessibleDiv;var a=o.hitArea,u=o.worldTransform;o.hitArea?(n.style.left=(u.tx+a.x*u.a)*e+"px",n.style.top=(u.ty+a.y*u.d)*r+"px",n.style.width=a.width*u.a*e+"px",n.style.height=a.height*u.d*r+"px"):(a=o.getBounds(),this.capHitArea(a),n.style.left=a.x*e+"px",n.style.top=a.y*r+"px",n.style.width=a.width*e+"px",n.style.height=a.height*r+"px")}}this.renderId++}},t.prototype.capHitArea=function(t){t.x<0&&(t.width+=t.x,t.x=0),t.y<0&&(t.height+=t.y,t.y=0),t.x+t.width>this.renderer.width&&(t.width=this.renderer.width-t.x),t.y+t.height>this.renderer.height&&(t.height=this.renderer.height-t.y)},t.prototype.addChild=function(t){var e=this.pool.pop();e||(e=document.createElement("button"),e.style.width=c+"px",e.style.height=c+"px",e.style.backgroundColor=this.debug?"rgba(255,0,0,0.5)":"transparent",e.style.position="absolute",e.style.zIndex=p,e.style.borderStyle="none",e.addEventListener("click",this._onClick.bind(this)),e.addEventListener("focus",this._onFocus.bind(this)),e.addEventListener("focusout",this._onFocusOut.bind(this))),t.accessibleTitle?e.title=t.accessibleTitle:t.accessibleTitle||t.accessibleHint||(e.title="displayObject "+this.tabIndex),t.accessibleHint&&e.setAttribute("aria-label",t.accessibleHint),t._accessibleActive=!0,t._accessibleDiv=e,e.displayObject=t,this.children.push(t),this.div.appendChild(t._accessibleDiv),t._accessibleDiv.tabIndex=t.tabIndex},t.prototype._onClick=function(t){var e=this.renderer.plugins.interaction;e.dispatchEvent(t.target.displayObject,"click",e.eventData)},t.prototype._onFocus=function(t){var e=this.renderer.plugins.interaction;e.dispatchEvent(t.target.displayObject,"mouseover",e.eventData)},t.prototype._onFocusOut=function(t){var e=this.renderer.plugins.interaction;e.dispatchEvent(t.target.displayObject,"mouseout",e.eventData)},t.prototype._onKeyDown=function(t){9===t.keyCode&&this.activate()},t.prototype._onMouseMove=function(){this.deactivate()},t.prototype.destroy=function(){this.div=null;for(var t=0;t<this.children.length;t++)this.children[t].div=null;window.document.removeEventListener("mousemove",this._onMouseMove),window.removeEventListener("keydown",this._onKeyDown),this.pool=null,this.children=null,this.renderer=null},t}();r.default=v,s.WebGLRenderer.registerPlugin("accessibility",v),s.CanvasRenderer.registerPlugin("accessibility",v)},{"../core":64,"./accessibleTarget":40,ismobilejs:4}],40:[function(t,e,r){"use strict";r.__esModule=!0,r.default={accessible:!1,accessibleTitle:null,accessibleHint:null,tabIndex:0,_accessibleActive:!1,_accessibleDiv:!1}},{}],41:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0;var i=t("./accessibleTarget");Object.defineProperty(r,"accessibleTarget",{enumerable:!0,get:function(){return n(i).default}});var o=t("./AccessibilityManager");Object.defineProperty(r,"AccessibilityManager",{enumerable:!0,get:function(){return n(o).default}})},{"./AccessibilityManager":39,"./accessibleTarget":40}],42:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),o=t("./autoDetectRenderer"),s=t("./display/Container"),a=function(t){return t&&t.__esModule?t:{default:t}}(s),u=t("./ticker"),h=function(){function t(e,r,i,s){var h=arguments.length>4&&void 0!==arguments[4]&&arguments[4];n(this,t),this.renderer=(0,o.autoDetectRenderer)(e,r,i,s),this.stage=new a.default,this._ticker=null,this.ticker=h?u.shared:new u.Ticker,this.start()}return t.prototype.render=function(){this.renderer.render(this.stage)},t.prototype.stop=function(){this._ticker.stop()},t.prototype.start=function(){this._ticker.start()},t.prototype.destroy=function(t){this.stop(),this.ticker=null,this.stage.destroy(),this.stage=null,this.renderer.destroy(t),this.renderer=null},i(t,[{key:"ticker",set:function(t){this._ticker&&this._ticker.remove(this.render,this),this._ticker=t,t&&t.add(this.render,this)},get:function(){return this._ticker}},{key:"view",get:function(){return this.renderer.view}},{key:"screen",get:function(){return this.renderer.screen}}]),t}();r.default=h},{"./autoDetectRenderer":44,"./display/Container":47,"./ticker":117}],43:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function s(t,e){if(t instanceof Array){if("precision"!==t[0].substring(0,9)){var r=t.slice(0);return r.unshift("precision "+e+" float;"),r}}else if("precision"!==t.substring(0,9))return"precision "+e+" float;\n"+t;return t}r.__esModule=!0;var a=t("pixi-gl-core"),u=t("./settings"),h=function(t){return t&&t.__esModule?t:{default:t}}(u),l=function(t){function e(r,o,a){return n(this,e),i(this,t.call(this,r,s(o,h.default.PRECISION_VERTEX),s(a,h.default.PRECISION_FRAGMENT)))}return o(e,t),e}(a.GLShader);r.default=l},{"./settings":100,"pixi-gl-core":12}],44:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:800,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:600,r=arguments[2];return!arguments[3]&&s.isWebGLSupported()?new l.default(t,e,r):new u.default(t,e,r)}r.__esModule=!0,r.autoDetectRenderer=i;var o=t("./utils"),s=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(o),a=t("./renderers/canvas/CanvasRenderer"),u=n(a),h=t("./renderers/webgl/WebGLRenderer"),l=n(h)},{"./renderers/canvas/CanvasRenderer":76,"./renderers/webgl/WebGLRenderer":83,"./utils":121}],45:[function(t,e,r){"use strict";r.__esModule=!0;r.VERSION="4.4.3",r.PI_2=2*Math.PI,r.RAD_TO_DEG=180/Math.PI,r.DEG_TO_RAD=Math.PI/180,r.RENDERER_TYPE={UNKNOWN:0,WEBGL:1,CANVAS:2},r.BLEND_MODES={NORMAL:0,ADD:1,MULTIPLY:2,SCREEN:3,OVERLAY:4,DARKEN:5,LIGHTEN:6,COLOR_DODGE:7,COLOR_BURN:8,HARD_LIGHT:9,SOFT_LIGHT:10,DIFFERENCE:11,EXCLUSION:12,HUE:13,SATURATION:14,COLOR:15,LUMINOSITY:16},r.DRAW_MODES={POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6},r.SCALE_MODES={LINEAR:0,NEAREST:1},r.WRAP_MODES={CLAMP:0,REPEAT:1,MIRRORED_REPEAT:2},r.GC_MODES={AUTO:0,MANUAL:1},r.URL_FILE_EXTENSION=/\.(\w{3,4})(?:$|\?|#)/i,r.DATA_URI=/^\s*data:(?:([\w-]+)\/([\w+.-]+))?(?:;(charset=[\w-]+|base64))?,(.*)/i,r.SVG_SIZE=/<svg[^>]*(?:\s(width|height)=('|")(\d*(?:\.\d+)?)(?:px)?('|"))[^>]*(?:\s(width|height)=('|")(\d*(?:\.\d+)?)(?:px)?('|"))[^>]*>/i,r.SHAPES={POLY:0,RECT:1,CIRC:2,ELIP:3,RREC:4},r.PRECISION={LOW:"lowp",MEDIUM:"mediump",HIGH:"highp"},r.TRANSFORM_MODE={STATIC:0,DYNAMIC:1},r.TEXT_GRADIENT={LINEAR_VERTICAL:0,LINEAR_HORIZONTAL:1}},{}],46:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../math"),o=function(){function t(){n(this,t),this.minX=1/0,this.minY=1/0,this.maxX=-(1/0),this.maxY=-(1/0),this.rect=null}return t.prototype.isEmpty=function(){return this.minX>this.maxX||this.minY>this.maxY},t.prototype.clear=function(){this.updateID++,this.minX=1/0,this.minY=1/0,this.maxX=-(1/0),this.maxY=-(1/0)},t.prototype.getRectangle=function(t){return this.minX>this.maxX||this.minY>this.maxY?i.Rectangle.EMPTY:(t=t||new i.Rectangle(0,0,1,1),t.x=this.minX,t.y=this.minY,t.width=this.maxX-this.minX,t.height=this.maxY-this.minY,t)},t.prototype.addPoint=function(t){this.minX=Math.min(this.minX,t.x),this.maxX=Math.max(this.maxX,t.x),this.minY=Math.min(this.minY,t.y),this.maxY=Math.max(this.maxY,t.y)},t.prototype.addQuad=function(t){var e=this.minX,r=this.minY,n=this.maxX,i=this.maxY,o=t[0],s=t[1];e=o<e?o:e,r=s<r?s:r,n=o>n?o:n,i=s>i?s:i,o=t[2],s=t[3],e=o<e?o:e,r=s<r?s:r,n=o>n?o:n,i=s>i?s:i,o=t[4],s=t[5],e=o<e?o:e,r=s<r?s:r,n=o>n?o:n,i=s>i?s:i,o=t[6],s=t[7],e=o<e?o:e,r=s<r?s:r,n=o>n?o:n,i=s>i?s:i,this.minX=e,this.minY=r,this.maxX=n,this.maxY=i},t.prototype.addFrame=function(t,e,r,n,i){var o=t.worldTransform,s=o.a,a=o.b,u=o.c,h=o.d,l=o.tx,c=o.ty,f=this.minX,d=this.minY,p=this.maxX,v=this.maxY,y=s*e+u*r+l,g=a*e+h*r+c;f=y<f?y:f,d=g<d?g:d,p=y>p?y:p,v=g>v?g:v,y=s*n+u*r+l,g=a*n+h*r+c,f=y<f?y:f,d=g<d?g:d,p=y>p?y:p,v=g>v?g:v,y=s*e+u*i+l,g=a*e+h*i+c,f=y<f?y:f,d=g<d?g:d,p=y>p?y:p,v=g>v?g:v,y=s*n+u*i+l,g=a*n+h*i+c,f=y<f?y:f,d=g<d?g:d,p=y>p?y:p,v=g>v?g:v,this.minX=f,this.minY=d,this.maxX=p,this.maxY=v},t.prototype.addVertices=function(t,e,r,n){for(var i=t.worldTransform,o=i.a,s=i.b,a=i.c,u=i.d,h=i.tx,l=i.ty,c=this.minX,f=this.minY,d=this.maxX,p=this.maxY,v=r;v<n;v+=2){var y=e[v],g=e[v+1],m=o*y+a*g+h,_=u*g+s*y+l;c=m<c?m:c,f=_<f?_:f,d=m>d?m:d,p=_>p?_:p}this.minX=c,this.minY=f,this.maxX=d,this.maxY=p},t.prototype.addBounds=function(t){var e=this.minX,r=this.minY,n=this.maxX,i=this.maxY;this.minX=t.minX<e?t.minX:e,this.minY=t.minY<r?t.minY:r,this.maxX=t.maxX>n?t.maxX:n,this.maxY=t.maxY>i?t.maxY:i},t.prototype.addBoundsMask=function(t,e){var r=t.minX>e.minX?t.minX:e.minX,n=t.minY>e.minY?t.minY:e.minY,i=t.maxX<e.maxX?t.maxX:e.maxX,o=t.maxY<e.maxY?t.maxY:e.maxY;if(r<=i&&n<=o){var s=this.minX,a=this.minY,u=this.maxX,h=this.maxY;this.minX=r<s?r:s,this.minY=n<a?n:a,this.maxX=i>u?i:u,this.maxY=o>h?o:h}},t.prototype.addBoundsArea=function(t,e){var r=t.minX>e.x?t.minX:e.x,n=t.minY>e.y?t.minY:e.y,i=t.maxX<e.x+e.width?t.maxX:e.x+e.width,o=t.maxY<e.y+e.height?t.maxY:e.y+e.height;if(r<=i&&n<=o){var s=this.minX,a=this.minY,u=this.maxX,h=this.maxY;this.minX=r<s?r:s,this.minY=n<a?n:a,this.maxX=i>u?i:u,this.maxY=o>h?o:h}},t}();r.default=o},{"../math":69}],47:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),a=t("../utils"),u=t("./DisplayObject"),h=function(t){return t&&t.__esModule?t:{default:t}}(u),l=function(t){function e(){n(this,e);var r=i(this,t.call(this));return r.children=[],r}return o(e,t),e.prototype.onChildrenChange=function(){},e.prototype.addChild=function(t){var e=arguments.length;if(e>1)for(var r=0;r<e;r++)this.addChild(arguments[r]);else t.parent&&t.parent.removeChild(t),t.parent=this,t.transform._parentID=-1,this.children.push(t),this._boundsID++,this.onChildrenChange(this.children.length-1),t.emit("added",this);return t},e.prototype.addChildAt=function(t,e){if(e<0||e>this.children.length)throw new Error(t+"addChildAt: The index "+e+" supplied is out of bounds "+this.children.length);return t.parent&&t.parent.removeChild(t),t.parent=this,t.transform._parentID=-1,this.children.splice(e,0,t),this._boundsID++,this.onChildrenChange(e),t.emit("added",this),t},e.prototype.swapChildren=function(t,e){if(t!==e){var r=this.getChildIndex(t),n=this.getChildIndex(e);this.children[r]=e,this.children[n]=t,this.onChildrenChange(r<n?r:n)}},e.prototype.getChildIndex=function(t){var e=this.children.indexOf(t);if(e===-1)throw new Error("The supplied DisplayObject must be a child of the caller");return e},e.prototype.setChildIndex=function(t,e){if(e<0||e>=this.children.length)throw new Error("The supplied index is out of bounds");var r=this.getChildIndex(t);(0,a.removeItems)(this.children,r,1),this.children.splice(e,0,t),this.onChildrenChange(e)},e.prototype.getChildAt=function(t){if(t<0||t>=this.children.length)throw new Error("getChildAt: Index ("+t+") does not exist.");return this.children[t]},e.prototype.removeChild=function(t){var e=arguments.length;if(e>1)for(var r=0;r<e;r++)this.removeChild(arguments[r]);else{var n=this.children.indexOf(t);if(n===-1)return null;t.parent=null,t.transform._parentID=-1,(0,a.removeItems)(this.children,n,1),this._boundsID++,this.onChildrenChange(n),t.emit("removed",this)}return t},e.prototype.removeChildAt=function(t){var e=this.getChildAt(t);return e.parent=null,e.transform._parentID=-1,(0,a.removeItems)(this.children,t,1),this._boundsID++,this.onChildrenChange(t),e.emit("removed",this),e},e.prototype.removeChildren=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments[1],r=t,n="number"==typeof e?e:this.children.length,i=n-r,o=void 0;if(i>0&&i<=n){o=this.children.splice(r,i);for(var s=0;s<o.length;++s)o[s].parent=null,o[s].transform&&(o[s].transform._parentID=-1);this._boundsID++,this.onChildrenChange(t);for(var a=0;a<o.length;++a)o[a].emit("removed",this);return o}if(0===i&&0===this.children.length)return[];throw new RangeError("removeChildren: numeric values are outside the acceptable range.")},e.prototype.updateTransform=function(){this._boundsID++,this.transform.updateTransform(this.parent.transform),this.worldAlpha=this.alpha*this.parent.worldAlpha;for(var t=0,e=this.children.length;t<e;++t){var r=this.children[t];r.visible&&r.updateTransform()}},e.prototype.calculateBounds=function(){this._bounds.clear(),this._calculateBounds();for(var t=0;t<this.children.length;t++){var e=this.children[t];e.visible&&e.renderable&&(e.calculateBounds(),e._mask?(e._mask.calculateBounds(),this._bounds.addBoundsMask(e._bounds,e._mask._bounds)):e.filterArea?this._bounds.addBoundsArea(e._bounds,e.filterArea):this._bounds.addBounds(e._bounds))}this._lastBoundsID=this._boundsID},e.prototype._calculateBounds=function(){},e.prototype.renderWebGL=function(t){if(this.visible&&!(this.worldAlpha<=0)&&this.renderable)if(this._mask||this._filters)this.renderAdvancedWebGL(t);else{this._renderWebGL(t);for(var e=0,r=this.children.length;e<r;++e)this.children[e].renderWebGL(t)}},e.prototype.renderAdvancedWebGL=function(t){t.flush();var e=this._filters,r=this._mask;if(e){this._enabledFilters||(this._enabledFilters=[]),this._enabledFilters.length=0;for(var n=0;n<e.length;n++)e[n].enabled&&this._enabledFilters.push(e[n]);this._enabledFilters.length&&t.filterManager.pushFilter(this,this._enabledFilters)}r&&t.maskManager.pushMask(this,this._mask),this._renderWebGL(t);for(var i=0,o=this.children.length;i<o;i++)this.children[i].renderWebGL(t);t.flush(),r&&t.maskManager.popMask(this,this._mask),e&&this._enabledFilters&&this._enabledFilters.length&&t.filterManager.popFilter()},e.prototype._renderWebGL=function(t){},e.prototype._renderCanvas=function(t){},e.prototype.renderCanvas=function(t){if(this.visible&&!(this.worldAlpha<=0)&&this.renderable){this._mask&&t.maskManager.pushMask(this._mask),this._renderCanvas(t);for(var e=0,r=this.children.length;e<r;++e)this.children[e].renderCanvas(t);this._mask&&t.maskManager.popMask(t)}},e.prototype.destroy=function(e){t.prototype.destroy.call(this);var r="boolean"==typeof e?e:e&&e.children,n=this.removeChildren(0,this.children.length);if(r)for(var i=0;i<n.length;++i)n[i].destroy(e)},s(e,[{key:"width",get:function(){return this.scale.x*this.getLocalBounds().width},set:function(t){var e=this.getLocalBounds().width;this.scale.x=0!==e?t/e:1,this._width=t}},{key:"height",get:function(){return this.scale.y*this.getLocalBounds().height},set:function(t){var e=this.getLocalBounds().height;this.scale.y=0!==e?t/e:1,this._height=t}}]),e}(h.default);r.default=l,l.prototype.containerUpdateTransform=l.prototype.updateTransform},{"../utils":121,"./DisplayObject":48}],48:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),u=t("eventemitter3"),h=n(u),l=t("../const"),c=t("../settings"),f=n(c),d=t("./TransformStatic"),p=n(d),v=t("./Transform"),y=n(v),g=t("./Bounds"),m=n(g),_=t("../math"),b=function(t){function e(){i(this,e);var r=o(this,t.call(this)),n=f.default.TRANSFORM_MODE===l.TRANSFORM_MODE.STATIC?p.default:y.default;return r.tempDisplayObjectParent=null,r.transform=new n,r.alpha=1,r.visible=!0,r.renderable=!0,r.parent=null,r.worldAlpha=1,r.filterArea=null,r._filters=null,r._enabledFilters=null,r._bounds=new m.default,r._boundsID=0,r._lastBoundsID=-1,r._boundsRect=null,r._localBoundsRect=null,r._mask=null,r._destroyed=!1,r}return s(e,t),e.prototype.updateTransform=function(){this.transform.updateTransform(this.parent.transform),this.worldAlpha=this.alpha*this.parent.worldAlpha,this._bounds.updateID++},e.prototype._recursivePostUpdateTransform=function(){this.parent?(this.parent._recursivePostUpdateTransform(),this.transform.updateTransform(this.parent.transform)):this.transform.updateTransform(this._tempDisplayObjectParent.transform)},e.prototype.getBounds=function(t,e){return t||(this.parent?(this._recursivePostUpdateTransform(),this.updateTransform()):(this.parent=this._tempDisplayObjectParent,this.updateTransform(),this.parent=null)),this._boundsID!==this._lastBoundsID&&this.calculateBounds(),e||(this._boundsRect||(this._boundsRect=new _.Rectangle),e=this._boundsRect),this._bounds.getRectangle(e)},e.prototype.getLocalBounds=function(t){var e=this.transform,r=this.parent;this.parent=null,this.transform=this._tempDisplayObjectParent.transform,t||(this._localBoundsRect||(this._localBoundsRect=new _.Rectangle),t=this._localBoundsRect);var n=this.getBounds(!1,t);return this.parent=r,this.transform=e,n},e.prototype.toGlobal=function(t,e){return arguments.length>2&&void 0!==arguments[2]&&arguments[2]||(this._recursivePostUpdateTransform(),this.parent?this.displayObjectUpdateTransform():(this.parent=this._tempDisplayObjectParent,this.displayObjectUpdateTransform(),this.parent=null)),this.worldTransform.apply(t,e)},e.prototype.toLocal=function(t,e,r,n){return e&&(t=e.toGlobal(t,r,n)),n||(this._recursivePostUpdateTransform(),this.parent?this.displayObjectUpdateTransform():(this.parent=this._tempDisplayObjectParent,this.displayObjectUpdateTransform(),this.parent=null)),this.worldTransform.applyInverse(t,r)},e.prototype.renderWebGL=function(t){},e.prototype.renderCanvas=function(t){},e.prototype.setParent=function(t){if(!t||!t.addChild)throw new Error("setParent: Argument must be a Container");return t.addChild(this),t},e.prototype.setTransform=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1,i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,o=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0,s=arguments.length>6&&void 0!==arguments[6]?arguments[6]:0,a=arguments.length>7&&void 0!==arguments[7]?arguments[7]:0,u=arguments.length>8&&void 0!==arguments[8]?arguments[8]:0;return this.position.x=t,this.position.y=e,this.scale.x=r?r:1,this.scale.y=n?n:1,this.rotation=i,this.skew.x=o,this.skew.y=s,this.pivot.x=a,this.pivot.y=u,this},e.prototype.destroy=function(){this.removeAllListeners(),this.parent&&this.parent.removeChild(this),this.transform=null,this.parent=null,this._bounds=null,this._currentBounds=null,this._mask=null,this.filterArea=null,this.interactive=!1,this.interactiveChildren=!1,this._destroyed=!0},a(e,[{key:"_tempDisplayObjectParent",get:function(){return null===this.tempDisplayObjectParent&&(this.tempDisplayObjectParent=new e),this.tempDisplayObjectParent}},{key:"x",get:function(){return this.position.x},set:function(t){this.transform.position.x=t}},{key:"y",get:function(){return this.position.y},set:function(t){this.transform.position.y=t}},{key:"worldTransform",get:function(){return this.transform.worldTransform}},{key:"localTransform",get:function(){return this.transform.localTransform}},{key:"position",get:function(){return this.transform.position},set:function(t){this.transform.position.copy(t)}},{key:"scale",get:function(){return this.transform.scale},set:function(t){this.transform.scale.copy(t)}},{key:"pivot",get:function(){return this.transform.pivot},set:function(t){this.transform.pivot.copy(t)}},{key:"skew",get:function(){return this.transform.skew},set:function(t){this.transform.skew.copy(t)}},{key:"rotation",get:function(){return this.transform.rotation},set:function(t){this.transform.rotation=t}},{key:"worldVisible",get:function(){var t=this;do{if(!t.visible)return!1;t=t.parent}while(t);return!0}},{key:"mask",get:function(){return this._mask},set:function(t){this._mask&&(this._mask.renderable=!0),this._mask=t,this._mask&&(this._mask.renderable=!1)}},{key:"filters",get:function(){return this._filters&&this._filters.slice()},set:function(t){this._filters=t&&t.slice()}}]),e}(h.default);r.default=b,b.prototype.displayObjectUpdateTransform=b.prototype.updateTransform},{"../const":45,"../math":69,"../settings":100,"./Bounds":46,"./Transform":49,"./TransformStatic":51,eventemitter3:3}],49:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),a=t("../math"),u=t("./TransformBase"),h=function(t){return t&&t.__esModule?t:{default:t}}(u),l=function(t){function e(){n(this,e);var r=i(this,t.call(this));return r.position=new a.Point(0,0),r.scale=new a.Point(1,1),r.skew=new a.ObservablePoint(r.updateSkew,r,0,0),r.pivot=new a.Point(0,0),r._rotation=0,r._cx=1,r._sx=0,r._cy=0,r._sy=1,r}return o(e,t),e.prototype.updateSkew=function(){this._cx=Math.cos(this._rotation+this.skew._y),this._sx=Math.sin(this._rotation+this.skew._y),this._cy=-Math.sin(this._rotation-this.skew._x),this._sy=Math.cos(this._rotation-this.skew._x)},e.prototype.updateLocalTransform=function(){var t=this.localTransform;t.a=this._cx*this.scale.x,t.b=this._sx*this.scale.x,t.c=this._cy*this.scale.y,t.d=this._sy*this.scale.y,t.tx=this.position.x-(this.pivot.x*t.a+this.pivot.y*t.c),t.ty=this.position.y-(this.pivot.x*t.b+this.pivot.y*t.d)},e.prototype.updateTransform=function(t){var e=this.localTransform;e.a=this._cx*this.scale.x,e.b=this._sx*this.scale.x,e.c=this._cy*this.scale.y,e.d=this._sy*this.scale.y,e.tx=this.position.x-(this.pivot.x*e.a+this.pivot.y*e.c),e.ty=this.position.y-(this.pivot.x*e.b+this.pivot.y*e.d);var r=t.worldTransform,n=this.worldTransform;n.a=e.a*r.a+e.b*r.c,n.b=e.a*r.b+e.b*r.d,n.c=e.c*r.a+e.d*r.c,n.d=e.c*r.b+e.d*r.d,n.tx=e.tx*r.a+e.ty*r.c+r.tx,n.ty=e.tx*r.b+e.ty*r.d+r.ty,this._worldID++},e.prototype.setFromMatrix=function(t){t.decompose(this)},s(e,[{key:"rotation",get:function(){return this._rotation},set:function(t){this._rotation=t,this.updateSkew()}}]),e}(h.default);r.default=l},{"../math":69,"./TransformBase":50}],50:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../math"),o=function(){function t(){n(this,t),this.worldTransform=new i.Matrix,this.localTransform=new i.Matrix,this._worldID=0,this._parentID=0}return t.prototype.updateLocalTransform=function(){},t.prototype.updateTransform=function(t){
+var e=t.worldTransform,r=this.worldTransform,n=this.localTransform;r.a=n.a*e.a+n.b*e.c,r.b=n.a*e.b+n.b*e.d,r.c=n.c*e.a+n.d*e.c,r.d=n.c*e.b+n.d*e.d,r.tx=n.tx*e.a+n.ty*e.c+e.tx,r.ty=n.tx*e.b+n.ty*e.d+e.ty,this._worldID++},t}();r.default=o,o.prototype.updateWorldTransform=o.prototype.updateTransform,o.IDENTITY=new o},{"../math":69}],51:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),a=t("../math"),u=t("./TransformBase"),h=function(t){return t&&t.__esModule?t:{default:t}}(u),l=function(t){function e(){n(this,e);var r=i(this,t.call(this));return r.position=new a.ObservablePoint(r.onChange,r,0,0),r.scale=new a.ObservablePoint(r.onChange,r,1,1),r.pivot=new a.ObservablePoint(r.onChange,r,0,0),r.skew=new a.ObservablePoint(r.updateSkew,r,0,0),r._rotation=0,r._cx=1,r._sx=0,r._cy=0,r._sy=1,r._localID=0,r._currentLocalID=0,r}return o(e,t),e.prototype.onChange=function(){this._localID++},e.prototype.updateSkew=function(){this._cx=Math.cos(this._rotation+this.skew._y),this._sx=Math.sin(this._rotation+this.skew._y),this._cy=-Math.sin(this._rotation-this.skew._x),this._sy=Math.cos(this._rotation-this.skew._x),this._localID++},e.prototype.updateLocalTransform=function(){var t=this.localTransform;this._localID!==this._currentLocalID&&(t.a=this._cx*this.scale._x,t.b=this._sx*this.scale._x,t.c=this._cy*this.scale._y,t.d=this._sy*this.scale._y,t.tx=this.position._x-(this.pivot._x*t.a+this.pivot._y*t.c),t.ty=this.position._y-(this.pivot._x*t.b+this.pivot._y*t.d),this._currentLocalID=this._localID,this._parentID=-1)},e.prototype.updateTransform=function(t){var e=this.localTransform;if(this._localID!==this._currentLocalID&&(e.a=this._cx*this.scale._x,e.b=this._sx*this.scale._x,e.c=this._cy*this.scale._y,e.d=this._sy*this.scale._y,e.tx=this.position._x-(this.pivot._x*e.a+this.pivot._y*e.c),e.ty=this.position._y-(this.pivot._x*e.b+this.pivot._y*e.d),this._currentLocalID=this._localID,this._parentID=-1),this._parentID!==t._worldID){var r=t.worldTransform,n=this.worldTransform;n.a=e.a*r.a+e.b*r.c,n.b=e.a*r.b+e.b*r.d,n.c=e.c*r.a+e.d*r.c,n.d=e.c*r.b+e.d*r.d,n.tx=e.tx*r.a+e.ty*r.c+r.tx,n.ty=e.tx*r.b+e.ty*r.d+r.ty,this._parentID=t._worldID,this._worldID++}},e.prototype.setFromMatrix=function(t){t.decompose(this),this._localID++},s(e,[{key:"rotation",get:function(){return this._rotation},set:function(t){this._rotation=t,this.updateSkew()}}]),e}(h.default);r.default=l},{"../math":69,"./TransformBase":50}],52:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("../display/Container"),u=n(a),h=t("../textures/RenderTexture"),l=n(h),c=t("../textures/Texture"),f=n(c),d=t("./GraphicsData"),p=n(d),v=t("../sprites/Sprite"),y=n(v),g=t("../math"),m=t("../utils"),_=t("../const"),b=t("../display/Bounds"),x=n(b),T=t("./utils/bezierCurveTo"),w=n(T),E=t("../renderers/canvas/CanvasRenderer"),S=n(E),O=void 0,M=new g.Matrix,P=new g.Point,C=new Float32Array(4),R=new Float32Array(4),A=function(t){function e(){var r=arguments.length>0&&void 0!==arguments[0]&&arguments[0];i(this,e);var n=o(this,t.call(this));return n.fillAlpha=1,n.lineWidth=0,n.nativeLines=r,n.lineColor=0,n.graphicsData=[],n.tint=16777215,n._prevTint=16777215,n.blendMode=_.BLEND_MODES.NORMAL,n.currentPath=null,n._webGL={},n.isMask=!1,n.boundsPadding=0,n._localBounds=new x.default,n.dirty=0,n.fastRectDirty=-1,n.clearDirty=0,n.boundsDirty=-1,n.cachedSpriteDirty=!1,n._spriteRect=null,n._fastRect=!1,n}return s(e,t),e.prototype.clone=function t(){var t=new e;t.renderable=this.renderable,t.fillAlpha=this.fillAlpha,t.lineWidth=this.lineWidth,t.lineColor=this.lineColor,t.tint=this.tint,t.blendMode=this.blendMode,t.isMask=this.isMask,t.boundsPadding=this.boundsPadding,t.dirty=0,t.cachedSpriteDirty=this.cachedSpriteDirty;for(var r=0;r<this.graphicsData.length;++r)t.graphicsData.push(this.graphicsData[r].clone());return t.currentPath=t.graphicsData[t.graphicsData.length-1],t.updateLocalBounds(),t},e.prototype.lineStyle=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;if(this.lineWidth=t,this.lineColor=e,this.lineAlpha=r,this.currentPath)if(this.currentPath.shape.points.length){var n=new g.Polygon(this.currentPath.shape.points.slice(-2));n.closed=!1,this.drawShape(n)}else this.currentPath.lineWidth=this.lineWidth,this.currentPath.lineColor=this.lineColor,this.currentPath.lineAlpha=this.lineAlpha;return this},e.prototype.moveTo=function(t,e){var r=new g.Polygon([t,e]);return r.closed=!1,this.drawShape(r),this},e.prototype.lineTo=function(t,e){return this.currentPath.shape.points.push(t,e),this.dirty++,this},e.prototype.quadraticCurveTo=function(t,e,r,n){this.currentPath?0===this.currentPath.shape.points.length&&(this.currentPath.shape.points=[0,0]):this.moveTo(0,0);var i=this.currentPath.shape.points,o=0,s=0;0===i.length&&this.moveTo(0,0);for(var a=i[i.length-2],u=i[i.length-1],h=1;h<=20;++h){var l=h/20;o=a+(t-a)*l,s=u+(e-u)*l,i.push(o+(t+(r-t)*l-o)*l,s+(e+(n-e)*l-s)*l)}return this.dirty++,this},e.prototype.bezierCurveTo=function(t,e,r,n,i,o){this.currentPath?0===this.currentPath.shape.points.length&&(this.currentPath.shape.points=[0,0]):this.moveTo(0,0);var s=this.currentPath.shape.points,a=s[s.length-2],u=s[s.length-1];return s.length-=2,(0,w.default)(a,u,t,e,r,n,i,o,s),this.dirty++,this},e.prototype.arcTo=function(t,e,r,n,i){this.currentPath?0===this.currentPath.shape.points.length&&this.currentPath.shape.points.push(t,e):this.moveTo(t,e);var o=this.currentPath.shape.points,s=o[o.length-2],a=o[o.length-1],u=a-e,h=s-t,l=n-e,c=r-t,f=Math.abs(u*c-h*l);if(f<1e-8||0===i)o[o.length-2]===t&&o[o.length-1]===e||o.push(t,e);else{var d=u*u+h*h,p=l*l+c*c,v=u*l+h*c,y=i*Math.sqrt(d)/f,g=i*Math.sqrt(p)/f,m=y*v/d,_=g*v/p,b=y*c+g*h,x=y*l+g*u,T=h*(g+m),w=u*(g+m),E=c*(y+_),S=l*(y+_),O=Math.atan2(w-x,T-b),M=Math.atan2(S-x,E-b);this.arc(b+t,x+e,i,O,M,h*l>c*u)}return this.dirty++,this},e.prototype.arc=function(t,e,r,n,i){var o=arguments.length>5&&void 0!==arguments[5]&&arguments[5];if(n===i)return this;!o&&i<=n?i+=2*Math.PI:o&&n<=i&&(n+=2*Math.PI);var s=i-n,a=40*Math.ceil(Math.abs(s)/(2*Math.PI));if(0===s)return this;var u=t+Math.cos(n)*r,h=e+Math.sin(n)*r,l=this.currentPath?this.currentPath.shape.points:null;l?l[l.length-2]===u&&l[l.length-1]===h||l.push(u,h):(this.moveTo(u,h),l=this.currentPath.shape.points);for(var c=s/(2*a),f=2*c,d=Math.cos(c),p=Math.sin(c),v=a-1,y=v%1/v,g=0;g<=v;++g){var m=g+y*g,_=c+n+f*m,b=Math.cos(_),x=-Math.sin(_);l.push((d*b+p*x)*r+t,(d*-x+p*b)*r+e)}return this.dirty++,this},e.prototype.beginFill=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return this.filling=!0,this.fillColor=t,this.fillAlpha=e,this.currentPath&&this.currentPath.shape.points.length<=2&&(this.currentPath.fill=this.filling,this.currentPath.fillColor=this.fillColor,this.currentPath.fillAlpha=this.fillAlpha),this},e.prototype.endFill=function(){return this.filling=!1,this.fillColor=null,this.fillAlpha=1,this},e.prototype.drawRect=function(t,e,r,n){return this.drawShape(new g.Rectangle(t,e,r,n)),this},e.prototype.drawRoundedRect=function(t,e,r,n,i){return this.drawShape(new g.RoundedRectangle(t,e,r,n,i)),this},e.prototype.drawCircle=function(t,e,r){return this.drawShape(new g.Circle(t,e,r)),this},e.prototype.drawEllipse=function(t,e,r,n){return this.drawShape(new g.Ellipse(t,e,r,n)),this},e.prototype.drawPolygon=function(t){var e=t,r=!0;if(e instanceof g.Polygon&&(r=e.closed,e=e.points),!Array.isArray(e)){e=new Array(arguments.length);for(var n=0;n<e.length;++n)e[n]=arguments[n]}var i=new g.Polygon(e);return i.closed=r,this.drawShape(i),this},e.prototype.clear=function(){return(this.lineWidth||this.filling||this.graphicsData.length>0)&&(this.lineWidth=0,this.filling=!1,this.boundsDirty=-1,this.dirty++,this.clearDirty++,this.graphicsData.length=0),this.currentPath=null,this._spriteRect=null,this},e.prototype.isFastRect=function(){return 1===this.graphicsData.length&&this.graphicsData[0].shape.type===_.SHAPES.RECT&&!this.graphicsData[0].lineWidth},e.prototype._renderWebGL=function(t){this.dirty!==this.fastRectDirty&&(this.fastRectDirty=this.dirty,this._fastRect=this.isFastRect()),this._fastRect?this._renderSpriteRect(t):(t.setObjectRenderer(t.plugins.graphics),t.plugins.graphics.render(this))},e.prototype._renderSpriteRect=function(t){var e=this.graphicsData[0].shape;this._spriteRect||(this._spriteRect=new y.default(new f.default(f.default.WHITE)));var r=this._spriteRect;if(16777215===this.tint)r.tint=this.graphicsData[0].fillColor;else{var n=C,i=R;(0,m.hex2rgb)(this.graphicsData[0].fillColor,n),(0,m.hex2rgb)(this.tint,i),n[0]*=i[0],n[1]*=i[1],n[2]*=i[2],r.tint=(0,m.rgb2hex)(n)}r.alpha=this.graphicsData[0].fillAlpha,r.worldAlpha=this.worldAlpha*r.alpha,r.blendMode=this.blendMode,r.texture._frame.width=e.width,r.texture._frame.height=e.height,r.transform.worldTransform=this.transform.worldTransform,r.anchor.set(-e.x/e.width,-e.y/e.height),r._onAnchorUpdate(),r._renderWebGL(t)},e.prototype._renderCanvas=function(t){this.isMask!==!0&&t.plugins.graphics.render(this)},e.prototype._calculateBounds=function(){this.boundsDirty!==this.dirty&&(this.boundsDirty=this.dirty,this.updateLocalBounds(),this.cachedSpriteDirty=!0);var t=this._localBounds;this._bounds.addFrame(this.transform,t.minX,t.minY,t.maxX,t.maxY)},e.prototype.containsPoint=function(t){this.worldTransform.applyInverse(t,P);for(var e=this.graphicsData,r=0;r<e.length;++r){var n=e[r];if(n.fill&&(n.shape&&n.shape.contains(P.x,P.y)))return!0}return!1},e.prototype.updateLocalBounds=function(){var t=1/0,e=-(1/0),r=1/0,n=-(1/0);if(this.graphicsData.length)for(var i=0,o=0,s=0,a=0,u=0,h=0;h<this.graphicsData.length;h++){var l=this.graphicsData[h],c=l.type,f=l.lineWidth;if(i=l.shape,c===_.SHAPES.RECT||c===_.SHAPES.RREC)o=i.x-f/2,s=i.y-f/2,a=i.width+f,u=i.height+f,t=o<t?o:t,e=o+a>e?o+a:e,r=s<r?s:r,n=s+u>n?s+u:n;else if(c===_.SHAPES.CIRC)o=i.x,s=i.y,a=i.radius+f/2,u=i.radius+f/2,t=o-a<t?o-a:t,e=o+a>e?o+a:e,r=s-u<r?s-u:r,n=s+u>n?s+u:n;else if(c===_.SHAPES.ELIP)o=i.x,s=i.y,a=i.width+f/2,u=i.height+f/2,t=o-a<t?o-a:t,e=o+a>e?o+a:e,r=s-u<r?s-u:r,n=s+u>n?s+u:n;else for(var d=i.points,p=0,v=0,y=0,g=0,m=0,b=0,x=0,T=0,w=0;w+2<d.length;w+=2)o=d[w],s=d[w+1],p=d[w+2],v=d[w+3],y=Math.abs(p-o),g=Math.abs(v-s),u=f,(a=Math.sqrt(y*y+g*g))<1e-9||(m=(u/a*g+y)/2,b=(u/a*y+g)/2,x=(p+o)/2,T=(v+s)/2,t=x-m<t?x-m:t,e=x+m>e?x+m:e,r=T-b<r?T-b:r,n=T+b>n?T+b:n)}else t=0,e=0,r=0,n=0;var E=this.boundsPadding;this._localBounds.minX=t-E,this._localBounds.maxX=e+2*E,this._localBounds.minY=r-E,this._localBounds.maxY=n+2*E},e.prototype.drawShape=function(t){this.currentPath&&this.currentPath.shape.points.length<=2&&this.graphicsData.pop(),this.currentPath=null;var e=new p.default(this.lineWidth,this.lineColor,this.lineAlpha,this.fillColor,this.fillAlpha,this.filling,this.nativeLines,t);return this.graphicsData.push(e),e.type===_.SHAPES.POLY&&(e.shape.closed=e.shape.closed||this.filling,this.currentPath=e),this.dirty++,e},e.prototype.generateCanvasTexture=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,r=this.getLocalBounds(),n=l.default.create(r.width,r.height,t,e);O||(O=new S.default),this.transform.updateLocalTransform(),this.transform.localTransform.copy(M),M.invert(),M.tx-=r.x,M.ty-=r.y,O.render(this,n,!0,M);var i=f.default.fromCanvas(n.baseTexture._canvasRenderTarget.canvas,t);return i.baseTexture.resolution=e,i.baseTexture.update(),i},e.prototype.closePath=function(){var t=this.currentPath;return t&&t.shape&&t.shape.close(),this},e.prototype.addHole=function(){var t=this.graphicsData.pop();return this.currentPath=this.graphicsData[this.graphicsData.length-1],this.currentPath.addHole(t.shape),this.currentPath=null,this},e.prototype.destroy=function(e){t.prototype.destroy.call(this,e);for(var r=0;r<this.graphicsData.length;++r)this.graphicsData[r].destroy();for(var n in this._webgl)for(var i=0;i<this._webgl[n].data.length;++i)this._webgl[n].data[i].destroy();this._spriteRect&&this._spriteRect.destroy(),this.graphicsData=null,this.currentPath=null,this._webgl=null,this._localBounds=null},e}(u.default);r.default=A,A._SPRITE_TEXTURE=null},{"../const":45,"../display/Bounds":46,"../display/Container":47,"../math":69,"../renderers/canvas/CanvasRenderer":76,"../sprites/Sprite":101,"../textures/RenderTexture":111,"../textures/Texture":113,"../utils":121,"./GraphicsData":53,"./utils/bezierCurveTo":55}],53:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(e,r,i,o,s,a,u,h){n(this,t),this.lineWidth=e,this.nativeLines=u,this.lineColor=r,this.lineAlpha=i,this._lineTint=r,this.fillColor=o,this.fillAlpha=s,this._fillTint=o,this.fill=a,this.holes=[],this.shape=h,this.type=h.type}return t.prototype.clone=function(){return new t(this.lineWidth,this.lineColor,this.lineAlpha,this.fillColor,this.fillAlpha,this.fill,this.nativeLines,this.shape)},t.prototype.addHole=function(t){this.holes.push(t)},t.prototype.destroy=function(){this.shape=null,this.holes=null},t}();r.default=i},{}],54:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../../renderers/canvas/CanvasRenderer"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=t("../../const"),a=function(){function t(e){n(this,t),this.renderer=e}return t.prototype.render=function(t){var e=this.renderer,r=e.context,n=t.worldAlpha,i=t.transform.worldTransform,o=e.resolution;this._prevTint!==this.tint&&(this.dirty=!0),r.setTransform(i.a*o,i.b*o,i.c*o,i.d*o,i.tx*o,i.ty*o),t.dirty&&(this.updateGraphicsTint(t),t.dirty=!1),e.setBlendMode(t.blendMode);for(var a=0;a<t.graphicsData.length;a++){var u=t.graphicsData[a],h=u.shape,l=u._fillTint,c=u._lineTint;if(r.lineWidth=u.lineWidth,u.type===s.SHAPES.POLY){r.beginPath(),this.renderPolygon(h.points,h.closed,r);for(var f=0;f<u.holes.length;f++)this.renderPolygon(u.holes[f].points,!0,r);u.fill&&(r.globalAlpha=u.fillAlpha*n,r.fillStyle="#"+("00000"+(0|l).toString(16)).substr(-6),r.fill()),u.lineWidth&&(r.globalAlpha=u.lineAlpha*n,r.strokeStyle="#"+("00000"+(0|c).toString(16)).substr(-6),r.stroke())}else if(u.type===s.SHAPES.RECT)(u.fillColor||0===u.fillColor)&&(r.globalAlpha=u.fillAlpha*n,r.fillStyle="#"+("00000"+(0|l).toString(16)).substr(-6),r.fillRect(h.x,h.y,h.width,h.height)),u.lineWidth&&(r.globalAlpha=u.lineAlpha*n,r.strokeStyle="#"+("00000"+(0|c).toString(16)).substr(-6),r.strokeRect(h.x,h.y,h.width,h.height));else if(u.type===s.SHAPES.CIRC)r.beginPath(),r.arc(h.x,h.y,h.radius,0,2*Math.PI),r.closePath(),u.fill&&(r.globalAlpha=u.fillAlpha*n,r.fillStyle="#"+("00000"+(0|l).toString(16)).substr(-6),r.fill()),u.lineWidth&&(r.globalAlpha=u.lineAlpha*n,r.strokeStyle="#"+("00000"+(0|c).toString(16)).substr(-6),r.stroke());else if(u.type===s.SHAPES.ELIP){var d=2*h.width,p=2*h.height,v=h.x-d/2,y=h.y-p/2;r.beginPath();var g=d/2*.5522848,m=p/2*.5522848,_=v+d,b=y+p,x=v+d/2,T=y+p/2;r.moveTo(v,T),r.bezierCurveTo(v,T-m,x-g,y,x,y),r.bezierCurveTo(x+g,y,_,T-m,_,T),r.bezierCurveTo(_,T+m,x+g,b,x,b),r.bezierCurveTo(x-g,b,v,T+m,v,T),r.closePath(),u.fill&&(r.globalAlpha=u.fillAlpha*n,r.fillStyle="#"+("00000"+(0|l).toString(16)).substr(-6),r.fill()),u.lineWidth&&(r.globalAlpha=u.lineAlpha*n,r.strokeStyle="#"+("00000"+(0|c).toString(16)).substr(-6),r.stroke())}else if(u.type===s.SHAPES.RREC){var w=h.x,E=h.y,S=h.width,O=h.height,M=h.radius,P=Math.min(S,O)/2|0;M=M>P?P:M,r.beginPath(),r.moveTo(w,E+M),r.lineTo(w,E+O-M),r.quadraticCurveTo(w,E+O,w+M,E+O),r.lineTo(w+S-M,E+O),r.quadraticCurveTo(w+S,E+O,w+S,E+O-M),r.lineTo(w+S,E+M),r.quadraticCurveTo(w+S,E,w+S-M,E),r.lineTo(w+M,E),r.quadraticCurveTo(w,E,w,E+M),r.closePath(),(u.fillColor||0===u.fillColor)&&(r.globalAlpha=u.fillAlpha*n,r.fillStyle="#"+("00000"+(0|l).toString(16)).substr(-6),r.fill()),u.lineWidth&&(r.globalAlpha=u.lineAlpha*n,r.strokeStyle="#"+("00000"+(0|c).toString(16)).substr(-6),r.stroke())}}},t.prototype.updateGraphicsTint=function(t){t._prevTint=t.tint;for(var e=(t.tint>>16&255)/255,r=(t.tint>>8&255)/255,n=(255&t.tint)/255,i=0;i<t.graphicsData.length;++i){var o=t.graphicsData[i],s=0|o.fillColor,a=0|o.lineColor;o._fillTint=((s>>16&255)/255*e*255<<16)+((s>>8&255)/255*r*255<<8)+(255&s)/255*n*255,o._lineTint=((a>>16&255)/255*e*255<<16)+((a>>8&255)/255*r*255<<8)+(255&a)/255*n*255}},t.prototype.renderPolygon=function(t,e,r){r.moveTo(t[0],t[1]);for(var n=1;n<t.length/2;++n)r.lineTo(t[2*n],t[2*n+1]);e&&r.closePath()},t.prototype.destroy=function(){this.renderer=null},t}();r.default=a,o.default.registerPlugin("graphics",a)},{"../../const":45,"../../renderers/canvas/CanvasRenderer":76}],55:[function(t,e,r){"use strict";function n(t,e,r,n,i,o,s,a){var u=arguments.length>8&&void 0!==arguments[8]?arguments[8]:[],h=0,l=0,c=0,f=0,d=0;u.push(t,e);for(var p=1,v=0;p<=20;++p)v=p/20,h=1-v,l=h*h,c=l*h,f=v*v,d=f*v,u.push(c*t+3*l*v*r+3*h*f*i+d*s,c*e+3*l*v*n+3*h*f*o+d*a);return u}r.__esModule=!0,r.default=n},{}],56:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("../../utils"),u=t("../../const"),h=t("../../renderers/webgl/utils/ObjectRenderer"),l=n(h),c=t("../../renderers/webgl/WebGLRenderer"),f=n(c),d=t("./WebGLGraphicsData"),p=n(d),v=t("./shaders/PrimitiveShader"),y=n(v),g=t("./utils/buildPoly"),m=n(g),_=t("./utils/buildRectangle"),b=n(_),x=t("./utils/buildRoundedRectangle"),T=n(x),w=t("./utils/buildCircle"),E=n(w),S=function(t){function e(r){i(this,e);var n=o(this,t.call(this,r));return n.graphicsDataPool=[],n.primitiveShader=null,n.gl=r.gl,n.CONTEXT_UID=0,n}return s(e,t),e.prototype.onContextChange=function(){this.gl=this.renderer.gl,this.CONTEXT_UID=this.renderer.CONTEXT_UID,this.primitiveShader=new y.default(this.gl)},e.prototype.destroy=function(){l.default.prototype.destroy.call(this);for(var t=0;t<this.graphicsDataPool.length;++t)this.graphicsDataPool[t].destroy();this.graphicsDataPool=null},e.prototype.render=function(t){var e=this.renderer,r=e.gl,n=void 0,i=t._webGL[this.CONTEXT_UID];i&&t.dirty===i.dirty||(this.updateGraphics(t),i=t._webGL[this.CONTEXT_UID]);var o=this.primitiveShader;e.bindShader(o),e.state.setBlendMode(t.blendMode);for(var s=0,u=i.data.length;s<u;s++){n=i.data[s];var h=n.shader;e.bindShader(h),h.uniforms.translationMatrix=t.transform.worldTransform.toArray(!0),h.uniforms.tint=(0,a.hex2rgb)(t.tint),h.uniforms.alpha=t.worldAlpha,e.bindVao(n.vao),t.nativeLines?r.drawArrays(r.LINES,0,n.points.length/6):n.vao.draw(r.TRIANGLE_STRIP,n.indices.length)}},e.prototype.updateGraphics=function(t){var e=this.renderer.gl,r=t._webGL[this.CONTEXT_UID];if(r||(r=t._webGL[this.CONTEXT_UID]={lastIndex:0,data:[],gl:e,clearDirty:-1,dirty:-1}),r.dirty=t.dirty,t.clearDirty!==r.clearDirty){r.clearDirty=t.clearDirty;for(var n=0;n<r.data.length;n++)this.graphicsDataPool.push(r.data[n]);r.data.length=0,r.lastIndex=0}for(var i=void 0,o=r.lastIndex;o<t.graphicsData.length;o++){var s=t.graphicsData[o];i=this.getWebGLData(r,0),s.type===u.SHAPES.POLY&&(0,m.default)(s,i),s.type===u.SHAPES.RECT?(0,b.default)(s,i):s.type===u.SHAPES.CIRC||s.type===u.SHAPES.ELIP?(0,E.default)(s,i):s.type===u.SHAPES.RREC&&(0,T.default)(s,i),r.lastIndex++}this.renderer.bindVao(null);for(var a=0;a<r.data.length;a++)i=r.data[a],i.dirty&&i.upload()},e.prototype.getWebGLData=function(t,e){var r=t.data[t.data.length-1];return(!r||r.points.length>32e4)&&(r=this.graphicsDataPool.pop()||new p.default(this.renderer.gl,this.primitiveShader,this.renderer.state.attribsState),r.reset(e),t.data.push(r)),r.dirty=!0,r},e}(l.default);r.default=S,f.default.registerPlugin("graphics",S)},{"../../const":45,"../../renderers/webgl/WebGLRenderer":83,"../../renderers/webgl/utils/ObjectRenderer":93,"../../utils":121,"./WebGLGraphicsData":57,"./shaders/PrimitiveShader":58,"./utils/buildCircle":59,"./utils/buildPoly":61,"./utils/buildRectangle":62,"./utils/buildRoundedRectangle":63}],57:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("pixi-gl-core"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=function(){function t(e,r,i){n(this,t),this.gl=e,this.color=[0,0,0],this.points=[],this.indices=[],this.buffer=o.default.GLBuffer.createVertexBuffer(e),this.indexBuffer=o.default.GLBuffer.createIndexBuffer(e),this.dirty=!0,this.glPoints=null,this.glIndices=null,this.shader=r,this.vao=new o.default.VertexArrayObject(e,i).addIndex(this.indexBuffer).addAttribute(this.buffer,r.attributes.aVertexPosition,e.FLOAT,!1,24,0).addAttribute(this.buffer,r.attributes.aColor,e.FLOAT,!1,24,8)}return t.prototype.reset=function(){this.points.length=0,this.indices.length=0},t.prototype.upload=function(){this.glPoints=new Float32Array(this.points),this.buffer.upload(this.glPoints),this.glIndices=new Uint16Array(this.indices),this.indexBuffer.upload(this.glIndices),this.dirty=!1},t.prototype.destroy=function(){this.color=null,this.points=null,this.indices=null,this.vao.destroy(),this.buffer.destroy(),this.indexBuffer.destroy(),this.gl=null,this.buffer=null,this.indexBuffer=null,this.glPoints=null,this.glIndices=null},t}();r.default=s},{"pixi-gl-core":12}],58:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=t("../../../Shader"),a=function(t){return t&&t.__esModule?t:{default:t}}(s),u=function(t){function e(r){return n(this,e),i(this,t.call(this,r,["attribute vec2 aVertexPosition;","attribute vec4 aColor;","uniform mat3 translationMatrix;","uniform mat3 projectionMatrix;","uniform float alpha;","uniform vec3 tint;","varying vec4 vColor;","void main(void){","   gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);","   vColor = aColor * vec4(tint * alpha, alpha);","}"].join("\n"),["varying vec4 vColor;","void main(void){","   gl_FragColor = vColor;","}"].join("\n")))}return o(e,t),e}(a.default);r.default=u},{"../../../Shader":43}],59:[function(t,e,r){"use strict";function n(t,e){var r=t.shape,n=r.x,i=r.y,u=void 0,h=void 0;if(t.type===s.SHAPES.CIRC?(u=r.radius,h=r.radius):(u=r.width,h=r.height),0!==u&&0!==h){var l=Math.floor(30*Math.sqrt(r.radius))||Math.floor(15*Math.sqrt(r.width+r.height)),c=2*Math.PI/l;if(t.fill){var f=(0,a.hex2rgb)(t.fillColor),d=t.fillAlpha,p=f[0]*d,v=f[1]*d,y=f[2]*d,g=e.points,m=e.indices,_=g.length/6;m.push(_);for(var b=0;b<l+1;b++)g.push(n,i,p,v,y,d),g.push(n+Math.sin(c*b)*u,i+Math.cos(c*b)*h,p,v,y,d),m.push(_++,_++);m.push(_-1)}if(t.lineWidth){var x=t.points;t.points=[];for(var T=0;T<l+1;T++)t.points.push(n+Math.sin(c*T)*u,i+Math.cos(c*T)*h);(0,o.default)(t,e),t.points=x}}}r.__esModule=!0,r.default=n;var i=t("./buildLine"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=t("../../../const"),a=t("../../../utils")},{"../../../const":45,"../../../utils":121,"./buildLine":60}],60:[function(t,e,r){"use strict";function n(t,e){var r=t.points;if(0!==r.length){var n=new o.Point(r[0],r[1]),i=new o.Point(r[r.length-2],r[r.length-1]);if(n.x===i.x&&n.y===i.y){r=r.slice(),r.pop(),r.pop(),i=new o.Point(r[r.length-2],r[r.length-1]);var a=i.x+.5*(n.x-i.x),u=i.y+.5*(n.y-i.y);r.unshift(a,u),r.push(a,u)}var h=e.points,l=e.indices,c=r.length/2,f=r.length,d=h.length/6,p=t.lineWidth/2,v=(0,s.hex2rgb)(t.lineColor),y=t.lineAlpha,g=v[0]*y,m=v[1]*y,_=v[2]*y,b=r[0],x=r[1],T=r[2],w=r[3],E=0,S=0,O=-(x-w),M=b-T,P=0,C=0,R=0,A=0,D=Math.sqrt(O*O+M*M);O/=D,M/=D,O*=p,M*=p,h.push(b-O,x-M,g,m,_,y),h.push(b+O,x+M,g,m,_,y);for(var I=1;I<c-1;++I){b=r[2*(I-1)],x=r[2*(I-1)+1],T=r[2*I],w=r[2*I+1],E=r[2*(I+1)],S=r[2*(I+1)+1],O=-(x-w),M=b-T,D=Math.sqrt(O*O+M*M),O/=D,M/=D,O*=p,M*=p,P=-(w-S),C=T-E,D=Math.sqrt(P*P+C*C),P/=D,C/=D,P*=p,C*=p;var L=-M+x-(-M+w),N=-O+T-(-O+b),j=(-O+b)*(-M+w)-(-O+T)*(-M+x),B=-C+S-(-C+w),k=-P+T-(-P+E),F=(-P+E)*(-C+w)-(-P+T)*(-C+S),U=L*k-B*N;if(Math.abs(U)<.1)U+=10.1,h.push(T-O,w-M,g,m,_,y),h.push(T+O,w+M,g,m,_,y);else{var X=(N*F-k*j)/U,G=(B*j-L*F)/U;(X-T)*(X-T)+(G-w)*(G-w)>196*p*p?(R=O-P,A=M-C,D=Math.sqrt(R*R+A*A),R/=D,A/=D,R*=p,A*=p,h.push(T-R,w-A),h.push(g,m,_,y),h.push(T+R,w+A),h.push(g,m,_,y),h.push(T-R,w-A),h.push(g,m,_,y),f++):(h.push(X,G),h.push(g,m,_,y),h.push(T-(X-T),w-(G-w)),h.push(g,m,_,y))}}b=r[2*(c-2)],x=r[2*(c-2)+1],T=r[2*(c-1)],w=r[2*(c-1)+1],O=-(x-w),M=b-T,D=Math.sqrt(O*O+M*M),O/=D,M/=D,O*=p,M*=p,h.push(T-O,w-M),h.push(g,m,_,y),h.push(T+O,w+M),h.push(g,m,_,y),l.push(d);for(var W=0;W<f;++W)l.push(d++);l.push(d-1)}}function i(t,e){var r=0,n=t.points;if(0!==n.length){var i=e.points,o=n.length/2,a=(0,s.hex2rgb)(t.lineColor),u=t.lineAlpha,h=a[0]*u,l=a[1]*u,c=a[2]*u;for(r=1;r<o;r++){var f=n[2*(r-1)],d=n[2*(r-1)+1],p=n[2*r],v=n[2*r+1];i.push(f,d),i.push(h,l,c,u),i.push(p,v),i.push(h,l,c,u)}}}r.__esModule=!0,r.default=function(t,e){t.nativeLines?i(t,e):n(t,e)};var o=t("../../../math"),s=t("../../../utils")},{"../../../math":69,"../../../utils":121}],61:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){t.points=t.shape.points.slice();var r=t.points;if(t.fill&&r.length>=6){for(var n=[],i=t.holes,o=0;o<i.length;o++){var u=i[o];n.push(r.length/2),r=r.concat(u.points)}var l=e.points,c=e.indices,f=r.length/2,d=(0,a.hex2rgb)(t.fillColor),p=t.fillAlpha,v=d[0]*p,y=d[1]*p,g=d[2]*p,m=(0,h.default)(r,n,2);if(!m)return;for(var _=l.length/6,b=0;b<m.length;b+=3)c.push(m[b]+_),c.push(m[b]+_),c.push(m[b+1]+_),c.push(m[b+2]+_),c.push(m[b+2]+_);for(var x=0;x<f;x++)l.push(r[2*x],r[2*x+1],v,y,g,p)}t.lineWidth>0&&(0,s.default)(t,e)}r.__esModule=!0,r.default=i;var o=t("./buildLine"),s=n(o),a=t("../../../utils"),u=t("earcut"),h=n(u)},{"../../../utils":121,"./buildLine":60,earcut:2}],62:[function(t,e,r){"use strict";function n(t,e){var r=t.shape,n=r.x,i=r.y,a=r.width,u=r.height;if(t.fill){var h=(0,s.hex2rgb)(t.fillColor),l=t.fillAlpha,c=h[0]*l,f=h[1]*l,d=h[2]*l,p=e.points,v=e.indices,y=p.length/6;p.push(n,i),p.push(c,f,d,l),p.push(n+a,i),p.push(c,f,d,l),p.push(n,i+u),p.push(c,f,d,l),p.push(n+a,i+u),p.push(c,f,d,l),v.push(y,y,y+1,y+2,y+3,y+3)}if(t.lineWidth){var g=t.points;t.points=[n,i,n+a,i,n+a,i+u,n,i+u,n,i],(0,o.default)(t,e),t.points=g}}r.__esModule=!0,r.default=n;var i=t("./buildLine"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=t("../../../utils")},{"../../../utils":121,"./buildLine":60}],63:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){var r=t.shape,n=r.x,i=r.y,o=r.width,a=r.height,h=r.radius,f=[];if(f.push(n,i+h),s(n,i+a-h,n,i+a,n+h,i+a,f),s(n+o-h,i+a,n+o,i+a,n+o,i+a-h,f),s(n+o,i+h,n+o,i,n+o-h,i,f),s(n+h,i,n,i,n,i+h+1e-10,f),t.fill){for(var d=(0,c.hex2rgb)(t.fillColor),p=t.fillAlpha,v=d[0]*p,y=d[1]*p,g=d[2]*p,m=e.points,_=e.indices,b=m.length/6,x=(0,u.default)(f,null,2),T=0,w=x.length;T<w;T+=3)_.push(x[T]+b),_.push(x[T]+b),_.push(x[T+1]+b),_.push(x[T+2]+b),_.push(x[T+2]+b);for(var E=0,S=f.length;E<S;E++)m.push(f[E],f[++E],v,y,g,p)}if(t.lineWidth){var O=t.points;t.points=f,(0,l.default)(t,e),t.points=O}}function o(t,e,r){return t+(e-t)*r}function s(t,e,r,n,i,s){for(var a=arguments.length>6&&void 0!==arguments[6]?arguments[6]:[],u=a,h=0,l=0,c=0,f=0,d=0,p=0,v=0,y=0;v<=20;++v)y=v/20,h=o(t,r,y),l=o(e,n,y),c=o(r,i,y),f=o(n,s,y),d=o(h,c,y),p=o(l,f,y),u.push(d,p);return u}r.__esModule=!0,r.default=i;var a=t("earcut"),u=n(a),h=t("./buildLine"),l=n(h),c=t("../../../utils")},{"../../../utils":121,"./buildLine":60,earcut:2}],64:[function(t,e,r){"use strict";function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}function i(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0,r.autoDetectRenderer=r.Application=r.Filter=r.SpriteMaskFilter=r.Quad=r.RenderTarget=r.ObjectRenderer=r.WebGLManager=r.Shader=r.CanvasRenderTarget=r.TextureUvs=r.VideoBaseTexture=r.BaseRenderTexture=r.RenderTexture=r.BaseTexture=r.Texture=r.Spritesheet=r.CanvasGraphicsRenderer=r.GraphicsRenderer=r.GraphicsData=r.Graphics=r.TextStyle=r.Text=r.SpriteRenderer=r.CanvasTinter=r.CanvasSpriteRenderer=r.Sprite=r.TransformBase=r.TransformStatic=r.Transform=r.Container=r.DisplayObject=r.Bounds=r.glCore=r.WebGLRenderer=r.CanvasRenderer=r.ticker=r.utils=r.settings=void 0;var o=t("./const");Object.keys(o).forEach(function(t){"default"!==t&&"__esModule"!==t&&Object.defineProperty(r,t,{enumerable:!0,get:function(){return o[t]}})});var s=t("./math");Object.keys(s).forEach(function(t){"default"!==t&&"__esModule"!==t&&Object.defineProperty(r,t,{enumerable:!0,get:function(){return s[t]}})});var a=t("pixi-gl-core");Object.defineProperty(r,"glCore",{enumerable:!0,get:function(){return i(a).default}});var u=t("./display/Bounds");Object.defineProperty(r,"Bounds",{enumerable:!0,get:function(){return i(u).default}});var h=t("./display/DisplayObject");Object.defineProperty(r,"DisplayObject",{enumerable:!0,get:function(){return i(h).default}});var l=t("./display/Container");Object.defineProperty(r,"Container",{enumerable:!0,get:function(){return i(l).default}});var c=t("./display/Transform");Object.defineProperty(r,"Transform",{enumerable:!0,get:function(){return i(c).default}});var f=t("./display/TransformStatic");Object.defineProperty(r,"TransformStatic",{enumerable:!0,get:function(){return i(f).default}});var d=t("./display/TransformBase");Object.defineProperty(r,"TransformBase",{enumerable:!0,get:function(){return i(d).default}})
+;var p=t("./sprites/Sprite");Object.defineProperty(r,"Sprite",{enumerable:!0,get:function(){return i(p).default}});var v=t("./sprites/canvas/CanvasSpriteRenderer");Object.defineProperty(r,"CanvasSpriteRenderer",{enumerable:!0,get:function(){return i(v).default}});var y=t("./sprites/canvas/CanvasTinter");Object.defineProperty(r,"CanvasTinter",{enumerable:!0,get:function(){return i(y).default}});var g=t("./sprites/webgl/SpriteRenderer");Object.defineProperty(r,"SpriteRenderer",{enumerable:!0,get:function(){return i(g).default}});var m=t("./text/Text");Object.defineProperty(r,"Text",{enumerable:!0,get:function(){return i(m).default}});var _=t("./text/TextStyle");Object.defineProperty(r,"TextStyle",{enumerable:!0,get:function(){return i(_).default}});var b=t("./graphics/Graphics");Object.defineProperty(r,"Graphics",{enumerable:!0,get:function(){return i(b).default}});var x=t("./graphics/GraphicsData");Object.defineProperty(r,"GraphicsData",{enumerable:!0,get:function(){return i(x).default}});var T=t("./graphics/webgl/GraphicsRenderer");Object.defineProperty(r,"GraphicsRenderer",{enumerable:!0,get:function(){return i(T).default}});var w=t("./graphics/canvas/CanvasGraphicsRenderer");Object.defineProperty(r,"CanvasGraphicsRenderer",{enumerable:!0,get:function(){return i(w).default}});var E=t("./textures/Spritesheet");Object.defineProperty(r,"Spritesheet",{enumerable:!0,get:function(){return i(E).default}});var S=t("./textures/Texture");Object.defineProperty(r,"Texture",{enumerable:!0,get:function(){return i(S).default}});var O=t("./textures/BaseTexture");Object.defineProperty(r,"BaseTexture",{enumerable:!0,get:function(){return i(O).default}});var M=t("./textures/RenderTexture");Object.defineProperty(r,"RenderTexture",{enumerable:!0,get:function(){return i(M).default}});var P=t("./textures/BaseRenderTexture");Object.defineProperty(r,"BaseRenderTexture",{enumerable:!0,get:function(){return i(P).default}});var C=t("./textures/VideoBaseTexture");Object.defineProperty(r,"VideoBaseTexture",{enumerable:!0,get:function(){return i(C).default}});var R=t("./textures/TextureUvs");Object.defineProperty(r,"TextureUvs",{enumerable:!0,get:function(){return i(R).default}});var A=t("./renderers/canvas/utils/CanvasRenderTarget");Object.defineProperty(r,"CanvasRenderTarget",{enumerable:!0,get:function(){return i(A).default}});var D=t("./Shader");Object.defineProperty(r,"Shader",{enumerable:!0,get:function(){return i(D).default}});var I=t("./renderers/webgl/managers/WebGLManager");Object.defineProperty(r,"WebGLManager",{enumerable:!0,get:function(){return i(I).default}});var L=t("./renderers/webgl/utils/ObjectRenderer");Object.defineProperty(r,"ObjectRenderer",{enumerable:!0,get:function(){return i(L).default}});var N=t("./renderers/webgl/utils/RenderTarget");Object.defineProperty(r,"RenderTarget",{enumerable:!0,get:function(){return i(N).default}});var j=t("./renderers/webgl/utils/Quad");Object.defineProperty(r,"Quad",{enumerable:!0,get:function(){return i(j).default}});var B=t("./renderers/webgl/filters/spriteMask/SpriteMaskFilter");Object.defineProperty(r,"SpriteMaskFilter",{enumerable:!0,get:function(){return i(B).default}});var k=t("./renderers/webgl/filters/Filter");Object.defineProperty(r,"Filter",{enumerable:!0,get:function(){return i(k).default}});var F=t("./Application");Object.defineProperty(r,"Application",{enumerable:!0,get:function(){return i(F).default}});var U=t("./autoDetectRenderer");Object.defineProperty(r,"autoDetectRenderer",{enumerable:!0,get:function(){return U.autoDetectRenderer}});var X=t("./utils"),G=n(X),W=t("./ticker"),H=n(W),V=t("./settings"),Y=i(V),z=t("./renderers/canvas/CanvasRenderer"),q=i(z),K=t("./renderers/webgl/WebGLRenderer"),Z=i(K);r.settings=Y.default,r.utils=G,r.ticker=H,r.CanvasRenderer=q.default,r.WebGLRenderer=Z.default},{"./Application":42,"./Shader":43,"./autoDetectRenderer":44,"./const":45,"./display/Bounds":46,"./display/Container":47,"./display/DisplayObject":48,"./display/Transform":49,"./display/TransformBase":50,"./display/TransformStatic":51,"./graphics/Graphics":52,"./graphics/GraphicsData":53,"./graphics/canvas/CanvasGraphicsRenderer":54,"./graphics/webgl/GraphicsRenderer":56,"./math":69,"./renderers/canvas/CanvasRenderer":76,"./renderers/canvas/utils/CanvasRenderTarget":78,"./renderers/webgl/WebGLRenderer":83,"./renderers/webgl/filters/Filter":85,"./renderers/webgl/filters/spriteMask/SpriteMaskFilter":88,"./renderers/webgl/managers/WebGLManager":92,"./renderers/webgl/utils/ObjectRenderer":93,"./renderers/webgl/utils/Quad":94,"./renderers/webgl/utils/RenderTarget":95,"./settings":100,"./sprites/Sprite":101,"./sprites/canvas/CanvasSpriteRenderer":102,"./sprites/canvas/CanvasTinter":103,"./sprites/webgl/SpriteRenderer":105,"./text/Text":107,"./text/TextStyle":108,"./textures/BaseRenderTexture":109,"./textures/BaseTexture":110,"./textures/RenderTexture":111,"./textures/Spritesheet":112,"./textures/Texture":113,"./textures/TextureUvs":114,"./textures/VideoBaseTexture":115,"./ticker":117,"./utils":121,"pixi-gl-core":12}],65:[function(t,e,r){"use strict";function n(t){return t<0?-1:t>0?1:0}r.__esModule=!0;var i=t("./Matrix"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=[1,1,0,-1,-1,-1,0,1,1,1,0,-1,-1,-1,0,1],a=[0,1,1,1,0,-1,-1,-1,0,1,1,1,0,-1,-1,-1],u=[0,-1,-1,-1,0,1,1,1,0,1,1,1,0,-1,-1,-1],h=[1,1,0,-1,-1,-1,0,1,-1,-1,0,1,1,1,0,-1],l=[],c=[];!function(){for(var t=0;t<16;t++){var e=[];c.push(e);for(var r=0;r<16;r++)for(var i=n(s[t]*s[r]+u[t]*a[r]),f=n(a[t]*s[r]+h[t]*a[r]),d=n(s[t]*u[r]+u[t]*h[r]),p=n(a[t]*u[r]+h[t]*h[r]),v=0;v<16;v++)if(s[v]===i&&a[v]===f&&u[v]===d&&h[v]===p){e.push(v);break}}for(var y=0;y<16;y++){var g=new o.default;g.set(s[y],a[y],u[y],h[y],0,0),l.push(g)}}();var f={E:0,SE:1,S:2,SW:3,W:4,NW:5,N:6,NE:7,MIRROR_VERTICAL:8,MIRROR_HORIZONTAL:12,uX:function(t){return s[t]},uY:function(t){return a[t]},vX:function(t){return u[t]},vY:function(t){return h[t]},inv:function(t){return 8&t?15&t:7&-t},add:function(t,e){return c[t][e]},sub:function(t,e){return c[t][f.inv(e)]},rotate180:function(t){return 4^t},isSwapWidthHeight:function(t){return 2==(3&t)},byDirection:function(t,e){return 2*Math.abs(t)<=Math.abs(e)?e>=0?f.S:f.N:2*Math.abs(e)<=Math.abs(t)?t>0?f.E:f.W:e>0?t>0?f.SE:f.SW:t>0?f.NE:f.NW},matrixAppendRotationInv:function(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,i=l[f.inv(e)];i.tx=r,i.ty=n,t.append(i)}};r.default=f},{"./Matrix":66}],66:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),o=t("./Point"),s=function(t){return t&&t.__esModule?t:{default:t}}(o),a=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1,s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;n(this,t),this.a=e,this.b=r,this.c=i,this.d=o,this.tx=s,this.ty=a,this.array=null}return t.prototype.fromArray=function(t){this.a=t[0],this.b=t[1],this.c=t[3],this.d=t[4],this.tx=t[2],this.ty=t[5]},t.prototype.set=function(t,e,r,n,i,o){return this.a=t,this.b=e,this.c=r,this.d=n,this.tx=i,this.ty=o,this},t.prototype.toArray=function(t,e){this.array||(this.array=new Float32Array(9));var r=e||this.array;return t?(r[0]=this.a,r[1]=this.b,r[2]=0,r[3]=this.c,r[4]=this.d,r[5]=0,r[6]=this.tx,r[7]=this.ty,r[8]=1):(r[0]=this.a,r[1]=this.c,r[2]=this.tx,r[3]=this.b,r[4]=this.d,r[5]=this.ty,r[6]=0,r[7]=0,r[8]=1),r},t.prototype.apply=function(t,e){e=e||new s.default;var r=t.x,n=t.y;return e.x=this.a*r+this.c*n+this.tx,e.y=this.b*r+this.d*n+this.ty,e},t.prototype.applyInverse=function(t,e){e=e||new s.default;var r=1/(this.a*this.d+this.c*-this.b),n=t.x,i=t.y;return e.x=this.d*r*n+-this.c*r*i+(this.ty*this.c-this.tx*this.d)*r,e.y=this.a*r*i+-this.b*r*n+(-this.ty*this.a+this.tx*this.b)*r,e},t.prototype.translate=function(t,e){return this.tx+=t,this.ty+=e,this},t.prototype.scale=function(t,e){return this.a*=t,this.d*=e,this.c*=t,this.b*=e,this.tx*=t,this.ty*=e,this},t.prototype.rotate=function(t){var e=Math.cos(t),r=Math.sin(t),n=this.a,i=this.c,o=this.tx;return this.a=n*e-this.b*r,this.b=n*r+this.b*e,this.c=i*e-this.d*r,this.d=i*r+this.d*e,this.tx=o*e-this.ty*r,this.ty=o*r+this.ty*e,this},t.prototype.append=function(t){var e=this.a,r=this.b,n=this.c,i=this.d;return this.a=t.a*e+t.b*n,this.b=t.a*r+t.b*i,this.c=t.c*e+t.d*n,this.d=t.c*r+t.d*i,this.tx=t.tx*e+t.ty*n+this.tx,this.ty=t.tx*r+t.ty*i+this.ty,this},t.prototype.setTransform=function(t,e,r,n,i,o,s,a,u){var h=Math.sin(s),l=Math.cos(s),c=Math.cos(u),f=Math.sin(u),d=-Math.sin(a),p=Math.cos(a),v=l*i,y=h*i,g=-h*o,m=l*o;return this.a=c*v+f*g,this.b=c*y+f*m,this.c=d*v+p*g,this.d=d*y+p*m,this.tx=t+(r*v+n*g),this.ty=e+(r*y+n*m),this},t.prototype.prepend=function(t){var e=this.tx;if(1!==t.a||0!==t.b||0!==t.c||1!==t.d){var r=this.a,n=this.c;this.a=r*t.a+this.b*t.c,this.b=r*t.b+this.b*t.d,this.c=n*t.a+this.d*t.c,this.d=n*t.b+this.d*t.d}return this.tx=e*t.a+this.ty*t.c+t.tx,this.ty=e*t.b+this.ty*t.d+t.ty,this},t.prototype.decompose=function(t){var e=this.a,r=this.b,n=this.c,i=this.d,o=-Math.atan2(-n,i),s=Math.atan2(r,e);return Math.abs(o+s)<1e-5?(t.rotation=s,e<0&&i>=0&&(t.rotation+=t.rotation<=0?Math.PI:-Math.PI),t.skew.x=t.skew.y=0):(t.skew.x=o,t.skew.y=s),t.scale.x=Math.sqrt(e*e+r*r),t.scale.y=Math.sqrt(n*n+i*i),t.position.x=this.tx,t.position.y=this.ty,t},t.prototype.invert=function(){var t=this.a,e=this.b,r=this.c,n=this.d,i=this.tx,o=t*n-e*r;return this.a=n/o,this.b=-e/o,this.c=-r/o,this.d=t/o,this.tx=(r*this.ty-n*i)/o,this.ty=-(t*this.ty-e*i)/o,this},t.prototype.identity=function(){return this.a=1,this.b=0,this.c=0,this.d=1,this.tx=0,this.ty=0,this},t.prototype.clone=function(){var e=new t;return e.a=this.a,e.b=this.b,e.c=this.c,e.d=this.d,e.tx=this.tx,e.ty=this.ty,e},t.prototype.copy=function(t){return t.a=this.a,t.b=this.b,t.c=this.c,t.d=this.d,t.tx=this.tx,t.ty=this.ty,t},i(t,null,[{key:"IDENTITY",get:function(){return new t}},{key:"TEMP_MATRIX",get:function(){return new t}}]),t}();r.default=a},{"./Point":68}],67:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),o=function(){function t(e,r){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0;n(this,t),this._x=i,this._y=o,this.cb=e,this.scope=r}return t.prototype.set=function(t,e){var r=t||0,n=e||(0!==e?r:0);this._x===r&&this._y===n||(this._x=r,this._y=n,this.cb.call(this.scope))},t.prototype.copy=function(t){this._x===t.x&&this._y===t.y||(this._x=t.x,this._y=t.y,this.cb.call(this.scope))},i(t,[{key:"x",get:function(){return this._x},set:function(t){this._x!==t&&(this._x=t,this.cb.call(this.scope))}},{key:"y",get:function(){return this._y},set:function(t){this._y!==t&&(this._y=t,this.cb.call(this.scope))}}]),t}();r.default=o},{}],68:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;n(this,t),this.x=e,this.y=r}return t.prototype.clone=function(){return new t(this.x,this.y)},t.prototype.copy=function(t){this.set(t.x,t.y)},t.prototype.equals=function(t){return t.x===this.x&&t.y===this.y},t.prototype.set=function(t,e){this.x=t||0,this.y=e||(0!==e?this.x:0)},t}();r.default=i},{}],69:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0;var i=t("./Point");Object.defineProperty(r,"Point",{enumerable:!0,get:function(){return n(i).default}});var o=t("./ObservablePoint");Object.defineProperty(r,"ObservablePoint",{enumerable:!0,get:function(){return n(o).default}});var s=t("./Matrix");Object.defineProperty(r,"Matrix",{enumerable:!0,get:function(){return n(s).default}});var a=t("./GroupD8");Object.defineProperty(r,"GroupD8",{enumerable:!0,get:function(){return n(a).default}});var u=t("./shapes/Circle");Object.defineProperty(r,"Circle",{enumerable:!0,get:function(){return n(u).default}});var h=t("./shapes/Ellipse");Object.defineProperty(r,"Ellipse",{enumerable:!0,get:function(){return n(h).default}});var l=t("./shapes/Polygon");Object.defineProperty(r,"Polygon",{enumerable:!0,get:function(){return n(l).default}});var c=t("./shapes/Rectangle");Object.defineProperty(r,"Rectangle",{enumerable:!0,get:function(){return n(c).default}});var f=t("./shapes/RoundedRectangle");Object.defineProperty(r,"RoundedRectangle",{enumerable:!0,get:function(){return n(f).default}})},{"./GroupD8":65,"./Matrix":66,"./ObservablePoint":67,"./Point":68,"./shapes/Circle":70,"./shapes/Ellipse":71,"./shapes/Polygon":72,"./shapes/Rectangle":73,"./shapes/RoundedRectangle":74}],70:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("./Rectangle"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=t("../../const"),a=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;n(this,t),this.x=e,this.y=r,this.radius=i,this.type=s.SHAPES.CIRC}return t.prototype.clone=function(){return new t(this.x,this.y,this.radius)},t.prototype.contains=function(t,e){if(this.radius<=0)return!1;var r=this.radius*this.radius,n=this.x-t,i=this.y-e;return n*=n,i*=i,n+i<=r},t.prototype.getBounds=function(){return new o.default(this.x-this.radius,this.y-this.radius,2*this.radius,2*this.radius)},t}();r.default=a},{"../../const":45,"./Rectangle":73}],71:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("./Rectangle"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=t("../../const"),a=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0;n(this,t),this.x=e,this.y=r,this.width=i,this.height=o,this.type=s.SHAPES.ELIP}return t.prototype.clone=function(){return new t(this.x,this.y,this.width,this.height)},t.prototype.contains=function(t,e){if(this.width<=0||this.height<=0)return!1;var r=(t-this.x)/this.width,n=(e-this.y)/this.height;return r*=r,n*=n,r+n<=1},t.prototype.getBounds=function(){return new o.default(this.x-this.width,this.y-this.height,this.width,this.height)},t}();r.default=a},{"../../const":45,"./Rectangle":73}],72:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../Point"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=t("../../const"),a=function(){function t(){for(var e=arguments.length,r=Array(e),i=0;i<e;i++)r[i]=arguments[i];if(n(this,t),Array.isArray(r[0])&&(r=r[0]),r[0]instanceof o.default){for(var a=[],u=0,h=r.length;u<h;u++)a.push(r[u].x,r[u].y);r=a}this.closed=!0,this.points=r,this.type=s.SHAPES.POLY}return t.prototype.clone=function(){return new t(this.points.slice())},t.prototype.close=function(){var t=this.points;t[0]===t[t.length-2]&&t[1]===t[t.length-1]||t.push(t[0],t[1])},t.prototype.contains=function(t,e){for(var r=!1,n=this.points.length/2,i=0,o=n-1;i<n;o=i++){var s=this.points[2*i],a=this.points[2*i+1],u=this.points[2*o],h=this.points[2*o+1];a>e!=h>e&&t<(e-a)/(h-a)*(u-s)+s&&(r=!r)}return r},t}();r.default=a},{"../../const":45,"../Point":68}],73:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),o=t("../../const"),s=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0;n(this,t),this.x=e,this.y=r,this.width=i,this.height=s,this.type=o.SHAPES.RECT}return t.prototype.clone=function(){return new t(this.x,this.y,this.width,this.height)},t.prototype.copy=function(t){return this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height,this},t.prototype.contains=function(t,e){return!(this.width<=0||this.height<=0)&&(t>=this.x&&t<this.x+this.width&&e>=this.y&&e<this.y+this.height)},t.prototype.pad=function(t,e){t=t||0,e=e||(0!==e?t:0),this.x-=t,this.y-=e,this.width+=2*t,this.height+=2*e},t.prototype.fit=function(t){this.x<t.x&&(this.width+=this.x,this.width<0&&(this.width=0),this.x=t.x),this.y<t.y&&(this.height+=this.y,this.height<0&&(this.height=0),this.y=t.y),this.x+this.width>t.x+t.width&&(this.width=t.width-this.x,this.width<0&&(this.width=0)),this.y+this.height>t.y+t.height&&(this.height=t.height-this.y,this.height<0&&(this.height=0))},t.prototype.enlarge=function(t){var e=Math.min(this.x,t.x),r=Math.max(this.x+this.width,t.x+t.width),n=Math.min(this.y,t.y),i=Math.max(this.y+this.height,t.y+t.height);this.x=e,this.width=r-e,this.y=n,this.height=i-n},i(t,[{key:"left",get:function(){return this.x}},{key:"right",get:function(){return this.x+this.width}},{key:"top",get:function(){return this.y}},{key:"bottom",get:function(){return this.y+this.height}}],[{key:"EMPTY",get:function(){return new t(0,0,0,0)}}]),t}();r.default=s},{"../../const":45}],74:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../../const"),o=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:20;n(this,t),this.x=e,this.y=r,this.width=o,this.height=s,this.radius=a,this.type=i.SHAPES.RREC}return t.prototype.clone=function(){return new t(this.x,this.y,this.width,this.height,this.radius)},t.prototype.contains=function(t,e){if(this.width<=0||this.height<=0)return!1;if(t>=this.x&&t<=this.x+this.width&&e>=this.y&&e<=this.y+this.height){if(e>=this.y+this.radius&&e<=this.y+this.height-this.radius||t>=this.x+this.radius&&t<=this.x+this.width-this.radius)return!0;var r=t-(this.x+this.radius),n=e-(this.y+this.radius),i=this.radius*this.radius;if(r*r+n*n<=i)return!0;if((r=t-(this.x+this.width-this.radius))*r+n*n<=i)return!0;if(n=e-(this.y+this.height-this.radius),r*r+n*n<=i)return!0;if((r=t-(this.x+this.radius))*r+n*n<=i)return!0}return!1},t}();r.default=o},{"../../const":45}],75:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),u=t("../utils"),h=t("../math"),l=t("../const"),c=t("../settings"),f=n(c),d=t("../display/Container"),p=n(d),v=t("../textures/RenderTexture"),y=n(v),g=t("eventemitter3"),m=n(g),_=new h.Matrix,b=function(t){function e(r,n,s,a){i(this,e);var c=o(this,t.call(this));if((0,u.sayHello)(r),a)for(var d in f.default.RENDER_OPTIONS)void 0===a[d]&&(a[d]=f.default.RENDER_OPTIONS[d]);else a=f.default.RENDER_OPTIONS;return c.type=l.RENDERER_TYPE.UNKNOWN,c.screen=new h.Rectangle(0,0,n||800,s||600),c.view=a.view||document.createElement("canvas"),c.resolution=a.resolution||f.default.RESOLUTION,c.transparent=a.transparent,c.autoResize=a.autoResize||!1,c.blendModes=null,c.preserveDrawingBuffer=a.preserveDrawingBuffer,c.clearBeforeRender=a.clearBeforeRender,c.roundPixels=a.roundPixels,c._backgroundColor=0,c._backgroundColorRgba=[0,0,0,0],c._backgroundColorString="#000000",c.backgroundColor=a.backgroundColor||c._backgroundColor,c._tempDisplayObjectParent=new p.default,c._lastObjectRendered=c._tempDisplayObjectParent,c}return s(e,t),e.prototype.resize=function(t,e){this.screen.width=t,this.screen.height=e,this.view.width=t*this.resolution,this.view.height=e*this.resolution,this.autoResize&&(this.view.style.width=t+"px",this.view.style.height=e+"px")},e.prototype.generateTexture=function(t,e,r){var n=t.getLocalBounds(),i=y.default.create(0|n.width,0|n.height,e,r);return _.tx=-n.x,_.ty=-n.y,this.render(t,i,!1,_,!0),i},e.prototype.destroy=function(t){t&&this.view.parentNode&&this.view.parentNode.removeChild(this.view),this.type=l.RENDERER_TYPE.UNKNOWN,this.view=null,this.screen=null,this.resolution=0,this.transparent=!1,this.autoResize=!1,this.blendModes=null,this.preserveDrawingBuffer=!1,this.clearBeforeRender=!1,this.roundPixels=!1,this._backgroundColor=0,this._backgroundColorRgba=null,this._backgroundColorString=null,this.backgroundColor=0,this._tempDisplayObjectParent=null,this._lastObjectRendered=null},a(e,[{key:"width",get:function(){return this.view.width}},{key:"height",get:function(){return this.view.height}},{key:"backgroundColor",get:function(){return this._backgroundColor},set:function(t){this._backgroundColor=t,this._backgroundColorString=(0,u.hex2string)(t),(0,u.hex2rgb)(t,this._backgroundColorRgba)}}]),e}(m.default);r.default=b},{"../const":45,"../display/Container":47,"../math":69,"../settings":100,"../textures/RenderTexture":111,"../utils":121,eventemitter3:3}],76:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("../SystemRenderer"),u=n(a),h=t("./utils/CanvasMaskManager"),l=n(h),c=t("./utils/CanvasRenderTarget"),f=n(c),d=t("./utils/mapCanvasBlendModesToPixi"),p=n(d),v=t("../../utils"),y=t("../../const"),g=t("../../settings"),m=n(g),_=function(t){function e(r,n){var s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};i(this,e);var a=o(this,t.call(this,"Canvas",r,n,s));return a.type=y.RENDERER_TYPE.CANVAS,a.rootContext=a.view.getContext("2d",{alpha:a.transparent}),a.refresh=!0,a.maskManager=new l.default(a),a.smoothProperty="imageSmoothingEnabled",a.rootContext.imageSmoothingEnabled||(a.rootContext.webkitImageSmoothingEnabled?a.smoothProperty="webkitImageSmoothingEnabled":a.rootContext.mozImageSmoothingEnabled?a.smoothProperty="mozImageSmoothingEnabled":a.rootContext.oImageSmoothingEnabled?a.smoothProperty="oImageSmoothingEnabled":a.rootContext.msImageSmoothingEnabled&&(a.smoothProperty="msImageSmoothingEnabled")),a.initPlugins(),a.blendModes=(0,p.default)(),a._activeBlendMode=null,a.context=null,a.renderingToScreen=!1,a.resize(r,n),a}return s(e,t),e.prototype.render=function(t,e,r,n,i){if(this.view){this.renderingToScreen=!e,this.emit("prerender");var o=this.resolution;e?(e=e.baseTexture||e,e._canvasRenderTarget||(e._canvasRenderTarget=new f.default(e.width,e.height,e.resolution),e.source=e._canvasRenderTarget.canvas,e.valid=!0),this.context=e._canvasRenderTarget.context,this.resolution=e._canvasRenderTarget.resolution):this.context=this.rootContext;var s=this.context;if(e||(this._lastObjectRendered=t),!i){var a=t.parent,u=this._tempDisplayObjectParent.transform.worldTransform;n?(n.copy(u),this._tempDisplayObjectParent.transform._worldID=-1):u.identity(),t.parent=this._tempDisplayObjectParent,t.updateTransform(),t.parent=a}s.setTransform(1,0,0,1,0,0),s.globalAlpha=1,s.globalCompositeOperation=this.blendModes[y.BLEND_MODES.NORMAL],navigator.isCocoonJS&&this.view.screencanvas&&(s.fillStyle="black",s.clear()),(void 0!==r?r:this.clearBeforeRender)&&this.renderingToScreen&&(this.transparent?s.clearRect(0,0,this.width,this.height):(s.fillStyle=this._backgroundColorString,s.fillRect(0,0,this.width,this.height)));var h=this.context;this.context=s,t.renderCanvas(this),this.context=h,this.resolution=o,this.emit("postrender")}},e.prototype.clear=function(t){var e=this.context;t=t||this._backgroundColorString,!this.transparent&&t?(e.fillStyle=t,e.fillRect(0,0,this.width,this.height)):e.clearRect(0,0,this.width,this.height)},e.prototype.setBlendMode=function(t){this._activeBlendMode!==t&&(this._activeBlendMode=t,this.context.globalCompositeOperation=this.blendModes[t])},e.prototype.destroy=function(e){this.destroyPlugins(),t.prototype.destroy.call(this,e),this.context=null,this.refresh=!0,this.maskManager.destroy(),this.maskManager=null,this.smoothProperty=null},e.prototype.resize=function(e,r){t.prototype.resize.call(this,e,r),this.smoothProperty&&(this.rootContext[this.smoothProperty]=m.default.SCALE_MODE===y.SCALE_MODES.LINEAR)},e}(u.default);r.default=_,v.pluginTarget.mixin(_)},{"../../const":45,"../../settings":100,"../../utils":121,"../SystemRenderer":75,"./utils/CanvasMaskManager":77,"./utils/CanvasRenderTarget":78,"./utils/mapCanvasBlendModesToPixi":80}],77:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../../../const"),o=function(){function t(e){n(this,t),this.renderer=e}return t.prototype.pushMask=function(t){var e=this.renderer;e.context.save();var r=t.alpha,n=t.transform.worldTransform,i=e.resolution;e.context.setTransform(n.a*i,n.b*i,n.c*i,n.d*i,n.tx*i,n.ty*i),t._texture||(this.renderGraphicsShape(t),e.context.clip()),t.worldAlpha=r},t.prototype.renderGraphicsShape=function(t){var e=this.renderer.context,r=t.graphicsData.length;if(0!==r){e.beginPath();for(var n=0;n<r;n++){var o=t.graphicsData[n],s=o.shape;if(o.type===i.SHAPES.POLY){var a=s.points;e.moveTo(a[0],a[1]);for(var u=1;u<a.length/2;u++)e.lineTo(a[2*u],a[2*u+1]);a[0]===a[a.length-2]&&a[1]===a[a.length-1]&&e.closePath()}else if(o.type===i.SHAPES.RECT)e.rect(s.x,s.y,s.width,s.height),e.closePath();else if(o.type===i.SHAPES.CIRC)e.arc(s.x,s.y,s.radius,0,2*Math.PI),e.closePath();else if(o.type===i.SHAPES.ELIP){var h=2*s.width,l=2*s.height,c=s.x-h/2,f=s.y-l/2,d=h/2*.5522848,p=l/2*.5522848,v=c+h,y=f+l,g=c+h/2,m=f+l/2;e.moveTo(c,m),e.bezierCurveTo(c,m-p,g-d,f,g,f),e.bezierCurveTo(g+d,f,v,m-p,v,m),e.bezierCurveTo(v,m+p,g+d,y,g,y),e.bezierCurveTo(g-d,y,c,m+p,c,m),e.closePath()}else if(o.type===i.SHAPES.RREC){var _=s.x,b=s.y,x=s.width,T=s.height,w=s.radius,E=Math.min(x,T)/2|0;w=w>E?E:w,e.moveTo(_,b+w),e.lineTo(_,b+T-w),e.quadraticCurveTo(_,b+T,_+w,b+T),e.lineTo(_+x-w,b+T),e.quadraticCurveTo(_+x,b+T,_+x,b+T-w),e.lineTo(_+x,b+w),e.quadraticCurveTo(_+x,b,_+x-w,b),e.lineTo(_+w,b),e.quadraticCurveTo(_,b,_,b+w),e.closePath()}}}},t.prototype.popMask=function(t){t.context.restore()},t.prototype.destroy=function(){},t}();r.default=o},{"../../../const":45}],78:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),o=t("../../../settings"),s=function(t){return t&&t.__esModule?t:{default:t}}(o),a=function(){function t(e,r,i){n(this,t),this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),this.resolution=i||s.default.RESOLUTION,this.resize(e,r)}return t.prototype.clear=function(){this.context.setTransform(1,0,0,1,0,0),this.context.clearRect(0,0,this.canvas.width,this.canvas.height)},t.prototype.resize=function(t,e){this.canvas.width=t*this.resolution,this.canvas.height=e*this.resolution},t.prototype.destroy=function(){this.context=null,this.canvas=null},i(t,[{key:"width",get:function(){return this.canvas.width},set:function(t){this.canvas.width=t}},{key:"height",get:function(){return this.canvas.height},set:function(t){this.canvas.height=t}}]),t}();r.default=a},{"../../../settings":100}],79:[function(t,e,r){"use strict";function n(t){var e=document.createElement("canvas");e.width=6,e.height=1;var r=e.getContext("2d");return r.fillStyle=t,r.fillRect(0,0,6,1),e}function i(){if("undefined"==typeof document)return!1;var t=n("#ff00ff"),e=n("#ffff00"),r=document.createElement("canvas");r.width=6,r.height=1;var i=r.getContext("2d");i.globalCompositeOperation="multiply",i.drawImage(t,0,0),i.drawImage(e,2,0);var o=i.getImageData(2,0,1,1);if(!o)return!1;var s=o.data;return 255===s[0]&&0===s[1]&&0===s[2]}r.__esModule=!0,r.default=i},{}],80:[function(t,e,r){"use strict";function n(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return(0,s.default)()?(t[i.BLEND_MODES.NORMAL]="source-over",t[i.BLEND_MODES.ADD]="lighter",t[i.BLEND_MODES.MULTIPLY]="multiply",t[i.BLEND_MODES.SCREEN]="screen",t[i.BLEND_MODES.OVERLAY]="overlay",t[i.BLEND_MODES.DARKEN]="darken",t[i.BLEND_MODES.LIGHTEN]="lighten",t[i.BLEND_MODES.COLOR_DODGE]="color-dodge",t[i.BLEND_MODES.COLOR_BURN]="color-burn",t[i.BLEND_MODES.HARD_LIGHT]="hard-light",t[i.BLEND_MODES.SOFT_LIGHT]="soft-light",t[i.BLEND_MODES.DIFFERENCE]="difference",t[i.BLEND_MODES.EXCLUSION]="exclusion",t[i.BLEND_MODES.HUE]="hue",t[i.BLEND_MODES.SATURATION]="saturate",t[i.BLEND_MODES.COLOR]="color",t[i.BLEND_MODES.LUMINOSITY]="luminosity"):(t[i.BLEND_MODES.NORMAL]="source-over",t[i.BLEND_MODES.ADD]="lighter",t[i.BLEND_MODES.MULTIPLY]="source-over",t[i.BLEND_MODES.SCREEN]="source-over",t[i.BLEND_MODES.OVERLAY]="source-over",t[i.BLEND_MODES.DARKEN]="source-over",t[i.BLEND_MODES.LIGHTEN]="source-over",t[i.BLEND_MODES.COLOR_DODGE]="source-over",t[i.BLEND_MODES.COLOR_BURN]="source-over",t[i.BLEND_MODES.HARD_LIGHT]="source-over",t[i.BLEND_MODES.SOFT_LIGHT]="source-over",t[i.BLEND_MODES.DIFFERENCE]="source-over",t[i.BLEND_MODES.EXCLUSION]="source-over",t[i.BLEND_MODES.HUE]="source-over",t[i.BLEND_MODES.SATURATION]="source-over",t[i.BLEND_MODES.COLOR]="source-over",t[i.BLEND_MODES.LUMINOSITY]="source-over"),t}r.__esModule=!0,r.default=n
+;var i=t("../../../const"),o=t("./canUseNewCanvasBlendModes"),s=function(t){return t&&t.__esModule?t:{default:t}}(o)},{"../../../const":45,"./canUseNewCanvasBlendModes":79}],81:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../../const"),o=t("../../settings"),s=function(t){return t&&t.__esModule?t:{default:t}}(o),a=function(){function t(e){n(this,t),this.renderer=e,this.count=0,this.checkCount=0,this.maxIdle=s.default.GC_MAX_IDLE,this.checkCountMax=s.default.GC_MAX_CHECK_COUNT,this.mode=s.default.GC_MODE}return t.prototype.update=function(){this.count++,this.mode!==i.GC_MODES.MANUAL&&++this.checkCount>this.checkCountMax&&(this.checkCount=0,this.run())},t.prototype.run=function(){for(var t=this.renderer.textureManager,e=t._managedTextures,r=!1,n=0;n<e.length;n++){var i=e[n];!i._glRenderTargets&&this.count-i.touched>this.maxIdle&&(t.destroyTexture(i,!0),e[n]=null,r=!0)}if(r){for(var o=0,s=0;s<e.length;s++)null!==e[s]&&(e[o++]=e[s]);e.length=o}},t.prototype.unload=function(t){var e=this.renderer.textureManager;t._texture&&t._texture._glRenderTargets&&e.destroyTexture(t._texture,!0);for(var r=t.children.length-1;r>=0;r--)this.unload(t.children[r])},t}();r.default=a},{"../../const":45,"../../settings":100}],82:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("pixi-gl-core"),o=t("../../const"),s=t("./utils/RenderTarget"),a=function(t){return t&&t.__esModule?t:{default:t}}(s),u=t("../../utils"),h=function(){function t(e){n(this,t),this.renderer=e,this.gl=e.gl,this._managedTextures=[]}return t.prototype.bindTexture=function(){},t.prototype.getTexture=function(){},t.prototype.updateTexture=function(t,e){var r=this.gl,n=!!t._glRenderTargets;if(!t.hasLoaded)return null;var s=this.renderer.boundTextures;if(void 0===e){e=0;for(var u=0;u<s.length;++u)if(s[u]===t){e=u;break}}s[e]=t,r.activeTexture(r.TEXTURE0+e);var h=t._glTextures[this.renderer.CONTEXT_UID];if(h)n?t._glRenderTargets[this.renderer.CONTEXT_UID].resize(t.width,t.height):h.upload(t.source);else{if(n){var l=new a.default(this.gl,t.width,t.height,t.scaleMode,t.resolution);l.resize(t.width,t.height),t._glRenderTargets[this.renderer.CONTEXT_UID]=l,h=l.texture}else h=new i.GLTexture(this.gl,null,null,null,null),h.bind(e),h.premultiplyAlpha=!0,h.upload(t.source);t._glTextures[this.renderer.CONTEXT_UID]=h,t.on("update",this.updateTexture,this),t.on("dispose",this.destroyTexture,this),this._managedTextures.push(t),t.isPowerOfTwo?(t.mipmap&&h.enableMipmap(),t.wrapMode===o.WRAP_MODES.CLAMP?h.enableWrapClamp():t.wrapMode===o.WRAP_MODES.REPEAT?h.enableWrapRepeat():h.enableWrapMirrorRepeat()):h.enableWrapClamp(),t.scaleMode===o.SCALE_MODES.NEAREST?h.enableNearestScaling():h.enableLinearScaling()}return h},t.prototype.destroyTexture=function(t,e){if(t=t.baseTexture||t,t.hasLoaded&&t._glTextures[this.renderer.CONTEXT_UID]&&(this.renderer.unbindTexture(t),t._glTextures[this.renderer.CONTEXT_UID].destroy(),t.off("update",this.updateTexture,this),t.off("dispose",this.destroyTexture,this),delete t._glTextures[this.renderer.CONTEXT_UID],!e)){var r=this._managedTextures.indexOf(t);r!==-1&&(0,u.removeItems)(this._managedTextures,r,1)}},t.prototype.removeAll=function(){for(var t=0;t<this._managedTextures.length;++t){var e=this._managedTextures[t];e._glTextures[this.renderer.CONTEXT_UID]&&delete e._glTextures[this.renderer.CONTEXT_UID]}},t.prototype.destroy=function(){for(var t=0;t<this._managedTextures.length;++t){var e=this._managedTextures[t];this.destroyTexture(e,!0),e.off("update",this.updateTexture,this),e.off("dispose",this.destroyTexture,this)}this._managedTextures=null},t}();r.default=h},{"../../const":45,"../../utils":121,"./utils/RenderTarget":95,"pixi-gl-core":12}],83:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("../SystemRenderer"),u=n(a),h=t("./managers/MaskManager"),l=n(h),c=t("./managers/StencilManager"),f=n(c),d=t("./managers/FilterManager"),p=n(d),v=t("./utils/RenderTarget"),y=n(v),g=t("./utils/ObjectRenderer"),m=n(g),_=t("./TextureManager"),b=n(_),x=t("../../textures/BaseTexture"),T=n(x),w=t("./TextureGarbageCollector"),E=n(w),S=t("./WebGLState"),O=n(S),M=t("./utils/mapWebGLDrawModesToPixi"),P=n(M),C=t("./utils/validateContext"),R=n(C),A=t("../../utils"),D=t("pixi-gl-core"),I=n(D),L=t("../../const"),N=0,j=function(t){function e(r,n){var s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};i(this,e);var a=o(this,t.call(this,"WebGL",r,n,s));return a.legacy=!!s.legacy,a.legacy&&(I.default.VertexArrayObject.FORCE_NATIVE=!0),a.type=L.RENDERER_TYPE.WEBGL,a.handleContextLost=a.handleContextLost.bind(a),a.handleContextRestored=a.handleContextRestored.bind(a),a.view.addEventListener("webglcontextlost",a.handleContextLost,!1),a.view.addEventListener("webglcontextrestored",a.handleContextRestored,!1),a._contextOptions={alpha:a.transparent,antialias:s.antialias,premultipliedAlpha:a.transparent&&"notMultiplied"!==a.transparent,stencil:!0,preserveDrawingBuffer:s.preserveDrawingBuffer},a._backgroundColorRgba[3]=a.transparent?0:1,a.maskManager=new l.default(a),a.stencilManager=new f.default(a),a.emptyRenderer=new m.default(a),a.currentRenderer=a.emptyRenderer,a.initPlugins(),s.context&&(0,R.default)(s.context),a.gl=s.context||I.default.createContext(a.view,a._contextOptions),a.CONTEXT_UID=N++,a.state=new O.default(a.gl),a.renderingToScreen=!0,a.boundTextures=null,a._activeShader=null,a._activeVao=null,a._activeRenderTarget=null,a._initContext(),a.filterManager=new p.default(a),a.drawModes=(0,P.default)(a.gl),a._nextTextureLocation=0,a.setBlendMode(0),a}return s(e,t),e.prototype._initContext=function(){var t=this.gl;t.isContextLost()&&t.getExtension("WEBGL_lose_context")&&t.getExtension("WEBGL_lose_context").restoreContext();var e=t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS);this.boundTextures=new Array(e),this.emptyTextures=new Array(e),this.textureManager=new b.default(this),this.textureGC=new E.default(this),this.state.resetToDefault(),this.rootRenderTarget=new y.default(t,this.width,this.height,null,this.resolution,!0),this.rootRenderTarget.clearColor=this._backgroundColorRgba,this.bindRenderTarget(this.rootRenderTarget);var r=new I.default.GLTexture.fromData(t,null,1,1),n={_glTextures:{}};n._glTextures[this.CONTEXT_UID]={};for(var i=0;i<e;i++){var o=new T.default;o._glTextures[this.CONTEXT_UID]=r,this.boundTextures[i]=n,this.emptyTextures[i]=o,this.bindTexture(null,i)}this.emit("context",t),this.resize(this.screen.width,this.screen.height)},e.prototype.render=function(t,e,r,n,i){if(this.renderingToScreen=!e,this.emit("prerender"),this.gl&&!this.gl.isContextLost()){if(this._nextTextureLocation=0,e||(this._lastObjectRendered=t),!i){var o=t.parent;t.parent=this._tempDisplayObjectParent,t.updateTransform(),t.parent=o}this.bindRenderTexture(e,n),this.currentRenderer.start(),(void 0!==r?r:this.clearBeforeRender)&&this._activeRenderTarget.clear(),t.renderWebGL(this),this.currentRenderer.flush(),this.textureGC.update(),this.emit("postrender")}},e.prototype.setObjectRenderer=function(t){this.currentRenderer!==t&&(this.currentRenderer.stop(),this.currentRenderer=t,this.currentRenderer.start())},e.prototype.flush=function(){this.setObjectRenderer(this.emptyRenderer)},e.prototype.resize=function(t,e){u.default.prototype.resize.call(this,t,e),this.rootRenderTarget.resize(t,e),this._activeRenderTarget===this.rootRenderTarget&&(this.rootRenderTarget.activate(),this._activeShader&&(this._activeShader.uniforms.projectionMatrix=this.rootRenderTarget.projectionMatrix.toArray(!0)))},e.prototype.setBlendMode=function(t){this.state.setBlendMode(t)},e.prototype.clear=function(t){this._activeRenderTarget.clear(t)},e.prototype.setTransform=function(t){this._activeRenderTarget.transform=t},e.prototype.clearRenderTexture=function(t,e){var r=t.baseTexture,n=r._glRenderTargets[this.CONTEXT_UID];return n&&n.clear(e),this},e.prototype.bindRenderTexture=function(t,e){var r=void 0;if(t){var n=t.baseTexture;n._glRenderTargets[this.CONTEXT_UID]||this.textureManager.updateTexture(n,0),this.unbindTexture(n),r=n._glRenderTargets[this.CONTEXT_UID],r.setFrame(t.frame)}else r=this.rootRenderTarget;return r.transform=e,this.bindRenderTarget(r),this},e.prototype.bindRenderTarget=function(t){return t!==this._activeRenderTarget&&(this._activeRenderTarget=t,t.activate(),this._activeShader&&(this._activeShader.uniforms.projectionMatrix=t.projectionMatrix.toArray(!0)),this.stencilManager.setMaskStack(t.stencilMaskStack)),this},e.prototype.bindShader=function(t,e){return this._activeShader!==t&&(this._activeShader=t,t.bind(),e!==!1&&(t.uniforms.projectionMatrix=this._activeRenderTarget.projectionMatrix.toArray(!0))),this},e.prototype.bindTexture=function(t,e,r){if(t=t||this.emptyTextures[e],t=t.baseTexture||t,t.touched=this.textureGC.count,r)e=e||0;else{for(var n=0;n<this.boundTextures.length;n++)if(this.boundTextures[n]===t)return n;void 0===e&&(this._nextTextureLocation++,this._nextTextureLocation%=this.boundTextures.length,e=this.boundTextures.length-this._nextTextureLocation-1)}var i=this.gl,o=t._glTextures[this.CONTEXT_UID];return o?(this.boundTextures[e]=t,i.activeTexture(i.TEXTURE0+e),i.bindTexture(i.TEXTURE_2D,o.texture)):this.textureManager.updateTexture(t,e),e},e.prototype.unbindTexture=function(t){var e=this.gl;t=t.baseTexture||t;for(var r=0;r<this.boundTextures.length;r++)this.boundTextures[r]===t&&(this.boundTextures[r]=this.emptyTextures[r],e.activeTexture(e.TEXTURE0+r),e.bindTexture(e.TEXTURE_2D,this.emptyTextures[r]._glTextures[this.CONTEXT_UID].texture));return this},e.prototype.createVao=function(){return new I.default.VertexArrayObject(this.gl,this.state.attribState)},e.prototype.bindVao=function(t){return this._activeVao===t?this:(t?t.bind():this._activeVao&&this._activeVao.unbind(),this._activeVao=t,this)},e.prototype.reset=function(){return this.setObjectRenderer(this.emptyRenderer),this._activeShader=null,this._activeRenderTarget=this.rootRenderTarget,this.rootRenderTarget.activate(),this.state.resetToDefault(),this},e.prototype.handleContextLost=function(t){t.preventDefault()},e.prototype.handleContextRestored=function(){this._initContext(),this.textureManager.removeAll()},e.prototype.destroy=function(e){this.destroyPlugins(),this.view.removeEventListener("webglcontextlost",this.handleContextLost),this.view.removeEventListener("webglcontextrestored",this.handleContextRestored),this.textureManager.destroy(),t.prototype.destroy.call(this,e),this.uid=0,this.maskManager.destroy(),this.stencilManager.destroy(),this.filterManager.destroy(),this.maskManager=null,this.filterManager=null,this.textureManager=null,this.currentRenderer=null,this.handleContextLost=null,this.handleContextRestored=null,this._contextOptions=null,this.gl.useProgram(null),this.gl.getExtension("WEBGL_lose_context")&&this.gl.getExtension("WEBGL_lose_context").loseContext(),this.gl=null},e}(u.default);r.default=j,A.pluginTarget.mixin(j)},{"../../const":45,"../../textures/BaseTexture":110,"../../utils":121,"../SystemRenderer":75,"./TextureGarbageCollector":81,"./TextureManager":82,"./WebGLState":84,"./managers/FilterManager":89,"./managers/MaskManager":90,"./managers/StencilManager":91,"./utils/ObjectRenderer":93,"./utils/RenderTarget":95,"./utils/mapWebGLDrawModesToPixi":98,"./utils/validateContext":99,"pixi-gl-core":12}],84:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("./utils/mapWebGLBlendModesToPixi"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=function(){function t(e){n(this,t),this.activeState=new Uint8Array(16),this.defaultState=new Uint8Array(16),this.defaultState[0]=1,this.stackIndex=0,this.stack=[],this.gl=e,this.maxAttribs=e.getParameter(e.MAX_VERTEX_ATTRIBS),this.attribState={tempAttribState:new Array(this.maxAttribs),attribState:new Array(this.maxAttribs)},this.blendModes=(0,o.default)(e),this.nativeVaoExtension=e.getExtension("OES_vertex_array_object")||e.getExtension("MOZ_OES_vertex_array_object")||e.getExtension("WEBKIT_OES_vertex_array_object")}return t.prototype.push=function(){var t=this.stack[this.stackIndex];t||(t=this.stack[this.stackIndex]=new Uint8Array(16)),++this.stackIndex;for(var e=0;e<this.activeState.length;e++)t[e]=this.activeState[e]},t.prototype.pop=function(){var t=this.stack[--this.stackIndex];this.setState(t)},t.prototype.setState=function(t){this.setBlend(t[0]),this.setDepthTest(t[1]),this.setFrontFace(t[2]),this.setCullFace(t[3]),this.setBlendMode(t[4])},t.prototype.setBlend=function(t){t=t?1:0,this.activeState[0]!==t&&(this.activeState[0]=t,this.gl[t?"enable":"disable"](this.gl.BLEND))},t.prototype.setBlendMode=function(t){t!==this.activeState[4]&&(this.activeState[4]=t,this.gl.blendFunc(this.blendModes[t][0],this.blendModes[t][1]))},t.prototype.setDepthTest=function(t){t=t?1:0,this.activeState[1]!==t&&(this.activeState[1]=t,this.gl[t?"enable":"disable"](this.gl.DEPTH_TEST))},t.prototype.setCullFace=function(t){t=t?1:0,this.activeState[3]!==t&&(this.activeState[3]=t,this.gl[t?"enable":"disable"](this.gl.CULL_FACE))},t.prototype.setFrontFace=function(t){t=t?1:0,this.activeState[2]!==t&&(this.activeState[2]=t,this.gl.frontFace(this.gl[t?"CW":"CCW"]))},t.prototype.resetAttributes=function(){for(var t=0;t<this.attribState.tempAttribState.length;t++)this.attribState.tempAttribState[t]=0;for(var e=0;e<this.attribState.attribState.length;e++)this.attribState.attribState[e]=0;for(var r=1;r<this.maxAttribs;r++)this.gl.disableVertexAttribArray(r)},t.prototype.resetToDefault=function(){this.nativeVaoExtension&&this.nativeVaoExtension.bindVertexArrayOES(null),this.resetAttributes();for(var t=0;t<this.activeState.length;++t)this.activeState[t]=32;this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,!1),this.setState(this.defaultState)},t}();r.default=s},{"./utils/mapWebGLBlendModesToPixi":97}],85:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var o=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),s=t("./extractUniformsFromSrc"),a=n(s),u=t("../../../utils"),h=t("../../../const"),l=t("../../../settings"),c=n(l),f={},d=function(){function t(e,r,n){i(this,t),this.vertexSrc=e||t.defaultVertexSrc,this.fragmentSrc=r||t.defaultFragmentSrc,this.blendMode=h.BLEND_MODES.NORMAL,this.uniformData=n||(0,a.default)(this.vertexSrc,this.fragmentSrc,"projectionMatrix|uSampler"),this.uniforms={};for(var o in this.uniformData)this.uniforms[o]=this.uniformData[o].value;this.glShaders={},f[this.vertexSrc+this.fragmentSrc]||(f[this.vertexSrc+this.fragmentSrc]=(0,u.uid)()),this.glShaderKey=f[this.vertexSrc+this.fragmentSrc],this.padding=4,this.resolution=c.default.RESOLUTION,this.enabled=!0}return t.prototype.apply=function(t,e,r,n,i){t.applyFilter(this,e,r,n)},o(t,null,[{key:"defaultVertexSrc",get:function(){return["attribute vec2 aVertexPosition;","attribute vec2 aTextureCoord;","uniform mat3 projectionMatrix;","uniform mat3 filterMatrix;","varying vec2 vTextureCoord;","varying vec2 vFilterCoord;","void main(void){","   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);","   vFilterCoord = ( filterMatrix * vec3( aTextureCoord, 1.0)  ).xy;","   vTextureCoord = aTextureCoord ;","}"].join("\n")}},{key:"defaultFragmentSrc",get:function(){return["varying vec2 vTextureCoord;","varying vec2 vFilterCoord;","uniform sampler2D uSampler;","uniform sampler2D filterSampler;","void main(void){","   vec4 masky = texture2D(filterSampler, vFilterCoord);","   vec4 sample = texture2D(uSampler, vTextureCoord);","   vec4 color;","   if(mod(vFilterCoord.x, 1.0) > 0.5)","   {","     color = vec4(1.0, 0.0, 0.0, 1.0);","   }","   else","   {","     color = vec4(0.0, 1.0, 0.0, 1.0);","   }","   gl_FragColor = mix(sample, masky, 0.5);","   gl_FragColor *= sample.a;","}"].join("\n")}}]),t}();r.default=d},{"../../../const":45,"../../../settings":100,"../../../utils":121,"./extractUniformsFromSrc":86}],86:[function(t,e,r){"use strict";function n(t,e,r){var n=i(t),o=i(e);return Object.assign(n,o)}function i(t){for(var e=new RegExp("^(projectionMatrix|uSampler|filterArea|filterClamp)$"),r={},n=void 0,i=t.replace(/\s+/g," ").split(/\s*;\s*/),o=0;o<i.length;o++){var s=i[o].trim();if(s.indexOf("uniform")>-1){var u=s.split(" "),h=u[1],l=u[2],c=1;l.indexOf("[")>-1&&(n=l.split(/\[|]/),l=n[0],c*=Number(n[1])),l.match(e)||(r[l]={value:a(h,c),name:l,type:h})}}return r}r.__esModule=!0,r.default=n;var o=t("pixi-gl-core"),s=function(t){return t&&t.__esModule?t:{default:t}}(o),a=s.default.shader.defaultValue},{"pixi-gl-core":12}],87:[function(t,e,r){"use strict";function n(t,e,r){var n=t.identity();return n.translate(e.x/r.width,e.y/r.height),n.scale(r.width,r.height),n}function i(t,e,r){var n=t.identity();n.translate(e.x/r.width,e.y/r.height);var i=r.width/e.width,o=r.height/e.height;return n.scale(i,o),n}function o(t,e,r,n){var i=n.worldTransform.copy(s.Matrix.TEMP_MATRIX),o=n._texture.baseTexture,a=t.identity(),u=r.height/r.width;a.translate(e.x/r.width,e.y/r.height),a.scale(1,u);var h=r.width/o.width,l=r.height/o.height;return i.tx/=o.width*h,i.ty/=o.width*h,i.invert(),a.prepend(i),a.scale(1,1/u),a.scale(h,l),a.translate(n.anchor.x,n.anchor.y),a}r.__esModule=!0,r.calculateScreenSpaceMatrix=n,r.calculateNormalizedScreenSpaceMatrix=i,r.calculateSpriteMatrix=o;var s=t("../../../math")},{"../../../math":69}],88:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=t("../Filter"),a=function(t){return t&&t.__esModule?t:{default:t}}(s),u=t("../../../../math"),h=(t("path"),function(t){function e(r){n(this,e);var o=new u.Matrix,s=i(this,t.call(this,"attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\nuniform mat3 otherMatrix;\n\nvarying vec2 vMaskCoord;\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n\n    vTextureCoord = aTextureCoord;\n    vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0)  ).xy;\n}\n","varying vec2 vMaskCoord;\nvarying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\nuniform float alpha;\nuniform sampler2D mask;\n\nvoid main(void)\n{\n    // check clip! this will stop the mask bleeding out from the edges\n    vec2 text = abs( vMaskCoord - 0.5 );\n    text = step(0.5, text);\n\n    float clip = 1.0 - max(text.y, text.x);\n    vec4 original = texture2D(uSampler, vTextureCoord);\n    vec4 masky = texture2D(mask, vMaskCoord);\n\n    original *= (masky.r * masky.a * alpha * clip);\n\n    gl_FragColor = original;\n}\n"));return r.renderable=!1,s.maskSprite=r,s.maskMatrix=o,s}return o(e,t),e.prototype.apply=function(t,e,r){var n=this.maskSprite;this.uniforms.mask=n._texture,this.uniforms.otherMatrix=t.calculateSpriteMatrix(this.maskMatrix,n),this.uniforms.alpha=n.worldAlpha,t.applyFilter(this,e,r)},e}(a.default));r.default=h},{"../../../../math":69,"../Filter":85,path:23}],89:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function s(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var a=t("./WebGLManager"),u=n(a),h=t("../utils/RenderTarget"),l=n(h),c=t("../utils/Quad"),f=n(c),d=t("../../../math"),p=t("../../../Shader"),v=n(p),y=t("../filters/filterTransforms"),g=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(y),m=t("bit-twiddle"),_=n(m),b=function t(){s(this,t),this.renderTarget=null,this.sourceFrame=new d.Rectangle,this.destinationFrame=new d.Rectangle,this.filters=[],this.target=null,this.resolution=1},x=function(t){function e(r){s(this,e);var n=i(this,t.call(this,r));return n.gl=n.renderer.gl,n.quad=new f.default(n.gl,r.state.attribState),n.shaderCache={},n.pool={},n.filterData=null,n}return o(e,t),e.prototype.pushFilter=function(t,e){var r=this.renderer,n=this.filterData;if(!n){n=this.renderer._activeRenderTarget.filterStack;var i=new b;i.sourceFrame=i.destinationFrame=this.renderer._activeRenderTarget.size,i.renderTarget=r._activeRenderTarget,this.renderer._activeRenderTarget.filterData=n={index:0,stack:[i]},this.filterData=n}var o=n.stack[++n.index];o||(o=n.stack[n.index]=new b);var s=e[0].resolution,a=0|e[0].padding,u=t.filterArea||t.getBounds(!0),h=o.sourceFrame,l=o.destinationFrame;h.x=(u.x*s|0)/s,h.y=(u.y*s|0)/s,h.width=(u.width*s|0)/s,h.height=(u.height*s|0)/s,n.stack[0].renderTarget.transform||h.fit(n.stack[0].destinationFrame),h.pad(a),l.width=h.width,l.height=h.height;var c=this.getPotRenderTarget(r.gl,h.width,h.height,s);o.target=t,o.filters=e,o.resolution=s,o.renderTarget=c,c.setFrame(l,h),r.bindRenderTarget(c),c.clear()},e.prototype.popFilter=function(){var t=this.filterData,e=t.stack[t.index-1],r=t.stack[t.index];this.quad.map(r.renderTarget.size,r.sourceFrame).upload();var n=r.filters;if(1===n.length)n[0].apply(this,r.renderTarget,e.renderTarget,!1,r),this.freePotRenderTarget(r.renderTarget);else{var i=r.renderTarget,o=this.getPotRenderTarget(this.renderer.gl,r.sourceFrame.width,r.sourceFrame.height,r.resolution);o.setFrame(r.destinationFrame,r.sourceFrame),o.clear();var s=0;for(s=0;s<n.length-1;++s){n[s].apply(this,i,o,!0,r);var a=i;i=o,o=a}n[s].apply(this,i,e.renderTarget,!1,r),this.freePotRenderTarget(i),this.freePotRenderTarget(o)}0===--t.index&&(this.filterData=null)},e.prototype.applyFilter=function(t,e,r,n){var i=this.renderer,o=i.gl,s=t.glShaders[i.CONTEXT_UID];s||(t.glShaderKey?(s=this.shaderCache[t.glShaderKey])||(s=new v.default(this.gl,t.vertexSrc,t.fragmentSrc),t.glShaders[i.CONTEXT_UID]=this.shaderCache[t.glShaderKey]=s):s=t.glShaders[i.CONTEXT_UID]=new v.default(this.gl,t.vertexSrc,t.fragmentSrc),i.bindVao(null),this.quad.initVao(s)),i.bindVao(this.quad.vao),i.bindRenderTarget(r),n&&(o.disable(o.SCISSOR_TEST),i.clear(),o.enable(o.SCISSOR_TEST)),r===i.maskManager.scissorRenderTarget&&i.maskManager.pushScissorMask(null,i.maskManager.scissorData),i.bindShader(s);var a=this.renderer.emptyTextures[0];this.renderer.boundTextures[0]=a,this.syncUniforms(s,t),i.state.setBlendMode(t.blendMode),o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,e.texture.texture),this.quad.vao.draw(this.renderer.gl.TRIANGLES,6,0),o.bindTexture(o.TEXTURE_2D,a._glTextures[this.renderer.CONTEXT_UID].texture)},e.prototype.syncUniforms=function(t,e){var r=e.uniformData,n=e.uniforms,i=1,o=void 0;if(t.uniforms.filterArea){o=this.filterData.stack[this.filterData.index];var s=t.uniforms.filterArea;s[0]=o.renderTarget.size.width,s[1]=o.renderTarget.size.height,s[2]=o.sourceFrame.x,s[3]=o.sourceFrame.y,t.uniforms.filterArea=s}if(t.uniforms.filterClamp){o=o||this.filterData.stack[this.filterData.index];var a=t.uniforms.filterClamp;a[0]=0,a[1]=0,a[2]=(o.sourceFrame.width-1)/o.renderTarget.size.width,a[3]=(o.sourceFrame.height-1)/o.renderTarget.size.height,t.uniforms.filterClamp=a}for(var u in r)if("sampler2D"===r[u].type&&0!==n[u]){if(n[u].baseTexture)t.uniforms[u]=this.renderer.bindTexture(n[u].baseTexture,i);else{t.uniforms[u]=i;var h=this.renderer.gl;this.renderer.boundTextures[i]=this.renderer.emptyTextures[i],h.activeTexture(h.TEXTURE0+i),n[u].texture.bind()}i++}else if("mat3"===r[u].type)void 0!==n[u].a?t.uniforms[u]=n[u].toArray(!0):t.uniforms[u]=n[u];else if("vec2"===r[u].type)if(void 0!==n[u].x){var l=t.uniforms[u]||new Float32Array(2);l[0]=n[u].x,l[1]=n[u].y,t.uniforms[u]=l}else t.uniforms[u]=n[u];else"float"===r[u].type?t.uniforms.data[u].value!==r[u]&&(t.uniforms[u]=n[u]):t.uniforms[u]=n[u]},e.prototype.getRenderTarget=function(t,e){var r=this.filterData.stack[this.filterData.index],n=this.getPotRenderTarget(this.renderer.gl,r.sourceFrame.width,r.sourceFrame.height,e||r.resolution);return n.setFrame(r.destinationFrame,r.sourceFrame),n},e.prototype.returnRenderTarget=function(t){this.freePotRenderTarget(t)},e.prototype.calculateScreenSpaceMatrix=function(t){var e=this.filterData.stack[this.filterData.index];return g.calculateScreenSpaceMatrix(t,e.sourceFrame,e.renderTarget.size)},e.prototype.calculateNormalizedScreenSpaceMatrix=function(t){var e=this.filterData.stack[this.filterData.index];return g.calculateNormalizedScreenSpaceMatrix(t,e.sourceFrame,e.renderTarget.size,e.destinationFrame)},e.prototype.calculateSpriteMatrix=function(t,e){var r=this.filterData.stack[this.filterData.index];return g.calculateSpriteMatrix(t,r.sourceFrame,r.renderTarget.size,e)},e.prototype.destroy=function(){this.shaderCache={},this.emptyPool()},e.prototype.getPotRenderTarget=function(t,e,r,n){e=_.default.nextPow2(e*n),r=_.default.nextPow2(r*n);var i=(65535&e)<<16|65535&r;this.pool[i]||(this.pool[i]=[]);var o=this.pool[i].pop();if(!o){var s=this.renderer.boundTextures[0];t.activeTexture(t.TEXTURE0),o=new l.default(t,e,r,null,1),t.bindTexture(t.TEXTURE_2D,s._glTextures[this.renderer.CONTEXT_UID].texture)}return o.resolution=n,o.defaultFrame.width=o.size.width=e/n,o.defaultFrame.height=o.size.height=r/n,o},e.prototype.emptyPool=function(){for(var t in this.pool){var e=this.pool[t];if(e)for(var r=0;r<e.length;r++)e[r].destroy(!0)}this.pool={}},e.prototype.freePotRenderTarget=function(t){var e=t.size.width*t.resolution,r=t.size.height*t.resolution,n=(65535&e)<<16|65535&r;this.pool[n].push(t)},e}(u.default);r.default=x},{"../../../Shader":43,"../../../math":69,"../filters/filterTransforms":87,"../utils/Quad":94,"../utils/RenderTarget":95,"./WebGLManager":92,"bit-twiddle":1}],90:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("./WebGLManager"),u=n(a),h=t("../filters/spriteMask/SpriteMaskFilter"),l=n(h),c=function(t){function e(r){i(this,e);var n=o(this,t.call(this,r));return n.scissor=!1,n.scissorData=null,n.scissorRenderTarget=null,n.enableScissor=!0,n.alphaMaskPool=[],n.alphaMaskIndex=0,n}return s(e,t),e.prototype.pushMask=function(t,e){if(e.texture)this.pushSpriteMask(t,e);else if(this.enableScissor&&!this.scissor&&this.renderer._activeRenderTarget.root&&!this.renderer.stencilManager.stencilMaskStack.length&&e.isFastRect()){var r=e.worldTransform,n=Math.atan2(r.b,r.a);n=Math.round(n*(180/Math.PI)),n%90?this.pushStencilMask(e):this.pushScissorMask(t,e)}else this.pushStencilMask(e)},e.prototype.popMask=function(t,e){e.texture?this.popSpriteMask(t,e):this.enableScissor&&!this.renderer.stencilManager.stencilMaskStack.length?this.popScissorMask(t,e):this.popStencilMask(t,e)},e.prototype.pushSpriteMask=function(t,e){var r=this.alphaMaskPool[this.alphaMaskIndex];r||(r=this.alphaMaskPool[this.alphaMaskIndex]=[new l.default(e)]),r[0].resolution=this.renderer.resolution,r[0].maskSprite=e,t.filterArea=e.getBounds(!0),this.renderer.filterManager.pushFilter(t,r),this.alphaMaskIndex++},e.prototype.popSpriteMask=function(){this.renderer.filterManager.popFilter(),this.alphaMaskIndex--},e.prototype.pushStencilMask=function(t){this.renderer.currentRenderer.stop(),this.renderer.stencilManager.pushStencil(t)},e.prototype.popStencilMask=function(){this.renderer.currentRenderer.stop(),this.renderer.stencilManager.popStencil()},e.prototype.pushScissorMask=function(t,e){e.renderable=!0;var r=this.renderer._activeRenderTarget,n=e.getBounds();n.fit(r.size),e.renderable=!1,this.renderer.gl.enable(this.renderer.gl.SCISSOR_TEST);var i=this.renderer.resolution;this.renderer.gl.scissor(n.x*i,(r.root?r.size.height-n.y-n.height:n.y)*i,n.width*i,n.height*i),this.scissorRenderTarget=r,this.scissorData=e,this.scissor=!0},e.prototype.popScissorMask=function(){this.scissorRenderTarget=null,this.scissorData=null,this.scissor=!1;var t=this.renderer.gl;t.disable(t.SCISSOR_TEST)},e}(u.default);r.default=c},{"../filters/spriteMask/SpriteMaskFilter":88,"./WebGLManager":92}],91:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=t("./WebGLManager"),a=function(t){return t&&t.__esModule?t:{default:t}}(s),u=function(t){function e(r){n(this,e);var o=i(this,t.call(this,r));return o.stencilMaskStack=null,o}return o(e,t),e.prototype.setMaskStack=function(t){this.stencilMaskStack=t;var e=this.renderer.gl;0===t.length?e.disable(e.STENCIL_TEST):e.enable(e.STENCIL_TEST)},e.prototype.pushStencil=function(t){this.renderer.setObjectRenderer(this.renderer.plugins.graphics),this.renderer._activeRenderTarget.attachStencilBuffer();var e=this.renderer.gl,r=this.stencilMaskStack;0===r.length&&(e.enable(e.STENCIL_TEST),e.clear(e.STENCIL_BUFFER_BIT),e.stencilFunc(e.ALWAYS,1,1)),r.push(t),e.colorMask(!1,!1,!1,!1),e.stencilOp(e.KEEP,e.KEEP,e.INCR),this.renderer.plugins.graphics.render(t),e.colorMask(!0,!0,!0,!0),e.stencilFunc(e.NOTEQUAL,0,r.length),e.stencilOp(e.KEEP,e.KEEP,e.KEEP)},e.prototype.popStencil=function(){this.renderer.setObjectRenderer(this.renderer.plugins.graphics);var t=this.renderer.gl,e=this.stencilMaskStack,r=e.pop();0===e.length?t.disable(t.STENCIL_TEST):(t.colorMask(!1,!1,!1,!1),
+t.stencilOp(t.KEEP,t.KEEP,t.DECR),this.renderer.plugins.graphics.render(r),t.colorMask(!0,!0,!0,!0),t.stencilFunc(t.NOTEQUAL,0,e.length),t.stencilOp(t.KEEP,t.KEEP,t.KEEP))},e.prototype.destroy=function(){a.default.prototype.destroy.call(this),this.stencilMaskStack.stencilStack=null},e}(a.default);r.default=u},{"./WebGLManager":92}],92:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(e){n(this,t),this.renderer=e,this.renderer.on("context",this.onContextChange,this)}return t.prototype.onContextChange=function(){},t.prototype.destroy=function(){this.renderer.off("context",this.onContextChange,this),this.renderer=null},t}();r.default=i},{}],93:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=t("../managers/WebGLManager"),a=function(t){return t&&t.__esModule?t:{default:t}}(s),u=function(t){function e(){return n(this,e),i(this,t.apply(this,arguments))}return o(e,t),e.prototype.start=function(){},e.prototype.stop=function(){this.flush()},e.prototype.flush=function(){},e.prototype.render=function(t){},e}(a.default);r.default=u},{"../managers/WebGLManager":92}],94:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var o=t("pixi-gl-core"),s=n(o),a=t("../../../utils/createIndicesForQuads"),u=n(a),h=function(){function t(e,r){i(this,t),this.gl=e,this.vertices=new Float32Array([-1,-1,1,-1,1,1,-1,1]),this.uvs=new Float32Array([0,0,1,0,1,1,0,1]),this.interleaved=new Float32Array(16);for(var n=0;n<4;n++)this.interleaved[4*n]=this.vertices[2*n],this.interleaved[4*n+1]=this.vertices[2*n+1],this.interleaved[4*n+2]=this.uvs[2*n],this.interleaved[4*n+3]=this.uvs[2*n+1];this.indices=(0,u.default)(1),this.vertexBuffer=s.default.GLBuffer.createVertexBuffer(e,this.interleaved,e.STATIC_DRAW),this.indexBuffer=s.default.GLBuffer.createIndexBuffer(e,this.indices,e.STATIC_DRAW),this.vao=new s.default.VertexArrayObject(e,r)}return t.prototype.initVao=function(t){this.vao.clear().addIndex(this.indexBuffer).addAttribute(this.vertexBuffer,t.attributes.aVertexPosition,this.gl.FLOAT,!1,16,0).addAttribute(this.vertexBuffer,t.attributes.aTextureCoord,this.gl.FLOAT,!1,16,8)},t.prototype.map=function(t,e){var r=0,n=0;return this.uvs[0]=r,this.uvs[1]=n,this.uvs[2]=r+e.width/t.width,this.uvs[3]=n,this.uvs[4]=r+e.width/t.width,this.uvs[5]=n+e.height/t.height,this.uvs[6]=r,this.uvs[7]=n+e.height/t.height,r=e.x,n=e.y,this.vertices[0]=r,this.vertices[1]=n,this.vertices[2]=r+e.width,this.vertices[3]=n,this.vertices[4]=r+e.width,this.vertices[5]=n+e.height,this.vertices[6]=r,this.vertices[7]=n+e.height,this},t.prototype.upload=function(){for(var t=0;t<4;t++)this.interleaved[4*t]=this.vertices[2*t],this.interleaved[4*t+1]=this.vertices[2*t+1],this.interleaved[4*t+2]=this.uvs[2*t],this.interleaved[4*t+3]=this.uvs[2*t+1];return this.vertexBuffer.upload(this.interleaved),this},t.prototype.destroy=function(){var t=this.gl;t.deleteBuffer(this.vertexBuffer),t.deleteBuffer(this.indexBuffer)},t}();r.default=h},{"../../../utils/createIndicesForQuads":119,"pixi-gl-core":12}],95:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../../../math"),o=t("../../../const"),s=t("../../../settings"),a=function(t){return t&&t.__esModule?t:{default:t}}(s),u=t("pixi-gl-core"),h=function(){function t(e,r,s,h,l,c){n(this,t),this.gl=e,this.frameBuffer=null,this.texture=null,this.clearColor=[0,0,0,0],this.size=new i.Rectangle(0,0,1,1),this.resolution=l||a.default.RESOLUTION,this.projectionMatrix=new i.Matrix,this.transform=null,this.frame=null,this.defaultFrame=new i.Rectangle,this.destinationFrame=null,this.sourceFrame=null,this.stencilBuffer=null,this.stencilMaskStack=[],this.filterData=null,this.scaleMode=void 0!==h?h:a.default.SCALE_MODE,this.root=c,this.root?(this.frameBuffer=new u.GLFramebuffer(e,100,100),this.frameBuffer.framebuffer=null):(this.frameBuffer=u.GLFramebuffer.createRGBA(e,100,100),this.scaleMode===o.SCALE_MODES.NEAREST?this.frameBuffer.texture.enableNearestScaling():this.frameBuffer.texture.enableLinearScaling(),this.texture=this.frameBuffer.texture),this.setFrame(),this.resize(r,s)}return t.prototype.clear=function(t){var e=t||this.clearColor;this.frameBuffer.clear(e[0],e[1],e[2],e[3])},t.prototype.attachStencilBuffer=function(){this.root||this.frameBuffer.enableStencil()},t.prototype.setFrame=function(t,e){this.destinationFrame=t||this.destinationFrame||this.defaultFrame,this.sourceFrame=e||this.sourceFrame||t},t.prototype.activate=function(){var t=this.gl;this.frameBuffer.bind(),this.calculateProjection(this.destinationFrame,this.sourceFrame),this.transform&&this.projectionMatrix.append(this.transform),this.destinationFrame!==this.sourceFrame?(t.enable(t.SCISSOR_TEST),t.scissor(0|this.destinationFrame.x,0|this.destinationFrame.y,this.destinationFrame.width*this.resolution|0,this.destinationFrame.height*this.resolution|0)):t.disable(t.SCISSOR_TEST),t.viewport(0|this.destinationFrame.x,0|this.destinationFrame.y,this.destinationFrame.width*this.resolution|0,this.destinationFrame.height*this.resolution|0)},t.prototype.calculateProjection=function(t,e){var r=this.projectionMatrix;e=e||t,r.identity(),this.root?(r.a=1/t.width*2,r.d=-1/t.height*2,r.tx=-1-e.x*r.a,r.ty=1-e.y*r.d):(r.a=1/t.width*2,r.d=1/t.height*2,r.tx=-1-e.x*r.a,r.ty=-1-e.y*r.d)},t.prototype.resize=function(t,e){if(t|=0,e|=0,this.size.width!==t||this.size.height!==e){this.size.width=t,this.size.height=e,this.defaultFrame.width=t,this.defaultFrame.height=e,this.frameBuffer.resize(t*this.resolution,e*this.resolution);var r=this.frame||this.size;this.calculateProjection(r)}},t.prototype.destroy=function(){this.frameBuffer.destroy(),this.frameBuffer=null,this.texture=null},t}();r.default=h},{"../../../const":45,"../../../math":69,"../../../settings":100,"pixi-gl-core":12}],96:[function(t,e,r){"use strict";function n(t,e){var r=!e;if(r){var n=document.createElement("canvas");n.width=1,n.height=1,e=s.default.createContext(n)}for(var o=e.createShader(e.FRAGMENT_SHADER);;){var u=a.replace(/%forloop%/gi,i(t));if(e.shaderSource(o,u),e.compileShader(o),e.getShaderParameter(o,e.COMPILE_STATUS))break;t=t/2|0}return r&&e.getExtension("WEBGL_lose_context")&&e.getExtension("WEBGL_lose_context").loseContext(),t}function i(t){for(var e="",r=0;r<t;++r)r>0&&(e+="\nelse "),r<t-1&&(e+="if(test == "+r+".0){}");return e}r.__esModule=!0,r.default=n;var o=t("pixi-gl-core"),s=function(t){return t&&t.__esModule?t:{default:t}}(o),a=["precision mediump float;","void main(void){","float test = 0.1;","%forloop%","gl_FragColor = vec4(0.0);","}"].join("\n")},{"pixi-gl-core":12}],97:[function(t,e,r){"use strict";function n(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];return e[i.BLEND_MODES.NORMAL]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.ADD]=[t.ONE,t.DST_ALPHA],e[i.BLEND_MODES.MULTIPLY]=[t.DST_COLOR,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.SCREEN]=[t.ONE,t.ONE_MINUS_SRC_COLOR],e[i.BLEND_MODES.OVERLAY]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.DARKEN]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.LIGHTEN]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.COLOR_DODGE]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.COLOR_BURN]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.HARD_LIGHT]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.SOFT_LIGHT]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.DIFFERENCE]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.EXCLUSION]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.HUE]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.SATURATION]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.COLOR]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e[i.BLEND_MODES.LUMINOSITY]=[t.ONE,t.ONE_MINUS_SRC_ALPHA],e}r.__esModule=!0,r.default=n;var i=t("../../../const")},{"../../../const":45}],98:[function(t,e,r){"use strict";function n(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e[i.DRAW_MODES.POINTS]=t.POINTS,e[i.DRAW_MODES.LINES]=t.LINES,e[i.DRAW_MODES.LINE_LOOP]=t.LINE_LOOP,e[i.DRAW_MODES.LINE_STRIP]=t.LINE_STRIP,e[i.DRAW_MODES.TRIANGLES]=t.TRIANGLES,e[i.DRAW_MODES.TRIANGLE_STRIP]=t.TRIANGLE_STRIP,e[i.DRAW_MODES.TRIANGLE_FAN]=t.TRIANGLE_FAN,e}r.__esModule=!0,r.default=n;var i=t("../../../const")},{"../../../const":45}],99:[function(t,e,r){"use strict";function n(t){t.getContextAttributes().stencil||console.warn("Provided WebGL context does not have a stencil buffer, masks may not render correctly")}r.__esModule=!0,r.default=n},{}],100:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0;var i=t("./utils/maxRecommendedTextures"),o=n(i),s=t("./utils/canUploadSameBuffer"),a=n(s);r.default={TARGET_FPMS:.06,MIPMAP_TEXTURES:!0,RESOLUTION:1,FILTER_RESOLUTION:1,SPRITE_MAX_TEXTURES:(0,o.default)(32),SPRITE_BATCH_SIZE:4096,RETINA_PREFIX:/@([0-9\.]+)x/,RENDER_OPTIONS:{view:null,antialias:!1,forceFXAA:!1,autoResize:!1,transparent:!1,backgroundColor:0,clearBeforeRender:!0,preserveDrawingBuffer:!1,roundPixels:!1},TRANSFORM_MODE:0,GC_MODE:0,GC_MAX_IDLE:3600,GC_MAX_CHECK_COUNT:600,WRAP_MODE:0,SCALE_MODE:0,PRECISION_VERTEX:"highp",PRECISION_FRAGMENT:"mediump",CAN_UPLOAD_SAME_BUFFER:(0,a.default)()}},{"./utils/canUploadSameBuffer":118,"./utils/maxRecommendedTextures":122}],101:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),u=t("../math"),h=t("../utils"),l=t("../const"),c=t("../textures/Texture"),f=n(c),d=t("../display/Container"),p=n(d),v=new u.Point,y=function(t){function e(r){i(this,e);var n=o(this,t.call(this));return n._anchor=new u.ObservablePoint(n._onAnchorUpdate,n),n._texture=null,n._width=0,n._height=0,n._tint=null,n._tintRGB=null,n.tint=16777215,n.blendMode=l.BLEND_MODES.NORMAL,n.shader=null,n.cachedTint=16777215,n.texture=r||f.default.EMPTY,n.vertexData=new Float32Array(8),n.vertexTrimmedData=null,n._transformID=-1,n._textureID=-1,n._transformTrimmedID=-1,n._textureTrimmedID=-1,n.pluginName="sprite",n}return s(e,t),e.prototype._onTextureUpdate=function(){this._textureID=-1,this._textureTrimmedID=-1,this._width&&(this.scale.x=(0,h.sign)(this.scale.x)*this._width/this.texture.orig.width),this._height&&(this.scale.y=(0,h.sign)(this.scale.y)*this._height/this.texture.orig.height)},e.prototype._onAnchorUpdate=function(){this._transformID=-1,this._transformTrimmedID=-1},e.prototype.calculateVertices=function(){if(this._transformID!==this.transform._worldID||this._textureID!==this._texture._updateID){this._transformID=this.transform._worldID,this._textureID=this._texture._updateID;var t=this._texture,e=this.transform.worldTransform,r=e.a,n=e.b,i=e.c,o=e.d,s=e.tx,a=e.ty,u=this.vertexData,h=t.trim,l=t.orig,c=this._anchor,f=0,d=0,p=0,v=0;h?(d=h.x-c._x*l.width,f=d+h.width,v=h.y-c._y*l.height,p=v+h.height):(d=-c._x*l.width,f=d+l.width,v=-c._y*l.height,p=v+l.height),u[0]=r*d+i*v+s,u[1]=o*v+n*d+a,u[2]=r*f+i*v+s,u[3]=o*v+n*f+a,u[4]=r*f+i*p+s,u[5]=o*p+n*f+a,u[6]=r*d+i*p+s,u[7]=o*p+n*d+a}},e.prototype.calculateTrimmedVertices=function(){if(this.vertexTrimmedData){if(this._transformTrimmedID===this.transform._worldID&&this._textureTrimmedID===this._texture._updateID)return}else this.vertexTrimmedData=new Float32Array(8);this._transformTrimmedID=this.transform._worldID,this._textureTrimmedID=this._texture._updateID;var t=this._texture,e=this.vertexTrimmedData,r=t.orig,n=this._anchor,i=this.transform.worldTransform,o=i.a,s=i.b,a=i.c,u=i.d,h=i.tx,l=i.ty,c=-n._x*r.width,f=c+r.width,d=-n._y*r.height,p=d+r.height;e[0]=o*c+a*d+h,e[1]=u*d+s*c+l,e[2]=o*f+a*d+h,e[3]=u*d+s*f+l,e[4]=o*f+a*p+h,e[5]=u*p+s*f+l,e[6]=o*c+a*p+h,e[7]=u*p+s*c+l},e.prototype._renderWebGL=function(t){this.calculateVertices(),t.setObjectRenderer(t.plugins[this.pluginName]),t.plugins[this.pluginName].render(this)},e.prototype._renderCanvas=function(t){t.plugins[this.pluginName].render(this)},e.prototype._calculateBounds=function(){var t=this._texture.trim,e=this._texture.orig;!t||t.width===e.width&&t.height===e.height?(this.calculateVertices(),this._bounds.addQuad(this.vertexData)):(this.calculateTrimmedVertices(),this._bounds.addQuad(this.vertexTrimmedData))},e.prototype.getLocalBounds=function(e){return 0===this.children.length?(this._bounds.minX=this._texture.orig.width*-this._anchor._x,this._bounds.minY=this._texture.orig.height*-this._anchor._y,this._bounds.maxX=this._texture.orig.width*(1-this._anchor._x),this._bounds.maxY=this._texture.orig.height*(1-this._anchor._x),e||(this._localBoundsRect||(this._localBoundsRect=new u.Rectangle),e=this._localBoundsRect),this._bounds.getRectangle(e)):t.prototype.getLocalBounds.call(this,e)},e.prototype.containsPoint=function(t){this.worldTransform.applyInverse(t,v);var e=this._texture.orig.width,r=this._texture.orig.height,n=-e*this.anchor.x,i=0;return v.x>n&&v.x<n+e&&(i=-r*this.anchor.y,v.y>i&&v.y<i+r)},e.prototype.destroy=function(e){if(t.prototype.destroy.call(this,e),this._anchor=null,"boolean"==typeof e?e:e&&e.texture){var r="boolean"==typeof e?e:e&&e.baseTexture;this._texture.destroy(!!r)}this._texture=null,this.shader=null},e.from=function(t){return new e(f.default.from(t))},e.fromFrame=function(t){var r=h.TextureCache[t];if(!r)throw new Error('The frameId "'+t+'" does not exist in the texture cache');return new e(r)},e.fromImage=function(t,r,n){return new e(f.default.fromImage(t,r,n))},a(e,[{key:"width",get:function(){return Math.abs(this.scale.x)*this._texture.orig.width},set:function(t){var e=(0,h.sign)(this.scale.x)||1;this.scale.x=e*t/this._texture.orig.width,this._width=t}},{key:"height",get:function(){return Math.abs(this.scale.y)*this._texture.orig.height},set:function(t){var e=(0,h.sign)(this.scale.y)||1;this.scale.y=e*t/this._texture.orig.height,this._height=t}},{key:"anchor",get:function(){return this._anchor},set:function(t){this._anchor.copy(t)}},{key:"tint",get:function(){return this._tint},set:function(t){this._tint=t,this._tintRGB=(t>>16)+(65280&t)+((255&t)<<16)}},{key:"texture",get:function(){return this._texture},set:function(t){this._texture!==t&&(this._texture=t,this.cachedTint=16777215,this._textureID=-1,this._textureTrimmedID=-1,t&&(t.baseTexture.hasLoaded?this._onTextureUpdate():t.once("update",this._onTextureUpdate,this)))}}]),e}(p.default);r.default=y},{"../const":45,"../display/Container":47,"../math":69,"../textures/Texture":113,"../utils":121}],102:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var o=t("../../renderers/canvas/CanvasRenderer"),s=n(o),a=t("../../const"),u=t("../../math"),h=t("./CanvasTinter"),l=n(h),c=new u.Matrix,f=function(){function t(e){i(this,t),this.renderer=e}return t.prototype.render=function(t){var e=t._texture,r=this.renderer,n=e._frame.width,i=e._frame.height,o=t.transform.worldTransform,s=0,h=0;if(!(e.orig.width<=0||e.orig.height<=0)&&e.baseTexture.source&&(r.setBlendMode(t.blendMode),e.valid)){r.context.globalAlpha=t.worldAlpha;var f=e.baseTexture.scaleMode===a.SCALE_MODES.LINEAR;r.smoothProperty&&r.context[r.smoothProperty]!==f&&(r.context[r.smoothProperty]=f),e.trim?(s=e.trim.width/2+e.trim.x-t.anchor.x*e.orig.width,h=e.trim.height/2+e.trim.y-t.anchor.y*e.orig.height):(s=(.5-t.anchor.x)*e.orig.width,h=(.5-t.anchor.y)*e.orig.height),e.rotate&&(o.copy(c),o=c,u.GroupD8.matrixAppendRotationInv(o,e.rotate,s,h),s=0,h=0),s-=n/2,h-=i/2,r.roundPixels?(r.context.setTransform(o.a,o.b,o.c,o.d,o.tx*r.resolution|0,o.ty*r.resolution|0),s|=0,h|=0):r.context.setTransform(o.a,o.b,o.c,o.d,o.tx*r.resolution,o.ty*r.resolution);var d=e.baseTexture.resolution;16777215!==t.tint?(t.cachedTint!==t.tint&&(t.cachedTint=t.tint,t.tintedTexture=l.default.getTintedTexture(t,t.tint)),r.context.drawImage(t.tintedTexture,0,0,n*d,i*d,s*r.resolution,h*r.resolution,n*r.resolution,i*r.resolution)):r.context.drawImage(e.baseTexture.source,e._frame.x*d,e._frame.y*d,n*d,i*d,s*r.resolution,h*r.resolution,n*r.resolution,i*r.resolution)}},t.prototype.destroy=function(){this.renderer=null},t}();r.default=f,s.default.registerPlugin("sprite",f)},{"../../const":45,"../../math":69,"../../renderers/canvas/CanvasRenderer":76,"./CanvasTinter":103}],103:[function(t,e,r){"use strict";r.__esModule=!0;var n=t("../../utils"),i=t("../../renderers/canvas/utils/canUseNewCanvasBlendModes"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s={getTintedTexture:function(t,e){var r=t.texture;e=s.roundColor(e);var n="#"+("00000"+(0|e).toString(16)).substr(-6);if(r.tintCache=r.tintCache||{},r.tintCache[n])return r.tintCache[n];var i=s.canvas||document.createElement("canvas");if(s.tintMethod(r,e,i),s.convertTintToImage){var o=new Image;o.src=i.toDataURL(),r.tintCache[n]=o}else r.tintCache[n]=i,s.canvas=null;return i},tintWithMultiply:function(t,e,r){var n=r.getContext("2d"),i=t._frame.clone(),o=t.baseTexture.resolution;i.x*=o,i.y*=o,i.width*=o,i.height*=o,r.width=Math.ceil(i.width),r.height=Math.ceil(i.height),n.fillStyle="#"+("00000"+(0|e).toString(16)).substr(-6),n.fillRect(0,0,i.width,i.height),n.globalCompositeOperation="multiply",n.drawImage(t.baseTexture.source,i.x,i.y,i.width,i.height,0,0,i.width,i.height),n.globalCompositeOperation="destination-atop",n.drawImage(t.baseTexture.source,i.x,i.y,i.width,i.height,0,0,i.width,i.height)},tintWithOverlay:function(t,e,r){var n=r.getContext("2d"),i=t._frame.clone(),o=t.baseTexture.resolution;i.x*=o,i.y*=o,i.width*=o,i.height*=o,r.width=Math.ceil(i.width),r.height=Math.ceil(i.height),n.globalCompositeOperation="copy",n.fillStyle="#"+("00000"+(0|e).toString(16)).substr(-6),n.fillRect(0,0,i.width,i.height),n.globalCompositeOperation="destination-atop",n.drawImage(t.baseTexture.source,i.x,i.y,i.width,i.height,0,0,i.width,i.height)},tintWithPerPixel:function(t,e,r){var i=r.getContext("2d"),o=t._frame.clone(),s=t.baseTexture.resolution;o.x*=s,o.y*=s,o.width*=s,o.height*=s,r.width=Math.ceil(o.width),r.height=Math.ceil(o.height),i.globalCompositeOperation="copy",i.drawImage(t.baseTexture.source,o.x,o.y,o.width,o.height,0,0,o.width,o.height);for(var a=(0,n.hex2rgb)(e),u=a[0],h=a[1],l=a[2],c=i.getImageData(0,0,o.width,o.height),f=c.data,d=0;d<f.length;d+=4)f[d+0]*=u,f[d+1]*=h,f[d+2]*=l;i.putImageData(c,0,0)},roundColor:function(t){var e=s.cacheStepsPerColorChannel,r=(0,n.hex2rgb)(t);return r[0]=Math.min(255,r[0]/e*e),r[1]=Math.min(255,r[1]/e*e),r[2]=Math.min(255,r[2]/e*e),(0,n.rgb2hex)(r)},cacheStepsPerColorChannel:8,convertTintToImage:!1,canUseMultiply:(0,o.default)(),tintMethod:0};s.tintMethod=s.canUseMultiply?s.tintWithMultiply:s.tintWithPerPixel,r.default=s},{"../../renderers/canvas/utils/canUseNewCanvasBlendModes":79,"../../utils":121}],104:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(e){n(this,t),this.vertices=new ArrayBuffer(e),this.float32View=new Float32Array(this.vertices),this.uint32View=new Uint32Array(this.vertices)}return t.prototype.destroy=function(){this.vertices=null,this.positions=null,this.uvs=null,this.colors=null},t}();r.default=i},{}],105:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("../../renderers/webgl/utils/ObjectRenderer"),u=n(a),h=t("../../renderers/webgl/WebGLRenderer"),l=n(h),c=t("../../utils/createIndicesForQuads"),f=n(c),d=t("./generateMultiTextureShader"),p=n(d),v=t("../../renderers/webgl/utils/checkMaxIfStatmentsInShader"),y=n(v),g=t("./BatchBuffer"),m=n(g),_=t("../../settings"),b=n(_),x=t("pixi-gl-core"),T=n(x),w=t("bit-twiddle"),E=n(w),S=0,O=0,M=function(t){function e(r){i(this,e);var n=o(this,t.call(this,r));n.vertSize=5,n.vertByteSize=4*n.vertSize,n.size=b.default.SPRITE_BATCH_SIZE,n.buffers=[];for(var s=1;s<=E.default.nextPow2(n.size);s*=2)n.buffers.push(new m.default(4*s*n.vertByteSize));n.indices=(0,f.default)(n.size),n.shader=null,n.currentIndex=0,n.groups=[];for(var a=0;a<n.size;a++)n.groups[a]={textures:[],textureCount:0,ids:[],size:0,start:0,blend:0};return n.sprites=[],n.vertexBuffers=[],n.vaos=[],n.vaoMax=2,n.vertexCount=0,n.renderer.on("prerender",n.onPrerender,n),n}return s(e,t),e.prototype.onContextChange=function(){var t=this.renderer.gl;this.renderer.legacy?this.MAX_TEXTURES=1:(this.MAX_TEXTURES=Math.min(t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS),b.default.SPRITE_MAX_TEXTURES),this.MAX_TEXTURES=(0,y.default)(this.MAX_TEXTURES,t));var e=this.shader=(0,p.default)(t,this.MAX_TEXTURES);this.indexBuffer=T.default.GLBuffer.createIndexBuffer(t,this.indices,t.STATIC_DRAW),this.renderer.bindVao(null);for(var r=0;r<this.vaoMax;r++)this.vertexBuffers[r]=T.default.GLBuffer.createVertexBuffer(t,null,t.STREAM_DRAW),this.vaos[r]=this.renderer.createVao().addIndex(this.indexBuffer).addAttribute(this.vertexBuffers[r],e.attributes.aVertexPosition,t.FLOAT,!1,this.vertByteSize,0).addAttribute(this.vertexBuffers[r],e.attributes.aTextureCoord,t.UNSIGNED_SHORT,!0,this.vertByteSize,8).addAttribute(this.vertexBuffers[r],e.attributes.aColor,t.UNSIGNED_BYTE,!0,this.vertByteSize,12),e.attributes.aTextureId&&this.vaos[r].addAttribute(this.vertexBuffers[r],e.attributes.aTextureId,t.FLOAT,!1,this.vertByteSize,16);this.vao=this.vaos[0],this.currentBlendMode=99999,this.boundTextures=new Array(this.MAX_TEXTURES)},e.prototype.onPrerender=function(){this.vertexCount=0},e.prototype.render=function(t){this.currentIndex>=this.size&&this.flush(),t._texture._uvs&&(this.sprites[this.currentIndex++]=t)},e.prototype.flush=function(){if(0!==this.currentIndex){var t=this.renderer.gl,e=this.MAX_TEXTURES,r=E.default.nextPow2(this.currentIndex),n=E.default.log2(r),i=this.buffers[n],o=this.sprites,s=this.groups,a=i.float32View,u=i.uint32View,h=this.boundTextures,l=this.renderer.boundTextures,c=this.renderer.textureGC.count,f=0,d=void 0,p=void 0,v=1,y=0,g=s[0],m=void 0,_=void 0,x=o[0].blendMode;g.textureCount=0,g.start=0,g.blend=x,S++;var w=void 0;for(w=0;w<e;++w)h[w]=l[w],h[w]._virtalBoundId=w;for(w=0;w<this.currentIndex;++w){var M=o[w];if(d=M._texture.baseTexture,x!==M.blendMode&&(x=M.blendMode,p=null,y=e,S++),p!==d&&(p=d,d._enabled!==S)){if(y===e&&(S++,g.size=w-g.start,y=0,g=s[v++],g.blend=x,g.textureCount=0,g.start=w),d.touched=c,d._virtalBoundId===-1)for(var P=0;P<e;++P){var C=(P+O)%e,R=h[C];if(R._enabled!==S){O++,R._virtalBoundId=-1,d._virtalBoundId=C,h[C]=d;break}}d._enabled=S,g.textureCount++,g.ids[y]=d._virtalBoundId,g.textures[y++]=d}if(m=M.vertexData,_=M._texture._uvs.uvsUint32,this.renderer.roundPixels){var A=this.renderer.resolution;a[f]=(m[0]*A|0)/A,a[f+1]=(m[1]*A|0)/A,a[f+5]=(m[2]*A|0)/A,a[f+6]=(m[3]*A|0)/A,a[f+10]=(m[4]*A|0)/A,a[f+11]=(m[5]*A|0)/A,a[f+15]=(m[6]*A|0)/A,a[f+16]=(m[7]*A|0)/A}else a[f]=m[0],a[f+1]=m[1],a[f+5]=m[2],a[f+6]=m[3],a[f+10]=m[4],a[f+11]=m[5],a[f+15]=m[6],a[f+16]=m[7];u[f+2]=_[0],u[f+7]=_[1],u[f+12]=_[2],u[f+17]=_[3],u[f+3]=u[f+8]=u[f+13]=u[f+18]=M._tintRGB+(255*Math.min(M.worldAlpha,1)<<24),a[f+4]=a[f+9]=a[f+14]=a[f+19]=d._virtalBoundId,f+=20}for(g.size=w-g.start,b.default.CAN_UPLOAD_SAME_BUFFER?this.vertexBuffers[this.vertexCount].upload(i.vertices,0,!0):(this.vaoMax<=this.vertexCount&&(this.vaoMax++,this.vertexBuffers[this.vertexCount]=T.default.GLBuffer.createVertexBuffer(t,null,t.STREAM_DRAW),this.vaos[this.vertexCount]=this.renderer.createVao().addIndex(this.indexBuffer).addAttribute(this.vertexBuffers[this.vertexCount],this.shader.attributes.aVertexPosition,t.FLOAT,!1,this.vertByteSize,0).addAttribute(this.vertexBuffers[this.vertexCount],this.shader.attributes.aTextureCoord,t.UNSIGNED_SHORT,!0,this.vertByteSize,8).addAttribute(this.vertexBuffers[this.vertexCount],this.shader.attributes.aColor,t.UNSIGNED_BYTE,!0,this.vertByteSize,12),this.shader.attributes.aTextureId&&this.vaos[this.vertexCount].addAttribute(this.vertexBuffers[this.vertexCount],this.shader.attributes.aTextureId,t.FLOAT,!1,this.vertByteSize,16)),this.renderer.bindVao(this.vaos[this.vertexCount]),this.vertexBuffers[this.vertexCount].upload(i.vertices,0,!1),this.vertexCount++),w=0;w<e;++w)l[w]._virtalBoundId=-1;for(w=0;w<v;++w){for(var D=s[w],I=D.textureCount,L=0;L<I;L++)p=D.textures[L],l[D.ids[L]]!==p&&this.renderer.bindTexture(p,D.ids[L],!0),p._virtalBoundId=-1;this.renderer.state.setBlendMode(D.blend),t.drawElements(t.TRIANGLES,6*D.size,t.UNSIGNED_SHORT,6*D.start*2)}this.currentIndex=0}},e.prototype.start=function(){this.renderer.bindShader(this.shader),b.default.CAN_UPLOAD_SAME_BUFFER&&(this.renderer.bindVao(this.vaos[this.vertexCount]),this.vertexBuffers[this.vertexCount].bind())},e.prototype.stop=function(){this.flush()},e.prototype.destroy=function(){for(var e=0;e<this.vaoMax;e++)this.vertexBuffers[e]&&this.vertexBuffers[e].destroy(),this.vaos[e]&&this.vaos[e].destroy();this.indexBuffer&&this.indexBuffer.destroy(),this.renderer.off("prerender",this.onPrerender,this),t.prototype.destroy.call(this),this.shader&&(this.shader.destroy(),this.shader=null),this.vertexBuffers=null,this.vaos=null,this.indexBuffer=null,this.indices=null,this.sprites=null;for(var r=0;r<this.buffers.length;++r)this.buffers[r].destroy()},e}(u.default);r.default=M,l.default.registerPlugin("sprite",M)},{"../../renderers/webgl/WebGLRenderer":83,"../../renderers/webgl/utils/ObjectRenderer":93,"../../renderers/webgl/utils/checkMaxIfStatmentsInShader":96,"../../settings":100,"../../utils/createIndicesForQuads":119,"./BatchBuffer":104,"./generateMultiTextureShader":106,"bit-twiddle":1,"pixi-gl-core":12}],106:[function(t,e,r){"use strict";function n(t,e){var r=a;r=r.replace(/%count%/gi,e),r=r.replace(/%forloop%/gi,i(e));for(var n=new s.default(t,"precision highp float;\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\nattribute vec4 aColor;\nattribute float aTextureId;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\nvarying float vTextureId;\n\nvoid main(void){\n    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n\n    vTextureCoord = aTextureCoord;\n    vTextureId = aTextureId;\n    vColor = vec4(aColor.rgb * aColor.a, aColor.a);\n}\n",r),o=[],u=0;u<e;u++)o[u]=u;return n.bind(),n.uniforms.uSamplers=o,n}function i(t){var e="";e+="\n",e+="\n";for(var r=0;r<t;r++)r>0&&(e+="\nelse "),r<t-1&&(e+="if(textureId == "+r+".0)"),e+="\n{",e+="\n\tcolor = texture2D(uSamplers["+r+"], vTextureCoord);",e+="\n}";return e+="\n",e+="\n"}r.__esModule=!0,r.default=n;var o=t("../../Shader"),s=function(t){return t&&t.__esModule?t:{default:t}}(o),a=(t("path"),["varying vec2 vTextureCoord;","varying vec4 vColor;","varying float vTextureId;","uniform sampler2D uSamplers[%count%];","void main(void){","vec4 color;","float textureId = floor(vTextureId+0.5);","%forloop%","gl_FragColor = color * vColor;","}"].join("\n"))},{"../../Shader":43,path:23}],107:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),u=t("../sprites/Sprite"),h=n(u),l=t("../textures/Texture"),c=n(l),f=t("../math"),d=t("../utils"),p=t("../const"),v=t("../settings"),y=n(v),g=t("./TextStyle"),m=n(g),_=t("../utils/trimCanvas"),b=n(_),x={texture:!0,children:!1,baseTexture:!0},T=function(t){function e(r,n,s){i(this,e),s=s||document.createElement("canvas"),s.width=3,s.height=3;var a=c.default.fromCanvas(s);a.orig=new f.Rectangle,a.trim=new f.Rectangle;var u=o(this,t.call(this,a));return u.canvas=s,u.context=u.canvas.getContext("2d"),u.resolution=y.default.RESOLUTION,u._text=null,u._style=null,u._styleListener=null,u._font="",u.text=r,u.style=n,u.localStyleID=-1,u}return s(e,t),e.prototype.updateText=function(t){var r=this._style;if(this.localStyleID!==r.styleID&&(this.dirty=!0,this.localStyleID=r.styleID),this.dirty||!t){this._font=e.getFontStyle(r),this.context.font=this._font;for(var n=r.wordWrap?this.wordWrap(this._text):this._text,i=n.split(/(?:\r\n|\r|\n)/),o=new Array(i.length),s=0,a=e.calculateFontProperties(this._font),u=0;u<i.length;u++){var h=this.context.measureText(i[u]).width+(i[u].length-1)*r.letterSpacing;o[u]=h,s=Math.max(s,h)}var l=s+r.strokeThickness;r.dropShadow&&(l+=r.dropShadowDistance),this.canvas.width=Math.ceil((l+2*r.padding)*this.resolution);var c=r.lineHeight||a.fontSize+r.strokeThickness,f=Math.max(c,a.fontSize+r.strokeThickness)+(i.length-1)*c;r.dropShadow&&(f+=r.dropShadowDistance),this.canvas.height=Math.ceil((f+2*r.padding)*this.resolution),this.context.scale(this.resolution,this.resolution),this.context.clearRect(0,0,this.canvas.width,this.canvas.height),this.context.font=this._font,this.context.strokeStyle=r.stroke,this.context.lineWidth=r.strokeThickness,this.context.textBaseline=r.textBaseline,this.context.lineJoin=r.lineJoin,this.context.miterLimit=r.miterLimit;var d=void 0,p=void 0;if(r.dropShadow){this.context.shadowBlur=r.dropShadowBlur,this.context.globalAlpha=r.dropShadowAlpha,r.dropShadowBlur>0?this.context.shadowColor=r.dropShadowColor:this.context.fillStyle=r.dropShadowColor;for(var v=Math.cos(r.dropShadowAngle)*r.dropShadowDistance,y=Math.sin(r.dropShadowAngle)*r.dropShadowDistance,g=0;g<i.length;g++)d=r.strokeThickness/2,p=r.strokeThickness/2+g*c+a.ascent,
+"right"===r.align?d+=s-o[g]:"center"===r.align&&(d+=(s-o[g])/2),r.fill&&(this.drawLetterSpacing(i[g],d+v+r.padding,p+y+r.padding),r.stroke&&r.strokeThickness&&(this.context.strokeStyle=r.dropShadowColor,this.drawLetterSpacing(i[g],d+v+r.padding,p+y+r.padding,!0),this.context.strokeStyle=r.stroke))}this.context.shadowBlur=0,this.context.globalAlpha=1,this.context.fillStyle=this._generateFillStyle(r,i);for(var m=0;m<i.length;m++)d=r.strokeThickness/2,p=r.strokeThickness/2+m*c+a.ascent,"right"===r.align?d+=s-o[m]:"center"===r.align&&(d+=(s-o[m])/2),r.stroke&&r.strokeThickness&&this.drawLetterSpacing(i[m],d+r.padding,p+r.padding,!0),r.fill&&this.drawLetterSpacing(i[m],d+r.padding,p+r.padding);this.updateTexture()}},e.prototype.drawLetterSpacing=function(t,e,r){var n=arguments.length>3&&void 0!==arguments[3]&&arguments[3],i=this._style,o=i.letterSpacing;if(0===o)return void(n?this.context.strokeText(t,e,r):this.context.fillText(t,e,r));for(var s=String.prototype.split.call(t,""),a=e,u=0,h="";u<t.length;)h=s[u++],n?this.context.strokeText(h,a,r):this.context.fillText(h,a,r),a+=this.context.measureText(h).width+o},e.prototype.updateTexture=function(){if(this._style.trim){var t=(0,b.default)(this.canvas);this.canvas.width=t.width,this.canvas.height=t.height,this.context.putImageData(t.data,0,0)}var e=this._texture,r=this._style;e.baseTexture.hasLoaded=!0,e.baseTexture.resolution=this.resolution,e.baseTexture.realWidth=this.canvas.width,e.baseTexture.realHeight=this.canvas.height,e.baseTexture.width=this.canvas.width/this.resolution,e.baseTexture.height=this.canvas.height/this.resolution,e.trim.width=e._frame.width=this.canvas.width/this.resolution,e.trim.height=e._frame.height=this.canvas.height/this.resolution,e.trim.x=-r.padding,e.trim.y=-r.padding,e.orig.width=e._frame.width-2*r.padding,e.orig.height=e._frame.height-2*r.padding,this._onTextureUpdate(),e.baseTexture.emit("update",e.baseTexture),this.dirty=!1},e.prototype.renderWebGL=function(e){this.resolution!==e.resolution&&(this.resolution=e.resolution,this.dirty=!0),this.updateText(!0),t.prototype.renderWebGL.call(this,e)},e.prototype._renderCanvas=function(e){this.resolution!==e.resolution&&(this.resolution=e.resolution,this.dirty=!0),this.updateText(!0),t.prototype._renderCanvas.call(this,e)},e.prototype.wordWrap=function(t){for(var e="",r=this._style,n=t.split("\n"),i=r.wordWrapWidth,o=0;o<n.length;o++){for(var s=i,a=n[o].split(" "),u=0;u<a.length;u++){var h=this.context.measureText(a[u]).width;if(r.breakWords&&h>i)for(var l=a[u].split(""),c=0;c<l.length;c++){var f=this.context.measureText(l[c]).width;f>s?(e+="\n"+l[c],s=i-f):(0===c&&(e+=" "),e+=l[c],s-=f)}else{var d=h+this.context.measureText(" ").width;0===u||d>s?(u>0&&(e+="\n"),e+=a[u],s=i-h):(s-=d,e+=" "+a[u])}}o<n.length-1&&(e+="\n")}return e},e.prototype.getLocalBounds=function(e){return this.updateText(!0),t.prototype.getLocalBounds.call(this,e)},e.prototype._calculateBounds=function(){this.updateText(!0),this.calculateVertices(),this._bounds.addQuad(this.vertexData)},e.prototype._onStyleChange=function(){this.dirty=!0},e.prototype._generateFillStyle=function(t,e){if(!Array.isArray(t.fill))return t.fill;if(navigator.isCocoonJS)return t.fill[0];var r=void 0,n=void 0,i=void 0,o=void 0,s=this.canvas.width/this.resolution,a=this.canvas.height/this.resolution,u=t.fill.slice(),h=t.fillGradientStops.slice();if(!h.length)for(var l=u.length+1,c=1;c<l;++c)h.push(c/l);if(u.unshift(t.fill[0]),h.unshift(0),u.push(t.fill[t.fill.length-1]),h.push(1),t.fillGradientType===p.TEXT_GRADIENT.LINEAR_VERTICAL){r=this.context.createLinearGradient(s/2,0,s/2,a),n=(u.length+1)*e.length,i=0;for(var f=0;f<e.length;f++){i+=1;for(var d=0;d<u.length;d++)o=h[d]?h[d]/e.length+f/e.length:i/n,r.addColorStop(o,u[d]),i++}}else{r=this.context.createLinearGradient(0,a/2,s,a/2),n=u.length+1,i=1;for(var v=0;v<u.length;v++)o=h[v]?h[v]:i/n,r.addColorStop(o,u[v]),i++}return r},e.prototype.destroy=function(e){"boolean"==typeof e&&(e={children:e}),e=Object.assign({},x,e),t.prototype.destroy.call(this,e),this.context=null,this.canvas=null,this._style=null},e.getFontStyle=function(t){(t=t||{})instanceof m.default||(t=new m.default(t));var e="number"==typeof t.fontSize?t.fontSize+"px":t.fontSize,r=t.fontFamily;Array.isArray(t.fontFamily)||(r=t.fontFamily.split(","));for(var n=r.length-1;n>=0;n--){var i=r[n].trim();/([\"\'])[^\'\"]+\1/.test(i)||(i='"'+i+'"'),r[n]=i}return t.fontStyle+" "+t.fontVariant+" "+t.fontWeight+" "+e+" "+r.join(",")},e.calculateFontProperties=function(t){if(e.fontPropertiesCache[t])return e.fontPropertiesCache[t];var r={},n=e.fontPropertiesCanvas,i=e.fontPropertiesContext;i.font=t;var o=Math.ceil(i.measureText("|MÉq").width),s=Math.ceil(i.measureText("M").width),a=2*s;s=1.4*s|0,n.width=o,n.height=a,i.fillStyle="#f00",i.fillRect(0,0,o,a),i.font=t,i.textBaseline="alphabetic",i.fillStyle="#000",i.fillText("|MÉq",0,s);var u=i.getImageData(0,0,o,a).data,h=u.length,l=4*o,c=0,f=0,d=!1;for(c=0;c<s;++c){for(var p=0;p<l;p+=4)if(255!==u[f+p]){d=!0;break}if(d)break;f+=l}for(r.ascent=s-c,f=h-l,d=!1,c=a;c>s;--c){for(var v=0;v<l;v+=4)if(255!==u[f+v]){d=!0;break}if(d)break;f-=l}return r.descent=c-s,r.fontSize=r.ascent+r.descent,e.fontPropertiesCache[t]=r,r},a(e,[{key:"width",get:function(){return this.updateText(!0),Math.abs(this.scale.x)*this._texture.orig.width},set:function(t){this.updateText(!0);var e=(0,d.sign)(this.scale.x)||1;this.scale.x=e*t/this._texture.orig.width,this._width=t}},{key:"height",get:function(){return this.updateText(!0),Math.abs(this.scale.y)*this._texture.orig.height},set:function(t){this.updateText(!0);var e=(0,d.sign)(this.scale.y)||1;this.scale.y=e*t/this._texture.orig.height,this._height=t}},{key:"style",get:function(){return this._style},set:function(t){t=t||{},t instanceof m.default?this._style=t:this._style=new m.default(t),this.localStyleID=-1,this.dirty=!0}},{key:"text",get:function(){return this._text},set:function(t){t=String(""===t||null===t||void 0===t?" ":t),this._text!==t&&(this._text=t,this.dirty=!0)}}]),e}(h.default);r.default=T,T.fontPropertiesCache={},T.fontPropertiesCanvas=document.createElement("canvas"),T.fontPropertiesContext=T.fontPropertiesCanvas.getContext("2d")},{"../const":45,"../math":69,"../settings":100,"../sprites/Sprite":101,"../textures/Texture":113,"../utils":121,"../utils/trimCanvas":125,"./TextStyle":108}],108:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t){return"number"==typeof t?(0,h.hex2string)(t):("string"==typeof t&&0===t.indexOf("0x")&&(t=t.replace("0x","#")),t)}function o(t){if(Array.isArray(t)){for(var e=0;e<t.length;++e)t[e]=i(t[e]);return t}return i(t)}function s(t,e){if(!Array.isArray(t)||!Array.isArray(e))return!1;if(t.length!==e.length)return!1;for(var r=0;r<t.length;++r)if(t[r]!==e[r])return!1;return!0}r.__esModule=!0;var a=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),u=t("../const"),h=t("../utils"),l={align:"left",breakWords:!1,dropShadow:!1,dropShadowAlpha:1,dropShadowAngle:Math.PI/6,dropShadowBlur:0,dropShadowColor:"#000000",dropShadowDistance:5,fill:"black",fillGradientType:u.TEXT_GRADIENT.LINEAR_VERTICAL,fillGradientStops:[],fontFamily:"Arial",fontSize:26,fontStyle:"normal",fontVariant:"normal",fontWeight:"normal",letterSpacing:0,lineHeight:0,lineJoin:"miter",miterLimit:10,padding:0,stroke:"black",strokeThickness:0,textBaseline:"alphabetic",trim:!1,wordWrap:!1,wordWrapWidth:100},c=function(){function t(e){n(this,t),this.styleID=0,Object.assign(this,l,e)}return t.prototype.clone=function(){var e={};for(var r in l)e[r]=this[r];return new t(e)},t.prototype.reset=function(){Object.assign(this,l)},a(t,[{key:"align",get:function(){return this._align},set:function(t){this._align!==t&&(this._align=t,this.styleID++)}},{key:"breakWords",get:function(){return this._breakWords},set:function(t){this._breakWords!==t&&(this._breakWords=t,this.styleID++)}},{key:"dropShadow",get:function(){return this._dropShadow},set:function(t){this._dropShadow!==t&&(this._dropShadow=t,this.styleID++)}},{key:"dropShadowAlpha",get:function(){return this._dropShadowAlpha},set:function(t){this._dropShadowAlpha!==t&&(this._dropShadowAlpha=t,this.styleID++)}},{key:"dropShadowAngle",get:function(){return this._dropShadowAngle},set:function(t){this._dropShadowAngle!==t&&(this._dropShadowAngle=t,this.styleID++)}},{key:"dropShadowBlur",get:function(){return this._dropShadowBlur},set:function(t){this._dropShadowBlur!==t&&(this._dropShadowBlur=t,this.styleID++)}},{key:"dropShadowColor",get:function(){return this._dropShadowColor},set:function(t){var e=o(t);this._dropShadowColor!==e&&(this._dropShadowColor=e,this.styleID++)}},{key:"dropShadowDistance",get:function(){return this._dropShadowDistance},set:function(t){this._dropShadowDistance!==t&&(this._dropShadowDistance=t,this.styleID++)}},{key:"fill",get:function(){return this._fill},set:function(t){var e=o(t);this._fill!==e&&(this._fill=e,this.styleID++)}},{key:"fillGradientType",get:function(){return this._fillGradientType},set:function(t){this._fillGradientType!==t&&(this._fillGradientType=t,this.styleID++)}},{key:"fillGradientStops",get:function(){return this._fillGradientStops},set:function(t){s(this._fillGradientStops,t)||(this._fillGradientStops=t,this.styleID++)}},{key:"fontFamily",get:function(){return this._fontFamily},set:function(t){this.fontFamily!==t&&(this._fontFamily=t,this.styleID++)}},{key:"fontSize",get:function(){return this._fontSize},set:function(t){this._fontSize!==t&&(this._fontSize=t,this.styleID++)}},{key:"fontStyle",get:function(){return this._fontStyle},set:function(t){this._fontStyle!==t&&(this._fontStyle=t,this.styleID++)}},{key:"fontVariant",get:function(){return this._fontVariant},set:function(t){this._fontVariant!==t&&(this._fontVariant=t,this.styleID++)}},{key:"fontWeight",get:function(){return this._fontWeight},set:function(t){this._fontWeight!==t&&(this._fontWeight=t,this.styleID++)}},{key:"letterSpacing",get:function(){return this._letterSpacing},set:function(t){this._letterSpacing!==t&&(this._letterSpacing=t,this.styleID++)}},{key:"lineHeight",get:function(){return this._lineHeight},set:function(t){this._lineHeight!==t&&(this._lineHeight=t,this.styleID++)}},{key:"lineJoin",get:function(){return this._lineJoin},set:function(t){this._lineJoin!==t&&(this._lineJoin=t,this.styleID++)}},{key:"miterLimit",get:function(){return this._miterLimit},set:function(t){this._miterLimit!==t&&(this._miterLimit=t,this.styleID++)}},{key:"padding",get:function(){return this._padding},set:function(t){this._padding!==t&&(this._padding=t,this.styleID++)}},{key:"stroke",get:function(){return this._stroke},set:function(t){var e=o(t);this._stroke!==e&&(this._stroke=e,this.styleID++)}},{key:"strokeThickness",get:function(){return this._strokeThickness},set:function(t){this._strokeThickness!==t&&(this._strokeThickness=t,this.styleID++)}},{key:"textBaseline",get:function(){return this._textBaseline},set:function(t){this._textBaseline!==t&&(this._textBaseline=t,this.styleID++)}},{key:"trim",get:function(){return this._trim},set:function(t){this._trim!==t&&(this._trim=t,this.styleID++)}},{key:"wordWrap",get:function(){return this._wordWrap},set:function(t){this._wordWrap!==t&&(this._wordWrap=t,this.styleID++)}},{key:"wordWrapWidth",get:function(){return this._wordWrapWidth},set:function(t){this._wordWrapWidth!==t&&(this._wordWrapWidth=t,this.styleID++)}}]),t}();r.default=c},{"../const":45,"../utils":121}],109:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("./BaseTexture"),u=n(a),h=t("../settings"),l=n(h),c=function(t){function e(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:100,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100,s=arguments[2],a=arguments[3];i(this,e);var u=o(this,t.call(this,null,s));return u.resolution=a||l.default.RESOLUTION,u.width=r,u.height=n,u.realWidth=u.width*u.resolution,u.realHeight=u.height*u.resolution,u.scaleMode=void 0!==s?s:l.default.SCALE_MODE,u.hasLoaded=!0,u._glRenderTargets={},u._canvasRenderTarget=null,u.valid=!1,u}return s(e,t),e.prototype.resize=function(t,e){t===this.width&&e===this.height||(this.valid=t>0&&e>0,this.width=t,this.height=e,this.realWidth=this.width*this.resolution,this.realHeight=this.height*this.resolution,this.valid&&this.emit("update",this))},e.prototype.destroy=function(){t.prototype.destroy.call(this,!0),this.renderer=null},e}(u.default);r.default=c},{"../settings":100,"./BaseTexture":110}],110:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("../utils"),u=t("../settings"),h=n(u),l=t("eventemitter3"),c=n(l),f=t("../utils/determineCrossOrigin"),d=n(f),p=t("bit-twiddle"),v=n(p),y=function(t){function e(r,n,s){i(this,e);var u=o(this,t.call(this));return u.uid=(0,a.uid)(),u.touched=0,u.resolution=s||h.default.RESOLUTION,u.width=100,u.height=100,u.realWidth=100,u.realHeight=100,u.scaleMode=void 0!==n?n:h.default.SCALE_MODE,u.hasLoaded=!1,u.isLoading=!1,u.source=null,u.origSource=null,u.imageType=null,u.sourceScale=1,u.premultipliedAlpha=!0,u.imageUrl=null,u.isPowerOfTwo=!1,u.mipmap=h.default.MIPMAP_TEXTURES,u.wrapMode=h.default.WRAP_MODE,u._glTextures={},u._enabled=0,u._virtalBoundId=-1,r&&u.loadSource(r),u._destroyed=!1,u}return s(e,t),e.prototype.update=function(){"svg"!==this.imageType&&(this.realWidth=this.source.naturalWidth||this.source.videoWidth||this.source.width,this.realHeight=this.source.naturalHeight||this.source.videoHeight||this.source.height,this._updateDimensions()),this.emit("update",this)},e.prototype._updateDimensions=function(){this.width=this.realWidth/this.resolution,this.height=this.realHeight/this.resolution,this.isPowerOfTwo=v.default.isPow2(this.realWidth)&&v.default.isPow2(this.realHeight)},e.prototype.loadSource=function(t){var e=this.isLoading;this.hasLoaded=!1,this.isLoading=!1,e&&this.source&&(this.source.onload=null,this.source.onerror=null);var r=!this.source;if(this.source=t,(t.src&&t.complete||t.getContext)&&t.width&&t.height)this._updateImageType(),"svg"===this.imageType?this._loadSvgSource():this._sourceLoaded(),r&&this.emit("loaded",this);else if(!t.getContext){this.isLoading=!0;var n=this;if(t.onload=function(){if(n._updateImageType(),t.onload=null,t.onerror=null,n.isLoading){if(n.isLoading=!1,n._sourceLoaded(),"svg"===n.imageType)return void n._loadSvgSource();n.emit("loaded",n)}},t.onerror=function(){t.onload=null,t.onerror=null,n.isLoading&&(n.isLoading=!1,n.emit("error",n))},t.complete&&t.src){if(t.onload=null,t.onerror=null,"svg"===n.imageType)return void n._loadSvgSource();this.isLoading=!1,t.width&&t.height?(this._sourceLoaded(),e&&this.emit("loaded",this)):e&&this.emit("error",this)}}},e.prototype._updateImageType=function(){if(this.imageUrl){var t=(0,a.decomposeDataUri)(this.imageUrl),e=void 0;if(t&&"image"===t.mediaType){var r=t.subType.split("+")[0];if(!(e=(0,a.getUrlFileExtension)("."+r)))throw new Error("Invalid image type in data URI.")}else(e=(0,a.getUrlFileExtension)(this.imageUrl))||(e="png");this.imageType=e}},e.prototype._loadSvgSource=function(){if("svg"===this.imageType){var t=(0,a.decomposeDataUri)(this.imageUrl);t?this._loadSvgSourceUsingDataUri(t):this._loadSvgSourceUsingXhr()}},e.prototype._loadSvgSourceUsingDataUri=function(t){var e=void 0;if("base64"===t.encoding){if(!atob)throw new Error("Your browser doesn't support base64 conversions.");e=atob(t.data)}else e=t.data;this._loadSvgSourceUsingString(e)},e.prototype._loadSvgSourceUsingXhr=function(){var t=this,e=new XMLHttpRequest;e.onload=function(){if(e.readyState!==e.DONE||200!==e.status)throw new Error("Failed to load SVG using XHR.");t._loadSvgSourceUsingString(e.response)},e.onerror=function(){return t.emit("error",t)},e.open("GET",this.imageUrl,!0),e.send()},e.prototype._loadSvgSourceUsingString=function(t){var e=(0,a.getSvgSize)(t),r=e.width,n=e.height;if(!r||!n)throw new Error("The SVG image must have width and height defined (in pixels), canvas API needs them.");this.realWidth=Math.round(r*this.sourceScale),this.realHeight=Math.round(n*this.sourceScale),this._updateDimensions();var i=document.createElement("canvas");i.width=this.realWidth,i.height=this.realHeight,i._pixiId="canvas_"+(0,a.uid)(),i.getContext("2d").drawImage(this.source,0,0,r,n,0,0,this.realWidth,this.realHeight),this.origSource=this.source,this.source=i,a.BaseTextureCache[i._pixiId]=this,this.isLoading=!1,this._sourceLoaded(),this.emit("loaded",this)},e.prototype._sourceLoaded=function(){this.hasLoaded=!0,this.update()},e.prototype.destroy=function(){this.imageUrl&&(delete a.BaseTextureCache[this.imageUrl],delete a.TextureCache[this.imageUrl],this.imageUrl=null,navigator.isCocoonJS||(this.source.src="")),this.source&&this.source._pixiId&&delete a.BaseTextureCache[this.source._pixiId],this.source=null,this.dispose(),this._destroyed=!0},e.prototype.dispose=function(){this.emit("dispose",this)},e.prototype.updateSourceImage=function(t){this.source.src=t,this.loadSource(this.source)},e.fromImage=function(t,r,n,i){var o=a.BaseTextureCache[t];if(!o){var s=new Image;void 0===r&&0!==t.indexOf("data:")&&(s.crossOrigin=(0,d.default)(t)),o=new e(s,n),o.imageUrl=t,i&&(o.sourceScale=i),o.resolution=(0,a.getResolutionOfUrl)(t),s.src=t,a.BaseTextureCache[t]=o}return o},e.fromCanvas=function(t,r){t._pixiId||(t._pixiId="canvas_"+(0,a.uid)());var n=a.BaseTextureCache[t._pixiId];return n||(n=new e(t,r),a.BaseTextureCache[t._pixiId]=n),n},e.from=function(t,r,n){if("string"==typeof t)return e.fromImage(t,void 0,r,n);if(t instanceof HTMLImageElement){var i=t.src,o=a.BaseTextureCache[i];return o||(o=new e(t,r),o.imageUrl=i,n&&(o.sourceScale=n),o.resolution=(0,a.getResolutionOfUrl)(i),a.BaseTextureCache[i]=o),o}return t instanceof HTMLCanvasElement?e.fromCanvas(t,r):t},e}(c.default);r.default=y},{"../settings":100,"../utils":121,"../utils/determineCrossOrigin":120,"bit-twiddle":1,eventemitter3:3}],111:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("./BaseRenderTexture"),u=n(a),h=t("./Texture"),l=n(h),c=function(t){function e(r,n){i(this,e);var s=null;if(!(r instanceof u.default)){var a=arguments[1],h=arguments[2],l=arguments[3],c=arguments[4];console.warn("Please use RenderTexture.create("+a+", "+h+") instead of the ctor directly."),s=arguments[0],n=null,r=new u.default(a,h,l,c)}var f=o(this,t.call(this,r,n));return f.legacyRenderer=s,f.valid=!0,f._updateUvs(),f}return s(e,t),e.prototype.resize=function(t,e,r){this.valid=t>0&&e>0,this._frame.width=this.orig.width=t,this._frame.height=this.orig.height=e,r||this.baseTexture.resize(t,e),this._updateUvs()},e.create=function(t,r,n,i){return new e(new u.default(t,r,n,i))},e}(l.default);r.default=c},{"./BaseRenderTexture":109,"./Texture":113}],112:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),o=t("../"),s=t("../utils"),a=function(){function t(e,r){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;n(this,t),this.baseTexture=e,this.textures={},this.data=r,this.resolution=this._updateResolution(i||this.baseTexture.imageUrl),this._frames=this.data.frames,this._frameKeys=Object.keys(this._frames),this._batchIndex=0,this._callback=null}return i(t,null,[{key:"BATCH_SIZE",get:function(){return 1e3}}]),t.prototype._updateResolution=function(t){var e=this.data.meta.scale,r=(0,s.getResolutionOfUrl)(t,null);return null===r&&(r=void 0!==e?parseFloat(e):1),1!==r&&(this.baseTexture.resolution=r,this.baseTexture.update()),r},t.prototype.parse=function(e){this._batchIndex=0,this._callback=e,this._frameKeys.length<=t.BATCH_SIZE?(this._processFrames(0),this._parseComplete()):this._nextBatch()},t.prototype._processFrames=function(e){for(var r=e,n=t.BATCH_SIZE;r-e<n&&r<this._frameKeys.length;){var i=this._frameKeys[r],a=this._frames[i].frame;if(a){var u=null,h=null,l=new o.Rectangle(0,0,this._frames[i].sourceSize.w/this.resolution,this._frames[i].sourceSize.h/this.resolution);u=this._frames[i].rotated?new o.Rectangle(a.x/this.resolution,a.y/this.resolution,a.h/this.resolution,a.w/this.resolution):new o.Rectangle(a.x/this.resolution,a.y/this.resolution,a.w/this.resolution,a.h/this.resolution),this._frames[i].trimmed&&(h=new o.Rectangle(this._frames[i].spriteSourceSize.x/this.resolution,this._frames[i].spriteSourceSize.y/this.resolution,a.w/this.resolution,a.h/this.resolution)),this.textures[i]=new o.Texture(this.baseTexture,u,l,h,this._frames[i].rotated?2:0),s.TextureCache[i]=this.textures[i]}r++}},t.prototype._parseComplete=function(){var t=this._callback;this._callback=null,this._batchIndex=0,t.call(this,this.textures)},t.prototype._nextBatch=function(){var e=this;this._processFrames(this._batchIndex*t.BATCH_SIZE),this._batchIndex++,setTimeout(function(){e._batchIndex*t.BATCH_SIZE<e._frameKeys.length?e._nextBatch():e._parseComplete()},0)},t.prototype.destroy=function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];for(var e in this.textures)this.textures[e].destroy();this._frames=null,this._frameKeys=null,this.data=null,this.textures=null,t&&this.baseTexture.destroy(),this.baseTexture=null},t}();r.default=a},{"../":64,"../utils":121}],113:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function a(t){t.destroy=function(){},t.on=function(){},t.once=function(){},t.emit=function(){}}r.__esModule=!0;var u=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),h=t("./BaseTexture"),l=n(h),c=t("./VideoBaseTexture"),f=n(c),d=t("./TextureUvs"),p=n(d),v=t("eventemitter3"),y=n(v),g=t("../math"),m=t("../utils"),_=function(t){function e(r,n,s,a,u){i(this,e);var h=o(this,t.call(this));if(h.noFrame=!1,n||(h.noFrame=!0,n=new g.Rectangle(0,0,1,1)),r instanceof e&&(r=r.baseTexture),h.baseTexture=r,h._frame=n,h.trim=a,h.valid=!1,h.requiresUpdate=!1,h._uvs=null,h.orig=s||n,h._rotate=Number(u||0),u===!0)h._rotate=2;else if(h._rotate%2!=0)throw new Error("attempt to use diamond-shaped UVs. If you are sure, set rotation manually");return r.hasLoaded?(h.noFrame&&(n=new g.Rectangle(0,0,r.width,r.height),r.on("update",h.onBaseTextureUpdated,h)),h.frame=n):r.once("loaded",h.onBaseTextureLoaded,h),h._updateID=0,h.transform=null,h}return s(e,t),e.prototype.update=function(){this.baseTexture.update()},e.prototype.onBaseTextureLoaded=function(t){this._updateID++,this.noFrame?this.frame=new g.Rectangle(0,0,t.width,t.height):this.frame=this._frame,this.baseTexture.on("update",this.onBaseTextureUpdated,this),this.emit("update",this)},e.prototype.onBaseTextureUpdated=function(t){this._updateID++,this._frame.width=t.width,this._frame.height=t.height,this.emit("update",this)},e.prototype.destroy=function(t){this.baseTexture&&(t&&(m.TextureCache[this.baseTexture.imageUrl]&&delete m.TextureCache[this.baseTexture.imageUrl],this.baseTexture.destroy()),this.baseTexture.off("update",this.onBaseTextureUpdated,this),this.baseTexture.off("loaded",this.onBaseTextureLoaded,this),this.baseTexture=null),this._frame=null,this._uvs=null,this.trim=null,this.orig=null,this.valid=!1,this.off("dispose",this.dispose,this),this.off("update",this.update,this)},e.prototype.clone=function(){return new e(this.baseTexture,this.frame,this.orig,this.trim,this.rotate)},e.prototype._updateUvs=function(){this._uvs||(this._uvs=new p.default),this._uvs.set(this._frame,this.baseTexture,this.rotate),this._updateID++},e.fromImage=function(t,r,n,i){var o=m.TextureCache[t];return o||(o=new e(l.default.fromImage(t,r,n,i)),m.TextureCache[t]=o),o},e.fromFrame=function(t){var e=m.TextureCache[t];if(!e)throw new Error('The frameId "'+t+'" does not exist in the texture cache');return e},e.fromCanvas=function(t,r){return new e(l.default.fromCanvas(t,r))},e.fromVideo=function(t,r){return"string"==typeof t?e.fromVideoUrl(t,r):new e(f.default.fromVideo(t,r))},e.fromVideoUrl=function(t,r){return new e(f.default.fromUrl(t,r))},e.from=function(t){if("string"==typeof t){var r=m.TextureCache[t];if(!r){return null!==t.match(/\.(mp4|webm|ogg|h264|avi|mov)$/)?e.fromVideoUrl(t):e.fromImage(t)}return r}return t instanceof HTMLImageElement?new e(l.default.from(t)):t instanceof HTMLCanvasElement?e.fromCanvas(t):t instanceof HTMLVideoElement?e.fromVideo(t):t instanceof l.default?new e(t):t},e.fromLoader=function(t,r,n){var i=new l.default(t,void 0,(0,m.getResolutionOfUrl)(r)),o=new e(i);return i.imageUrl=r,n||(n=r),m.BaseTextureCache[n]=i,m.TextureCache[n]=o,n!==r&&(m.BaseTextureCache[r]=i,m.TextureCache[r]=o),o},e.addTextureToCache=function(t,e){m.TextureCache[e]=t},e.removeTextureFromCache=function(t){var e=m.TextureCache[t];return delete m.TextureCache[t],delete m.BaseTextureCache[t],e},u(e,[{key:"frame",get:function(){return this._frame},set:function(t){if(this._frame=t,this.noFrame=!1,t.x+t.width>this.baseTexture.width||t.y+t.height>this.baseTexture.height)throw new Error("Texture Error: frame does not fit inside the base Texture dimensions: X: "+t.x+" + "+t.width+" > "+this.baseTexture.width+" Y: "+t.y+" + "+t.height+" > "+this.baseTexture.height);this.valid=t&&t.width&&t.height&&this.baseTexture.hasLoaded,this.trim||this.rotate||(this.orig=t),this.valid&&this._updateUvs()}},{key:"rotate",get:function(){return this._rotate},set:function(t){this._rotate=t,this.valid&&this._updateUvs()}},{key:"width",get:function(){return this.orig.width}},{key:"height",get:function(){return this.orig.height}}]),e}(y.default);r.default=_,_.EMPTY=new _(new l.default),a(_.EMPTY),_.WHITE=function(){var t=document.createElement("canvas");t.width=10,t.height=10;var e=t.getContext("2d");return e.fillStyle="white",e.fillRect(0,0,10,10),new _(new l.default(t))}(),a(_.WHITE)},{"../math":69,"../utils":121,"./BaseTexture":110,"./TextureUvs":114,"./VideoBaseTexture":115,eventemitter3:3}],114:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../math/GroupD8"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=function(){function t(){n(this,t),this.x0=0,this.y0=0,this.x1=1,this.y1=0,this.x2=1,this.y2=1,this.x3=0,this.y3=1,this.uvsUint32=new Uint32Array(4)}return t.prototype.set=function(t,e,r){var n=e.width,i=e.height;if(r){var s=t.width/2/n,a=t.height/2/i,u=t.x/n+s,h=t.y/i+a;r=o.default.add(r,o.default.NW),this.x0=u+s*o.default.uX(r),this.y0=h+a*o.default.uY(r),r=o.default.add(r,2),this.x1=u+s*o.default.uX(r),this.y1=h+a*o.default.uY(r),r=o.default.add(r,2),this.x2=u+s*o.default.uX(r),this.y2=h+a*o.default.uY(r),r=o.default.add(r,2),this.x3=u+s*o.default.uX(r),this.y3=h+a*o.default.uY(r)}else this.x0=t.x/n,this.y0=t.y/i,this.x1=(t.x+t.width)/n,this.y1=t.y/i,this.x2=(t.x+t.width)/n,this.y2=(t.y+t.height)/i,this.x3=t.x/n,this.y3=(t.y+t.height)/i;this.uvsUint32[0]=(65535*this.y0&65535)<<16|65535*this.x0&65535,this.uvsUint32[1]=(65535*this.y1&65535)<<16|65535*this.x1&65535,this.uvsUint32[2]=(65535*this.y2&65535)<<16|65535*this.x2&65535,this.uvsUint32[3]=(65535*this.y3&65535)<<16|65535*this.x3&65535},t}();r.default=s},{"../math/GroupD8":65}],115:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function s(t,e){e||(e="video/"+t.substr(t.lastIndexOf(".")+1));var r=document.createElement("source");return r.src=t,r.type=e,r}r.__esModule=!0;var a=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),u=t("./BaseTexture"),h=function(t){return t&&t.__esModule?t:{default:t}}(u),l=t("../utils"),c=t("../ticker"),f=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(c),d=function(t){function e(r,o){if(n(this,e),!r)throw new Error("No video source element specified.");(r.readyState===r.HAVE_ENOUGH_DATA||r.readyState===r.HAVE_FUTURE_DATA)&&r.width&&r.height&&(r.complete=!0);var s=i(this,t.call(this,r,o));return s.width=r.videoWidth,s.height=r.videoHeight,s._autoUpdate=!0,s._isAutoUpdating=!1,s.autoPlay=!0,s.update=s.update.bind(s),s._onCanPlay=s._onCanPlay.bind(s),r.addEventListener("play",s._onPlayStart.bind(s)),r.addEventListener("pause",s._onPlayStop.bind(s)),s.hasLoaded=!1,s.__loaded=!1,s._isSourceReady()?s._onCanPlay():(r.addEventListener("canplay",s._onCanPlay),r.addEventListener("canplaythrough",s._onCanPlay)),s}return o(e,t),e.prototype._isSourcePlaying=function(){
+var t=this.source;return t.currentTime>0&&t.paused===!1&&t.ended===!1&&t.readyState>2},e.prototype._isSourceReady=function(){return 3===this.source.readyState||4===this.source.readyState},e.prototype._onPlayStart=function(){this.hasLoaded||this._onCanPlay(),!this._isAutoUpdating&&this.autoUpdate&&(f.shared.add(this.update,this),this._isAutoUpdating=!0)},e.prototype._onPlayStop=function(){this._isAutoUpdating&&(f.shared.remove(this.update,this),this._isAutoUpdating=!1)},e.prototype._onCanPlay=function(){this.hasLoaded=!0,this.source&&(this.source.removeEventListener("canplay",this._onCanPlay),this.source.removeEventListener("canplaythrough",this._onCanPlay),this.width=this.source.videoWidth,this.height=this.source.videoHeight,this.__loaded||(this.__loaded=!0,this.emit("loaded",this)),this._isSourcePlaying()?this._onPlayStart():this.autoPlay&&this.source.play())},e.prototype.destroy=function(){this._isAutoUpdating&&f.shared.remove(this.update,this),this.source&&this.source._pixiId&&(delete l.BaseTextureCache[this.source._pixiId],delete this.source._pixiId),t.prototype.destroy.call(this)},e.fromVideo=function(t,r){t._pixiId||(t._pixiId="video_"+(0,l.uid)());var n=l.BaseTextureCache[t._pixiId];return n||(n=new e(t,r),l.BaseTextureCache[t._pixiId]=n),n},e.fromUrl=function(t,r){var n=document.createElement("video");if(n.setAttribute("webkit-playsinline",""),n.setAttribute("playsinline",""),Array.isArray(t))for(var i=0;i<t.length;++i)n.appendChild(s(t[i].src||t[i],t[i].mime));else n.appendChild(s(t.src||t,t.mime));return n.load(),e.fromVideo(n,r)},a(e,[{key:"autoUpdate",get:function(){return this._autoUpdate},set:function(t){t!==this._autoUpdate&&(this._autoUpdate=t,!this._autoUpdate&&this._isAutoUpdating?(f.shared.remove(this.update,this),this._isAutoUpdating=!1):this._autoUpdate&&!this._isAutoUpdating&&(f.shared.add(this.update,this),this._isAutoUpdating=!0))}}]),e}(h.default);r.default=d,d.fromUrls=d.fromUrl},{"../ticker":117,"../utils":121,"./BaseTexture":110}],116:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var o=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),s=t("../settings"),a=n(s),u=t("eventemitter3"),h=n(u),l="tick",c=function(){function t(){var e=this;i(this,t),this._emitter=new h.default,this._requestId=null,this._maxElapsedMS=100,this.autoStart=!1,this.deltaTime=1,this.elapsedMS=1/a.default.TARGET_FPMS,this.lastTime=0,this.speed=1,this.started=!1,this._tick=function(t){e._requestId=null,e.started&&(e.update(t),e.started&&null===e._requestId&&e._emitter.listeners(l,!0)&&(e._requestId=requestAnimationFrame(e._tick)))}}return t.prototype._requestIfNeeded=function(){null===this._requestId&&this._emitter.listeners(l,!0)&&(this.lastTime=performance.now(),this._requestId=requestAnimationFrame(this._tick))},t.prototype._cancelIfNeeded=function(){null!==this._requestId&&(cancelAnimationFrame(this._requestId),this._requestId=null)},t.prototype._startIfPossible=function(){this.started?this._requestIfNeeded():this.autoStart&&this.start()},t.prototype.add=function(t,e){return this._emitter.on(l,t,e),this._startIfPossible(),this},t.prototype.addOnce=function(t,e){return this._emitter.once(l,t,e),this._startIfPossible(),this},t.prototype.remove=function(t,e){return this._emitter.off(l,t,e),this._emitter.listeners(l,!0)||this._cancelIfNeeded(),this},t.prototype.start=function(){this.started||(this.started=!0,this._requestIfNeeded())},t.prototype.stop=function(){this.started&&(this.started=!1,this._cancelIfNeeded())},t.prototype.update=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:performance.now(),e=void 0;t>this.lastTime?(e=this.elapsedMS=t-this.lastTime,e>this._maxElapsedMS&&(e=this._maxElapsedMS),this.deltaTime=e*a.default.TARGET_FPMS*this.speed,this._emitter.emit(l,this.deltaTime)):this.deltaTime=this.elapsedMS=0,this.lastTime=t},o(t,[{key:"FPS",get:function(){return 1e3/this.elapsedMS}},{key:"minFPS",get:function(){return 1e3/this._maxElapsedMS},set:function(t){var e=Math.min(Math.max(0,t)/1e3,a.default.TARGET_FPMS);this._maxElapsedMS=1/e}}]),t}();r.default=c},{"../settings":100,eventemitter3:3}],117:[function(t,e,r){"use strict";r.__esModule=!0,r.Ticker=r.shared=void 0;var n=t("./Ticker"),i=function(t){return t&&t.__esModule?t:{default:t}}(n),o=new i.default;o.autoStart=!0,r.shared=o,r.Ticker=i.default},{"./Ticker":116}],118:[function(t,e,r){"use strict";function n(){return!(!!navigator.platform&&/iPad|iPhone|iPod/.test(navigator.platform))}r.__esModule=!0,r.default=n},{}],119:[function(t,e,r){"use strict";function n(t){for(var e=6*t,r=new Uint16Array(e),n=0,i=0;n<e;n+=6,i+=4)r[n+0]=i+0,r[n+1]=i+1,r[n+2]=i+2,r[n+3]=i+0,r[n+4]=i+2,r[n+5]=i+3;return r}r.__esModule=!0,r.default=n},{}],120:[function(t,e,r){"use strict";function n(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:window.location;if(0===t.indexOf("data:"))return"";e=e||window.location,s||(s=document.createElement("a")),s.href=t,t=o.default.parse(s.href);var r=!t.port&&""===e.port||t.port===e.port;return t.hostname===e.hostname&&r&&t.protocol===e.protocol?"":"anonymous"}r.__esModule=!0,r.default=n;var i=t("url"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=void 0},{url:29}],121:[function(t,e,r){"use strict";function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}function i(t){return t&&t.__esModule?t:{default:t}}function o(){return++A}function s(t,e){return e=e||[],e[0]=(t>>16&255)/255,e[1]=(t>>8&255)/255,e[2]=(255&t)/255,e}function a(t){return t=t.toString(16),"#"+(t="000000".substr(0,6-t.length)+t)}function u(t){return(255*t[0]<<16)+(255*t[1]<<8)+(255*t[2]|0)}function h(t,e){var r=T.default.RETINA_PREFIX.exec(t);return r?parseFloat(r[1]):void 0!==e?e:1}function l(t){var e=b.DATA_URI.exec(t);if(e)return{mediaType:e[1]?e[1].toLowerCase():void 0,subType:e[2]?e[2].toLowerCase():void 0,encoding:e[3]?e[3].toLowerCase():void 0,data:e[4]}}function c(t){var e=b.URL_FILE_EXTENSION.exec(t);if(e)return e[1].toLowerCase()}function f(t){var e=b.SVG_SIZE.exec(t),r={};return e&&(r[e[1]]=Math.round(parseFloat(e[3])),r[e[5]]=Math.round(parseFloat(e[7]))),r}function d(){D=!0}function p(t){if(!D){if(navigator.userAgent.toLowerCase().indexOf("chrome")>-1){var e=["\n %c %c %c Pixi.js "+b.VERSION+" - ✰ "+t+" ✰  %c  %c  http://www.pixijs.com/  %c %c ♥%c♥%c♥ \n\n","background: #ff66a5; padding:5px 0;","background: #ff66a5; padding:5px 0;","color: #ff66a5; background: #030307; padding:5px 0;","background: #ff66a5; padding:5px 0;","background: #ffc3dc; padding:5px 0;","background: #ff66a5; padding:5px 0;","color: #ff2424; background: #fff; padding:5px 0;","color: #ff2424; background: #fff; padding:5px 0;","color: #ff2424; background: #fff; padding:5px 0;"];window.console.log.apply(console,e)}else window.console&&window.console.log("Pixi.js "+b.VERSION+" - "+t+" - http://www.pixijs.com/");D=!0}}function v(){var t={stencil:!0,failIfMajorPerformanceCaveat:!0};try{if(!window.WebGLRenderingContext)return!1;var e=document.createElement("canvas"),r=e.getContext("webgl",t)||e.getContext("experimental-webgl",t),n=!(!r||!r.getContextAttributes().stencil);if(r){var i=r.getExtension("WEBGL_lose_context");i&&i.loseContext()}return r=null,n}catch(t){return!1}}function y(t){return 0===t?0:t<0?-1:1}function g(t,e,r){var n=t.length;if(!(e>=n||0===r)){r=e+r>n?n-e:r;for(var i=n-r,o=e;o<i;++o)t[o]=t[o+r];t.length=i}}function m(){var t=void 0;for(t in I)I[t].destroy();for(t in L)L[t].destroy()}function _(){var t=void 0;for(t in I)delete I[t];for(t in L)delete L[t]}r.__esModule=!0,r.BaseTextureCache=r.TextureCache=r.mixins=r.pluginTarget=r.EventEmitter=r.isMobile=void 0,r.uid=o,r.hex2rgb=s,r.hex2string=a,r.rgb2hex=u,r.getResolutionOfUrl=h,r.decomposeDataUri=l,r.getUrlFileExtension=c,r.getSvgSize=f,r.skipHello=d,r.sayHello=p,r.isWebGLSupported=v,r.sign=y,r.removeItems=g,r.destroyTextureCache=m,r.clearTextureCache=_;var b=t("../const"),x=t("../settings"),T=i(x),w=t("eventemitter3"),E=i(w),S=t("./pluginTarget"),O=i(S),M=t("./mixin"),P=n(M),C=t("ismobilejs"),R=n(C),A=0,D=!1;r.isMobile=R,r.EventEmitter=E.default,r.pluginTarget=O.default,r.mixins=P;var I=r.TextureCache={},L=r.BaseTextureCache={}},{"../const":45,"../settings":100,"./mixin":123,"./pluginTarget":124,eventemitter3:3,ismobilejs:4}],122:[function(t,e,r){"use strict";function n(t){return o.default.tablet||o.default.phone?4:t}r.__esModule=!0,r.default=n;var i=t("ismobilejs"),o=function(t){return t&&t.__esModule?t:{default:t}}(i)},{ismobilejs:4}],123:[function(t,e,r){"use strict";function n(t,e){if(t&&e)for(var r=Object.keys(e),n=0;n<r.length;++n){var i=r[n];Object.defineProperty(t,i,Object.getOwnPropertyDescriptor(e,i))}}function i(t,e){s.push(t,e)}function o(){for(var t=0;t<s.length;t+=2)n(s[t],s[t+1]);s.length=0}r.__esModule=!0,r.mixin=n,r.delayMixin=i,r.performMixins=o;var s=[]},{}],124:[function(t,e,r){"use strict";function n(t){t.__plugins={},t.registerPlugin=function(e,r){t.__plugins[e]=r},t.prototype.initPlugins=function(){this.plugins=this.plugins||{};for(var e in t.__plugins)this.plugins[e]=new t.__plugins[e](this)},t.prototype.destroyPlugins=function(){for(var t in this.plugins)this.plugins[t].destroy(),this.plugins[t]=null;this.plugins=null}}r.__esModule=!0,r.default={mixin:function(t){n(t)}}},{}],125:[function(t,e,r){"use strict";function n(t){var e=t.width,r=t.height,n=t.getContext("2d"),i=n.getImageData(0,0,e,r),o=i.data,s=o.length,a={top:null,left:null,right:null,bottom:null},u=void 0,h=void 0,l=void 0;for(u=0;u<s;u+=4)0!==o[u+3]&&(h=u/4%e,l=~~(u/4/e),null===a.top&&(a.top=l),null===a.left?a.left=h:h<a.left&&(a.left=h),null===a.right?a.right=h+1:a.right<h&&(a.right=h+1),null===a.bottom?a.bottom=l:a.bottom<l&&(a.bottom=l));return e=a.right-a.left,r=a.bottom-a.top+1,{height:r,width:e,data:n.getImageData(a.left,a.top,e,r)}}r.__esModule=!0,r.default=n},{}],126:[function(t,e,r){"use strict";function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}var i=t("./core"),o=n(i),s=t("./mesh"),a=n(s),u=t("./particles"),h=n(u),l=t("./extras"),c=n(l),f=t("./filters"),d=n(f),p=t("./prepare"),v=n(p),y=t("./loaders"),g=n(y),m=t("./interaction"),_=n(m);o.SpriteBatch=function(){throw new ReferenceError("SpriteBatch does not exist any more, please use the new ParticleContainer instead.")},o.AssetLoader=function(){throw new ReferenceError("The loader system was overhauled in pixi v3, please see the new PIXI.loaders.Loader class.")},Object.defineProperties(o,{Stage:{enumerable:!0,get:function(){return o.Container}},DisplayObjectContainer:{enumerable:!0,get:function(){return o.Container}},Strip:{enumerable:!0,get:function(){return a.Mesh}},Rope:{enumerable:!0,get:function(){return a.Rope}},ParticleContainer:{enumerable:!0,get:function(){return h.ParticleContainer}},MovieClip:{enumerable:!0,get:function(){return c.AnimatedSprite}},TilingSprite:{enumerable:!0,get:function(){return c.TilingSprite}},BitmapText:{enumerable:!0,get:function(){return c.BitmapText}},blendModes:{enumerable:!0,get:function(){return o.BLEND_MODES}},scaleModes:{enumerable:!0,get:function(){return o.SCALE_MODES}},BaseTextureCache:{enumerable:!0,get:function(){return o.utils.BaseTextureCache}},TextureCache:{enumerable:!0,get:function(){return o.utils.TextureCache}},math:{enumerable:!0,get:function(){return o}},AbstractFilter:{enumerable:!0,get:function(){return o.Filter}},TransformManual:{enumerable:!0,get:function(){return o.TransformBase}},TARGET_FPMS:{enumerable:!0,get:function(){return o.settings.TARGET_FPMS},set:function(t){o.settings.TARGET_FPMS=t}},FILTER_RESOLUTION:{enumerable:!0,get:function(){return o.settings.FILTER_RESOLUTION},set:function(t){o.settings.FILTER_RESOLUTION=t}},RESOLUTION:{enumerable:!0,get:function(){return o.settings.RESOLUTION},set:function(t){o.settings.RESOLUTION=t}},MIPMAP_TEXTURES:{enumerable:!0,get:function(){return o.settings.MIPMAP_TEXTURES},set:function(t){o.settings.MIPMAP_TEXTURES=t}},SPRITE_BATCH_SIZE:{enumerable:!0,get:function(){return o.settings.SPRITE_BATCH_SIZE},set:function(t){o.settings.SPRITE_BATCH_SIZE=t}},SPRITE_MAX_TEXTURES:{enumerable:!0,get:function(){return o.settings.SPRITE_MAX_TEXTURES},set:function(t){o.settings.SPRITE_MAX_TEXTURES=t}},RETINA_PREFIX:{enumerable:!0,get:function(){return o.settings.RETINA_PREFIX},set:function(t){o.settings.RETINA_PREFIX=t}},DEFAULT_RENDER_OPTIONS:{enumerable:!0,get:function(){return o.settings.RENDER_OPTIONS}}});for(var b=[{parent:"TRANSFORM_MODE",target:"TRANSFORM_MODE"},{parent:"GC_MODES",target:"GC_MODE"},{parent:"WRAP_MODES",target:"WRAP_MODE"},{parent:"SCALE_MODES",target:"SCALE_MODE"},{parent:"PRECISION",target:"PRECISION_FRAGMENT"}],x=0;x<b.length;x++)!function(t){var e=b[t];Object.defineProperty(o[e.parent],"DEFAULT",{enumerable:!0,get:function(){return e.parent,e.target,o.settings[e.target]},set:function(t){e.parent,e.target,o.settings[e.target]=t}})}(x);Object.defineProperties(o.settings,{PRECISION:{enumerable:!0,get:function(){return o.settings.PRECISION_FRAGMENT},set:function(t){o.settings.PRECISION_FRAGMENT=t}}}),Object.defineProperties(c,{MovieClip:{enumerable:!0,get:function(){return c.AnimatedSprite}}}),o.DisplayObject.prototype.generateTexture=function(t,e,r){return t.generateTexture(this,e,r)},o.Graphics.prototype.generateTexture=function(t,e){return this.generateCanvasTexture(t,e)},o.RenderTexture.prototype.render=function(t,e,r,n){this.legacyRenderer.render(t,this,r,e,!n)},o.RenderTexture.prototype.getImage=function(t){return this.legacyRenderer.extract.image(t)},o.RenderTexture.prototype.getBase64=function(t){return this.legacyRenderer.extract.base64(t)},o.RenderTexture.prototype.getCanvas=function(t){return this.legacyRenderer.extract.canvas(t)},o.RenderTexture.prototype.getPixels=function(t){return this.legacyRenderer.pixels(t)},o.Sprite.prototype.setTexture=function(t){this.texture=t},c.BitmapText.prototype.setText=function(t){this.text=t},o.Text.prototype.setText=function(t){this.text=t},o.Text.prototype.setStyle=function(t){this.style=t},o.Text.prototype.determineFontProperties=function(t){return o.Text.calculateFontProperties(t)},Object.defineProperties(o.TextStyle.prototype,{font:{get:function(){var t="number"==typeof this._fontSize?this._fontSize+"px":this._fontSize;return this._fontStyle+" "+this._fontVariant+" "+this._fontWeight+" "+t+" "+this._fontFamily},set:function(t){t.indexOf("italic")>1?this._fontStyle="italic":t.indexOf("oblique")>-1?this._fontStyle="oblique":this._fontStyle="normal",t.indexOf("small-caps")>-1?this._fontVariant="small-caps":this._fontVariant="normal";var e=t.split(" "),r=-1;this._fontSize=26;for(var n=0;n<e.length;++n)if(e[n].match(/(px|pt|em|%)/)){r=n,this._fontSize=e[n];break}this._fontWeight="normal";for(var i=0;i<r;++i)if(e[i].match(/(bold|bolder|lighter|100|200|300|400|500|600|700|800|900)/)){this._fontWeight=e[i];break}if(r>-1&&r<e.length-1){this._fontFamily="";for(var o=r+1;o<e.length;++o)this._fontFamily+=e[o]+" ";this._fontFamily=this._fontFamily.slice(0,-1)}else this._fontFamily="Arial";this.styleID++}}}),o.Texture.prototype.setFrame=function(t){this.frame=t},Object.defineProperties(d,{AbstractFilter:{get:function(){return o.AbstractFilter}},SpriteMaskFilter:{get:function(){return o.SpriteMaskFilter}}}),o.utils.uuid=function(){return o.utils.uid()},o.utils.canUseNewCanvasBlendModes=function(){return o.CanvasTinter.canUseMultiply};var T=!0;Object.defineProperty(o.utils,"_saidHello",{set:function(t){t&&this.skipHello(),T=t},get:function(){return T}}),Object.defineProperty(v.canvas,"UPLOADS_PER_FRAME",{set:function(){},get:function(){return NaN}}),Object.defineProperty(v.webgl,"UPLOADS_PER_FRAME",{set:function(){},get:function(){return NaN}}),Object.defineProperties(g.Resource.prototype,{isJson:{get:function(){return this.type===g.Loader.Resource.TYPE.JSON}},isXml:{get:function(){return this.type===g.Loader.Resource.TYPE.XML}},isImage:{get:function(){return this.type===g.Loader.Resource.TYPE.IMAGE}},isAudio:{get:function(){return this.type===g.Loader.Resource.TYPE.AUDIO}},isVideo:{get:function(){return this.type===g.Loader.Resource.TYPE.VIDEO}}}),Object.defineProperties(g.Loader.prototype,{before:{get:function(){return this.pre}},after:{get:function(){return this.use}}}),Object.defineProperty(_.interactiveTarget,"defaultCursor",{set:function(t){this.cursor=t},get:function(){return this.cursor},enumerable:!0}),Object.defineProperty(_.InteractionManager,"defaultCursorStyle",{set:function(t){this.cursorStyles.default=t},get:function(){return this.cursorStyles.default}}),Object.defineProperty(_.InteractionManager,"currentCursorStyle",{set:function(t){this.currentCursorMode=t},get:function(){return this.currentCursorMode}})},{"./core":64,"./extras":137,"./filters":148,"./interaction":155,"./loaders":158,"./mesh":167,"./particles":170,"./prepare":180}],127:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../../core"),o=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(i),s=new o.Rectangle,a=function(){function t(e){n(this,t),this.renderer=e,e.extract=this}return t.prototype.image=function t(e){var t=new Image;return t.src=this.base64(e),t},t.prototype.base64=function(t){return this.canvas(t).toDataURL()},t.prototype.canvas=function(t){var e=this.renderer,r=void 0,n=void 0,i=void 0,a=void 0;t&&(a=t instanceof o.RenderTexture?t:e.generateTexture(t)),a?(r=a.baseTexture._canvasRenderTarget.context,n=a.baseTexture._canvasRenderTarget.resolution,i=a.frame):(r=e.rootContext,i=s,i.width=this.renderer.width,i.height=this.renderer.height);var u=i.width*n,h=i.height*n,l=new o.CanvasRenderTarget(u,h),c=r.getImageData(i.x*n,i.y*n,u,h);return l.context.putImageData(c,0,0),l.canvas},t.prototype.pixels=function(t){var e=this.renderer,r=void 0,n=void 0,i=void 0,a=void 0;return t&&(a=t instanceof o.RenderTexture?t:e.generateTexture(t)),a?(r=a.baseTexture._canvasRenderTarget.context,n=a.baseTexture._canvasRenderTarget.resolution,i=a.frame):(r=e.rootContext,i=s,i.width=e.width,i.height=e.height),r.getImageData(0,0,i.width*n,i.height*n).data},t.prototype.destroy=function(){this.renderer.extract=null,this.renderer=null},t}();r.default=a,o.CanvasRenderer.registerPlugin("extract",a)},{"../../core":64}],128:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0;var i=t("./webgl/WebGLExtract");Object.defineProperty(r,"webgl",{enumerable:!0,get:function(){return n(i).default}});var o=t("./canvas/CanvasExtract");Object.defineProperty(r,"canvas",{enumerable:!0,get:function(){return n(o).default}})},{"./canvas/CanvasExtract":127,"./webgl/WebGLExtract":129}],129:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../../core"),o=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(i),s=new o.Rectangle,a=function(){function t(e){n(this,t),this.renderer=e,e.extract=this}return t.prototype.image=function t(e){var t=new Image;return t.src=this.base64(e),t},t.prototype.base64=function(t){return this.canvas(t).toDataURL()},t.prototype.canvas=function(t){var e=this.renderer,r=void 0,n=void 0,i=void 0,a=!1,u=void 0;t&&(u=t instanceof o.RenderTexture?t:this.renderer.generateTexture(t)),u?(r=u.baseTexture._glRenderTargets[this.renderer.CONTEXT_UID],n=r.resolution,i=u.frame,a=!1):(r=this.renderer.rootRenderTarget,n=r.resolution,a=!0,i=s,i.width=r.size.width,i.height=r.size.height);var h=i.width*n,l=i.height*n,c=new o.CanvasRenderTarget(h,l);if(r){e.bindRenderTarget(r);var f=new Uint8Array(4*h*l),d=e.gl;d.readPixels(i.x*n,i.y*n,h,l,d.RGBA,d.UNSIGNED_BYTE,f);var p=c.context.getImageData(0,0,h,l);p.data.set(f),c.context.putImageData(p,0,0),a&&(c.context.scale(1,-1),c.context.drawImage(c.canvas,0,-l))}return c.canvas},t.prototype.pixels=function(t){var e=this.renderer,r=void 0,n=void 0,i=void 0,a=void 0;t&&(a=t instanceof o.RenderTexture?t:this.renderer.generateTexture(t)),a?(r=a.baseTexture._glRenderTargets[this.renderer.CONTEXT_UID],n=r.resolution,i=a.frame):(r=this.renderer.rootRenderTarget,n=r.resolution,i=s,i.width=r.size.width,i.height=r.size.height);var u=i.width*n,h=i.height*n,l=new Uint8Array(4*u*h);if(r){e.bindRenderTarget(r);var c=e.gl;c.readPixels(i.x*n,i.y*n,u,h,c.RGBA,c.UNSIGNED_BYTE,l)}return l},t.prototype.destroy=function(){this.renderer.extract=null,this.renderer=null},t}();r.default=a,o.WebGLRenderer.registerPlugin("extract",a)},{"../../core":64}],130:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),a=t("../core"),u=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(a),h=function(t){function e(r,o){n(this,e);var s=i(this,t.call(this,r[0]instanceof u.Texture?r[0]:r[0].texture));return s._textures=null,s._durations=null,s.textures=r,s._autoUpdate=o!==!1,s.animationSpeed=1,s.loop=!0,s.onComplete=null,s.onFrameChange=null,s._currentTime=0,s.playing=!1,s}return o(e,t),e.prototype.stop=function(){this.playing&&(this.playing=!1,this._autoUpdate&&u.ticker.shared.remove(this.update,this))},e.prototype.play=function(){this.playing||(this.playing=!0,this._autoUpdate&&u.ticker.shared.add(this.update,this))},e.prototype.gotoAndStop=function(t){this.stop();var e=this.currentFrame;this._currentTime=t,e!==this.currentFrame&&this.updateTexture()},e.prototype.gotoAndPlay=function(t){var e=this.currentFrame;this._currentTime=t,e!==this.currentFrame&&this.updateTexture(),this.play()},e.prototype.update=function(t){var e=this.animationSpeed*t,r=this.currentFrame;if(null!==this._durations){var n=this._currentTime%1*this._durations[this.currentFrame];for(n+=e/60*1e3;n<0;)this._currentTime--,n+=this._durations[this.currentFrame];var i=Math.sign(this.animationSpeed*t);for(this._currentTime=Math.floor(this._currentTime);n>=this._durations[this.currentFrame];)n-=this._durations[this.currentFrame]*i,this._currentTime+=i;this._currentTime+=n/this._durations[this.currentFrame]}else this._currentTime+=e;this._currentTime<0&&!this.loop?(this.gotoAndStop(0),this.onComplete&&this.onComplete()):this._currentTime>=this._textures.length&&!this.loop?(this.gotoAndStop(this._textures.length-1),this.onComplete&&this.onComplete()):r!==this.currentFrame&&this.updateTexture()},e.prototype.updateTexture=function(){this._texture=this._textures[this.currentFrame],this._textureID=-1,this.onFrameChange&&this.onFrameChange(this.currentFrame)},e.prototype.destroy=function(){this.stop(),t.prototype.destroy.call(this)},e.fromFrames=function(t){for(var r=[],n=0;n<t.length;++n)r.push(u.Texture.fromFrame(t[n]));return new e(r)},e.fromImages=function(t){for(var r=[],n=0;n<t.length;++n)r.push(u.Texture.fromImage(t[n]));return new e(r)},s(e,[{key:"totalFrames",get:function(){return this._textures.length}},{key:"textures",get:function(){return this._textures},set:function(t){if(t[0]instanceof u.Texture)this._textures=t,this._durations=null;else{this._textures=[],this._durations=[];for(var e=0;e<t.length;e++)this._textures.push(t[e].texture),this._durations.push(t[e].time)}}},{key:"currentFrame",get:function(){var t=Math.floor(this._currentTime)%this._textures.length;return t<0&&(t+=this._textures.length),t}}]),e}(u.Sprite);r.default=h},{"../core":64}],131:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),a=t("../core"),u=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(a),h=t("../core/math/ObservablePoint"),l=function(t){return t&&t.__esModule?t:{default:t}}(h),c=function(t){function e(r){var o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};n(this,e);var s=i(this,t.call(this));return s._textWidth=0,s._textHeight=0,s._glyphs=[],s._font={tint:void 0!==o.tint?o.tint:16777215,align:o.align||"left",name:null,size:0},s.font=o.font,s._text=r,s.maxWidth=0,s.maxLineHeight=0,s._anchor=new l.default(function(){s.dirty=!0},s,0,0),s.dirty=!1,s.updateText(),s}return o(e,t),e.prototype.updateText=function(){for(var t=e.fonts[this._font.name],r=this._font.size/t.size,n=new u.Point,i=[],o=[],s=null,a=0,h=0,l=0,c=-1,f=0,d=0,p=0;p<this.text.length;p++){var v=this.text.charCodeAt(p);if(/(\s)/.test(this.text.charAt(p))&&(c=p,f=a),/(?:\r\n|\r|\n)/.test(this.text.charAt(p)))o.push(a),h=Math.max(h,a),l++,n.x=0,n.y+=t.lineHeight,s=null;else if(c!==-1&&this.maxWidth>0&&n.x*r>this.maxWidth)u.utils.removeItems(i,c,p-c),p=c,c=-1,o.push(f),h=Math.max(h,f),l++,n.x=0,n.y+=t.lineHeight,s=null;else{var y=t.chars[v];y&&(s&&y.kerning[s]&&(n.x+=y.kerning[s]),i.push({texture:y.texture,line:l,charCode:v,position:new u.Point(n.x+y.xOffset,n.y+y.yOffset)}),a=n.x+(y.texture.width+y.xOffset),n.x+=y.xAdvance,d=Math.max(d,y.yOffset+y.texture.height),s=v)}}o.push(a),h=Math.max(h,a);for(var g=[],m=0;m<=l;m++){var _=0;"right"===this._font.align?_=h-o[m]:"center"===this._font.align&&(_=(h-o[m])/2),g.push(_)}for(var b=i.length,x=this.tint,T=0;T<b;T++){var w=this._glyphs[T];w?w.texture=i[T].texture:(w=new u.Sprite(i[T].texture),this._glyphs.push(w)),w.position.x=(i[T].position.x+g[i[T].line])*r,w.position.y=i[T].position.y*r,w.scale.x=w.scale.y=r,w.tint=x,w.parent||this.addChild(w)}for(var E=b;E<this._glyphs.length;++E)this.removeChild(this._glyphs[E]);if(this._textWidth=h*r,this._textHeight=(n.y+t.lineHeight)*r,0!==this.anchor.x||0!==this.anchor.y)for(var S=0;S<b;S++)this._glyphs[S].x-=this._textWidth*this.anchor.x,this._glyphs[S].y-=this._textHeight*this.anchor.y;this.maxLineHeight=d*r},e.prototype.updateTransform=function(){this.validate(),this.containerUpdateTransform()},e.prototype.getLocalBounds=function(){return this.validate(),t.prototype.getLocalBounds.call(this)},e.prototype.validate=function(){this.dirty&&(this.updateText(),this.dirty=!1)},e.registerFont=function(t,r){var n={},i=t.getElementsByTagName("info")[0],o=t.getElementsByTagName("common")[0];n.font=i.getAttribute("face"),n.size=parseInt(i.getAttribute("size"),10),n.lineHeight=parseInt(o.getAttribute("lineHeight"),10),n.chars={};for(var s=t.getElementsByTagName("char"),a=0;a<s.length;a++){var h=s[a],l=parseInt(h.getAttribute("id"),10),c=new u.Rectangle(parseInt(h.getAttribute("x"),10)+r.frame.x,parseInt(h.getAttribute("y"),10)+r.frame.y,parseInt(h.getAttribute("width"),10),parseInt(h.getAttribute("height"),10));n.chars[l]={xOffset:parseInt(h.getAttribute("xoffset"),10),yOffset:parseInt(h.getAttribute("yoffset"),10),xAdvance:parseInt(h.getAttribute("xadvance"),10),kerning:{},texture:new u.Texture(r.baseTexture,c)}}for(var f=t.getElementsByTagName("kerning"),d=0;d<f.length;d++){var p=f[d],v=parseInt(p.getAttribute("first"),10),y=parseInt(p.getAttribute("second"),10),g=parseInt(p.getAttribute("amount"),10);n.chars[y]&&(n.chars[y].kerning[v]=g)}return e.fonts[n.font]=n,n},s(e,[{key:"tint",get:function(){return this._font.tint},set:function(t){this._font.tint="number"==typeof t&&t>=0?t:16777215,this.dirty=!0}},{key:"align",get:function(){return this._font.align},set:function(t){this._font.align=t||"left",this.dirty=!0}},{key:"anchor",get:function(){return this._anchor},set:function(t){"number"==typeof t?this._anchor.set(t):this._anchor.copy(t)}},{key:"font",get:function(){return this._font},set:function(t){t&&("string"==typeof t?(t=t.split(" "),this._font.name=1===t.length?t[0]:t.slice(1).join(" "),this._font.size=t.length>=2?parseInt(t[0],10):e.fonts[this._font.name].size):(this._font.name=t.name,this._font.size="number"==typeof t.size?t.size:parseInt(t.size,10)),this.dirty=!0)}},{key:"text",get:function(){return this._text},set:function(t){t=t.toString()||" ",this._text!==t&&(this._text=t,this.dirty=!0)}},{key:"textWidth",get:function(){return this.validate(),this._textWidth}},{key:"textHeight",get:function(){return this.validate(),this._textHeight}}]),e}(u.Container);r.default=c,c.fonts={}},{"../core":64,"../core/math/ObservablePoint":67}],132:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),o=t("../core/math/Matrix"),s=function(t){return t&&t.__esModule?t:{default:t}}(o),a=new s.default,u=function(){function t(e,r){n(this,t),this._texture=e,this.mapCoord=new s.default,this.uClampFrame=new Float32Array(4),this.uClampOffset=new Float32Array(2),this._lastTextureID=-1,this.clampOffset=0,this.clampMargin=void 0===r?.5:r}return t.prototype.update=function(t){var e=this._texture;if(e&&e.valid&&(t||this._lastTextureID!==e._updateID)){this._lastTextureID=e._updateID;var r=e._uvs;this.mapCoord.set(r.x1-r.x0,r.y1-r.y0,r.x3-r.x0,r.y3-r.y0,r.x0,r.y0);var n=e.orig,i=e.trim;i&&(a.set(n.width/i.width,0,0,n.height/i.height,-i.x/i.width,-i.y/i.height),this.mapCoord.append(a));var o=e.baseTexture,s=this.uClampFrame,u=this.clampMargin/o.resolution,h=this.clampOffset;s[0]=(e._frame.x+u+h)/o.width,s[1]=(e._frame.y+u+h)/o.height,s[2]=(e._frame.x+e._frame.width-u+h)/o.width,s[3]=(e._frame.y+e._frame.height-u+h)/o.height,this.uClampOffset[0]=h/o.realWidth,this.uClampOffset[1]=h/o.realHeight}},i(t,[{key:"texture",get:function(){return this._texture},set:function(t){this._texture=t,this._lastTextureID=-1}}]),t}();r.default=u},{"../core/math/Matrix":66}],133:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called")
+;return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),u=t("../core"),h=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(u),l=t("../core/sprites/canvas/CanvasTinter"),c=n(l),f=t("./TextureTransform"),d=n(f),p=new h.Point,v=function(t){function e(r){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:100;i(this,e);var a=o(this,t.call(this,r));return a.tileTransform=new h.TransformStatic,a._width=n,a._height=s,a._canvasPattern=null,a.uvTransform=r.transform||new d.default(r),a.pluginName="tilingSprite",a.uvRespectAnchor=!1,a}return s(e,t),e.prototype._onTextureUpdate=function(){this.uvTransform&&(this.uvTransform.texture=this._texture)},e.prototype._renderWebGL=function(t){var e=this._texture;e&&e.valid&&(this.tileTransform.updateLocalTransform(),this.uvTransform.update(),t.setObjectRenderer(t.plugins[this.pluginName]),t.plugins[this.pluginName].render(this))},e.prototype._renderCanvas=function(t){var e=this._texture;if(e.baseTexture.hasLoaded){var r=t.context,n=this.worldTransform,i=t.resolution,o=e.baseTexture,s=e.baseTexture.resolution,a=this.tilePosition.x/this.tileScale.x%e._frame.width,u=this.tilePosition.y/this.tileScale.y%e._frame.height;if(!this._canvasPattern){var l=new h.CanvasRenderTarget(e._frame.width,e._frame.height,s);16777215!==this.tint?(this.cachedTint!==this.tint&&(this.cachedTint=this.tint,this.tintedTexture=c.default.getTintedTexture(this,this.tint)),l.context.drawImage(this.tintedTexture,0,0)):l.context.drawImage(o.source,-e._frame.x,-e._frame.y),this._canvasPattern=l.context.createPattern(l.canvas,"repeat")}r.globalAlpha=this.worldAlpha,r.setTransform(n.a*i,n.b*i,n.c*i,n.d*i,n.tx*i,n.ty*i),t.setBlendMode(this.blendMode),r.fillStyle=this._canvasPattern,r.scale(this.tileScale.x/s,this.tileScale.y/s);var f=this.anchor.x*-this._width,d=this.anchor.y*-this._height;this.uvRespectAnchor?(r.translate(a,u),r.fillRect(-a+f,-u+d,this._width/this.tileScale.x*s,this._height/this.tileScale.y*s)):(r.translate(a+f,u+d),r.fillRect(-a,-u,this._width/this.tileScale.x*s,this._height/this.tileScale.y*s))}},e.prototype._calculateBounds=function(){var t=this._width*-this._anchor._x,e=this._height*-this._anchor._y,r=this._width*(1-this._anchor._x),n=this._height*(1-this._anchor._y);this._bounds.addFrame(this.transform,t,e,r,n)},e.prototype.getLocalBounds=function(e){return 0===this.children.length?(this._bounds.minX=this._width*-this._anchor._x,this._bounds.minY=this._height*-this._anchor._y,this._bounds.maxX=this._width*(1-this._anchor._x),this._bounds.maxY=this._height*(1-this._anchor._x),e||(this._localBoundsRect||(this._localBoundsRect=new h.Rectangle),e=this._localBoundsRect),this._bounds.getRectangle(e)):t.prototype.getLocalBounds.call(this,e)},e.prototype.containsPoint=function(t){this.worldTransform.applyInverse(t,p);var e=this._width,r=this._height,n=-e*this.anchor._x;if(p.x>n&&p.x<n+e){var i=-r*this.anchor._y;if(p.y>i&&p.y<i+r)return!0}return!1},e.prototype.destroy=function(){t.prototype.destroy.call(this),this.tileTransform=null,this.uvTransform=null},e.from=function(t,r,n){return new e(h.Texture.from(t),r,n)},e.fromFrame=function(t,r,n){var i=h.utils.TextureCache[t];if(!i)throw new Error('The frameId "'+t+'" does not exist in the texture cache '+this);return new e(i,r,n)},e.fromImage=function(t,r,n,i,o){return new e(h.Texture.fromImage(t,i,o),r,n)},a(e,[{key:"clampMargin",get:function(){return this.uvTransform.clampMargin},set:function(t){this.uvTransform.clampMargin=t,this.uvTransform.update(!0)}},{key:"tileScale",get:function(){return this.tileTransform.scale},set:function(t){this.tileTransform.scale.copy(t)}},{key:"tilePosition",get:function(){return this.tileTransform.position},set:function(t){this.tileTransform.position.copy(t)}},{key:"width",get:function(){return this._width},set:function(t){this._width=t}},{key:"height",get:function(){return this._height},set:function(t){this._height=t}}]),e}(h.Sprite);r.default=v},{"../core":64,"../core/sprites/canvas/CanvasTinter":103,"./TextureTransform":132}],134:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i=t("../core"),o=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(i),s=o.DisplayObject,a=new o.Matrix;s.prototype._cacheAsBitmap=!1,s.prototype._cacheData=!1;var u=function t(){n(this,t),this.originalRenderWebGL=null,this.originalRenderCanvas=null,this.originalCalculateBounds=null,this.originalGetLocalBounds=null,this.originalUpdateTransform=null,this.originalHitTest=null,this.originalDestroy=null,this.originalMask=null,this.originalFilterArea=null,this.sprite=null};Object.defineProperties(s.prototype,{cacheAsBitmap:{get:function(){return this._cacheAsBitmap},set:function(t){if(this._cacheAsBitmap!==t){this._cacheAsBitmap=t;var e=void 0;t?(this._cacheData||(this._cacheData=new u),e=this._cacheData,e.originalRenderWebGL=this.renderWebGL,e.originalRenderCanvas=this.renderCanvas,e.originalUpdateTransform=this.updateTransform,e.originalCalculateBounds=this._calculateBounds,e.originalGetLocalBounds=this.getLocalBounds,e.originalDestroy=this.destroy,e.originalContainsPoint=this.containsPoint,e.originalMask=this._mask,e.originalFilterArea=this.filterArea,this.renderWebGL=this._renderCachedWebGL,this.renderCanvas=this._renderCachedCanvas,this.destroy=this._cacheAsBitmapDestroy):(e=this._cacheData,e.sprite&&this._destroyCachedDisplayObject(),this.renderWebGL=e.originalRenderWebGL,this.renderCanvas=e.originalRenderCanvas,this._calculateBounds=e.originalCalculateBounds,this.getLocalBounds=e.originalGetLocalBounds,this.destroy=e.originalDestroy,this.updateTransform=e.originalUpdateTransform,this.containsPoint=e.originalContainsPoint,this._mask=e.originalMask,this.filterArea=e.originalFilterArea)}}}}),s.prototype._renderCachedWebGL=function(t){!this.visible||this.worldAlpha<=0||!this.renderable||(this._initCachedDisplayObject(t),this._cacheData.sprite._transformID=-1,this._cacheData.sprite.worldAlpha=this.worldAlpha,this._cacheData.sprite._renderWebGL(t))},s.prototype._initCachedDisplayObject=function(t){if(!this._cacheData||!this._cacheData.sprite){var e=this.alpha;this.alpha=1,t.currentRenderer.flush();var r=this.getLocalBounds().clone();if(this._filters){var n=this._filters[0].padding;r.pad(n)}var i=t._activeRenderTarget,s=t.filterManager.filterStack,u=o.RenderTexture.create(0|r.width,0|r.height),h=a;h.tx=-r.x,h.ty=-r.y,this.transform.worldTransform.identity(),this.renderWebGL=this._cacheData.originalRenderWebGL,t.render(this,u,!0,h,!0),t.bindRenderTarget(i),t.filterManager.filterStack=s,this.renderWebGL=this._renderCachedWebGL,this.updateTransform=this.displayObjectUpdateTransform,this._mask=null,this.filterArea=null;var l=new o.Sprite(u);l.transform.worldTransform=this.transform.worldTransform,l.anchor.x=-(r.x/r.width),l.anchor.y=-(r.y/r.height),l.alpha=e,l._bounds=this._bounds,this._calculateBounds=this._calculateCachedBounds,this.getLocalBounds=this._getCachedLocalBounds,this._cacheData.sprite=l,this.transform._parentID=-1,this.updateTransform(),this.containsPoint=l.containsPoint.bind(l)}},s.prototype._renderCachedCanvas=function(t){!this.visible||this.worldAlpha<=0||!this.renderable||(this._initCachedDisplayObjectCanvas(t),this._cacheData.sprite.worldAlpha=this.worldAlpha,this._cacheData.sprite.renderCanvas(t))},s.prototype._initCachedDisplayObjectCanvas=function(t){if(!this._cacheData||!this._cacheData.sprite){var e=this.getLocalBounds(),r=this.alpha;this.alpha=1;var n=t.context,i=o.RenderTexture.create(0|e.width,0|e.height),s=a;this.transform.localTransform.copy(s),s.invert(),s.tx-=e.x,s.ty-=e.y,this.renderCanvas=this._cacheData.originalRenderCanvas,t.render(this,i,!0,s,!1),t.context=n,this.renderCanvas=this._renderCachedCanvas,this._calculateBounds=this._calculateCachedBounds,this._mask=null,this.filterArea=null;var u=new o.Sprite(i);u.transform.worldTransform=this.transform.worldTransform,u.anchor.x=-(e.x/e.width),u.anchor.y=-(e.y/e.height),u._bounds=this._bounds,u.alpha=r,this.updateTransform(),this.updateTransform=this.displayObjectUpdateTransform,this._cacheData.sprite=u,this.containsPoint=u.containsPoint.bind(u)}},s.prototype._calculateCachedBounds=function(){this._cacheData.sprite._calculateBounds()},s.prototype._getCachedLocalBounds=function(){return this._cacheData.sprite.getLocalBounds()},s.prototype._destroyCachedDisplayObject=function(){this._cacheData.sprite._texture.destroy(!0),this._cacheData.sprite=null},s.prototype._cacheAsBitmapDestroy=function(t){this.cacheAsBitmap=!1,this.destroy(t)}},{"../core":64}],135:[function(t,e,r){"use strict";var n=t("../core"),i=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(n);i.DisplayObject.prototype.name=null,i.Container.prototype.getChildByName=function(t){for(var e=0;e<this.children.length;e++)if(this.children[e].name===t)return this.children[e];return null}},{"../core":64}],136:[function(t,e,r){"use strict";var n=t("../core"),i=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(n);i.DisplayObject.prototype.getGlobalPosition=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:new i.Point,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return this.parent?this.parent.toGlobal(this.position,t,e):(t.x=this.position.x,t.y=this.position.y),t}},{"../core":64}],137:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0,r.BitmapText=r.TilingSpriteRenderer=r.TilingSprite=r.AnimatedSprite=r.TextureTransform=void 0;var i=t("./TextureTransform");Object.defineProperty(r,"TextureTransform",{enumerable:!0,get:function(){return n(i).default}});var o=t("./AnimatedSprite");Object.defineProperty(r,"AnimatedSprite",{enumerable:!0,get:function(){return n(o).default}});var s=t("./TilingSprite");Object.defineProperty(r,"TilingSprite",{enumerable:!0,get:function(){return n(s).default}});var a=t("./webgl/TilingSpriteRenderer");Object.defineProperty(r,"TilingSpriteRenderer",{enumerable:!0,get:function(){return n(a).default}});var u=t("./BitmapText");Object.defineProperty(r,"BitmapText",{enumerable:!0,get:function(){return n(u).default}}),t("./cacheAsBitmap"),t("./getChildByName"),t("./getGlobalPosition")},{"./AnimatedSprite":130,"./BitmapText":131,"./TextureTransform":132,"./TilingSprite":133,"./cacheAsBitmap":134,"./getChildByName":135,"./getGlobalPosition":136,"./webgl/TilingSpriteRenderer":138}],138:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=t("../../core"),a=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(s),u=t("../../core/const"),h=(t("path"),new a.Matrix),l=new Float32Array(4),c=function(t){function e(r){n(this,e);var o=i(this,t.call(this,r));return o.shader=null,o.simpleShader=null,o.quad=null,o}return o(e,t),e.prototype.onContextChange=function(){var t=this.renderer.gl;this.shader=new a.Shader(t,"attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\nuniform mat3 translationMatrix;\nuniform mat3 uTransform;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n\n    vTextureCoord = (uTransform * vec3(aTextureCoord, 1.0)).xy;\n}\n","varying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\nuniform vec4 uColor;\nuniform mat3 uMapCoord;\nuniform vec4 uClampFrame;\nuniform vec2 uClampOffset;\n\nvoid main(void)\n{\n    vec2 coord = mod(vTextureCoord - uClampOffset, vec2(1.0, 1.0)) + uClampOffset;\n    coord = (uMapCoord * vec3(coord, 1.0)).xy;\n    coord = clamp(coord, uClampFrame.xy, uClampFrame.zw);\n\n    vec4 sample = texture2D(uSampler, coord);\n    vec4 color = vec4(uColor.rgb * uColor.a, uColor.a);\n\n    gl_FragColor = sample * color ;\n}\n"),this.simpleShader=new a.Shader(t,"attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\nuniform mat3 translationMatrix;\nuniform mat3 uTransform;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n\n    vTextureCoord = (uTransform * vec3(aTextureCoord, 1.0)).xy;\n}\n","varying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\nuniform vec4 uColor;\n\nvoid main(void)\n{\n    vec4 sample = texture2D(uSampler, vTextureCoord);\n    vec4 color = vec4(uColor.rgb * uColor.a, uColor.a);\n    gl_FragColor = sample * color;\n}\n"),this.renderer.bindVao(null),this.quad=new a.Quad(t,this.renderer.state.attribState),this.quad.initVao(this.shader)},e.prototype.render=function(t){var e=this.renderer,r=this.quad;e.bindVao(r.vao);var n=r.vertices;n[0]=n[6]=t._width*-t.anchor.x,n[1]=n[3]=t._height*-t.anchor.y,n[2]=n[4]=t._width*(1-t.anchor.x),n[5]=n[7]=t._height*(1-t.anchor.y),t.uvRespectAnchor&&(n=r.uvs,n[0]=n[6]=-t.anchor.x,n[1]=n[3]=-t.anchor.y,n[2]=n[4]=1-t.anchor.x,n[5]=n[7]=1-t.anchor.y),r.upload();var i=t._texture,o=i.baseTexture,s=t.tileTransform.localTransform,c=t.uvTransform,f=o.isPowerOfTwo&&i.frame.width===o.width&&i.frame.height===o.height;f&&(o._glTextures[e.CONTEXT_UID]?f=o.wrapMode!==u.WRAP_MODES.CLAMP:o.wrapMode===u.WRAP_MODES.CLAMP&&(o.wrapMode=u.WRAP_MODES.REPEAT));var d=f?this.simpleShader:this.shader;e.bindShader(d);var p=i.width,v=i.height,y=t._width,g=t._height;h.set(s.a*p/y,s.b*p/g,s.c*v/y,s.d*v/g,s.tx/y,s.ty/g),h.invert(),f?h.append(c.mapCoord):(d.uniforms.uMapCoord=c.mapCoord.toArray(!0),d.uniforms.uClampFrame=c.uClampFrame,d.uniforms.uClampOffset=c.uClampOffset),d.uniforms.uTransform=h.toArray(!0);var m=l;a.utils.hex2rgb(t.tint,m),m[3]=t.worldAlpha,d.uniforms.uColor=m,d.uniforms.translationMatrix=t.transform.worldTransform.toArray(!0),d.uniforms.uSampler=e.bindTexture(i),e.setBlendMode(t.blendMode),r.vao.draw(this.renderer.gl.TRIANGLES,6,0)},e}(a.ObjectRenderer);r.default=c,a.WebGLRenderer.registerPlugin("tilingSprite",c)},{"../../core":64,"../../core/const":45,path:23}],139:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),u=t("../../core"),h=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(u),l=t("./BlurXFilter"),c=n(l),f=t("./BlurYFilter"),d=n(f),p=function(t){function e(r,n,s,a){i(this,e);var u=o(this,t.call(this));return u.blurXFilter=new c.default(r,n,s,a),u.blurYFilter=new d.default(r,n,s,a),u.padding=0,u.resolution=s||h.settings.RESOLUTION,u.quality=n||4,u.blur=r||8,u}return s(e,t),e.prototype.apply=function(t,e,r){var n=t.getRenderTarget(!0);this.blurXFilter.apply(t,e,n,!0),this.blurYFilter.apply(t,n,r,!1),t.returnRenderTarget(n)},a(e,[{key:"blur",get:function(){return this.blurXFilter.blur},set:function(t){this.blurXFilter.blur=this.blurYFilter.blur=t,this.padding=2*Math.max(Math.abs(this.blurXFilter.strength),Math.abs(this.blurYFilter.strength))}},{key:"quality",get:function(){return this.blurXFilter.quality},set:function(t){this.blurXFilter.quality=this.blurYFilter.quality=t}},{key:"blurX",get:function(){return this.blurXFilter.blur},set:function(t){this.blurXFilter.blur=t,this.padding=2*Math.max(Math.abs(this.blurXFilter.strength),Math.abs(this.blurYFilter.strength))}},{key:"blurY",get:function(){return this.blurYFilter.blur},set:function(t){this.blurYFilter.blur=t,this.padding=2*Math.max(Math.abs(this.blurXFilter.strength),Math.abs(this.blurYFilter.strength))}}]),e}(h.Filter);r.default=p},{"../../core":64,"./BlurXFilter":140,"./BlurYFilter":141}],140:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),u=t("../../core"),h=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(u),l=t("./generateBlurVertSource"),c=n(l),f=t("./generateBlurFragSource"),d=n(f),p=t("./getMaxBlurKernelSize"),v=n(p),y=function(t){function e(r,n,s,a){i(this,e),a=a||5;var u=(0,c.default)(a,!0),l=(0,d.default)(a),f=o(this,t.call(this,u,l));return f.resolution=s||h.settings.RESOLUTION,f._quality=0,f.quality=n||4,f.strength=r||8,f.firstRun=!0,f}return s(e,t),e.prototype.apply=function(t,e,r,n){if(this.firstRun){var i=t.renderer.gl,o=(0,v.default)(i);this.vertexSrc=(0,c.default)(o,!0),this.fragmentSrc=(0,d.default)(o),this.firstRun=!1}if(this.uniforms.strength=1/r.size.width*(r.size.width/e.size.width),this.uniforms.strength*=this.strength,this.uniforms.strength/=this.passes,1===this.passes)t.applyFilter(this,e,r,n);else{for(var s=t.getRenderTarget(!0),a=e,u=s,h=0;h<this.passes-1;h++){t.applyFilter(this,a,u,!0);var l=u;u=a,a=l}t.applyFilter(this,a,r,n),t.returnRenderTarget(s)}},a(e,[{key:"blur",get:function(){return this.strength},set:function(t){this.padding=2*Math.abs(t),this.strength=t}},{key:"quality",get:function(){return this._quality},set:function(t){this._quality=t,this.passes=t}}]),e}(h.Filter);r.default=y},{"../../core":64,"./generateBlurFragSource":142,"./generateBlurVertSource":143,"./getMaxBlurKernelSize":144}],141:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),u=t("../../core"),h=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(u),l=t("./generateBlurVertSource"),c=n(l),f=t("./generateBlurFragSource"),d=n(f),p=t("./getMaxBlurKernelSize"),v=n(p),y=function(t){function e(r,n,s,a){i(this,e),a=a||5;var u=(0,c.default)(a,!1),l=(0,d.default)(a),f=o(this,t.call(this,u,l));return f.resolution=s||h.settings.RESOLUTION,f._quality=0,f.quality=n||4,f.strength=r||8,f.firstRun=!0,f}return s(e,t),e.prototype.apply=function(t,e,r,n){if(this.firstRun){var i=t.renderer.gl,o=(0,v.default)(i);this.vertexSrc=(0,c.default)(o,!1),this.fragmentSrc=(0,d.default)(o),this.firstRun=!1}if(this.uniforms.strength=1/r.size.height*(r.size.height/e.size.height),this.uniforms.strength*=this.strength,this.uniforms.strength/=this.passes,1===this.passes)t.applyFilter(this,e,r,n);else{for(var s=t.getRenderTarget(!0),a=e,u=s,h=0;h<this.passes-1;h++){t.applyFilter(this,a,u,!0);var l=u;u=a,a=l}t.applyFilter(this,a,r,n),t.returnRenderTarget(s)}},a(e,[{key:"blur",get:function(){return this.strength},set:function(t){this.padding=2*Math.abs(t),this.strength=t}},{key:"quality",get:function(){return this._quality},set:function(t){this._quality=t,this.passes=t}}]),e}(h.Filter);r.default=y},{"../../core":64,"./generateBlurFragSource":142,"./generateBlurVertSource":143,"./getMaxBlurKernelSize":144}],142:[function(t,e,r){"use strict";function n(t){for(var e=i[t],r=e.length,n=o,s="",a="gl_FragColor += texture2D(uSampler, vBlurTexCoords[%index%]) * %value%;",u=void 0,h=0;h<t;h++){var l=a.replace("%index%",h);u=h,h>=r&&(u=t-h-1),l=l.replace("%value%",e[u]),s+=l,s+="\n"}return n=n.replace("%blur%",s),n=n.replace("%size%",t)}r.__esModule=!0,r.default=n;var i={5:[.153388,.221461,.250301],7:[.071303,.131514,.189879,.214607],9:[.028532,.067234,.124009,.179044,.20236],11:[.0093,.028002,.065984,.121703,.175713,.198596],13:[.002406,.009255,.027867,.065666,.121117,.174868,.197641],15:[489e-6,.002403,.009246,.02784,.065602,.120999,.174697,.197448]},o=["varying vec2 vBlurTexCoords[%size%];","uniform sampler2D uSampler;","void main(void)","{","    gl_FragColor = vec4(0.0);","    %blur%","}"].join("\n")},{}],143:[function(t,e,r){"use strict";function n(t,e){var r=Math.ceil(t/2),n=i,o="",s=void 0;s=e?"vBlurTexCoords[%index%] = aTextureCoord + vec2(%sampleIndex% * strength, 0.0);":"vBlurTexCoords[%index%] = aTextureCoord + vec2(0.0, %sampleIndex% * strength);";for(var a=0;a<t;a++){var u=s.replace("%index%",a);u=u.replace("%sampleIndex%",a-(r-1)+".0"),o+=u,o+="\n"}return n=n.replace("%blur%",o),n=n.replace("%size%",t)}r.__esModule=!0,r.default=n;var i=["attribute vec2 aVertexPosition;","attribute vec2 aTextureCoord;","uniform float strength;","uniform mat3 projectionMatrix;","varying vec2 vBlurTexCoords[%size%];","void main(void)","{","gl_Position = vec4((projectionMatrix * vec3((aVertexPosition), 1.0)).xy, 0.0, 1.0);","%blur%","}"].join("\n")},{}],144:[function(t,e,r){"use strict";function n(t){for(var e=t.getParameter(t.MAX_VARYING_VECTORS),r=15;r>e;)r-=2;return r}r.__esModule=!0,r.default=n},{}],145:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),a=t("../../core"),u=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(a),h=(t("path"),function(t){function e(){n(this,e);var r=i(this,t.call(this,"attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n    vTextureCoord = aTextureCoord;\n}","varying vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform float m[20];\n\nvoid main(void)\n{\n    vec4 c = texture2D(uSampler, vTextureCoord);\n    // Un-premultiply alpha before applying the color matrix. See issue #3539.\n    if (c.a > 0.0) {\n      c.rgb /= c.a;\n    }\n    vec4 result;\n    result.r = (m[0] * c.r);\n        result.r += (m[1] * c.g);\n        result.r += (m[2] * c.b);\n        result.r += (m[3] * c.a);\n        result.r += m[4];\n\n    result.g = (m[5] * c.r);\n        result.g += (m[6] * c.g);\n        result.g += (m[7] * c.b);\n        result.g += (m[8] * c.a);\n        result.g += m[9];\n\n    result.b = (m[10] * c.r);\n       result.b += (m[11] * c.g);\n       result.b += (m[12] * c.b);\n       result.b += (m[13] * c.a);\n       result.b += m[14];\n\n    result.a = (m[15] * c.r);\n       result.a += (m[16] * c.g);\n       result.a += (m[17] * c.b);\n       result.a += (m[18] * c.a);\n       result.a += m[19];\n\n    // Premultiply alpha again.\n    result.rgb *= result.a;\n\n    gl_FragColor = result;\n}\n"));return r.uniforms.m=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],r}return o(e,t),e.prototype._loadMatrix=function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=t;e&&(this._multiply(r,this.uniforms.m,t),r=this._colorMatrix(r)),this.uniforms.m=r},e.prototype._multiply=function(t,e,r){return t[0]=e[0]*r[0]+e[1]*r[5]+e[2]*r[10]+e[3]*r[15],t[1]=e[0]*r[1]+e[1]*r[6]+e[2]*r[11]+e[3]*r[16],t[2]=e[0]*r[2]+e[1]*r[7]+e[2]*r[12]+e[3]*r[17],t[3]=e[0]*r[3]+e[1]*r[8]+e[2]*r[13]+e[3]*r[18],t[4]=e[0]*r[4]+e[1]*r[9]+e[2]*r[14]+e[3]*r[19]+e[4],t[5]=e[5]*r[0]+e[6]*r[5]+e[7]*r[10]+e[8]*r[15],t[6]=e[5]*r[1]+e[6]*r[6]+e[7]*r[11]+e[8]*r[16],t[7]=e[5]*r[2]+e[6]*r[7]+e[7]*r[12]+e[8]*r[17],t[8]=e[5]*r[3]+e[6]*r[8]+e[7]*r[13]+e[8]*r[18],t[9]=e[5]*r[4]+e[6]*r[9]+e[7]*r[14]+e[8]*r[19]+e[9],t[10]=e[10]*r[0]+e[11]*r[5]+e[12]*r[10]+e[13]*r[15],t[11]=e[10]*r[1]+e[11]*r[6]+e[12]*r[11]+e[13]*r[16],t[12]=e[10]*r[2]+e[11]*r[7]+e[12]*r[12]+e[13]*r[17],t[13]=e[10]*r[3]+e[11]*r[8]+e[12]*r[13]+e[13]*r[18],t[14]=e[10]*r[4]+e[11]*r[9]+e[12]*r[14]+e[13]*r[19]+e[14],t[15]=e[15]*r[0]+e[16]*r[5]+e[17]*r[10]+e[18]*r[15],t[16]=e[15]*r[1]+e[16]*r[6]+e[17]*r[11]+e[18]*r[16],t[17]=e[15]*r[2]+e[16]*r[7]+e[17]*r[12]+e[18]*r[17],t[18]=e[15]*r[3]+e[16]*r[8]+e[17]*r[13]+e[18]*r[18],t[19]=e[15]*r[4]+e[16]*r[9]+e[17]*r[14]+e[18]*r[19]+e[19],t},e.prototype._colorMatrix=function(t){var e=new Float32Array(t);return e[4]/=255,e[9]/=255,e[14]/=255,e[19]/=255,e},e.prototype.brightness=function(t,e){var r=[t,0,0,0,0,0,t,0,0,0,0,0,t,0,0,0,0,0,1,0];this._loadMatrix(r,e)},e.prototype.greyscale=function(t,e){var r=[t,t,t,0,0,t,t,t,0,0,t,t,t,0,0,0,0,0,1,0];this._loadMatrix(r,e)},e.prototype.blackAndWhite=function(t){var e=[.3,.6,.1,0,0,.3,.6,.1,0,0,.3,.6,.1,0,0,0,0,0,1,0];this._loadMatrix(e,t)},e.prototype.hue=function(t,e){t=(t||0)/180*Math.PI;var r=Math.cos(t),n=Math.sin(t),i=Math.sqrt,o=1/3,s=i(o),a=r+(1-r)*o,u=o*(1-r)-s*n,h=o*(1-r)+s*n,l=o*(1-r)+s*n,c=r+o*(1-r),f=o*(1-r)-s*n,d=o*(1-r)-s*n,p=o*(1-r)+s*n,v=r+o*(1-r),y=[a,u,h,0,0,l,c,f,0,0,d,p,v,0,0,0,0,0,1,0];this._loadMatrix(y,e)},e.prototype.contrast=function(t,e){var r=(t||0)+1,n=-128*(r-1),i=[r,0,0,0,n,0,r,0,0,n,0,0,r,0,n,0,0,0,1,0];this._loadMatrix(i,e)},e.prototype.saturate=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments[1],r=2*t/3+1,n=(r-1)*-.5,i=[r,n,n,0,0,n,r,n,0,0,n,n,r,0,0,0,0,0,1,0];this._loadMatrix(i,e)},e.prototype.desaturate=function(){this.saturate(-1)},e.prototype.negative=function(t){var e=[0,1,1,0,0,1,0,1,0,0,1,1,0,0,0,0,0,0,1,0];this._loadMatrix(e,t)},e.prototype.sepia=function(t){var e=[.393,.7689999,.18899999,0,0,.349,.6859999,.16799999,0,0,.272,.5339999,.13099999,0,0,0,0,0,1,0];this._loadMatrix(e,t)},e.prototype.technicolor=function(t){var e=[1.9125277891456083,-.8545344976951645,-.09155508482755585,0,11.793603434377337,-.3087833385928097,1.7658908555458428,-.10601743074722245,0,-70.35205161461398,-.231103377548616,-.7501899197440212,1.847597816108189,0,30.950940869491138,0,0,0,1,0];this._loadMatrix(e,t)},e.prototype.polaroid=function(t){var e=[1.438,-.062,-.062,0,0,-.122,1.378,-.122,0,0,-.016,-.016,1.483,0,0,0,0,0,1,0];this._loadMatrix(e,t)},e.prototype.toBGR=function(t){var e=[0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0];this._loadMatrix(e,t)},e.prototype.kodachrome=function(t){var e=[1.1285582396593525,-.3967382283601348,-.03992559172921793,0,63.72958762196502,-.16404339962244616,1.0835251566291304,-.05498805115633132,0,24.732407896706203,-.16786010706155763,-.5603416277695248,1.6014850761964943,0,35.62982807460946,0,0,0,1,0];this._loadMatrix(e,t)},e.prototype.browni=function(t){var e=[.5997023498159715,.34553243048391263,-.2708298674538042,0,47.43192855600873,-.037703249837783157,.8609577587992641,.15059552388459913,0,-36.96841498319127,.24113635128153335,-.07441037908422492,.44972182064877153,0,-7.562075277591283,0,0,0,1,0];this._loadMatrix(e,t)},e.prototype.vintage=function(t){var e=[.6279345635605994,.3202183420819367,-.03965408211312453,0,9.651285835294123,.02578397704808868,.6441188644374771,.03259127616149294,0,7.462829176470591,.0466055556782719,-.0851232987247891,.5241648018700465,0,5.159190588235296,0,0,0,1,0];this._loadMatrix(e,t)},e.prototype.colorTone=function(t,e,r,n,i){t=t||.2,e=e||.15,r=r||16770432,n=n||3375104;var o=(r>>16&255)/255,s=(r>>8&255)/255,a=(255&r)/255,u=(n>>16&255)/255,h=(n>>8&255)/255,l=(255&n)/255,c=[.3,.59,.11,0,0,o,s,a,t,0,u,h,l,e,0,o-u,s-h,a-l,0,0];this._loadMatrix(c,i)},e.prototype.night=function(t,e){t=t||.1;var r=[t*-2,-t,0,0,0,-t,0,t,0,0,0,t,2*t,0,0,0,0,0,1,0];this._loadMatrix(r,e)},e.prototype.predator=function(t,e){var r=[11.224130630493164*t,-4.794486999511719*t,-2.8746118545532227*t,0*t,.40342438220977783*t,-3.6330697536468506*t,9.193157196044922*t,-2.951810836791992*t,0*t,-1.316135048866272*t,-3.2184197902679443*t,-4.2375030517578125*t,7.476448059082031*t,0*t,.8044459223747253*t,0,0,0,1,0];this._loadMatrix(r,e)},e.prototype.lsd=function(t){var e=[2,-.4,.5,0,0,-.5,2,-.4,0,0,-.4,-.5,3,0,0,0,0,0,1,0];this._loadMatrix(e,t)},e.prototype.reset=function(){var t=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0];this._loadMatrix(t,!1)},s(e,[{key:"matrix",get:function(){return this.uniforms.m},set:function(t){
+this.uniforms.m=t}}]),e}(u.Filter));r.default=h,h.prototype.grayscale=h.prototype.greyscale},{"../../core":64,path:23}],146:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),a=t("../../core"),u=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(a),h=(t("path"),function(t){function e(r,o){n(this,e);var s=new u.Matrix;r.renderable=!1;var a=i(this,t.call(this,"attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\nuniform mat3 filterMatrix;\n\nvarying vec2 vTextureCoord;\nvarying vec2 vFilterCoord;\n\nvoid main(void)\n{\n   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n   vFilterCoord = ( filterMatrix * vec3( aTextureCoord, 1.0)  ).xy;\n   vTextureCoord = aTextureCoord;\n}","varying vec2 vFilterCoord;\nvarying vec2 vTextureCoord;\n\nuniform vec2 scale;\n\nuniform sampler2D uSampler;\nuniform sampler2D mapSampler;\n\nuniform vec4 filterClamp;\n\nvoid main(void)\n{\n   vec4 map =  texture2D(mapSampler, vFilterCoord);\n\n   map -= 0.5;\n   map.xy *= scale;\n\n   gl_FragColor = texture2D(uSampler, clamp(vec2(vTextureCoord.x + map.x, vTextureCoord.y + map.y), filterClamp.xy, filterClamp.zw));\n}\n"));return a.maskSprite=r,a.maskMatrix=s,a.uniforms.mapSampler=r.texture,a.uniforms.filterMatrix=s,a.uniforms.scale={x:1,y:1},null!==o&&void 0!==o||(o=20),a.scale=new u.Point(o,o),a}return o(e,t),e.prototype.apply=function(t,e,r){var n=1/r.destinationFrame.width*(r.size.width/e.size.width);this.uniforms.filterMatrix=t.calculateSpriteMatrix(this.maskMatrix,this.maskSprite),this.uniforms.scale.x=this.scale.x*n,this.uniforms.scale.y=this.scale.y*n,t.applyFilter(this,e,r)},s(e,[{key:"map",get:function(){return this.uniforms.mapSampler},set:function(t){this.uniforms.mapSampler=t}}]),e}(u.Filter));r.default=h},{"../../core":64,path:23}],147:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=t("../../core"),a=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(s),u=(t("path"),function(t){function e(){return n(this,e),i(this,t.call(this,"\nattribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 v_rgbNW;\nvarying vec2 v_rgbNE;\nvarying vec2 v_rgbSW;\nvarying vec2 v_rgbSE;\nvarying vec2 v_rgbM;\n\nuniform vec4 filterArea;\n\nvarying vec2 vTextureCoord;\n\nvec2 mapCoord( vec2 coord )\n{\n    coord *= filterArea.xy;\n    coord += filterArea.zw;\n\n    return coord;\n}\n\nvec2 unmapCoord( vec2 coord )\n{\n    coord -= filterArea.zw;\n    coord /= filterArea.xy;\n\n    return coord;\n}\n\nvoid texcoords(vec2 fragCoord, vec2 resolution,\n               out vec2 v_rgbNW, out vec2 v_rgbNE,\n               out vec2 v_rgbSW, out vec2 v_rgbSE,\n               out vec2 v_rgbM) {\n    vec2 inverseVP = 1.0 / resolution.xy;\n    v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\n    v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\n    v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\n    v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\n    v_rgbM = vec2(fragCoord * inverseVP);\n}\n\nvoid main(void) {\n\n   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n\n   vTextureCoord = aTextureCoord;\n\n   vec2 fragCoord = vTextureCoord * filterArea.xy;\n\n   texcoords(fragCoord, filterArea.xy, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n}",'varying vec2 v_rgbNW;\nvarying vec2 v_rgbNE;\nvarying vec2 v_rgbSW;\nvarying vec2 v_rgbSE;\nvarying vec2 v_rgbM;\n\nvarying vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform vec4 filterArea;\n\n/**\n Basic FXAA implementation based on the code on geeks3d.com with the\n modification that the texture2DLod stuff was removed since it\'s\n unsupported by WebGL.\n \n --\n \n From:\n https://github.com/mitsuhiko/webgl-meincraft\n \n Copyright (c) 2011 by Armin Ronacher.\n \n Some rights reserved.\n \n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are\n met:\n \n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n \n * Redistributions in binary form must reproduce the above\n copyright notice, this list of conditions and the following\n disclaimer in the documentation and/or other materials provided\n with the distribution.\n \n * The names of the contributors may not be used to endorse or\n promote products derived from this software without specific\n prior written permission.\n \n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef FXAA_REDUCE_MIN\n#define FXAA_REDUCE_MIN   (1.0/ 128.0)\n#endif\n#ifndef FXAA_REDUCE_MUL\n#define FXAA_REDUCE_MUL   (1.0 / 8.0)\n#endif\n#ifndef FXAA_SPAN_MAX\n#define FXAA_SPAN_MAX     8.0\n#endif\n\n//optimized version for mobile, where dependent\n//texture reads can be a bottleneck\nvec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution,\n          vec2 v_rgbNW, vec2 v_rgbNE,\n          vec2 v_rgbSW, vec2 v_rgbSE,\n          vec2 v_rgbM) {\n    vec4 color;\n    mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y);\n    vec3 rgbNW = texture2D(tex, v_rgbNW).xyz;\n    vec3 rgbNE = texture2D(tex, v_rgbNE).xyz;\n    vec3 rgbSW = texture2D(tex, v_rgbSW).xyz;\n    vec3 rgbSE = texture2D(tex, v_rgbSE).xyz;\n    vec4 texColor = texture2D(tex, v_rgbM);\n    vec3 rgbM  = texColor.xyz;\n    vec3 luma = vec3(0.299, 0.587, 0.114);\n    float lumaNW = dot(rgbNW, luma);\n    float lumaNE = dot(rgbNE, luma);\n    float lumaSW = dot(rgbSW, luma);\n    float lumaSE = dot(rgbSE, luma);\n    float lumaM  = dot(rgbM,  luma);\n    float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\n    float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\n    \n    mediump vec2 dir;\n    dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n    dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n    \n    float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\n                          (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);\n    \n    float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\n    dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),\n              max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\n                  dir * rcpDirMin)) * inverseVP;\n    \n    vec3 rgbA = 0.5 * (\n                       texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\n                       texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\n    vec3 rgbB = rgbA * 0.5 + 0.25 * (\n                                     texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz +\n                                     texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);\n    \n    float lumaB = dot(rgbB, luma);\n    if ((lumaB < lumaMin) || (lumaB > lumaMax))\n        color = vec4(rgbA, texColor.a);\n    else\n        color = vec4(rgbB, texColor.a);\n    return color;\n}\n\nvoid main() {\n\n      vec2 fragCoord = vTextureCoord * filterArea.xy;\n\n      vec4 color;\n\n    color = fxaa(uSampler, fragCoord, filterArea.xy, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n\n      gl_FragColor = color;\n}\n'))}return o(e,t),e}(a.Filter));r.default=u},{"../../core":64,path:23}],148:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0;var i=t("./fxaa/FXAAFilter");Object.defineProperty(r,"FXAAFilter",{enumerable:!0,get:function(){return n(i).default}});var o=t("./noise/NoiseFilter");Object.defineProperty(r,"NoiseFilter",{enumerable:!0,get:function(){return n(o).default}});var s=t("./displacement/DisplacementFilter");Object.defineProperty(r,"DisplacementFilter",{enumerable:!0,get:function(){return n(s).default}});var a=t("./blur/BlurFilter");Object.defineProperty(r,"BlurFilter",{enumerable:!0,get:function(){return n(a).default}});var u=t("./blur/BlurXFilter");Object.defineProperty(r,"BlurXFilter",{enumerable:!0,get:function(){return n(u).default}});var h=t("./blur/BlurYFilter");Object.defineProperty(r,"BlurYFilter",{enumerable:!0,get:function(){return n(h).default}});var l=t("./colormatrix/ColorMatrixFilter");Object.defineProperty(r,"ColorMatrixFilter",{enumerable:!0,get:function(){return n(l).default}});var c=t("./void/VoidFilter");Object.defineProperty(r,"VoidFilter",{enumerable:!0,get:function(){return n(c).default}})},{"./blur/BlurFilter":139,"./blur/BlurXFilter":140,"./blur/BlurYFilter":141,"./colormatrix/ColorMatrixFilter":145,"./displacement/DisplacementFilter":146,"./fxaa/FXAAFilter":147,"./noise/NoiseFilter":149,"./void/VoidFilter":150}],149:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),a=t("../../core"),u=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(a),h=(t("path"),function(t){function e(){n(this,e);var r=i(this,t.call(this,"attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n    vTextureCoord = aTextureCoord;\n}","precision highp float;\n\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\n\nuniform float noise;\nuniform sampler2D uSampler;\n\nfloat rand(vec2 co)\n{\n    return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main()\n{\n    vec4 color = texture2D(uSampler, vTextureCoord);\n\n    float diff = (rand(gl_FragCoord.xy) - 0.5) * noise;\n\n    color.r += diff;\n    color.g += diff;\n    color.b += diff;\n\n    gl_FragColor = color;\n}\n"));return r.noise=.5,r}return o(e,t),s(e,[{key:"noise",get:function(){return this.uniforms.noise},set:function(t){this.uniforms.noise=t}}]),e}(u.Filter));r.default=h},{"../../core":64,path:23}],150:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=t("../../core"),a=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(s),u=(t("path"),function(t){function e(){n(this,e);var r=i(this,t.call(this,"attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n    vTextureCoord = aTextureCoord;\n}","varying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\n\nvoid main(void)\n{\n   gl_FragColor = texture2D(uSampler, vTextureCoord);\n}\n"));return r.glShaderKey="void",r}return o(e,t),e}(a.Filter));r.default=u},{"../../core":64,path:23}],151:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../core"),o=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(i),s=function(){function t(){n(this,t),this.global=new o.Point,this.target=null,this.originalEvent=null,this.identifier=null}return t.prototype.getLocalPosition=function(t,e,r){return t.worldTransform.applyInverse(r||this.global,e)},t}();r.default=s},{"../core":64}],152:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(){n(this,t),this.stopped=!1,this.target=null,this.currentTarget=null,this.type=null,this.data=null}return t.prototype.stopPropagation=function(){this.stopped=!0},t.prototype._reset=function(){this.stopped=!1,this.currentTarget=null,this.target=null},t}();r.default=i},{}],153:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},u=t("../core"),h=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(u),l=t("./InteractionData"),c=n(l),f=t("./InteractionEvent"),d=n(f),p=t("./InteractionTrackingData"),v=n(p),y=t("eventemitter3"),g=n(y),m=t("./interactiveTarget"),_=n(m);h.utils.mixins.delayMixin(h.DisplayObject.prototype,_.default);var b="MOUSE",x=function(t){function e(r,n){i(this,e);var s=o(this,t.call(this));return n=n||{},s.renderer=r,s.autoPreventDefault=void 0===n.autoPreventDefault||n.autoPreventDefault,s.interactionFrequency=n.interactionFrequency||10,s.mouse=new c.default,s.mouse.identifier=b,s.mouse.global.set(-999999),s.activeInteractionData={},s.activeInteractionData[b]=s.mouse,s.interactionDataPool=[],s.eventData=new d.default,s.interactionDOMElement=null,s.moveWhenInside=!1,s.eventsAdded=!1,s.mouseOverRenderer=!1,s.supportsTouchEvents="ontouchstart"in window,s.supportsPointerEvents=!!window.PointerEvent,s.onPointerUp=s.onPointerUp.bind(s),s.processPointerUp=s.processPointerUp.bind(s),s.onPointerCancel=s.onPointerCancel.bind(s),s.processPointerCancel=s.processPointerCancel.bind(s),s.onPointerDown=s.onPointerDown.bind(s),s.processPointerDown=s.processPointerDown.bind(s),s.onPointerMove=s.onPointerMove.bind(s),s.processPointerMove=s.processPointerMove.bind(s),s.onPointerOut=s.onPointerOut.bind(s),s.processPointerOverOut=s.processPointerOverOut.bind(s),s.onPointerOver=s.onPointerOver.bind(s),s.cursorStyles={default:"inherit",pointer:"pointer"},s.currentCursorMode=null,s.cursor=null,s._tempPoint=new h.Point,s.resolution=1,s.setTargetElement(s.renderer.view,s.renderer.resolution),s}return s(e,t),e.prototype.setTargetElement=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;this.removeEvents(),this.interactionDOMElement=t,this.resolution=e,this.addEvents()},e.prototype.addEvents=function(){this.interactionDOMElement&&(h.ticker.shared.add(this.update,this),window.navigator.msPointerEnabled?(this.interactionDOMElement.style["-ms-content-zooming"]="none",this.interactionDOMElement.style["-ms-touch-action"]="none"):this.supportsPointerEvents&&(this.interactionDOMElement.style["touch-action"]="none"),this.supportsPointerEvents?(window.document.addEventListener("pointermove",this.onPointerMove,!0),this.interactionDOMElement.addEventListener("pointerdown",this.onPointerDown,!0),this.interactionDOMElement.addEventListener("pointerleave",this.onPointerOut,!0),this.interactionDOMElement.addEventListener("pointerover",this.onPointerOver,!0),window.addEventListener("pointercancel",this.onPointerCancel,!0),window.addEventListener("pointerup",this.onPointerUp,!0)):(window.document.addEventListener("mousemove",this.onPointerMove,!0),this.interactionDOMElement.addEventListener("mousedown",this.onPointerDown,!0),this.interactionDOMElement.addEventListener("mouseout",this.onPointerOut,!0),this.interactionDOMElement.addEventListener("mouseover",this.onPointerOver,!0),window.addEventListener("mouseup",this.onPointerUp,!0),this.supportsTouchEvents&&(this.interactionDOMElement.addEventListener("touchstart",this.onPointerDown,!0),this.interactionDOMElement.addEventListener("touchcancel",this.onPointerCancel,!0),this.interactionDOMElement.addEventListener("touchend",this.onPointerUp,!0),this.interactionDOMElement.addEventListener("touchmove",this.onPointerMove,!0))),this.eventsAdded=!0)},e.prototype.removeEvents=function(){this.interactionDOMElement&&(h.ticker.shared.remove(this.update,this),window.navigator.msPointerEnabled?(this.interactionDOMElement.style["-ms-content-zooming"]="",this.interactionDOMElement.style["-ms-touch-action"]=""):this.supportsPointerEvents&&(this.interactionDOMElement.style["touch-action"]=""),this.supportsPointerEvents?(window.document.removeEventListener("pointermove",this.onPointerMove,!0),this.interactionDOMElement.removeEventListener("pointerdown",this.onPointerDown,!0),this.interactionDOMElement.removeEventListener("pointerleave",this.onPointerOut,!0),this.interactionDOMElement.removeEventListener("pointerover",this.onPointerOver,!0),window.removeEventListener("pointercancel",this.onPointerCancel,!0),window.removeEventListener("pointerup",this.onPointerUp,!0)):(window.document.removeEventListener("mousemove",this.onPointerMove,!0),this.interactionDOMElement.removeEventListener("mousedown",this.onPointerDown,!0),this.interactionDOMElement.removeEventListener("mouseout",this.onPointerOut,!0),this.interactionDOMElement.removeEventListener("mouseover",this.onPointerOver,!0),window.removeEventListener("mouseup",this.onPointerUp,!0),this.supportsTouchEvents&&(this.interactionDOMElement.removeEventListener("touchstart",this.onPointerDown,!0),this.interactionDOMElement.removeEventListener("touchcancel",this.onPointerCancel,!0),this.interactionDOMElement.removeEventListener("touchend",this.onPointerUp,!0),this.interactionDOMElement.removeEventListener("touchmove",this.onPointerMove,!0))),this.interactionDOMElement=null,this.eventsAdded=!1)},e.prototype.update=function(t){if(this._deltaTime+=t,!(this._deltaTime<this.interactionFrequency)&&(this._deltaTime=0,this.interactionDOMElement)){if(this.didMove)return void(this.didMove=!1);this.cursor=null;for(var e in this.activeInteractionData)if(this.activeInteractionData.hasOwnProperty(e)){var r=this.activeInteractionData[e];if(r.originalEvent&&"touch"!==r.pointerType){var n=this.configureInteractionEventForDOMEvent(this.eventData,r.originalEvent,r);this.processInteractive(n,this.renderer._lastObjectRendered,this.processPointerOverOut,!0)}}this.setCursorMode(this.cursor)}},e.prototype.setCursorMode=function(t){if(t=t||"default",this.currentCursorMode!==t){this.currentCursorMode=t;var e=this.cursorStyles[t];if(e)switch(void 0===e?"undefined":a(e)){case"string":this.interactionDOMElement.style.cursor=e;break;case"function":e(t);break;case"object":Object.assign(this.interactionDOMElement.style,e)}}},e.prototype.dispatchEvent=function(t,e,r){r.stopped||(r.currentTarget=t,r.type=e,t.emit(e,r),t[e]&&t[e](r))},e.prototype.mapPositionToPoint=function(t,e,r){var n=void 0;n=this.interactionDOMElement.parentElement?this.interactionDOMElement.getBoundingClientRect():{x:0,y:0,width:0,height:0};var i=navigator.isCocoonJS?this.resolution:1/this.resolution;t.x=(e-n.left)*(this.interactionDOMElement.width/n.width)*i,t.y=(r-n.top)*(this.interactionDOMElement.height/n.height)*i},e.prototype.processInteractive=function(t,e,r,n,i){if(!e||!e.visible)return!1;var o=t.data.global;i=e.interactive||i;var s=0,a=i;if(e.hitArea?a=!1:n&&e._mask&&(e._mask.containsPoint(o)||(n=!1)),e.interactiveChildren&&e.children)for(var u=e.children,h=u.length-1;h>=0;h--){var l=u[h],c=this.processInteractive(t,l,r,n,a);if(c){if(!l.parent)continue;a=!1,2===c?(n=!1,s=2):0===s&&(s=1)}}return i&&(n&&2!==s&&(e.hitArea?(e.worldTransform.applyInverse(o,this._tempPoint),e.hitArea.contains(this._tempPoint.x,this._tempPoint.y)&&(s=e.interactive?2:1)):e.containsPoint&&e.containsPoint(o)&&(s=e.interactive?2:1)),e.interactive&&(s&&!t.target&&(t.target=e),r(t,e,!!s))),s},e.prototype.onPointerDown=function(t){var e=this.normalizeToPointerData(t);this.autoPreventDefault&&e[0].isNormalized&&t.preventDefault();for(var r=e.length,n=0;n<r;n++){var i=e[n],o=this.getInteractionDataForPointerId(i),s=this.configureInteractionEventForDOMEvent(this.eventData,i,o);if(s.data.originalEvent=t,this.processInteractive(s,this.renderer._lastObjectRendered,this.processPointerDown,!0),this.emit("pointerdown",s),"touch"===i.pointerType)this.emit("touchstart",s);else if("mouse"===i.pointerType){var a=2===i.button||3===i.which;this.emit(a?"rightdown":"mousedown",this.eventData)}}},e.prototype.processPointerDown=function(t,e,r){var n=t.data.originalEvent,i=t.data.identifier;if(r)if(e.trackedPointers[i]||(e.trackedPointers[i]=new v.default(i)),this.dispatchEvent(e,"pointerdown",t),"touchstart"===n.type||"touch"===n.pointerType)this.dispatchEvent(e,"touchstart",t);else if("mousedown"===n.type||"mouse"===n.pointerType){var o=2===n.button||3===n.which;o?e.trackedPointers[i].rightDown=!0:e.trackedPointers[i].leftDown=!0,this.dispatchEvent(e,o?"rightdown":"mousedown",t)}},e.prototype.onPointerComplete=function(t,e,r){for(var n=this.normalizeToPointerData(t),i=n.length,o=0;o<i;o++){var s=n[o],a=this.getInteractionDataForPointerId(s),u=this.configureInteractionEventForDOMEvent(this.eventData,s,a);if(u.data.originalEvent=t,this.processInteractive(u,this.renderer._lastObjectRendered,r,!0),this.emit(e?"pointercancel":"pointerup",u),"mouse"===s.pointerType){var h=2===s.button||3===s.which;this.emit(h?"rightup":"mouseup",u)}else"touch"===s.pointerType&&(this.emit(e?"touchcancel":"touchend",u),this.releaseInteractionDataForPointerId(s.pointerId,a))}},e.prototype.onPointerCancel=function(t){this.onPointerComplete(t,!0,this.processPointerCancel)},e.prototype.processPointerCancel=function(t,e){var r=t.data.originalEvent,n=t.data.identifier;void 0!==e.trackedPointers[n]&&(delete e.trackedPointers[n],this.dispatchEvent(e,"pointercancel",t),"touchcancel"!==r.type&&"touch"!==r.pointerType||this.dispatchEvent(e,"touchcancel",t))},e.prototype.onPointerUp=function(t){this.onPointerComplete(t,!1,this.processPointerUp)},e.prototype.processPointerUp=function(t,e,r){var n=t.data.originalEvent,i=t.data.identifier,o=e.trackedPointers[i],s="touchend"===n.type||"touch"===n.pointerType;if(0===n.type.indexOf("mouse")||"mouse"===n.pointerType){var a=2===n.button||3===n.which,u=v.default.FLAGS,h=a?u.RIGHT_DOWN:u.LEFT_DOWN,l=void 0!==o&&o.flags&h;r?(this.dispatchEvent(e,a?"rightup":"mouseup",t),l&&this.dispatchEvent(e,a?"rightclick":"click",t)):l&&this.dispatchEvent(e,a?"rightupoutside":"mouseupoutside",t),o&&(a?o.rightDown=!1:o.leftDown=!1)}r?(this.dispatchEvent(e,"pointerup",t),s&&this.dispatchEvent(e,"touchend",t),o&&(this.dispatchEvent(e,"pointertap",t),s&&(this.dispatchEvent(e,"tap",t),o.over=!1))):o&&(this.dispatchEvent(e,"pointerupoutside",t),s&&this.dispatchEvent(e,"touchendoutside",t)),o&&o.none&&delete e.trackedPointers[i]},e.prototype.onPointerMove=function(t){var e=this.normalizeToPointerData(t);"mouse"===e[0].pointerType&&(this.didMove=!0,this.cursor=null);for(var r=e.length,n=0;n<r;n++){var i=e[n],o=this.getInteractionDataForPointerId(i),s=this.configureInteractionEventForDOMEvent(this.eventData,i,o);s.data.originalEvent=t;var a="touch"!==i.pointerType||this.moveWhenInside;this.processInteractive(s,this.renderer._lastObjectRendered,this.processPointerMove,a),this.emit("pointermove",s),"touch"===i.pointerType&&this.emit("touchmove",s),"mouse"===i.pointerType&&this.emit("mousemove",s)}"mouse"===e[0].pointerType&&this.setCursorMode(this.cursor)},e.prototype.processPointerMove=function(t,e,r){var n=t.data.originalEvent,i="touchmove"===n.type||"touch"===n.pointerType,o="mousemove"===n.type||"mouse"===n.pointerType;o&&this.processPointerOverOut(t,e,r),this.moveWhenInside&&!r||(this.dispatchEvent(e,"pointermove",t),i&&this.dispatchEvent(e,"touchmove",t),o&&this.dispatchEvent(e,"mousemove",t))},e.prototype.onPointerOut=function(t){var e=this.normalizeToPointerData(t),r=e[0];"mouse"===r.pointerType&&(this.mouseOverRenderer=!1,this.setCursorMode(null));var n=this.getInteractionDataForPointerId(r),i=this.configureInteractionEventForDOMEvent(this.eventData,r,n);i.data.originalEvent=r,this.processInteractive(i,this.renderer._lastObjectRendered,this.processPointerOverOut,!1),this.emit("pointerout",i),"mouse"===r.pointerType?this.emit("mouseout",i):this.releaseInteractionDataForPointerId(n.identifier)},e.prototype.processPointerOverOut=function(t,e,r){var n=t.data.originalEvent,i=t.data.identifier,o="mouseover"===n.type||"mouseout"===n.type||"mouse"===n.pointerType,s=e.trackedPointers[i];r&&!s&&(s=e.trackedPointers[i]=new v.default(i)),void 0!==s&&(r&&this.mouseOverRenderer?(s.over||(s.over=!0,this.dispatchEvent(e,"pointerover",t),o&&this.dispatchEvent(e,"mouseover",t)),o&&null===this.cursor&&(this.cursor=e.cursor)):s.over&&(s.over=!1,this.dispatchEvent(e,"pointerout",this.eventData),o&&this.dispatchEvent(e,"mouseout",t),s.none&&delete e.trackedPointers[i]))},e.prototype.onPointerOver=function(t){var e=this.normalizeToPointerData(t),r=e[0],n=this.getInteractionDataForPointerId(r),i=this.configureInteractionEventForDOMEvent(this.eventData,r,n);i.data.originalEvent=r,"mouse"===r.pointerType&&(this.mouseOverRenderer=!0),this.emit("pointerover",i),"mouse"===r.pointerType&&this.emit("mouseover",i)},e.prototype.getInteractionDataForPointerId=function(t){var e=t.pointerId;if(e===b||"mouse"===t.pointerType)return this.mouse;if(this.activeInteractionData[e])return this.activeInteractionData[e];var r=this.interactionDataPool.pop()||new c.default;return r.identifier=e,this.activeInteractionData[e]=r,r},e.prototype.releaseInteractionDataForPointerId=function(t){var e=this.activeInteractionData[t];e&&(delete this.activeInteractionData[t],this.interactionDataPool.push(e))},e.prototype.configureInteractionEventForDOMEvent=function(t,e,r){return t.data=r,this.mapPositionToPoint(r.global,e.clientX,e.clientY),navigator.isCocoonJS&&"touch"===e.pointerType&&(r.global.x=r.global.x/this.resolution,r.global.y=r.global.y/this.resolution),"touch"===e.pointerType&&(e.globalX=r.global.x,e.globalY=r.global.y),r.originalEvent=e,t._reset(),t},e.prototype.normalizeToPointerData=function(t){var e=[];if(this.supportsTouchEvents&&t instanceof TouchEvent)for(var r=0,n=t.changedTouches.length;r<n;r++){var i=t.changedTouches[r];void 0===i.button&&(i.button=t.touches.length?1:0),void 0===i.buttons&&(i.buttons=t.touches.length?1:0),void 0===i.isPrimary&&(i.isPrimary=1===t.touches.length),void 0===i.width&&(i.width=i.radiusX||1),void 0===i.height&&(i.height=i.radiusY||1),void 0===i.tiltX&&(i.tiltX=0),void 0===i.tiltY&&(i.tiltY=0),void 0===i.pointerType&&(i.pointerType="touch"),void 0===i.pointerId&&(i.pointerId=i.identifier||0),void 0===i.pressure&&(i.pressure=i.force||.5),void 0===i.rotation&&(i.rotation=i.rotationAngle||0),void 0===i.layerX&&(i.layerX=i.offsetX=i.clientX),void 0===i.layerY&&(i.layerY=i.offsetY=i.clientY),i.isNormalized=!0,e.push(i)}else!(t instanceof MouseEvent)||this.supportsPointerEvents&&t instanceof window.PointerEvent?e.push(t):(void 0===t.isPrimary&&(t.isPrimary=!0),void 0===t.width&&(t.width=1),void 0===t.height&&(t.height=1),void 0===t.tiltX&&(t.tiltX=0),void 0===t.tiltY&&(t.tiltY=0),void 0===t.pointerType&&(t.pointerType="mouse"),void 0===t.pointerId&&(t.pointerId=b),void 0===t.pressure&&(t.pressure=.5),void 0===t.rotation&&(t.rotation=0),t.isNormalized=!0,e.push(t));return e},e.prototype.destroy=function(){this.removeEvents(),this.removeAllListeners(),this.renderer=null,this.mouse=null,this.eventData=null,this.interactionDOMElement=null,this.onPointerDown=null,this.processPointerDown=null,this.onPointerUp=null,this.processPointerUp=null,this.onPointerCancel=null,this.processPointerCancel=null,this.onPointerMove=null,this.processPointerMove=null,this.onPointerOut=null,this.processPointerOverOut=null,this.onPointerOver=null,this._tempPoint=null},e}(g.default);r.default=x,h.WebGLRenderer.registerPlugin("interaction",x),h.CanvasRenderer.registerPlugin("interaction",x)},{"../core":64,"./InteractionData":151,"./InteractionEvent":152,"./InteractionTrackingData":154,"./interactiveTarget":156,eventemitter3:3}],154:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),o=function(){function t(e){n(this,t),
+this._pointerId=e,this._flags=t.FLAGS.NONE}return t.prototype._doSet=function(t,e){this._flags=e?this._flags|t:this._flags&~t},i(t,[{key:"pointerId",get:function(){return this._pointerId}},{key:"flags",get:function(){return this._flags},set:function(t){this._flags=t}},{key:"none",get:function(){return this._flags===this.constructor.FLAGS.NONE}},{key:"over",get:function(){return 0!=(this._flags&this.constructor.FLAGS.OVER)},set:function(t){this._doSet(this.constructor.FLAGS.OVER,t)}},{key:"rightDown",get:function(){return 0!=(this._flags&this.constructor.FLAGS.RIGHT_DOWN)},set:function(t){this._doSet(this.constructor.FLAGS.RIGHT_DOWN,t)}},{key:"leftDown",get:function(){return 0!=(this._flags&this.constructor.FLAGS.LEFT_DOWN)},set:function(t){this._doSet(this.constructor.FLAGS.LEFT_DOWN,t)}}]),t}();r.default=o,o.FLAGS=Object.freeze({NONE:0,OVER:1,LEFT_DOWN:2,RIGHT_DOWN:4})},{}],155:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0;var i=t("./InteractionData");Object.defineProperty(r,"InteractionData",{enumerable:!0,get:function(){return n(i).default}});var o=t("./InteractionManager");Object.defineProperty(r,"InteractionManager",{enumerable:!0,get:function(){return n(o).default}});var s=t("./interactiveTarget");Object.defineProperty(r,"interactiveTarget",{enumerable:!0,get:function(){return n(s).default}})},{"./InteractionData":151,"./InteractionManager":153,"./interactiveTarget":156}],156:[function(t,e,r){"use strict";r.__esModule=!0,r.default={interactive:!1,interactiveChildren:!0,hitArea:null,get buttonMode(){return"pointer"===this.cursor},set buttonMode(t){t?this.cursor="pointer":"pointer"===this.cursor&&(this.cursor=null)},cursor:null,get trackedPointers(){return void 0===this._trackedPointers&&(this._trackedPointers={}),this._trackedPointers},_trackedPointers:void 0}},{}],157:[function(t,e,r){"use strict";function n(t,e){t.bitmapFont=u.BitmapText.registerFont(t.data,e)}r.__esModule=!0,r.parse=n,r.default=function(){return function(t,e){if(!t.data||t.type!==a.Resource.TYPE.XML)return void e();if(0===t.data.getElementsByTagName("page").length||0===t.data.getElementsByTagName("info").length||null===t.data.getElementsByTagName("info")[0].getAttribute("face"))return void e();var r=t.isDataUrl?"":o.dirname(t.url);t.isDataUrl&&("."===r&&(r=""),this.baseUrl&&r&&("/"===this.baseUrl.charAt(this.baseUrl.length-1)&&(r+="/"),r=r.replace(this.baseUrl,""))),r&&"/"!==r.charAt(r.length-1)&&(r+="/");var i=r+t.data.getElementsByTagName("page")[0].getAttribute("file");if(s.utils.TextureCache[i])n(t,s.utils.TextureCache[i]),e();else{var u={crossOrigin:t.crossOrigin,loadType:a.Resource.LOAD_TYPE.IMAGE,metadata:t.metadata.imageMetadata,parentResource:t};this.add(t.name+"_image",i,u,function(r){n(t,r.texture),e()})}}};var i=t("path"),o=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(i),s=t("../core"),a=t("resource-loader"),u=t("../extras")},{"../core":64,"../extras":137,path:23,"resource-loader":35}],158:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0;var i=t("./loader");Object.defineProperty(r,"Loader",{enumerable:!0,get:function(){return n(i).default}});var o=t("./bitmapFontParser");Object.defineProperty(r,"bitmapFontParser",{enumerable:!0,get:function(){return n(o).default}}),Object.defineProperty(r,"parseBitmapFontData",{enumerable:!0,get:function(){return o.parse}});var s=t("./spritesheetParser");Object.defineProperty(r,"spritesheetParser",{enumerable:!0,get:function(){return n(s).default}});var a=t("./textureParser");Object.defineProperty(r,"textureParser",{enumerable:!0,get:function(){return n(a).default}});var u=t("resource-loader");Object.defineProperty(r,"Resource",{enumerable:!0,get:function(){return u.Resource}})},{"./bitmapFontParser":157,"./loader":159,"./spritesheetParser":160,"./textureParser":161,"resource-loader":35}],159:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("resource-loader"),u=n(a),h=t("resource-loader/lib/middlewares/parsing/blob"),l=t("eventemitter3"),c=n(l),f=t("./textureParser"),d=n(f),p=t("./spritesheetParser"),v=n(p),y=t("./bitmapFontParser"),g=n(y),m=function(t){function e(r,n){i(this,e);var s=o(this,t.call(this,r,n));c.default.call(s);for(var a=0;a<e._pixiMiddleware.length;++a)s.use(e._pixiMiddleware[a]());return s.onStart.add(function(t){return s.emit("start",t)}),s.onProgress.add(function(t,e){return s.emit("progress",t,e)}),s.onError.add(function(t,e,r){return s.emit("error",t,e,r)}),s.onLoad.add(function(t,e){return s.emit("load",t,e)}),s.onComplete.add(function(t,e){return s.emit("complete",t,e)}),s}return s(e,t),e.addPixiMiddleware=function(t){e._pixiMiddleware.push(t)},e}(u.default);r.default=m;for(var _ in c.default.prototype)m.prototype[_]=c.default.prototype[_];m._pixiMiddleware=[h.blobMiddlewareFactory,d.default,v.default,g.default];var b=u.default.Resource;b.setExtensionXhrType("fnt",b.XHR_RESPONSE_TYPE.DOCUMENT)},{"./bitmapFontParser":157,"./spritesheetParser":160,"./textureParser":161,eventemitter3:3,"resource-loader":35,"resource-loader/lib/middlewares/parsing/blob":36}],160:[function(t,e,r){"use strict";r.__esModule=!0,r.default=function(){return function(t,e){var r=void 0,i=t.name+"_image";if(!t.data||t.type!==n.Resource.TYPE.JSON||!t.data.frames||this.resources[i])return void e();var a={crossOrigin:t.crossOrigin,loadType:n.Resource.LOAD_TYPE.IMAGE,metadata:t.metadata.imageMetadata,parentResource:t};r=t.isDataUrl?t.data.meta.image:o.default.dirname(t.url.replace(this.baseUrl,""))+"/"+t.data.meta.image,this.add(i,r,a,function(r){var n=new s.Spritesheet(r.texture.baseTexture,t.data,t.url);n.parse(function(){t.spritesheet=n,t.textures=n.textures,e()})})}};var n=t("resource-loader"),i=t("path"),o=function(t){return t&&t.__esModule?t:{default:t}}(i),s=t("../core")},{"../core":64,path:23,"resource-loader":35}],161:[function(t,e,r){"use strict";r.__esModule=!0,r.default=function(){return function(t,e){t.data&&t.type===n.Resource.TYPE.IMAGE&&(t.texture=o.default.fromLoader(t.data,t.url,t.name)),e()}};var n=t("resource-loader"),i=t("../core/textures/Texture"),o=function(t){return t&&t.__esModule?t:{default:t}}(i)},{"../core/textures/Texture":113,"resource-loader":35}],162:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),a=t("../core"),u=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(a),h=new u.Point,l=new u.Polygon,c=function(t){function e(r,o,s,a,h){n(this,e);var l=i(this,t.call(this));return l._texture=null,l.uvs=s||new Float32Array([0,0,1,0,1,1,0,1]),l.vertices=o||new Float32Array([0,0,100,0,100,100,0,100]),l.indices=a||new Uint16Array([0,1,3,2]),l.dirty=0,l.indexDirty=0,l.blendMode=u.BLEND_MODES.NORMAL,l.canvasPadding=0,l.drawMode=h||e.DRAW_MODES.TRIANGLE_MESH,l.texture=r,l.shader=null,l.tintRgb=new Float32Array([1,1,1]),l._glDatas={},l.pluginName="mesh",l}return o(e,t),e.prototype._renderWebGL=function(t){t.setObjectRenderer(t.plugins[this.pluginName]),t.plugins[this.pluginName].render(this)},e.prototype._renderCanvas=function(t){t.plugins[this.pluginName].render(this)},e.prototype._onTextureUpdate=function(){},e.prototype._calculateBounds=function(){this._bounds.addVertices(this.transform,this.vertices,0,this.vertices.length)},e.prototype.containsPoint=function(t){if(!this.getBounds().contains(t.x,t.y))return!1;this.worldTransform.applyInverse(t,h);for(var r=this.vertices,n=l.points,i=this.indices,o=this.indices.length,s=this.drawMode===e.DRAW_MODES.TRIANGLES?3:1,a=0;a+2<o;a+=s){var u=2*i[a],c=2*i[a+1],f=2*i[a+2];if(n[0]=r[u],n[1]=r[u+1],n[2]=r[c],n[3]=r[c+1],n[4]=r[f],n[5]=r[f+1],l.contains(h.x,h.y))return!0}return!1},s(e,[{key:"texture",get:function(){return this._texture},set:function(t){this._texture!==t&&(this._texture=t,t&&(t.baseTexture.hasLoaded?this._onTextureUpdate():t.once("update",this._onTextureUpdate,this)))}},{key:"tint",get:function(){return u.utils.rgb2hex(this.tintRgb)},set:function(t){this.tintRgb=u.utils.hex2rgb(t,this.tintRgb)}}]),e}(u.Container);r.default=c,c.DRAW_MODES={TRIANGLE_MESH:0,TRIANGLES:1}},{"../core":64}],163:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}(),a=t("./Plane"),u=function(t){return t&&t.__esModule?t:{default:t}}(a),h=10,l=function(t){function e(r,o,s,a,u){n(this,e);var l=i(this,t.call(this,r,4,4)),c=l.uvs;return c[6]=c[14]=c[22]=c[30]=1,c[25]=c[27]=c[29]=c[31]=1,l._origWidth=r.width,l._origHeight=r.height,l._uvw=1/l._origWidth,l._uvh=1/l._origHeight,l.width=r.width,l.height=r.height,c[2]=c[10]=c[18]=c[26]=l._uvw*o,c[4]=c[12]=c[20]=c[28]=1-l._uvw*a,c[9]=c[11]=c[13]=c[15]=l._uvh*s,c[17]=c[19]=c[21]=c[23]=1-l._uvh*u,l.leftWidth=void 0!==o?o:h,l.rightWidth=void 0!==a?a:h,l.topHeight=void 0!==s?s:h,l.bottomHeight=void 0!==u?u:h,l}return o(e,t),e.prototype.updateHorizontalVertices=function(){var t=this.vertices;t[9]=t[11]=t[13]=t[15]=this._topHeight,t[17]=t[19]=t[21]=t[23]=this._height-this._bottomHeight,t[25]=t[27]=t[29]=t[31]=this._height},e.prototype.updateVerticalVertices=function(){var t=this.vertices;t[2]=t[10]=t[18]=t[26]=this._leftWidth,t[4]=t[12]=t[20]=t[28]=this._width-this._rightWidth,t[6]=t[14]=t[22]=t[30]=this._width},e.prototype._renderCanvas=function(t){var e=t.context;e.globalAlpha=this.worldAlpha;var r=this.worldTransform,n=t.resolution;t.roundPixels?e.setTransform(r.a*n,r.b*n,r.c*n,r.d*n,r.tx*n|0,r.ty*n|0):e.setTransform(r.a*n,r.b*n,r.c*n,r.d*n,r.tx*n,r.ty*n);var i=this._texture.baseTexture,o=i.source,s=i.width,a=i.height;this.drawSegment(e,o,s,a,0,1,10,11),this.drawSegment(e,o,s,a,2,3,12,13),this.drawSegment(e,o,s,a,4,5,14,15),this.drawSegment(e,o,s,a,8,9,18,19),this.drawSegment(e,o,s,a,10,11,20,21),this.drawSegment(e,o,s,a,12,13,22,23),this.drawSegment(e,o,s,a,16,17,26,27),this.drawSegment(e,o,s,a,18,19,28,29),this.drawSegment(e,o,s,a,20,21,30,31)},e.prototype.drawSegment=function(t,e,r,n,i,o,s,a){var u=this.uvs,h=this.vertices,l=(u[s]-u[i])*r,c=(u[a]-u[o])*n,f=h[s]-h[i],d=h[a]-h[o];l<1&&(l=1),c<1&&(c=1),f<1&&(f=1),d<1&&(d=1),t.drawImage(e,u[i]*r,u[o]*n,l,c,h[i],h[o],f,d)},s(e,[{key:"width",get:function(){return this._width},set:function(t){this._width=t,this.updateVerticalVertices()}},{key:"height",get:function(){return this._height},set:function(t){this._height=t,this.updateHorizontalVertices()}},{key:"leftWidth",get:function(){return this._leftWidth},set:function(t){this._leftWidth=t;var e=this.uvs,r=this.vertices;e[2]=e[10]=e[18]=e[26]=this._uvw*t,r[2]=r[10]=r[18]=r[26]=t,this.dirty=!0}},{key:"rightWidth",get:function(){return this._rightWidth},set:function(t){this._rightWidth=t;var e=this.uvs,r=this.vertices;e[4]=e[12]=e[20]=e[28]=1-this._uvw*t,r[4]=r[12]=r[20]=r[28]=this._width-t,this.dirty=!0}},{key:"topHeight",get:function(){return this._topHeight},set:function(t){this._topHeight=t;var e=this.uvs,r=this.vertices;e[9]=e[11]=e[13]=e[15]=this._uvh*t,r[9]=r[11]=r[13]=r[15]=t,this.dirty=!0}},{key:"bottomHeight",get:function(){return this._bottomHeight},set:function(t){this._bottomHeight=t;var e=this.uvs,r=this.vertices;e[17]=e[19]=e[21]=e[23]=1-this._uvh*t,r[17]=r[19]=r[21]=r[23]=this._height-t,this.dirty=!0}}]),e}(u.default);r.default=l},{"./Plane":164}],164:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=t("./Mesh"),a=function(t){return t&&t.__esModule?t:{default:t}}(s),u=function(t){function e(r,o,s){n(this,e);var u=i(this,t.call(this,r));return u._ready=!0,u.verticesX=o||10,u.verticesY=s||10,u.drawMode=a.default.DRAW_MODES.TRIANGLES,u.refresh(),u}return o(e,t),e.prototype.refresh=function(){for(var t=this.verticesX*this.verticesY,e=[],r=[],n=[],i=[],o=this.texture,s=this.verticesX-1,a=this.verticesY-1,u=o.width/s,h=o.height/a,l=0;l<t;l++)if(o._uvs){var c=l%this.verticesX,f=l/this.verticesX|0;e.push(c*u,f*h),n.push(o._uvs.x0+(o._uvs.x1-o._uvs.x0)*(c/(this.verticesX-1)),o._uvs.y0+(o._uvs.y3-o._uvs.y0)*(f/(this.verticesY-1)))}else n.push(0);for(var d=s*a,p=0;p<d;p++){var v=p%s,y=p/s|0,g=y*this.verticesX+v,m=y*this.verticesX+v+1,_=(y+1)*this.verticesX+v,b=(y+1)*this.verticesX+v+1;i.push(g,m,_),i.push(m,b,_)}this.vertices=new Float32Array(e),this.uvs=new Float32Array(n),this.colors=new Float32Array(r),this.indices=new Uint16Array(i),this.indexDirty=!0},e.prototype._onTextureUpdate=function(){a.default.prototype._onTextureUpdate.call(this),this._ready&&this.refresh()},e}(a.default);r.default=u},{"./Mesh":162}],165:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=t("./Mesh"),a=function(t){return t&&t.__esModule?t:{default:t}}(s),u=t("../core"),h=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(u),l=function(t){function e(r,o){n(this,e);var s=i(this,t.call(this,r));return s.points=o,s.vertices=new Float32Array(4*o.length),s.uvs=new Float32Array(4*o.length),s.colors=new Float32Array(2*o.length),s.indices=new Uint16Array(2*o.length),s._ready=!0,s.refresh(),s}return o(e,t),e.prototype.refresh=function(){var t=this.points;if(!(t.length<1)&&this._texture._uvs){this.vertices.length/4!==t.length&&(this.vertices=new Float32Array(4*t.length),this.uvs=new Float32Array(4*t.length),this.colors=new Float32Array(2*t.length),this.indices=new Uint16Array(2*t.length));var e=this.uvs,r=this.indices,n=this.colors,i=this._texture._uvs,o=new h.Point(i.x0,i.y0),s=new h.Point(i.x2-i.x0,Number(i.y2-i.y0));e[0]=0+o.x,e[1]=0+o.y,e[2]=0+o.x,e[3]=s.y+o.y,n[0]=1,n[1]=1,r[0]=0,r[1]=1;for(var a=t.length,u=1;u<a;u++){var l=4*u,c=u/(a-1);e[l]=c*s.x+o.x,e[l+1]=0+o.y,e[l+2]=c*s.x+o.x,e[l+3]=s.y+o.y,l=2*u,n[l]=1,n[l+1]=1,l=2*u,r[l]=l,r[l+1]=l+1}this.dirty++,this.indexDirty++}},e.prototype._onTextureUpdate=function(){t.prototype._onTextureUpdate.call(this),this._ready&&this.refresh()},e.prototype.updateTransform=function(){var t=this.points;if(!(t.length<1)){for(var e=t[0],r=void 0,n=0,i=0,o=this.vertices,s=t.length,a=0;a<s;a++){var u=t[a],h=4*a;r=a<t.length-1?t[a+1]:u,i=-(r.x-e.x),n=r.y-e.y;var l=10*(1-a/(s-1));l>1&&(l=1);var c=Math.sqrt(n*n+i*i),f=this._texture.height/2;n/=c,i/=c,n*=f,i*=f,o[h]=u.x+n,o[h+1]=u.y+i,o[h+2]=u.x-n,o[h+3]=u.y-i,e=u}this.containerUpdateTransform()}},e}(a.default);r.default=l},{"../core":64,"./Mesh":162}],166:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=t("../../core"),o=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(i),s=t("../Mesh"),a=function(t){return t&&t.__esModule?t:{default:t}}(s),u=function(){function t(e){n(this,t),this.renderer=e}return t.prototype.render=function(t){var e=this.renderer,r=e.context,n=t.worldTransform,i=e.resolution;e.roundPixels?r.setTransform(n.a*i,n.b*i,n.c*i,n.d*i,n.tx*i|0,n.ty*i|0):r.setTransform(n.a*i,n.b*i,n.c*i,n.d*i,n.tx*i,n.ty*i),e.setBlendMode(t.blendMode),t.drawMode===a.default.DRAW_MODES.TRIANGLE_MESH?this._renderTriangleMesh(t):this._renderTriangles(t)},t.prototype._renderTriangleMesh=function(t){for(var e=t.vertices.length/2,r=0;r<e-2;r++){var n=2*r;this._renderDrawTriangle(t,n,n+2,n+4)}},t.prototype._renderTriangles=function(t){for(var e=t.indices,r=e.length,n=0;n<r;n+=3){var i=2*e[n],o=2*e[n+1],s=2*e[n+2];this._renderDrawTriangle(t,i,o,s)}},t.prototype._renderDrawTriangle=function(t,e,r,n){var i=this.renderer.context,o=t.uvs,s=t.vertices,a=t._texture;if(a.valid){var u=a.baseTexture,h=u.source,l=u.width,c=u.height,f=o[e]*u.width,d=o[r]*u.width,p=o[n]*u.width,v=o[e+1]*u.height,y=o[r+1]*u.height,g=o[n+1]*u.height,m=s[e],_=s[r],b=s[n],x=s[e+1],T=s[r+1],w=s[n+1];if(t.canvasPadding>0){var E=t.canvasPadding/t.worldTransform.a,S=t.canvasPadding/t.worldTransform.d,O=(m+_+b)/3,M=(x+T+w)/3,P=m-O,C=x-M,R=Math.sqrt(P*P+C*C);m=O+P/R*(R+E),x=M+C/R*(R+S),P=_-O,C=T-M,R=Math.sqrt(P*P+C*C),_=O+P/R*(R+E),T=M+C/R*(R+S),P=b-O,C=w-M,R=Math.sqrt(P*P+C*C),b=O+P/R*(R+E),w=M+C/R*(R+S)}i.save(),i.beginPath(),i.moveTo(m,x),i.lineTo(_,T),i.lineTo(b,w),i.closePath(),i.clip();var A=f*y+v*p+d*g-y*p-v*d-f*g,D=m*y+v*b+_*g-y*b-v*_-m*g,I=f*_+m*p+d*b-_*p-m*d-f*b,L=f*y*b+v*_*p+m*d*g-m*y*p-v*d*b-f*_*g,N=x*y+v*w+T*g-y*w-v*T-x*g,j=f*T+x*p+d*w-T*p-x*d-f*w,B=f*y*w+v*T*p+x*d*g-x*y*p-v*d*w-f*T*g;i.transform(D/A,N/A,I/A,j/A,L/A,B/A),i.drawImage(h,0,0,l*u.resolution,c*u.resolution,0,0,l,c),i.restore()}},t.prototype.renderMeshFlat=function(t){var e=this.renderer.context,r=t.vertices,n=r.length/2;e.beginPath();for(var i=1;i<n-2;++i){var o=2*i,s=r[o],a=r[o+1],u=r[o+2],h=r[o+3],l=r[o+4],c=r[o+5];e.moveTo(s,a),e.lineTo(u,h),e.lineTo(l,c)}e.fillStyle="#FF0000",e.fill(),e.closePath()},t.prototype.destroy=function(){this.renderer=null},t}();r.default=u,o.CanvasRenderer.registerPlugin("mesh",u)},{"../../core":64,"../Mesh":162}],167:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0;var i=t("./Mesh");Object.defineProperty(r,"Mesh",{enumerable:!0,get:function(){return n(i).default}});var o=t("./webgl/MeshRenderer");Object.defineProperty(r,"MeshRenderer",{enumerable:!0,get:function(){return n(o).default}});var s=t("./canvas/CanvasMeshRenderer");Object.defineProperty(r,"CanvasMeshRenderer",{enumerable:!0,get:function(){return n(s).default}});var a=t("./Plane");Object.defineProperty(r,"Plane",{enumerable:!0,get:function(){return n(a).default}});var u=t("./NineSlicePlane");Object.defineProperty(r,"NineSlicePlane",{enumerable:!0,get:function(){return n(u).default}});var h=t("./Rope");Object.defineProperty(r,"Rope",{enumerable:!0,get:function(){return n(h).default}})},{"./Mesh":162,"./NineSlicePlane":163,"./Plane":164,"./Rope":165,"./canvas/CanvasMeshRenderer":166,"./webgl/MeshRenderer":168}],168:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("../../core"),u=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(a),h=t("pixi-gl-core"),l=n(h),c=t("../Mesh"),f=n(c),d=(t("path"),function(t){function e(r){i(this,e);var n=o(this,t.call(this,r));return n.shader=null,n}return s(e,t),e.prototype.onContextChange=function(){var t=this.renderer.gl;this.shader=new u.Shader(t,"attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 translationMatrix;\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n    gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n\n    vTextureCoord = aTextureCoord;\n}\n","varying vec2 vTextureCoord;\nuniform float alpha;\nuniform vec3 tint;\n\nuniform sampler2D uSampler;\n\nvoid main(void)\n{\n    gl_FragColor = texture2D(uSampler, vTextureCoord) * vec4(tint * alpha, alpha);\n}\n")},e.prototype.render=function(t){var e=this.renderer,r=e.gl,n=t._texture;if(n.valid){var i=t._glDatas[e.CONTEXT_UID];i||(e.bindVao(null),i={shader:this.shader,vertexBuffer:l.default.GLBuffer.createVertexBuffer(r,t.vertices,r.STREAM_DRAW),uvBuffer:l.default.GLBuffer.createVertexBuffer(r,t.uvs,r.STREAM_DRAW),indexBuffer:l.default.GLBuffer.createIndexBuffer(r,t.indices,r.STATIC_DRAW),vao:null,dirty:t.dirty,indexDirty:t.indexDirty},i.vao=new l.default.VertexArrayObject(r).addIndex(i.indexBuffer).addAttribute(i.vertexBuffer,i.shader.attributes.aVertexPosition,r.FLOAT,!1,8,0).addAttribute(i.uvBuffer,i.shader.attributes.aTextureCoord,r.FLOAT,!1,8,0),t._glDatas[e.CONTEXT_UID]=i),e.bindVao(i.vao),t.dirty!==i.dirty&&(i.dirty=t.dirty,i.uvBuffer.upload(t.uvs)),t.indexDirty!==i.indexDirty&&(i.indexDirty=t.indexDirty,i.indexBuffer.upload(t.indices)),i.vertexBuffer.upload(t.vertices),e.bindShader(i.shader),i.shader.uniforms.uSampler=e.bindTexture(n),e.state.setBlendMode(t.blendMode),i.shader.uniforms.translationMatrix=t.worldTransform.toArray(!0),i.shader.uniforms.alpha=t.worldAlpha,i.shader.uniforms.tint=t.tintRgb;var o=t.drawMode===f.default.DRAW_MODES.TRIANGLE_MESH?r.TRIANGLE_STRIP:r.TRIANGLES;i.vao.draw(o,t.indices.length,0)}},e}(u.ObjectRenderer));r.default=d,u.WebGLRenderer.registerPlugin("mesh",d)},{"../../core":64,"../Mesh":162,path:23,"pixi-gl-core":12}],169:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=t("../core"),a=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(s),u=function(t){function e(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1500,o=arguments[1],s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:16384;n(this,e);var u=i(this,t.call(this));return s>16384&&(s=16384),s>r&&(s=r),u._properties=[!1,!0,!1,!1,!1],u._maxSize=r,u._batchSize=s,u._glBuffers={},u._bufferToUpdate=0,u.interactiveChildren=!1,u.blendMode=a.BLEND_MODES.NORMAL,u.roundPixels=!0,u.baseTexture=null,u.setProperties(o),u}return o(e,t),e.prototype.setProperties=function(t){t&&(this._properties[0]="scale"in t?!!t.scale:this._properties[0],this._properties[1]="position"in t?!!t.position:this._properties[1],this._properties[2]="rotation"in t?!!t.rotation:this._properties[2],this._properties[3]="uvs"in t?!!t.uvs:this._properties[3],this._properties[4]="alpha"in t?!!t.alpha:this._properties[4])},e.prototype.updateTransform=function(){this.displayObjectUpdateTransform()},e.prototype.renderWebGL=function(t){var e=this;this.visible&&!(this.worldAlpha<=0)&&this.children.length&&this.renderable&&(this.baseTexture||(this.baseTexture=this.children[0]._texture.baseTexture,this.baseTexture.hasLoaded||this.baseTexture.once("update",function(){return e.onChildrenChange(0)})),t.setObjectRenderer(t.plugins.particle),t.plugins.particle.render(this))},e.prototype.onChildrenChange=function(t){var e=Math.floor(t/this._batchSize);e<this._bufferToUpdate&&(this._bufferToUpdate=e)},e.prototype.renderCanvas=function(t){if(this.visible&&!(this.worldAlpha<=0)&&this.children.length&&this.renderable){var e=t.context,r=this.worldTransform,n=!0,i=0,o=0,s=0,a=0,u=t.blendModes[this.blendMode];u!==e.globalCompositeOperation&&(e.globalCompositeOperation=u),e.globalAlpha=this.worldAlpha,this.displayObjectUpdateTransform();for(var h=0;h<this.children.length;++h){var l=this.children[h];if(l.visible){var c=l._texture.frame;if(e.globalAlpha=this.worldAlpha*l.alpha,l.rotation%(2*Math.PI)==0)n&&(e.setTransform(r.a,r.b,r.c,r.d,r.tx*t.resolution,r.ty*t.resolution),n=!1),i=l.anchor.x*(-c.width*l.scale.x)+l.position.x+.5,o=l.anchor.y*(-c.height*l.scale.y)+l.position.y+.5,s=c.width*l.scale.x,a=c.height*l.scale.y;else{n||(n=!0),l.displayObjectUpdateTransform();var f=l.worldTransform;t.roundPixels?e.setTransform(f.a,f.b,f.c,f.d,f.tx*t.resolution|0,f.ty*t.resolution|0):e.setTransform(f.a,f.b,f.c,f.d,f.tx*t.resolution,f.ty*t.resolution),i=l.anchor.x*-c.width+.5,o=l.anchor.y*-c.height+.5,s=c.width,a=c.height}var d=l._texture.baseTexture.resolution;e.drawImage(l._texture.baseTexture.source,c.x*d,c.y*d,c.width*d,c.height*d,i*d,o*d,s*d,a*d)}}}},e.prototype.destroy=function(e){if(t.prototype.destroy.call(this,e),this._buffers)for(var r=0;r<this._buffers.length;++r)this._buffers[r].destroy();this._properties=null,this._buffers=null},e}(a.Container);r.default=u},{"../core":64}],170:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0;var i=t("./ParticleContainer");Object.defineProperty(r,"ParticleContainer",{enumerable:!0,get:function(){return n(i).default}});var o=t("./webgl/ParticleRenderer");Object.defineProperty(r,"ParticleRenderer",{enumerable:!0,get:function(){return n(o).default}})},{"./ParticleContainer":169,"./webgl/ParticleRenderer":172}],171:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var o=t("pixi-gl-core"),s=n(o),a=t("../../core/utils/createIndicesForQuads"),u=n(a),h=function(){function t(e,r,n,o){i(this,t),this.gl=e,this.vertSize=2,this.vertByteSize=4*this.vertSize,this.size=o,this.dynamicProperties=[],this.staticProperties=[];for(var s=0;s<r.length;++s){var a=r[s];a={attribute:a.attribute,size:a.size,uploadFunction:a.uploadFunction,offset:a.offset},n[s]?this.dynamicProperties.push(a):this.staticProperties.push(a)}this.staticStride=0,this.staticBuffer=null,this.staticData=null,this.dynamicStride=0,this.dynamicBuffer=null,this.dynamicData=null,this.initBuffers()}return t.prototype.initBuffers=function(){var t=this.gl,e=0;this.indices=(0,u.default)(this.size),this.indexBuffer=s.default.GLBuffer.createIndexBuffer(t,this.indices,t.STATIC_DRAW),this.dynamicStride=0;for(var r=0;r<this.dynamicProperties.length;++r){var n=this.dynamicProperties[r];n.offset=e,e+=n.size,this.dynamicStride+=n.size}this.dynamicData=new Float32Array(this.size*this.dynamicStride*4),this.dynamicBuffer=s.default.GLBuffer.createVertexBuffer(t,this.dynamicData,t.STREAM_DRAW);var i=0;this.staticStride=0;for(var o=0;o<this.staticProperties.length;++o){var a=this.staticProperties[o];a.offset=i,i+=a.size,this.staticStride+=a.size}this.staticData=new Float32Array(this.size*this.staticStride*4),this.staticBuffer=s.default.GLBuffer.createVertexBuffer(t,this.staticData,t.STATIC_DRAW),this.vao=new s.default.VertexArrayObject(t).addIndex(this.indexBuffer);for(var h=0;h<this.dynamicProperties.length;++h){var l=this.dynamicProperties[h];this.vao.addAttribute(this.dynamicBuffer,l.attribute,t.FLOAT,!1,4*this.dynamicStride,4*l.offset)}for(var c=0;c<this.staticProperties.length;++c){var f=this.staticProperties[c];this.vao.addAttribute(this.staticBuffer,f.attribute,t.FLOAT,!1,4*this.staticStride,4*f.offset)}},t.prototype.uploadDynamic=function(t,e,r){for(var n=0;n<this.dynamicProperties.length;n++){var i=this.dynamicProperties[n];i.uploadFunction(t,e,r,this.dynamicData,this.dynamicStride,i.offset)}this.dynamicBuffer.upload()},t.prototype.uploadStatic=function(t,e,r){for(var n=0;n<this.staticProperties.length;n++){var i=this.staticProperties[n];i.uploadFunction(t,e,r,this.staticData,this.staticStride,i.offset)}this.staticBuffer.upload()},t.prototype.destroy=function(){this.dynamicProperties=null,this.dynamicData=null,this.dynamicBuffer.destroy(),this.staticProperties=null,this.staticData=null,this.staticBuffer.destroy()},t}();r.default=h},{"../../core/utils/createIndicesForQuads":119,"pixi-gl-core":12}],172:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var a=t("../../core"),u=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(a),h=t("./ParticleShader"),l=n(h),c=t("./ParticleBuffer"),f=n(c),d=function(t){function e(r){i(this,e);var n=o(this,t.call(this,r));return n.shader=null,n.indexBuffer=null,n.properties=null,n.tempMatrix=new u.Matrix,n.CONTEXT_UID=0,n}
+return s(e,t),e.prototype.onContextChange=function(){var t=this.renderer.gl;this.CONTEXT_UID=this.renderer.CONTEXT_UID,this.shader=new l.default(t),this.properties=[{attribute:this.shader.attributes.aVertexPosition,size:2,uploadFunction:this.uploadVertices,offset:0},{attribute:this.shader.attributes.aPositionCoord,size:2,uploadFunction:this.uploadPosition,offset:0},{attribute:this.shader.attributes.aRotation,size:1,uploadFunction:this.uploadRotation,offset:0},{attribute:this.shader.attributes.aTextureCoord,size:2,uploadFunction:this.uploadUvs,offset:0},{attribute:this.shader.attributes.aColor,size:1,uploadFunction:this.uploadAlpha,offset:0}]},e.prototype.start=function(){this.renderer.bindShader(this.shader)},e.prototype.render=function(t){var e=t.children,r=t._maxSize,n=t._batchSize,i=this.renderer,o=e.length;if(0!==o){o>r&&(o=r);var s=t._glBuffers[i.CONTEXT_UID];s||(s=t._glBuffers[i.CONTEXT_UID]=this.generateBuffers(t)),this.renderer.setBlendMode(t.blendMode);var a=i.gl,u=t.worldTransform.copy(this.tempMatrix);u.prepend(i._activeRenderTarget.projectionMatrix),this.shader.uniforms.projectionMatrix=u.toArray(!0),this.shader.uniforms.uAlpha=t.worldAlpha;var h=e[0]._texture.baseTexture;this.shader.uniforms.uSampler=i.bindTexture(h);for(var l=0,c=0;l<o;l+=n,c+=1){var f=o-l;f>n&&(f=n);var d=s[c];d.uploadDynamic(e,l,f),t._bufferToUpdate===c&&(d.uploadStatic(e,l,f),t._bufferToUpdate=c+1),i.bindVao(d.vao),d.vao.draw(a.TRIANGLES,6*f)}}},e.prototype.generateBuffers=function(t){for(var e=this.renderer.gl,r=[],n=t._maxSize,i=t._batchSize,o=t._properties,s=0;s<n;s+=i)r.push(new f.default(e,this.properties,o,i));return r},e.prototype.uploadVertices=function(t,e,r,n,i,o){for(var s=0,a=0,u=0,h=0,l=0;l<r;++l){var c=t[e+l],f=c._texture,d=c.scale.x,p=c.scale.y,v=f.trim,y=f.orig;v?(a=v.x-c.anchor.x*y.width,s=a+v.width,h=v.y-c.anchor.y*y.height,u=h+v.height):(s=y.width*(1-c.anchor.x),a=y.width*-c.anchor.x,u=y.height*(1-c.anchor.y),h=y.height*-c.anchor.y),n[o]=a*d,n[o+1]=h*p,n[o+i]=s*d,n[o+i+1]=h*p,n[o+2*i]=s*d,n[o+2*i+1]=u*p,n[o+3*i]=a*d,n[o+3*i+1]=u*p,o+=4*i}},e.prototype.uploadPosition=function(t,e,r,n,i,o){for(var s=0;s<r;s++){var a=t[e+s].position;n[o]=a.x,n[o+1]=a.y,n[o+i]=a.x,n[o+i+1]=a.y,n[o+2*i]=a.x,n[o+2*i+1]=a.y,n[o+3*i]=a.x,n[o+3*i+1]=a.y,o+=4*i}},e.prototype.uploadRotation=function(t,e,r,n,i,o){for(var s=0;s<r;s++){var a=t[e+s].rotation;n[o]=a,n[o+i]=a,n[o+2*i]=a,n[o+3*i]=a,o+=4*i}},e.prototype.uploadUvs=function(t,e,r,n,i,o){for(var s=0;s<r;++s){var a=t[e+s]._texture._uvs;a?(n[o]=a.x0,n[o+1]=a.y0,n[o+i]=a.x1,n[o+i+1]=a.y1,n[o+2*i]=a.x2,n[o+2*i+1]=a.y2,n[o+3*i]=a.x3,n[o+3*i+1]=a.y3,o+=4*i):(n[o]=0,n[o+1]=0,n[o+i]=0,n[o+i+1]=0,n[o+2*i]=0,n[o+2*i+1]=0,n[o+3*i]=0,n[o+3*i+1]=0,o+=4*i)}},e.prototype.uploadAlpha=function(t,e,r,n,i,o){for(var s=0;s<r;s++){var a=t[e+s].alpha;n[o]=a,n[o+i]=a,n[o+2*i]=a,n[o+3*i]=a,o+=4*i}},e.prototype.destroy=function(){this.renderer.gl&&this.renderer.gl.deleteBuffer(this.indexBuffer),t.prototype.destroy.call(this),this.shader.destroy(),this.indices=null,this.tempMatrix=null},e}(u.ObjectRenderer);r.default=d,u.WebGLRenderer.registerPlugin("particle",d)},{"../../core":64,"./ParticleBuffer":171,"./ParticleShader":173}],173:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}r.__esModule=!0;var s=t("../../core/Shader"),a=function(t){return t&&t.__esModule?t:{default:t}}(s),u=function(t){function e(r){return n(this,e),i(this,t.call(this,r,["attribute vec2 aVertexPosition;","attribute vec2 aTextureCoord;","attribute float aColor;","attribute vec2 aPositionCoord;","attribute vec2 aScale;","attribute float aRotation;","uniform mat3 projectionMatrix;","varying vec2 vTextureCoord;","varying float vColor;","void main(void){","   vec2 v = aVertexPosition;","   v.x = (aVertexPosition.x) * cos(aRotation) - (aVertexPosition.y) * sin(aRotation);","   v.y = (aVertexPosition.x) * sin(aRotation) + (aVertexPosition.y) * cos(aRotation);","   v = v + aPositionCoord;","   gl_Position = vec4((projectionMatrix * vec3(v, 1.0)).xy, 0.0, 1.0);","   vTextureCoord = aTextureCoord;","   vColor = aColor;","}"].join("\n"),["varying vec2 vTextureCoord;","varying float vColor;","uniform sampler2D uSampler;","uniform float uAlpha;","void main(void){","  vec4 color = texture2D(uSampler, vTextureCoord) * vColor * uAlpha;","  if (color.a == 0.0) discard;","  gl_FragColor = color;","}"].join("\n")))}return o(e,t),e}(a.default);r.default=u},{"../../core/Shader":43}],174:[function(t,e,r){"use strict";Math.sign||(Math.sign=function(t){return t=Number(t),0===t||isNaN(t)?t:t>0?1:-1})},{}],175:[function(t,e,r){"use strict";var n=t("object-assign"),i=function(t){return t&&t.__esModule?t:{default:t}}(n);Object.assign||(Object.assign=i.default)},{"object-assign":5}],176:[function(t,e,r){"use strict";t("./Object.assign"),t("./requestAnimationFrame"),t("./Math.sign"),window.ArrayBuffer||(window.ArrayBuffer=Array),window.Float32Array||(window.Float32Array=Array),window.Uint32Array||(window.Uint32Array=Array),window.Uint16Array||(window.Uint16Array=Array)},{"./Math.sign":174,"./Object.assign":175,"./requestAnimationFrame":177}],177:[function(t,e,r){(function(t){"use strict";if(Date.now&&Date.prototype.getTime||(Date.now=function(){return(new Date).getTime()}),!t.performance||!t.performance.now){var e=Date.now();t.performance||(t.performance={}),t.performance.now=function(){return Date.now()-e}}for(var r=Date.now(),n=["ms","moz","webkit","o"],i=0;i<n.length&&!t.requestAnimationFrame;++i){var o=n[i];t.requestAnimationFrame=t[o+"RequestAnimationFrame"],t.cancelAnimationFrame=t[o+"CancelAnimationFrame"]||t[o+"CancelRequestAnimationFrame"]}t.requestAnimationFrame||(t.requestAnimationFrame=function(t){if("function"!=typeof t)throw new TypeError(t+"is not a function");var e=Date.now(),n=16+r-e;return n<0&&(n=0),r=e,setTimeout(function(){r=Date.now(),t(performance.now())},n)}),t.cancelAnimationFrame||(t.cancelAnimationFrame=function(t){return clearTimeout(t)})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],178:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){return e instanceof h.Text&&(e.updateText(!0),!0)}function o(t,e){if(e instanceof h.TextStyle){var r=h.Text.getFontStyle(e);return h.Text.fontPropertiesCache[r]||h.Text.calculateFontProperties(r),!0}return!1}function s(t,e){if(t instanceof h.Text){e.indexOf(t.style)===-1&&e.push(t.style),e.indexOf(t)===-1&&e.push(t);var r=t._texture.baseTexture;return e.indexOf(r)===-1&&e.push(r),!0}return!1}function a(t,e){return t instanceof h.TextStyle&&(e.indexOf(t)===-1&&e.push(t),!0)}r.__esModule=!0;var u=t("../core"),h=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(u),l=t("./limiters/CountLimiter"),c=function(t){return t&&t.__esModule?t:{default:t}}(l),f=h.ticker.shared;h.settings.UPLOADS_PER_FRAME=4;var d=function(){function t(e){var r=this;n(this,t),this.limiter=new c.default(h.settings.UPLOADS_PER_FRAME),this.renderer=e,this.uploadHookHelper=null,this.queue=[],this.addHooks=[],this.uploadHooks=[],this.completes=[],this.ticking=!1,this.delayedTick=function(){r.queue&&r.prepareItems()},this.register(s,i),this.register(a,o)}return t.prototype.upload=function(t,e){"function"==typeof t&&(e=t,t=null),t&&this.add(t),this.queue.length?(e&&this.completes.push(e),this.ticking||(this.ticking=!0,f.addOnce(this.tick,this))):e&&e()},t.prototype.tick=function(){setTimeout(this.delayedTick,0)},t.prototype.prepareItems=function(){for(this.limiter.beginFrame();this.queue.length&&this.limiter.allowedToUpload();){var t=this.queue[0],e=!1;if(t&&!t._destroyed)for(var r=0,n=this.uploadHooks.length;r<n;r++)if(this.uploadHooks[r](this.uploadHookHelper,t)){this.queue.shift(),e=!0;break}e||this.queue.shift()}if(this.queue.length)f.addOnce(this.tick,this);else{this.ticking=!1;var i=this.completes.slice(0);this.completes.length=0;for(var o=0,s=i.length;o<s;o++)i[o]()}},t.prototype.register=function(t,e){return t&&this.addHooks.push(t),e&&this.uploadHooks.push(e),this},t.prototype.add=function(t){for(var e=0,r=this.addHooks.length;e<r&&!this.addHooks[e](t,this.queue);e++);if(t instanceof h.Container)for(var n=t.children.length-1;n>=0;n--)this.add(t.children[n]);return this},t.prototype.destroy=function(){this.ticking&&f.remove(this.tick,this),this.ticking=!1,this.addHooks=null,this.uploadHooks=null,this.renderer=null,this.completes=null,this.queue=null,this.limiter=null,this.uploadHookHelper=null},t}();r.default=d},{"../core":64,"./limiters/CountLimiter":181}],179:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function s(t,e){if(e instanceof h.BaseTexture){var r=e.source,n=0===r.width?t.canvas.width:Math.min(t.canvas.width,r.width),i=0===r.height?t.canvas.height:Math.min(t.canvas.height,r.height);return t.ctx.drawImage(r,0,0,n,i,0,0,t.canvas.width,t.canvas.height),!0}return!1}function a(t,e){if(t instanceof h.BaseTexture)return e.indexOf(t)===-1&&e.push(t),!0;if(t._texture&&t._texture instanceof h.Texture){var r=t._texture.baseTexture;return e.indexOf(r)===-1&&e.push(r),!0}return!1}r.__esModule=!0;var u=t("../../core"),h=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(u),l=t("../BasePrepare"),c=function(t){return t&&t.__esModule?t:{default:t}}(l),f=16,d=function(t){function e(r){n(this,e);var o=i(this,t.call(this,r));return o.uploadHookHelper=o,o.canvas=document.createElement("canvas"),o.canvas.width=f,o.canvas.height=f,o.ctx=o.canvas.getContext("2d"),o.register(a,s),o}return o(e,t),e.prototype.destroy=function(){t.prototype.destroy.call(this),this.ctx=null,this.canvas=null},e}(c.default);r.default=d,h.CanvasRenderer.registerPlugin("prepare",d)},{"../../core":64,"../BasePrepare":178}],180:[function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}r.__esModule=!0;var i=t("./webgl/WebGLPrepare");Object.defineProperty(r,"webgl",{enumerable:!0,get:function(){return n(i).default}});var o=t("./canvas/CanvasPrepare");Object.defineProperty(r,"canvas",{enumerable:!0,get:function(){return n(o).default}});var s=t("./BasePrepare");Object.defineProperty(r,"BasePrepare",{enumerable:!0,get:function(){return n(s).default}});var a=t("./limiters/CountLimiter");Object.defineProperty(r,"CountLimiter",{enumerable:!0,get:function(){return n(a).default}});var u=t("./limiters/TimeLimiter");Object.defineProperty(r,"TimeLimiter",{enumerable:!0,get:function(){return n(u).default}})},{"./BasePrepare":178,"./canvas/CanvasPrepare":179,"./limiters/CountLimiter":181,"./limiters/TimeLimiter":182,"./webgl/WebGLPrepare":183}],181:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(e){n(this,t),this.maxItemsPerFrame=e,this.itemsLeft=0}return t.prototype.beginFrame=function(){this.itemsLeft=this.maxItemsPerFrame},t.prototype.allowedToUpload=function(){return this.itemsLeft-- >0},t}();r.default=i},{}],182:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.__esModule=!0;var i=function(){function t(e){n(this,t),this.maxMilliseconds=e,this.frameStart=0}return t.prototype.beginFrame=function(){this.frameStart=Date.now()},t.prototype.allowedToUpload=function(){return Date.now()-this.frameStart<this.maxMilliseconds},t}();r.default=i},{}],183:[function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function s(t,e){return e instanceof c.BaseTexture&&(e._glTextures[t.CONTEXT_UID]||t.textureManager.updateTexture(e),!0)}function a(t,e){return e instanceof c.Graphics&&((e.dirty||e.clearDirty||!e._webGL[t.plugins.graphics.CONTEXT_UID])&&t.plugins.graphics.updateGraphics(e),!0)}function u(t,e){if(t instanceof c.BaseTexture)return e.indexOf(t)===-1&&e.push(t),!0;if(t._texture&&t._texture instanceof c.Texture){var r=t._texture.baseTexture;return e.indexOf(r)===-1&&e.push(r),!0}return!1}function h(t,e){return t instanceof c.Graphics&&(e.push(t),!0)}r.__esModule=!0;var l=t("../../core"),c=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}(l),f=t("../BasePrepare"),d=function(t){return t&&t.__esModule?t:{default:t}}(f),p=function(t){function e(r){n(this,e);var o=i(this,t.call(this,r));return o.uploadHookHelper=o.renderer,o.register(u,s).register(h,a),o}return o(e,t),e}(d.default);r.default=p,c.WebGLRenderer.registerPlugin("prepare",p)},{"../../core":64,"../BasePrepare":178}],184:[function(t,e,r){(function(e){"use strict";function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e.default=t,e}r.__esModule=!0,r.loader=r.prepare=r.particles=r.mesh=r.loaders=r.interaction=r.filters=r.extras=r.extract=r.accessibility=void 0;var i=t("./polyfill");Object.keys(i).forEach(function(t){"default"!==t&&"__esModule"!==t&&Object.defineProperty(r,t,{enumerable:!0,get:function(){return i[t]}})});var o=t("./deprecation");Object.keys(o).forEach(function(t){"default"!==t&&"__esModule"!==t&&Object.defineProperty(r,t,{enumerable:!0,get:function(){return o[t]}})});var s=t("./core");Object.keys(s).forEach(function(t){"default"!==t&&"__esModule"!==t&&Object.defineProperty(r,t,{enumerable:!0,get:function(){return s[t]}})});var a=t("./accessibility"),u=n(a),h=t("./extract"),l=n(h),c=t("./extras"),f=n(c),d=t("./filters"),p=n(d),v=t("./interaction"),y=n(v),g=t("./loaders"),m=n(g),_=t("./mesh"),b=n(_),x=t("./particles"),T=n(x),w=t("./prepare"),E=n(w);s.utils.mixins.performMixins(),r.accessibility=u,r.extract=l,r.extras=f,r.filters=p,r.interaction=y,r.loaders=m,r.mesh=b,r.particles=T,r.prepare=E;var S=m&&m.Loader?new m.Loader:null;r.loader=S,e.PIXI=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./accessibility":41,"./core":64,"./deprecation":126,"./extract":128,"./extras":137,"./filters":148,"./interaction":155,"./loaders":158,"./mesh":167,"./particles":170,"./polyfill":176,"./prepare":180}]},{},[184])(184)});
+//# sourceMappingURL=pixi.min.js.map
\ No newline at end of file
diff --git a/player/js/animation/AnimationItem.js b/player/js/animation/AnimationItem.js
index 3183ae7..15dcd8f 100644
--- a/player/js/animation/AnimationItem.js
+++ b/player/js/animation/AnimationItem.js
@@ -46,6 +46,11 @@
         case 'svg':
             this.renderer = new SVGRenderer(this, params.rendererSettings);
             break;
+        case 'pixi':
+            this.renderer = new PIXIRenderer(this, params.rendererSettings);
+            break;
+        case 'hybrid':
+        case 'html':
         default:
             this.renderer = new HybridRenderer(this, params.rendererSettings);
             break;
diff --git a/player/js/elements/canvasElements/CVImageElement.js b/player/js/elements/canvasElements/CVImageElement.js
index e5b63a8..dfc0617 100644
--- a/player/js/elements/canvasElements/CVImageElement.js
+++ b/player/js/elements/canvasElements/CVImageElement.js
@@ -8,6 +8,7 @@
 }
 extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
 
+//TODO: refactor this
 CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
 CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
 
diff --git a/player/js/elements/helpers/shapes/PIXIElementsRenderer.js b/player/js/elements/helpers/shapes/PIXIElementsRenderer.js
new file mode 100644
index 0000000..2fc2aaa
--- /dev/null
+++ b/player/js/elements/helpers/shapes/PIXIElementsRenderer.js
@@ -0,0 +1,230 @@
+var PIXIElementsRenderer = (function() {
+	var _identityMatrix = new Matrix();
+	var _matrixHelper = new Matrix();
+
+	var ob = {
+		createRenderFunction: createRenderFunction
+	}
+
+	function createRenderFunction(data) {
+	    var ty = data.ty;
+	    switch(data.ty) {
+	        case 'fl':
+	        return renderFill;
+	        case 'gf':
+	        return renderGradient;
+	        case 'gs':
+	        return renderGradientStroke;
+	        case 'st':
+	        return renderStroke;
+	        case 'sh':
+	        case 'el':
+	        case 'rc':
+	        case 'sr':
+	        return renderPath;
+	        case 'tr':
+	        return renderContentTransform;
+	    }
+	}
+
+	function renderContentTransform(styleData, itemData, isFirstFrame) {
+	    if(isFirstFrame || itemData.transform.op._mdf){
+	        itemData.transform.container.alpha = itemData.transform.op.v;
+	    }
+	    if(isFirstFrame || itemData.transform.mProps._mdf){
+	    	var finalMat = itemData.transform.mProps.v;
+            var mt = new PIXI.Matrix();
+            mt.a = finalMat.props[0];
+            mt.b = finalMat.props[1];
+            mt.c = finalMat.props[4];
+            mt.d = finalMat.props[5];
+            mt.tx = finalMat.props[12];
+            mt.ty = finalMat.props[13];
+            itemData.transform.container.transform.setFromMatrix(mt);
+	    }
+	}
+
+	function renderPath(styleData, itemData, isFirstFrame) {
+	    var j, jLen,pathStringTransformed,redraw,pathNodes,l, lLen = itemData.styles.length;
+	    var lvl = itemData.lvl;
+	    var paths, mat, props, iterations, k, PPathString;
+	    for(l=0;l<lLen;l+=1){
+        	PPathString = [];
+	        redraw = itemData.sh._mdf || isFirstFrame;
+	        if(itemData.styles[l].lvl < lvl){
+	            mat = _matrixHelper.reset();
+	            iterations = lvl - itemData.styles[l].lvl;
+	            k = itemData.transformers.length-1;
+	            while(!redraw && iterations > 0) {
+	                redraw = itemData.transformers[k].mProps._mdf || redraw;
+	                iterations --;
+	                k --;
+	            }
+	            if(redraw) {
+	                iterations = lvl - itemData.styles[l].lvl;
+	                k = itemData.transformers.length-1;
+	                while(iterations > 0) {
+	                    props = itemData.transformers[k].mProps.v.props;
+	                    mat.transform(props[0],props[1],props[2],props[3],props[4],props[5],props[6],props[7],props[8],props[9],props[10],props[11],props[12],props[13],props[14],props[15]);
+	                    iterations --;
+	                    k --;
+	                }
+	            }
+	        } else {
+	            mat = _identityMatrix;
+	        }
+	        paths = itemData.sh.paths;
+	        jLen = paths._length;
+	        if(redraw){
+	            pathStringTransformed = '';
+	            for(j=0;j<jLen;j+=1){
+	                pathNodes = paths.shapes[j];
+	                if(pathNodes && pathNodes._length){
+	                	PPathString = PPathString.concat(buildPIXIShape(pathNodes, pathNodes._length, pathNodes.c, mat))
+	                    //pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+	                }
+	            }
+	            itemData.caches[l] = PPathString;
+	        } else {
+	            PPathString = itemData.caches[l];
+	        }
+	        itemData.styles[l].PD = itemData.styles[l].PD.concat(PPathString);
+	        itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+	    }
+	}
+
+	function renderFill (styleData,itemData, isFirstFrame){
+	    var styleElem = itemData.style;
+
+	    if(itemData.c._mdf || isFirstFrame){
+	        //styleElem.pElem.setAttribute('fill','rgb('+bm_floor(itemData.c.v[0])+','+bm_floor(itemData.c.v[1])+','+bm_floor(itemData.c.v[2])+')');
+	    	//Todo: this shouldn't be invoked every frame
+	    	styleElem._mdf = true;
+	    	styleElem._styleType = 'fill';
+	    	styleElem._styleColor = rgbToHex(bm_floor(itemData.c.v[0]),bm_floor(itemData.c.v[1]),bm_floor(itemData.c.v[2]),'0x');
+		    //styleElem.PpElem.clear();
+		    //styleElem.PpElem.beginFill(rgbToHex(bm_floor(itemData.c.v[0]),bm_floor(itemData.c.v[1]),bm_floor(itemData.c.v[2]),'0x'));
+	    }
+	    if(itemData.o._mdf || isFirstFrame){
+	        styleElem.pElem.setAttribute('fill-opacity',itemData.o.v);
+	    }
+
+	};
+
+	function renderGradientStroke (styleData, itemData, isFirstFrame) {
+	    renderGradient(styleData, itemData, isFirstFrame);
+	    renderStroke(styleData, itemData, isFirstFrame);
+	}
+
+	function renderGradient(styleData, itemData, isFirstFrame) {
+	    var gfill = itemData.gf;
+	    var hasOpacity = itemData.g._hasOpacity;
+	    var pt1 = itemData.s.v, pt2 = itemData.e.v;
+
+	    if (itemData.o._mdf || isFirstFrame) {
+	        var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+	        itemData.style.pElem.setAttribute(attr, itemData.o.v);
+	    }
+	    if (itemData.s._mdf || isFirstFrame) {
+	        var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+	        var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+	        gfill.setAttribute(attr1, pt1[0]);
+	        gfill.setAttribute(attr2, pt1[1]);
+	        if (hasOpacity && !itemData.g._collapsable) {
+	            itemData.of.setAttribute(attr1, pt1[0]);
+	            itemData.of.setAttribute(attr2, pt1[1]);
+	        }
+	    }
+	    var stops, i, len, stop;
+	    if (itemData.g._cmdf || isFirstFrame) {
+	        stops = itemData.cst;
+	        var cValues = itemData.g.c;
+	        len = stops.length;
+	        for (i = 0; i < len; i += 1){
+	            stop = stops[i];
+	            stop.setAttribute('offset', cValues[i * 4] + '%');
+	            stop.setAttribute('stop-color','rgb('+ cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ','+cValues[i * 4 + 3] + ')');
+	        }
+	    }
+	    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+	        var oValues = itemData.g.o;
+	        if(itemData.g._collapsable) {
+	            stops = itemData.cst;
+	        } else {
+	            stops = itemData.ost;
+	        }
+	        len = stops.length;
+	        for (i = 0; i < len; i += 1) {
+	            stop = stops[i];
+	            if(!itemData.g._collapsable) {
+	                stop.setAttribute('offset', oValues[i * 2] + '%');
+	            }
+	            stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+	        }
+	    }
+	    if (styleData.t === 1) {
+	        if (itemData.e._mdf  || isFirstFrame) {
+	            gfill.setAttribute('x2', pt2[0]);
+	            gfill.setAttribute('y2', pt2[1]);
+	            if (hasOpacity && !itemData.g._collapsable) {
+	                itemData.of.setAttribute('x2', pt2[0]);
+	                itemData.of.setAttribute('y2', pt2[1]);
+	            }
+	        }
+	    } else {
+	        var rad;
+	        if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+	            rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+	            gfill.setAttribute('r', rad);
+	            if(hasOpacity && !itemData.g._collapsable){
+	                itemData.of.setAttribute('r', rad);
+	            }
+	        }
+	        if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+	            if (!rad) {
+	                rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+	            }
+	            var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+	            var percent = itemData.h.v >= 1 ? 0.99 : itemData.h.v <= -1 ? -0.99: itemData.h.v;
+	            var dist = rad * percent;
+	            var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+	            var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+	            gfill.setAttribute('fx', x);
+	            gfill.setAttribute('fy', y);
+	            if (hasOpacity && !itemData.g._collapsable) {
+	                itemData.of.setAttribute('fx', x);
+	                itemData.of.setAttribute('fy', y);
+	            }
+	        }
+	        //gfill.setAttribute('fy','200');
+	    }
+	};
+
+	function renderStroke(styleData, itemData, isFirstFrame) {
+	    var styleElem = itemData.style;
+	    /*var d = itemData.d;
+	    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+	        styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+	        styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+	    }
+	    if(itemData.c && (itemData.c._mdf || isFirstFrame)){
+	        styleElem.pElem.setAttribute('stroke','rgb(' + bm_floor(itemData.c.v[0]) + ',' + bm_floor(itemData.c.v[1]) + ',' + bm_floor(itemData.c.v[2]) + ')');
+	    }
+	    if(itemData.o._mdf || isFirstFrame){
+	        styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+	    }
+	    if(itemData.w._mdf || isFirstFrame){
+	        styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+	        if(styleElem.msElem){
+	            styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+	        }
+	    }*/
+    	styleElem._mdf = true;
+    	styleElem._styleType = 'stroke';
+    	styleElem._styleColor = rgbToHex(bm_floor(itemData.c.v[0]),bm_floor(itemData.c.v[1]),bm_floor(itemData.c.v[2]),'0x');
+    	styleElem._styleWidth = itemData.w.v;
+	};
+
+	return ob;
+}())
\ No newline at end of file
diff --git a/player/js/elements/helpers/shapes/SVGStyleData.js b/player/js/elements/helpers/shapes/SVGStyleData.js
index 63b9761..cb783fa 100644
--- a/player/js/elements/helpers/shapes/SVGStyleData.js
+++ b/player/js/elements/helpers/shapes/SVGStyleData.js
@@ -6,10 +6,13 @@
 	this._mdf = false;
 	this.closed = false;
 	this.pElem = createNS('path');
+	this.PpElem = new PIXI.Graphics();
+	this.PD = [];
 	this.msElem = null;
 }
 
 SVGStyleData.prototype.reset = function() {
 	this.d = '';
+	this.PD.length = 0;
 	this._mdf = false;
 };
\ No newline at end of file
diff --git a/player/js/elements/pixiElements/PIXIBaseElement.js b/player/js/elements/pixiElements/PIXIBaseElement.js
new file mode 100644
index 0000000..e2bd947
--- /dev/null
+++ b/player/js/elements/pixiElements/PIXIBaseElement.js
@@ -0,0 +1,121 @@
+function PIXIBaseElement(data,parentContainer,globalData,comp, placeholder){
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.matteElement = null;
+    this.parentContainer = parentContainer;
+    this.layerId = placeholder ? placeholder.layerId : 'ly_'+randomString(10);
+    this.placeholder = placeholder;
+    this.init();
+};
+
+PIXIBaseElement.prototype = {
+    initRendererElement: function() {
+        this.layerElement = new PIXI.DisplayObjectContainer();
+    },
+    createContainerElements: function(){
+        this.transformedElement = this.layerElement;
+        this.maskedElement = this.layerElement;
+        this._sizeChanged = false;
+        var layerElementParent = null;
+        //If this layer acts as a mask for the following layer
+        var filId, fil, gg;
+        if (this.data.td) {
+            if (this.data.td == 3 || this.data.td == 1) {
+            } else if(this.data.td == 2) {
+            }
+        } else if (this.data.tt) {
+        } else {
+            this.baseElement = this.layerElement;
+        }
+        //Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+        if (this.data.ty === 0 && !this.data.hd) {
+            //Todo Clip compositions
+
+            if (this.checkMasks()) {
+                if (layerElementParent) {
+                    layerElementParent.appendChild(this.transformedElement);
+                } else {
+                    this.baseElement = this.transformedElement;
+                }
+            } else {
+                //this.layerElement.setAttribute('clip-path','url(' + locationHref + '#'+clipId+')');
+            }
+            
+        }
+        if (this.data.bm !== 0) {
+            //this.setBlendMode();
+        }
+        this.renderableEffectsManager = new PIXIEffects(this);
+    },
+    renderInnerContent: function() {},
+    renderFrame: function() {
+        if (this.hidden) {
+            return;
+        }
+        this.renderTransform();
+        //this.setBlendMode();
+        this.renderRenderable();
+        this.renderElement();
+        this.renderInnerContent();
+        if (this._isFirstFrame) {
+            this._isFirstFrame = false;
+        }
+    },
+    renderElement: function() {
+        if (this.finalTransform._matMdf) {
+            var finalMat = this.finalTransform.mat;
+            var mt = new PIXI.Matrix();
+            mt.a = finalMat.props[0];
+            mt.b = finalMat.props[1];
+            mt.c = finalMat.props[4];
+            mt.d = finalMat.props[5];
+            mt.tx = finalMat.props[12];
+            mt.ty = finalMat.props[13];
+            this.transformedElement.transform.setFromMatrix(mt);
+        }
+        if (this.finalTransform._opMdf) {
+            this.transformedElement.alpha = this.finalTransform.mProp.o.v;
+        }
+    },
+}
+
+PIXIBaseElement.prototype.destroy = function(){
+    this.layerElement = null;
+    this.parentContainer = null;
+    if(this.matteElement) {
+        this.matteElement = null;
+    }
+    if(this.maskManager) {
+        this.maskManager.destroy();
+    }
+};
+
+PIXIBaseElement.prototype.getBaseElement = function(){
+    return this.baseElement;
+};
+PIXIBaseElement.prototype.addMasks = function(){
+    this.maskManager = new PIXIMaskElement(this.data, this, this.globalData);
+};
+
+PIXIBaseElement.prototype.setMatte = function(id){
+    if(!this.matteElement){
+        return;
+    }
+    this.matteElement.setAttribute("mask", "url(#" + id + ")");
+};
+
+PIXIBaseElement.prototype.show = function(){
+    if (this.isInRange && !this.isTransparent){
+        this.hidden = false;
+        this._isFirstFrame = true;
+        this.layerElement.visible = true;
+    }
+};
+
+PIXIBaseElement.prototype.hide = function(){
+    if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        this.layerElement.visible = false;
+        this.hidden = true;
+    }
+};
\ No newline at end of file
diff --git a/player/js/elements/pixiElements/PIXICompElement.js b/player/js/elements/pixiElements/PIXICompElement.js
new file mode 100644
index 0000000..e0ee205
--- /dev/null
+++ b/player/js/elements/pixiElements/PIXICompElement.js
@@ -0,0 +1,19 @@
+function PIXICompElement(data, globalData, comp){
+    this.completeLayers = false;
+    this.layers = data.layers;
+    this.pendingElements = [];
+    this.elements = createSizedArray(this.layers.length);
+    this.initElement(data, globalData, comp);
+    this.tm = data.tm ? PropertyFactory.getProp(this,data.tm,0,globalData.frameRate, this) : {_placeholder:true};
+}
+
+extendPrototype([PIXIRenderer, ICompElement, PIXIBaseElement], PIXICompElement);
+
+PIXICompElement.prototype.renderInnerContent = function() {
+    var i,len = this.layers.length;
+    for( i = len - 1; i >= 0; i -= 1 ){
+        if(this.completeLayers || this.elements[i]){
+            this.elements[i].renderFrame();
+        }
+    }
+};
\ No newline at end of file
diff --git a/player/js/elements/pixiElements/PIXIEffects.js b/player/js/elements/pixiElements/PIXIEffects.js
new file mode 100644
index 0000000..cb1e5ac
--- /dev/null
+++ b/player/js/elements/pixiElements/PIXIEffects.js
@@ -0,0 +1,31 @@
+function PIXIEffects(elem){
+    var i, len = elem.data.ef ? elem.data.ef.length : 0;
+    var count = 0;
+    this.filters = [];
+    var filterManager;
+    for(i = 0; i < len; i += 1) {
+        filterManager = null;
+        if (elem.data.ef[i].ty === 29) {
+            filterManager = new PIXIGaussianBlurEffect(elem.effectsManager.effectElements[i]);
+        }
+        if (filterManager) {
+            this.filters.push(filterManager);
+        }
+    }
+    if (this.filters.length) {
+        var i, len = this.filters.length;
+        var pixiFilters = [];
+        for(i = 0; i < len ; i += 1) {
+            pixiFilters.push(this.filters[i].pixiFilter);
+        }
+        elem.layerElement.filters = pixiFilters;
+        elem.addRenderableComponent(this);
+    }
+}
+
+PIXIEffects.prototype.renderFrame = function(_isFirstFrame){
+    var i, len = this.filters.length;
+    for(i=0;i<len;i+=1){
+        this.filters[i].renderFrame(_isFirstFrame);
+    }
+};
\ No newline at end of file
diff --git a/player/js/elements/pixiElements/PIXIImageElement.js b/player/js/elements/pixiElements/PIXIImageElement.js
new file mode 100644
index 0000000..e4da173
--- /dev/null
+++ b/player/js/elements/pixiElements/PIXIImageElement.js
@@ -0,0 +1,28 @@
+function PIXIImageElement(data,globalData,comp){
+    this.assetData = globalData.getAssetData(data.refId);
+    this.initElement(data,globalData,comp);
+}
+extendPrototype([BaseElement, TransformElement, PIXIBaseElement, HierarchyElement, FrameElement, RenderableElement], PIXIImageElement);
+
+PIXIImageElement.prototype.createContent = function(){
+    var assetPath = this.globalData.getAssetsPath(this.assetData);
+    var texture = PIXI.Texture.fromImage(assetPath);
+    this.innerElem = new PIXI.Sprite(texture);
+    this.layerElement.addChild(this.innerElem);
+
+};
+
+PIXIImageElement.prototype.initElement = function(data,globalData,comp) {
+    this.initFrame();
+    this.initBaseData(data, globalData, comp);
+    this.initTransform(data, globalData, comp);
+    this.initHierarchy();
+    this.initRenderable();
+    this.initRendererElement();
+    this.createContainerElements();
+    this.addMasks();
+    this.createContent();
+    this.hide();
+}
+
+PIXIImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
\ No newline at end of file
diff --git a/player/js/elements/pixiElements/PIXIMask.js b/player/js/elements/pixiElements/PIXIMask.js
new file mode 100644
index 0000000..695d99d
--- /dev/null
+++ b/player/js/elements/pixiElements/PIXIMask.js
@@ -0,0 +1,240 @@
+function PIXIMaskElement(data,element,globalData) {
+    this.dynamicProperties = [];
+    this.data = data;
+    this.element = element;
+    this.globalData = globalData;
+    this.paths = [];
+    this.storedData = [];
+    this.masksProperties = this.data.masksProperties || [];
+    this.viewData = new Array(this.masksProperties.length);
+    this.maskElement = null;
+    this.PMaskElement = null;
+    var defs = this.globalData.defs;
+    var i, len = this.masksProperties.length;
+
+
+    var path,PPath, properties = this.masksProperties;
+    var count = 0;
+    var currentMasks = [],currentPMasks = [];
+    var j, jLen;
+    var layerId = randomString(10);
+    var rect, expansor, feMorph,x;
+    var maskType = 'clipPath', maskRef = 'clip-path';
+    for (i = 0; i < len; i++) {
+
+        if((properties[i].mode !== 'a' && properties[i].mode !== 'n')|| properties[i].inv){
+            maskType = 'mask';
+            maskRef = 'mask';
+        }
+
+        if((properties[i].mode == 's' || properties[i].mode == 'i') && count == 0){
+            rect = document.createElementNS(svgNS, 'rect');
+            rect.setAttribute('fill', '#ffffff');
+            rect.setAttribute('width', this.element.comp.data ? this.element.comp.data.w : this.element.globalData.compSize.w);
+            rect.setAttribute('height', this.element.comp.data ? this.element.comp.data.h : this.element.globalData.compSize.h);
+            currentMasks.push(rect);
+        } else {
+            rect = null;
+        }
+
+        path = document.createElementNS(svgNS, 'path');
+        PPath = new PIXI.Graphics;
+        if(properties[i].mode == 'n' || properties[i].cl === false) {
+            this.viewData[i] = {
+                prop: ShapePropertyFactory.getShapeProp(this.element,properties[i],3),
+                elem: path
+            };
+            defs.appendChild(path);
+            continue;
+        }
+        count += 1;
+        if (properties[i].cl) {
+            if(properties[i].mode == 's'){
+                path.setAttribute('fill', '#000000');
+            }else{
+                path.setAttribute('fill', '#ffffff');
+            }
+        } else {
+            path.setAttribute('fill', 'none');
+            if(properties[i].mode == 's'){
+                path.setAttribute('fill', '#000000');
+            }else{
+                path.setAttribute('fill', '#ffffff');
+            }
+            path.setAttribute('stroke-width', '1');
+            path.setAttribute('stroke-miterlimit', '10');
+        }
+        path.setAttribute('clip-rule','nonzero');
+
+        if(properties[i].x.k !== 0){
+            maskType = 'mask';
+            maskRef = 'mask';
+            x = PropertyFactory.getProp(this.element,properties[i].x,0,null,this.element);
+            var filterID = 'fi_'+randomString(10);
+            expansor = document.createElementNS(svgNS,'filter');
+            expansor.setAttribute('id',filterID);
+            feMorph = document.createElementNS(svgNS,'feMorphology');
+            feMorph.setAttribute('operator','dilate');
+            feMorph.setAttribute('in','SourceGraphic');
+            feMorph.setAttribute('radius','0');
+            expansor.appendChild(feMorph);
+            defs.appendChild(expansor);
+            if(properties[i].mode == 's'){
+                path.setAttribute('stroke', '#000000');
+            }else{
+                path.setAttribute('stroke', '#ffffff');
+            }
+        }else{
+            feMorph = null;
+            x = null;
+        }
+
+
+        this.storedData[i] = {
+             elem: path,
+             PElem: PPath,
+             x: x,
+             expan: feMorph,
+            lastPath: '',
+            lastOperator:'',
+            filterId:filterID,
+            lastRadius:0
+        };
+        if(properties[i].mode == 'i'){
+            jLen = currentMasks.length;
+            var g = document.createElementNS(svgNS,'g');
+            for(j=0;j<jLen;j+=1){
+                g.appendChild(currentMasks[j]);
+            }
+            var mask = document.createElementNS(svgNS,'mask');
+            mask.setAttribute('mask-type','alpha');
+            mask.setAttribute('id',layerId+'_'+count);
+            mask.appendChild(path);
+            defs.appendChild(mask);
+            g.setAttribute('mask','url(#'+layerId+'_'+count+')');
+
+            currentMasks.length = 0;
+            currentMasks.push(g);
+        }else{
+            currentMasks.push(path);
+            currentPMasks.push(PPath);
+        }
+        if(properties[i].inv && !this.solidPath){
+            this.solidPath = this.createLayerSolidPath();
+        }
+        this.viewData[i] = {
+            elem: path,
+            PElem: PPath,
+            lastPath: '',
+            prop:ShapePropertyFactory.getShapeProp(this.element,properties[i],3)
+        };
+        if(rect){
+            this.viewData[i].invRect = rect;
+        }
+        if(!this.viewData[i].prop.k){
+            this.drawPath(properties[i],this.viewData[i].prop.v,this.viewData[i]);
+        }
+    }
+
+    this.maskElement = document.createElementNS(svgNS, maskType);
+    this.PMaskElement = new PIXI.DisplayObjectContainer();
+
+    len = currentMasks.length;
+    for(i=0;i<len;i+=1){
+        this.maskElement.appendChild(currentMasks[i]);
+        //this.PMaskElement.addChild(currentPMasks[i]);
+    }
+
+    if(count > 0){
+        this.element.maskedElement.mask = currentPMasks[0];
+        this.element.maskedElement.addChild(currentPMasks[0]);
+    }
+    if (this.viewData.length) {
+        this.element.addRenderableComponent(this);
+    }
+
+};
+
+PIXIMaskElement.prototype.getMaskProperty = function(pos){
+    return this.viewData[pos].prop;
+};
+
+PIXIMaskElement.prototype.renderFrame = function (isFirstFrame) {
+    var i, len = this.masksProperties.length;
+    for (i = 0; i < len; i++) {
+        if(this.viewData[i].prop._mdf || isFirstFrame){
+            this.drawPath(this.masksProperties[i],this.viewData[i].prop.v,this.viewData[i]);
+        }
+    }
+};
+
+PIXIMaskElement.prototype.getMaskelement = function () {
+    return this.maskElement;
+};
+
+PIXIMaskElement.prototype.createLayerSolidPath = function(){
+    var path = 'M0,0 ';
+    path += ' h' + this.globalData.compSize.w ;
+    path += ' v' + this.globalData.compSize.h ;
+    path += ' h-' + this.globalData.compSize.w ;
+    path += ' v-' + this.globalData.compSize.h + ' ';
+    return path;
+};
+
+PIXIMaskElement.prototype.drawPath = function(pathData,pathNodes,viewData){
+    var pathString = '';
+    var i, len;
+    len = pathNodes._length;
+    viewData.PElem.clear();
+    viewData.PElem.beginFill(0xffffff);
+    for(i=1;i<len;i+=1){
+        if(i==1){
+            //pathString += " M"+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+            pathString += " M"+bm_rnd(pathNodes.v[0][0])+','+bm_rnd(pathNodes.v[0][1]);
+            viewData.PElem.moveTo(pathNodes.v[0][0],pathNodes.v[0][1]);
+        }
+        //pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+        pathString += " C"+bm_rnd(pathNodes.o[i-1][0])+','+bm_rnd(pathNodes.o[i-1][1]) + " "+bm_rnd(pathNodes.i[i][0])+','+bm_rnd(pathNodes.i[i][1]) + " "+bm_rnd(pathNodes.v[i][0])+','+bm_rnd(pathNodes.v[i][1]);
+        viewData.PElem.bezierCurveTo(pathNodes.o[i-1][0],pathNodes.o[i-1][1],pathNodes.i[i][0],pathNodes.i[i][1],pathNodes.v[i][0],pathNodes.v[i][1]);
+    }
+    if(pathData.cl){
+        //pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+        pathString += " C"+bm_rnd(pathNodes.o[i-1][0])+','+bm_rnd(pathNodes.o[i-1][1]) + " "+bm_rnd(pathNodes.i[0][0])+','+bm_rnd(pathNodes.i[0][1]) + " "+bm_rnd(pathNodes.v[0][0])+','+bm_rnd(pathNodes.v[0][1]);
+        viewData.PElem.bezierCurveTo(pathNodes.o[i-1][0],pathNodes.o[i-1][1],pathNodes.i[0][0],pathNodes.i[0][1],pathNodes.v[0][0],pathNodes.v[0][1]);
+    }
+    viewData.PElem.endFill();
+    //pathNodes.__renderedString = pathString;
+
+
+    if(viewData.lastPath !== pathString){
+        if(viewData.elem){
+            if(pathData.inv){
+                viewData.elem.setAttribute('d',this.solidPath + pathString);
+            }else{
+                viewData.elem.setAttribute('d',pathString);
+            }
+        }
+        viewData.lastPath = pathString;
+    }
+};
+
+PIXIMaskElement.prototype.getMask = function(nm){
+    var i = 0, len = this.masksProperties.length;
+    while(i<len){
+        if(this.masksProperties[i].nm === nm){
+            return {
+                maskPath: this.viewData[i].prop.pv
+            }
+        }
+        i += 1;
+    }
+};
+
+PIXIMaskElement.prototype.destroy = function(){
+    this.element = null;
+    this.globalData = null;
+    this.maskElement = null;
+    this.data = null;
+    this.paths = null;
+    this.masksProperties = null;
+};
\ No newline at end of file
diff --git a/player/js/elements/pixiElements/PIXIShapeElement.js b/player/js/elements/pixiElements/PIXIShapeElement.js
new file mode 100644
index 0000000..416518f
--- /dev/null
+++ b/player/js/elements/pixiElements/PIXIShapeElement.js
@@ -0,0 +1,338 @@
+function PIXIShapeElement(data, globalData, comp){
+    this.shapes = [];
+    this.shapesData = data.shapes;
+    this.stylesList = [];
+    this.itemsData = [];
+    this.prevViewData = [];
+    this.animatedContents = [];
+    this.shapeModifiers = [];
+    this.processedElements = [];
+    this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement,TransformElement,PIXIBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement], PIXIShapeElement);
+
+PIXIShapeElement.prototype.lcEnum = {
+    '1': 'butt',
+    '2': 'round',
+    '3': 'butt'
+}
+
+PIXIShapeElement.prototype.ljEnum = {
+    '1': 'miter',
+    '2': 'round',
+    '3': 'butt'
+}
+
+PIXIShapeElement.prototype.initElement = function(data,globalData,comp) {
+    this.initFrame();
+    this.initBaseData(data, globalData, comp);
+    this.initTransform(data, globalData, comp);
+    this.initHierarchy();
+    this.initRenderable();
+    this.initRendererElement();
+    this.createContainerElements();
+    this.addMasks();
+    this.createContent();
+    this.hide();
+}
+
+PIXIShapeElement.prototype.initSecondaryElement = function() {
+};
+
+PIXIShapeElement.prototype.identityMatrix = new Matrix();
+
+PIXIShapeElement.prototype.buildExpressionInterface = function(){};
+
+PIXIShapeElement.prototype.createContent = function(){
+    this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement, 0, [], true);
+    this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+PIXIShapeElement.prototype.filterUniqueShapes = function(){
+    var i, len = this.shapes.length, shape;
+    var j, jLen = this.stylesList.length;
+    var style, count = 0;
+    var tempShapes = [];
+    var areAnimated = false;
+    for(j = 0; j < jLen; j += 1) {
+        style = this.stylesList[j];
+        areAnimated = false;
+        tempShapes.length = 0;
+        for(i = 0; i < len; i += 1) {
+            shape = this.shapes[i];
+            if(shape.styles.indexOf(style) !== -1) {
+                tempShapes.push(shape);
+                areAnimated = shape._isAnimated || areAnimated;
+            }
+        }
+        if(tempShapes.length > 1 && areAnimated) {
+            this.setShapesAsAnimated(tempShapes);
+        }
+    }
+}
+
+PIXIShapeElement.prototype.setShapesAsAnimated = function(shapes){
+    var i, len = shapes.length;
+    for(i = 0; i < len; i += 1) {
+        shapes[i].setAsAnimated();
+    }
+}
+
+PIXIShapeElement.prototype.createStyleElement = function(data, level){
+    //TODO: prevent drawing of hidden styles
+    var elementData;
+    var styleOb = new SVGStyleData(data, level);
+
+    var pathElement = styleOb.pElem;
+    if(data.ty === 'st') {
+        elementData = new SVGStrokeStyleData(this, data, styleOb);
+    } else if(data.ty === 'fl') {
+        elementData = new SVGFillStyleData(this, data, styleOb);
+    } else if(data.ty === 'gf' || data.ty === 'gs') {
+        var gradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+        elementData = new gradientConstructor(this, data, styleOb);
+        this.globalData.defs.appendChild(elementData.gf);
+        if (elementData.maskId) {
+            this.globalData.defs.appendChild(elementData.ms);
+            this.globalData.defs.appendChild(elementData.of);
+            pathElement.setAttribute('mask','url(#' + elementData.maskId + ')');
+        }
+    }
+    
+    if(data.ty === 'st' || data.ty === 'gs') {
+        pathElement.setAttribute('stroke-linecap', this.lcEnum[data.lc] || 'round');
+        pathElement.setAttribute('stroke-linejoin',this.ljEnum[data.lj] || 'round');
+        pathElement.setAttribute('fill-opacity','0');
+        if(data.lj === 1) {
+            pathElement.setAttribute('stroke-miterlimit',data.ml);
+        }
+    }
+
+    if(data.r === 2) {
+        pathElement.setAttribute('fill-rule', 'evenodd');
+    }
+
+    this.stylesList.push(styleOb);
+    this.addToAnimatedContents(data, elementData);
+    return elementData;
+};
+
+PIXIShapeElement.prototype.createGroupElement = function(data) {
+    var elementData = {
+        it: [],
+        prevViewData: [],
+        gr: new PIXI.DisplayObjectContainer()
+    }
+    return elementData;
+};
+
+PIXIShapeElement.prototype.createTransformElement = function(data, container) {
+    var transformProperty = TransformPropertyFactory.getTransformProperty(this,data,this);
+    var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+    this.addToAnimatedContents(data, elementData);
+    return elementData;
+};
+
+PIXIShapeElement.prototype.createShapeElement = function(data, ownTransformers, level) {
+    var ty = 4;
+    if(data.ty === 'rc'){
+        ty = 5;
+    }else if(data.ty === 'el'){
+        ty = 6;
+    }else if(data.ty === 'sr'){
+        ty = 7;
+    }
+    var shapeProperty = ShapePropertyFactory.getShapeProp(this,data,ty,this);
+    var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+    this.shapes.push(elementData);
+    this.addShapeToModifiers(elementData);
+    this.addToAnimatedContents(data, elementData);
+    return elementData;
+};
+
+PIXIShapeElement.prototype.addToAnimatedContents = function(data, element) {
+    var i = 0, len = this.animatedContents.length;
+    while(i < len) {
+        if(this.animatedContents[i].element === element) {
+            return;
+        }
+        i += 1;
+    }
+    this.animatedContents.push({
+        fn: PIXIElementsRenderer.createRenderFunction(data),
+        element: element,
+        data: data
+    });
+};
+
+PIXIShapeElement.prototype.setElementStyles = function(elementData){
+    var arr = elementData.styles;
+    var j, jLen = this.stylesList.length;
+    for (j = 0; j < jLen; j += 1) {
+        if (!this.stylesList[j].closed) {
+            arr.push(this.stylesList[j]);
+        }
+    }
+};
+
+PIXIShapeElement.prototype.reloadShapes = function(){
+    this._isFirstFrame = true;
+    var i, len = this.itemsData.length;
+    for( i = 0; i < len; i += 1) {
+        this.prevViewData[i] = this.itemsData[i];
+    }
+    this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement, 0, [], true);
+    this.filterUniqueShapes();
+    len = this.dynamicProperties.length;
+    for(i = 0; i < len; i += 1) {
+        this.dynamicProperties[i].getValue();
+    }
+    this.renderModifiers();
+};
+
+PIXIShapeElement.prototype.searchShapes = function(arr,itemsData,prevViewData,container, level, transformers, render){
+    var ownTransformers = [].concat(transformers);
+    var i, len = arr.length - 1;
+    var j, jLen;
+    var ownStyles = [], ownModifiers = [], styleOb, currentTransform, modifier, processedPos;
+    for(i=len;i>=0;i-=1){
+        processedPos = this.searchProcessedElement(arr[i]);
+        if(!processedPos){
+            arr[i]._render = render;
+        } else {
+            itemsData[i] = prevViewData[processedPos - 1];
+        }
+        if(arr[i].ty == 'fl' || arr[i].ty == 'st' || arr[i].ty == 'gf' || arr[i].ty == 'gs'){
+            if(!processedPos){
+                itemsData[i] = this.createStyleElement(arr[i], level);
+            } else {
+                itemsData[i].style.closed = false;
+            }
+            if(arr[i]._render){
+                container.addChild(itemsData[i].style.PpElem);
+            }
+            ownStyles.push(itemsData[i].style);
+        }else if(arr[i].ty == 'gr'){
+            if(!processedPos){
+                itemsData[i] = this.createGroupElement(arr[i]);
+            } else {
+                jLen = itemsData[i].it.length;
+                for(j=0;j<jLen;j+=1){
+                    itemsData[i].prevViewData[j] = itemsData[i].it[j];
+                }
+            }
+            this.searchShapes(arr[i].it,itemsData[i].it,itemsData[i].prevViewData,itemsData[i].gr, level + 1, ownTransformers, render);
+            if(arr[i]._render){
+                container.addChild(itemsData[i].gr);
+            }
+        }else if(arr[i].ty == 'tr'){
+            if(!processedPos){
+                itemsData[i] = this.createTransformElement(arr[i], container);
+            }
+            currentTransform = itemsData[i].transform;
+            ownTransformers.push(currentTransform);
+        }else if(arr[i].ty == 'sh' || arr[i].ty == 'rc' || arr[i].ty == 'el' || arr[i].ty == 'sr'){
+            if(!processedPos){
+                itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+            }
+            this.setElementStyles(itemsData[i]);
+
+        }else if(arr[i].ty == 'tm' || arr[i].ty == 'rd' || arr[i].ty == 'ms'){
+            if(!processedPos){
+                modifier = ShapeModifiers.getModifier(arr[i].ty);
+                modifier.init(this,arr[i]);
+                itemsData[i] = modifier;
+                this.shapeModifiers.push(modifier);
+            } else {
+                modifier = itemsData[i];
+                modifier.closed = false;
+            }
+            ownModifiers.push(modifier);
+        }else if(arr[i].ty == 'rp'){
+            if(!processedPos){
+                modifier = ShapeModifiers.getModifier(arr[i].ty);
+                itemsData[i] = modifier;
+                modifier.init(this,arr,i,itemsData);
+                this.shapeModifiers.push(modifier);
+                render = false;
+            }else{
+                modifier = itemsData[i];
+                modifier.closed = true;
+            }
+            ownModifiers.push(modifier);
+        }
+        this.addProcessedElement(arr[i], i + 1);
+    }
+    len = ownStyles.length;
+    for(i=0;i<len;i+=1){
+        ownStyles[i].closed = true;
+    }
+    len = ownModifiers.length;
+    for(i=0;i<len;i+=1){
+        ownModifiers[i].closed = true;
+    }
+};
+
+PIXIShapeElement.prototype.drawShapeCommands = function(styleData) {
+    var shapeCommands = styleData.PD, PIXIElem = styleData.PpElem;
+    PIXIElem.clear();
+    if(styleData._styleType === 'fill') {
+        PIXIElem.beginFill(styleData._styleColor);
+    } else if(styleData._styleType === 'stroke') {
+        PIXIElem.lineStyle(styleData._styleWidth,styleData._styleColor);
+    }
+    var i, len = shapeCommands.length;
+    for(i = 0; i < len; i += 1) {
+        if(shapeCommands[i].t === 'm'){
+            PIXIElem.moveTo(shapeCommands[i].c[0],shapeCommands[i].c[1]);
+        } else {
+            PIXIElem.bezierCurveTo(shapeCommands[i].c[0],shapeCommands[i].c[1],shapeCommands[i].c[3],shapeCommands[i].c[4],shapeCommands[i].c[6],shapeCommands[i].c[7]);
+        }
+    }
+    if(styleData._styleType === 'fill') {
+        PIXIElem.endFill();
+    } else if(styleData._styleType === 'stroke') {
+        //TODO: search iff stroke needs to be ended
+    }
+}
+
+PIXIShapeElement.prototype.renderInnerContent = function() {
+    this.renderModifiers();
+    var i, len = this.stylesList.length;
+    for(i=0;i<len;i+=1){
+        this.stylesList[i].reset();
+    }
+    this.renderShape();
+
+    for (i = 0; i < len; i += 1) {
+        if (this.stylesList[i]._mdf || this._isFirstFrame) {
+            if(this.stylesList[i].msElem){
+                this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+                //Adding M0 0 fixes same mask bug on all browsers
+                this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+            }
+            this.drawShapeCommands(this.stylesList[i]);
+            this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+        }
+    }
+};
+
+PIXIShapeElement.prototype.renderShape = function() {
+    var i, len = this.animatedContents.length;
+    var animatedContent;
+    for(i = 0; i < len; i += 1) {
+        animatedContent = this.animatedContents[i];
+        if(this._isFirstFrame || animatedContent.element._isAnimated) {
+            animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+        }
+    }
+}
+
+PIXIShapeElement.prototype.destroy = function(){
+    this.destroyBaseElement();
+    this.shapeData = null;
+    this.itemsData = null;
+};
diff --git a/player/js/elements/pixiElements/PIXISolidElement.js b/player/js/elements/pixiElements/PIXISolidElement.js
new file mode 100644
index 0000000..0317beb
--- /dev/null
+++ b/player/js/elements/pixiElements/PIXISolidElement.js
@@ -0,0 +1,26 @@
+function PIXISolidElement(data,globalData,comp){
+    this.initElement(data,globalData,comp);
+}
+extendPrototype([BaseElement, TransformElement, PIXIBaseElement, HierarchyElement, FrameElement, RenderableElement], PIXISolidElement);
+
+PIXISolidElement.prototype.createContent = function(){
+    var graphics = new PIXI.Graphics();
+    graphics.beginFill(this.data.sc.replace('#','0x'));
+    graphics.drawRect(0, 0, this.data.sw, this.data.sh);
+    this.layerElement.addChild(graphics);
+};
+
+PIXISolidElement.prototype.initElement = function(data,globalData,comp) {
+    this.initFrame();
+    this.initBaseData(data, globalData, comp);
+    this.initTransform(data, globalData, comp);
+    this.initHierarchy();
+    this.initRenderable();
+    this.initRendererElement();
+    this.createContainerElements();
+    this.addMasks();
+    this.createContent();
+    this.hide();
+}
+
+PIXISolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
\ No newline at end of file
diff --git a/player/js/elements/pixiElements/effects/PIXIGaussianBlurEffect.js b/player/js/elements/pixiElements/effects/PIXIGaussianBlurEffect.js
new file mode 100644
index 0000000..28019d7
--- /dev/null
+++ b/player/js/elements/pixiElements/effects/PIXIGaussianBlurEffect.js
@@ -0,0 +1,26 @@
+function PIXIGaussianBlurEffect(filterManager){
+    this.filterManager = filterManager;
+    this.pixiFilter = new PIXI.filters.BlurFilter(0, 10, 1, 5);
+}
+
+PIXIGaussianBlurEffect.prototype.renderFrame = function(forceRender){
+    if(forceRender || this.filterManager._mdf){
+        if(forceRender || this.filterManager.effectElements[0]._mdf || this.filterManager.effectElements[1]._mdf) {
+            var blurStrength = this.filterManager.effectElements[0].p.v;
+            switch(this.filterManager.effectElements[1].p.v) {
+                case 1:
+                    this.pixiFilter.blurX = blurStrength;
+                    this.pixiFilter.blurY = blurStrength;
+                    break;
+                case 2:
+                    this.pixiFilter.blurX = blurStrength;
+                    this.pixiFilter.blurY = 0;
+                    break;
+                case 3:
+                    this.pixiFilter.blurX = 0;
+                    this.pixiFilter.blurY = blurStrength;
+                    break;
+            }
+        }
+    }
+};
\ No newline at end of file
diff --git a/player/js/renderers/CanvasRenderer.js b/player/js/renderers/CanvasRenderer.js
index 6c273dc..c240327 100644
--- a/player/js/renderers/CanvasRenderer.js
+++ b/player/js/renderers/CanvasRenderer.js
@@ -135,6 +135,10 @@
 };
 
 CanvasRenderer.prototype.configAnimation = function(animData){
+    animData.width = animData.width/blitter;
+    animData.height = animData.height/blitter;
+    animData.w = animData.w/blitter;
+    animData.h = animData.h/blitter;
     if(this.animationItem.wrapper){
         this.animationItem.container = createTag('canvas');
         this.animationItem.container.style.width = '100%';
diff --git a/player/js/renderers/PIXIRenderer.js b/player/js/renderers/PIXIRenderer.js
new file mode 100644
index 0000000..aa1388b
--- /dev/null
+++ b/player/js/renderers/PIXIRenderer.js
@@ -0,0 +1,229 @@
+function PIXIRenderer(animationItem, config){
+    this.animationItem = animationItem;
+    this.layers = null;
+    this.renderedFrame = -1;
+    this.globalData = {
+        frameNum: -1
+    };
+    this.renderConfig = {
+        preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+        progressiveLoad: (config && config.progressiveLoad) || false
+    };
+    this.elements = [];
+    this.pendingElements = [];
+    this.destroyed = false;
+
+}
+
+extendPrototype([BaseRenderer],PIXIRenderer);
+
+PIXIRenderer.prototype.createBase = function (data) {
+    return new PIXIBaseElement(data,this.globalData,this);
+};
+
+PIXIRenderer.prototype.createShape = function (data) {
+    return new PIXIShapeElement(data,this.globalData,this);
+};
+
+PIXIRenderer.prototype.createText = function (data) {
+    return new SVGTextElement(data,this.globalData,this);
+
+};
+
+PIXIRenderer.prototype.createImage = function (data) {
+    return new PIXIImageElement(data,this.globalData,this);
+};
+
+PIXIRenderer.prototype.createComp = function (data) {
+    return new PIXICompElement(data,this.globalData,this);
+};
+
+PIXIRenderer.prototype.createSolid = function (data) {
+    return new PIXISolidElement(data,this.globalData,this);
+};
+
+PIXIRenderer.prototype.createNull = SVGRenderer.prototype.createNull;
+
+PIXIRenderer.prototype.configAnimation = function(animData){
+    animData.width = animData.width/blitter;
+    animData.height = animData.height/blitter;
+    animData.w = animData.w/blitter;
+    animData.h = animData.h/blitter;
+
+    this.layerElement = document.createElementNS(svgNS,'svg');
+    this.layerElement.setAttribute('xmlns','http://www.w3.org/2000/svg');
+    this.layerElement.setAttribute('width',animData.w);
+    this.layerElement.setAttribute('height',animData.h);
+    this.layerElement.setAttribute('viewBox','0 0 '+animData.w+' '+animData.h);
+    this.layerElement.setAttribute('preserveAspectRatio',this.renderConfig.preserveAspectRatio);
+    this.layerElement.style.width = '100%';
+    this.layerElement.style.height = '100%';
+    this.layerElement.style.transform = 'translate3d(0,0,0)';
+    this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+    //this.animationItem.wrapper.appendChild(this.layerElement);
+    ///
+    this.renderer = new PIXI.WebGLRenderer(animData.w, animData.h,{antialias:true,transparent:true});
+    this.renderer.view.style.transform = 'scale(0.5,0.5)';
+    this.renderer.view.style.transformOrigin = '0 0';
+    this.animationItem.wrapper.appendChild(this.renderer.view);
+    this.stage = new PIXI.Container();
+    this.layerElement = this.stage;
+
+    ///
+    //Mask animation
+    var defs = document.createElementNS(svgNS, 'defs');
+    this.globalData.defs = defs;
+    this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+    this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+    this.globalData.renderConfig = this.renderConfig;
+    this.globalData.frameId = 0;
+    this.globalData.compSize = {
+        w: animData.w,
+        h: animData.h
+    };
+    this.data = animData;
+    this.globalData.frameRate = animData.fr;
+
+    //Todo mask main container and remove this block of code
+    /*var maskElement = document.createElementNS(svgNS, 'clipPath');
+    var rect = document.createElementNS(svgNS,'rect');
+    rect.setAttribute('width',animData.w);
+    rect.setAttribute('height',animData.h);
+    rect.setAttribute('x',0);
+    rect.setAttribute('y',0);
+    var maskId = 'animationMask_'+randomString(10);
+    maskElement.setAttribute('id', maskId);
+    maskElement.appendChild(rect);
+    var maskedElement = document.createElementNS(svgNS,'g');
+    maskedElement.setAttribute("clip-path", "url(#"+maskId+")");
+    this.layerElement.appendChild(maskedElement);
+    defs.appendChild(maskElement);
+    this.layerElement = maskedElement;*/
+
+    this.layers = animData.layers;
+    this.globalData.fontManager = new FontManager();
+    this.globalData.fontManager.addChars(animData.chars);
+    this.globalData.fontManager.addFonts(animData.fonts,defs);
+    this.elements = Array.apply(null,{length:animData.layers.length});
+};
+
+PIXIRenderer.prototype.destroy = function () {
+    this.animationItem.wrapper.innerHTML = '';
+    this.layerElement = null;
+    this.globalData.defs = null;
+    var i, len = this.layers ? this.layers.length : 0;
+    for (i = 0; i < len; i++) {
+        if(this.elements[i]){
+            this.elements[i].destroy();
+        }
+    }
+    this.elements.length = 0;
+    this.destroyed = true;
+    this.animationItem = null;
+};
+
+PIXIRenderer.prototype.updateContainerSize = function () {
+};
+
+PIXIRenderer.prototype.buildItem  = function(pos){
+    var elements = this.elements;
+    if(elements[pos] || this.layers[pos].ty == 99){
+        return;
+    }
+    var element = this.createItem(this.layers[pos]);
+
+    elements[pos] = element;
+    if(expressionsPlugin){
+        if(this.layers[pos].ty === 0){
+            this.globalData.projectInterface.registerComposition(element);
+        }
+        element.initExpressions();
+    }
+    this.appendElementInPos(element,pos);
+    if(this.layers[pos].tt){
+        this.buildItem(pos - 1);
+        element.setMatte(elements[pos - 1].layerId);
+    }
+};
+
+PIXIRenderer.prototype.checkPendingElements  = function(){
+    while(this.pendingElements.length){
+        var element = this.pendingElements.pop();
+        element.checkParenting();
+    }
+};
+
+PIXIRenderer.prototype.renderFrame = function(num){
+    if(this.renderedFrame == num || this.destroyed){
+        return;
+    }
+    if(num === null){
+        num = this.renderedFrame;
+    }else{
+        this.renderedFrame = num;
+    }
+    //clearPoints();
+    /*console.log('-------');
+    console.log('FRAME ',num);*/
+    this.globalData.frameNum = num;
+    this.globalData.frameId += 1;
+    this.globalData.projectInterface.currentFrame = num;
+    var i, len = this.layers.length;
+    if(!this.completeLayers){
+        this.checkLayers(num);
+    }
+    for (i = len - 1; i >= 0; i--) {
+        if(this.completeLayers || this.elements[i]){
+            this.elements[i].prepareFrame(num - this.layers[i].st);
+        }
+    }
+    for (i = len - 1; i >= 0; i--) {
+        if(this.completeLayers || this.elements[i]){
+            this.elements[i].renderFrame();
+        }
+    }
+    this.renderer.render(this.stage);
+};
+
+PIXIRenderer.prototype.appendElementInPos = function(element, pos){
+    var newElement = element.getBaseElement();
+    if(!newElement){
+        return;
+    }
+    var i = 0;
+    var nextElement;
+    while(i<pos){
+        if(this.elements[i] && this.elements[i].getBaseElement()){
+            nextElement = this.elements[i].getBaseElement();
+        }
+        i += 1;
+    }
+    if(nextElement){
+        var index = this.layerElement.getChildIndex(nextElement);
+        this.layerElement.addChildAt(newElement,index);
+    } else {
+        this.layerElement.addChild(newElement);
+    }
+};
+
+PIXIRenderer.prototype.hide = function(){
+    this.layerElement.style.display = 'none';
+};
+
+PIXIRenderer.prototype.show = function(){
+    this.layerElement.style.display = 'block';
+};
+
+PIXIRenderer.prototype.searchExtraCompositions = function(assets){
+    var i, len = assets.length;
+    var floatingContainer = document.createElementNS(svgNS,'g');
+    for(i=0;i<len;i+=1){
+        if(assets[i].xt){
+            var comp = this.createComp(assets[i],floatingContainer,this.globalData.comp,null);
+            comp.initExpressions();
+            //comp.compInterface = CompExpressionInterface(comp);
+            //Expressions.addLayersInterface(comp.elements, this.globalData.projectInterface);
+            this.globalData.projectInterface.registerComposition(comp);
+        }
+    }
+};
diff --git a/player/js/utils/DataManager.js b/player/js/utils/DataManager.js
index e3b0671..7dc626a 100644
--- a/player/js/utils/DataManager.js
+++ b/player/js/utils/DataManager.js
@@ -342,7 +342,9 @@
         checkShapes(animationData);
         completeLayers(animationData.layers, animationData.assets, fontManager);
         animationData.__complete = true;
+        //console.log((JSON.stringify(animationData)));
         //blitAnimation(animationData, animationData.assets, fontManager);
+        //console.log((JSON.stringify(animationData)));
     }
 
     function completeText(data, fontManager){
diff --git a/player/js/utils/common.js b/player/js/utils/common.js
index c52c881..4ecae5b 100644
--- a/player/js/utils/common.js
+++ b/player/js/utils/common.js
@@ -1,4 +1,5 @@
 var subframeEnabled = true;
+var blitter = 1;
 var expressionsPlugin;
 var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
 var cachedColors = {};
@@ -10,7 +11,6 @@
 var bm_floor = Math.floor;
 var bm_max = Math.max;
 var bm_min = Math.min;
-var blitter = 10;
 
 var BMMath = {};
 (function(){
@@ -188,7 +188,8 @@
         colorMap[i] = hex.length == 1 ? '0' + hex : hex;
     }
 
-    return function(r, g, b) {
+    return function(r, g, b, prefix) {
+        prefix = prefix || '#';
         if(r<0){
             r = 0;
         }
@@ -198,6 +199,6 @@
         if(b<0){
             b = 0;
         }
-        return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+        return prefix + colorMap[r] + colorMap[g] + colorMap[b];
     };
-}());
\ No newline at end of file
+}());
diff --git a/player/js/utils/shapes/shapePathBuilder.js b/player/js/utils/shapes/shapePathBuilder.js
index 13e407c..c68e21a 100644
--- a/player/js/utils/shapes/shapePathBuilder.js
+++ b/player/js/utils/shapes/shapePathBuilder.js
@@ -14,4 +14,46 @@
             shapeString += 'z';
         }
         return shapeString;
-}
\ No newline at end of file
+};
+
+var buildPIXIShape = function(pathNodes, length, closed, mat) {
+    if(length === 0) {
+            return '';
+    }
+    var _o = pathNodes.o;
+    var _i = pathNodes.i;
+    var _v = pathNodes.v;
+    var _PIXIcommands = [];
+    _PIXIcommands.push({
+        t:'m',
+        c:mat.applyToPointArray(_v[0][0], _v[0][1], 0)
+    })
+    var i, shapeString = " M" + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    for(i = 1; i < length; i += 1) {
+        _PIXIcommands.push({
+            t:'c',
+            c:mat.applyToPointArray(_o[i - 1][0], _o[i - 1][1], 0).concat(mat.applyToPointArray(_i[i][0], _i[i][1], 0)).concat(mat.applyToPointArray(_v[i][0], _v[i][1], 0))
+        })
+    }
+    if (closed && length) {
+        _PIXIcommands.push({
+            t:'c',
+            c:mat.applyToPointArray(_o[i - 1][0], _o[i - 1][1], 0).concat(mat.applyToPointArray(_i[0][0], _i[0][1], 0)).concat(mat.applyToPointArray(_v[0][0], _v[0][1], 0))
+        })
+    }
+
+    //Fix for shapes with no length.
+    //Todo: search a better solution. AE draws a point on this cases so the shape can't be removed.
+    if(_PIXIcommands.length === 2 
+        && _PIXIcommands[0].c[0] === _PIXIcommands[1].c[0]
+        && _PIXIcommands[0].c[1] === _PIXIcommands[1].c[1]
+        && _PIXIcommands[0].c[0] === _PIXIcommands[1].c[3]
+        && _PIXIcommands[0].c[1] === _PIXIcommands[1].c[4]
+        && _PIXIcommands[0].c[0] === _PIXIcommands[1].c[6]
+        && _PIXIcommands[0].c[1] === _PIXIcommands[1].c[7]
+        ) {
+        _PIXIcommands[1].c[6] += 0.5;
+        _PIXIcommands[1].c[7] += 0.5;
+    }
+    return _PIXIcommands;
+};
\ No newline at end of file
