diff --git a/bower.json b/bower.json
index 792180b..1a1fa1f 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "cutjs",
-  "version": "0.5.0-beta.4",
+  "version": "0.5.0-beta.5",
   "description": "Lightweight, fast, interactable 2D HTML5 rendering engine for cross-platform game development.",
   "homepage": "http://cutjs.org/",
   "keywords": [
diff --git a/dist/cut.cordova.js b/dist/cut.cordova.js
index 89a7fc6..82e3e56 100644
--- a/dist/cut.cordova.js
+++ b/dist/cut.cordova.js
@@ -1,5 +1,5 @@
 /*
- * CutJS 0.5.0-beta.4
+ * CutJS 0.5.0-beta.5
  * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
  * Available under the MIT license
  * @license
@@ -8,18 +8,649 @@
 !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Cut=e()}}(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){
 module.exports = require("../lib/");
 
-module.exports.Mouse = require("../lib/mouse");
+require("../lib/canvas");
+
+require("../lib/image");
+
+require("../lib/anim");
+
+require("../lib/str");
+
+require("../lib/layout");
+
+require("../lib/addon/tween");
+
+module.exports.Mouse = require("../lib/addon/mouse");
 
 module.exports.Math = require("../lib/util/math");
 
-require("../lib/tween");
+module.exports._extend = require("../lib/util/extend");
+
+module.exports._create = require("../lib/util/create");
+
+require("../lib/loader/cordova");
+},{"../lib/":11,"../lib/addon/mouse":3,"../lib/addon/tween":4,"../lib/anim":5,"../lib/canvas":7,"../lib/image":10,"../lib/layout":12,"../lib/loader/cordova":13,"../lib/str":19,"../lib/util/create":21,"../lib/util/extend":22,"../lib/util/math":24}],2:[function(require,module,exports){
+function _identity(x) {
+    return x;
+}
+
+var _cache = {};
+
+var _modes = {};
+
+var _easings = {};
+
+function Easing(token) {
+    if (typeof token === "function") {
+        return token;
+    }
+    if (typeof token !== "string") {
+        return _identity;
+    }
+    var fn = _cache[token];
+    if (fn) {
+        return fn;
+    }
+    var match = /^(\w+)(-(in|out|in-out|out-in))?(\((.*)\))?$/i.exec(token);
+    if (!match || !match.length) {
+        return _identity;
+    }
+    easing = _easings[match[1]];
+    mode = _modes[match[3]];
+    params = match[5];
+    if (easing && easing.fn) {
+        fn = easing.fn;
+    } else if (easing && easing.fc) {
+        fn = easing.fc.apply(easing.fc, params && params.replace(/\s+/, "").split(","));
+    } else {
+        fn = _identity;
+    }
+    if (mode) {
+        fn = mode.fn(fn);
+    }
+    // TODO: It can be a memory leak with different `params`.
+    _cache[token] = fn;
+    return fn;
+}
+
+Easing.add = function(data) {
+    var names = (data.name || data.mode).split(/\s+/);
+    for (var i = 0; i < names.length; i++) {
+        var name = names[i];
+        if (name) {
+            (data.name ? _easings : _modes)[name] = data;
+        }
+    }
+};
+
+Easing.add({
+    mode: "in",
+    fn: function(f) {
+        return f;
+    }
+});
+
+Easing.add({
+    mode: "out",
+    fn: function(f) {
+        return function(t) {
+            return 1 - f(1 - t);
+        };
+    }
+});
+
+Easing.add({
+    mode: "in-out",
+    fn: function(f) {
+        return function(t) {
+            return t < .5 ? f(2 * t) / 2 : 1 - f(2 * (1 - t)) / 2;
+        };
+    }
+});
+
+Easing.add({
+    mode: "out-in",
+    fn: function(f) {
+        return function(t) {
+            return t < .5 ? 1 - f(2 * (1 - t)) / 2 : f(2 * t) / 2;
+        };
+    }
+});
+
+Easing.add({
+    name: "linear",
+    fn: function(t) {
+        return t;
+    }
+});
+
+Easing.add({
+    name: "quad",
+    fn: function(t) {
+        return t * t;
+    }
+});
+
+Easing.add({
+    name: "cubic",
+    fn: function(t) {
+        return t * t * t;
+    }
+});
+
+Easing.add({
+    name: "quart",
+    fn: function(t) {
+        return t * t * t * t;
+    }
+});
+
+Easing.add({
+    name: "quint",
+    fn: function(t) {
+        return t * t * t * t * t;
+    }
+});
+
+Easing.add({
+    name: "sin sine",
+    fn: function(t) {
+        return 1 - Math.cos(t * Math.PI / 2);
+    }
+});
+
+Easing.add({
+    name: "exp",
+    fn: function(t) {
+        return t == 0 ? 0 : Math.pow(2, 10 * (t - 1));
+    }
+});
+
+Easing.add({
+    name: "circle circ",
+    fn: function(t) {
+        return 1 - Math.sqrt(1 - t * t);
+    }
+});
+
+Easing.add({
+    name: "bounce",
+    fn: function(t) {
+        return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
+    }
+});
+
+Easing.add({
+    name: "poly",
+    fc: function(e) {
+        return function(t) {
+            return Math.pow(t, e);
+        };
+    }
+});
+
+Easing.add({
+    name: "elastic",
+    fc: function(a, p) {
+        p = p || .45;
+        a = a || 1;
+        var s = p / (2 * Math.PI) * Math.asin(1 / a);
+        return function(t) {
+            return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p);
+        };
+    }
+});
+
+Easing.add({
+    name: "back",
+    fc: function(s) {
+        s = typeof s !== "undefined" ? s : 1.70158;
+        return function(t) {
+            return t * t * ((s + 1) * t - s);
+        };
+    }
+});
+
+module.exports = Easing;
+
+
+},{}],3:[function(require,module,exports){
+if (typeof DEBUG === "undefined") DEBUG = true;
+
+function Mouse() {
+    Mouse.subscribe.apply(Mouse, arguments);
+}
+
+Mouse.CLICK = "click";
+
+Mouse.START = "touchstart mousedown";
+
+Mouse.MOVE = "touchmove mousemove";
+
+Mouse.END = "touchend mouseup";
+
+Mouse.CANCEL = "touchcancel";
+
+Mouse.subscribe = function(root, elem) {
+    var visitor = null, data = {}, abs = null, rel = null, clicked = [];
+    elem = elem || document;
+    // click events are synthesized from start/end events on same nodes
+    // elem.addEventListener('click', handleClick);
+    elem.addEventListener("touchstart", handleStart);
+    elem.addEventListener("touchend", handleEnd);
+    elem.addEventListener("touchmove", handleMove);
+    elem.addEventListener("touchcancel", handleCancel);
+    elem.addEventListener("mousedown", handleStart);
+    elem.addEventListener("mouseup", handleEnd);
+    elem.addEventListener("mousemove", handleMove);
+    function handleStart(event) {
+        Mouse._xy(root, elem, event, abs);
+        DEBUG && console.log("Mouse Start: " + event.type + " " + abs);
+        event.preventDefault();
+        publish(event.type, event);
+        findClicks();
+    }
+    function handleEnd(event) {
+        // New xy is not valid/available, last xy is used instead.
+        DEBUG && console.log("Mouse End: " + event.type + " " + abs);
+        event.preventDefault();
+        publish(event.type, event);
+        if (clicked.length) {
+            DEBUG && console.log("Mouse Click: " + clicked.length);
+            fireClicks(event);
+        }
+    }
+    function handleCancel(event) {
+        DEBUG && console.log("Mouse Cancel: " + event.type);
+        event.preventDefault();
+        publish(event.type, event);
+    }
+    function handleMove(event) {
+        Mouse._xy(root, elem, event, abs);
+        // DEBUG && console.log('Mouse Move: ' + event.type + ' ' +
+        // abs);
+        if (!root._flag(event.type)) {
+            return;
+        }
+        event.preventDefault();
+        publish(event.type, event);
+    }
+    function findClicks() {
+        while (clicked.length) {
+            clicked.pop();
+        }
+        publish("click", null, clicked);
+    }
+    function fireClicks(event) {
+        data.event = event;
+        data.type = "click";
+        data.root = root;
+        data.collect = false;
+        var cancel = false;
+        while (clicked.length) {
+            var node = clicked.shift();
+            if (cancel) {
+                continue;
+            }
+            cancel = visitor.end(node, data) ? true : cancel;
+        }
+    }
+    function publish(type, event, collect) {
+        rel.x = abs.x;
+        rel.y = abs.y;
+        data.event = event;
+        data.type = type;
+        data.root = /* root._capture || */ root;
+        data.collect = collect;
+        data.root.visit(visitor, data);
+    }
+    visitor = {
+        reverse: true,
+        visible: true,
+        start: function(node, data) {
+            return !node._flag(data.type);
+        },
+        end: function(node, data) {
+            // data: event, type, root, collect
+            rel.raw = data.event;
+            rel.type = data.type;
+            var listeners = node.listeners(data.type);
+            if (!listeners) {
+                return;
+            }
+            node.matrix().reverse().map(abs, rel);
+            if (!(node === data.root || node.attr("spy") || Mouse._isInside(node, rel))) {
+                return;
+            }
+            if (data.collect) {
+                data.collect.push(node);
+                return;
+            }
+            var cancel = false;
+            for (var l = 0; l < listeners.length; l++) {
+                cancel = listeners[l].call(node, rel) ? true : cancel;
+            }
+            return cancel;
+        }
+    };
+    abs = {
+        x: 0,
+        y: 0,
+        toString: function() {
+            return (this.x | 0) + "x" + (this.y | 0);
+        }
+    };
+    rel = {
+        x: 0,
+        y: 0,
+        toString: function() {
+            return abs + " / " + (this.x | 0) + "x" + (this.y | 0);
+        }
+    };
+};
+
+Mouse._isInside = function(node, point) {
+    return point.x >= 0 && point.x <= node._pin._width && point.y >= 0 && point.y <= node._pin._height;
+};
+
+Mouse._xy = function(root, elem, event, point) {
+    var isTouch = false;
+    // touch screen events
+    if (event.touches) {
+        if (event.touches.length) {
+            isTouch = true;
+            point.x = event.touches[0].pageX;
+            point.y = event.touches[0].pageY;
+        } else {
+            return;
+        }
+    } else {
+        // mouse events
+        point.x = event.clientX;
+        point.y = event.clientY;
+        // See http://goo.gl/JuVnF2
+        if (document.body.scrollLeft || document.body.scrollTop) {} else if (document.documentElement) {
+            point.x += document.documentElement.scrollLeft;
+            point.y += document.documentElement.scrollTop;
+        }
+    }
+    // accounts for border
+    point.x -= elem.clientLeft || 0;
+    point.y -= elem.clientTop || 0;
+    var par = elem;
+    while (par) {
+        point.x -= par.offsetLeft || 0;
+        point.y -= par.offsetTop || 0;
+        if (!isTouch) {
+            // touch events offset scrolling with pageX/Y
+            // so scroll offset not needed for them
+            point.x += par.scrollLeft || 0;
+            point.y += par.scrollTop || 0;
+        }
+        par = par.offsetParent;
+    }
+    point.x *= root.viewport().ratio || 1;
+    point.y *= root.viewport().ratio || 1;
+};
+
+module.exports = Mouse;
+
+
+},{}],4:[function(require,module,exports){
+var Easing = require("./easing");
+
+var Cut = require("../core");
+
+var Pin = require("../pin");
+
+Cut.prototype.tween = function(duration, delay) {
+    if (!this._tween) {
+        this._tween = new Tween(this);
+    }
+    return this._tween.tween(duration, delay);
+};
+
+var iid = 0;
+
+function Tween(node) {
+    // TODO: reuse head.start/keys/end
+    var tween = this;
+    this._owner = node;
+    this._queue = [];
+    this._next = null;
+    var lastTime = 0;
+    node.tick(function(elapsed, now, last) {
+        if (!tween._queue.length) {
+            return;
+        }
+        // ignore old elapsed
+        var ignore = lastTime != last;
+        lastTime = now;
+        this.touch();
+        if (ignore) {
+            return;
+        }
+        var head = tween._queue[0];
+        if (!head.time) {
+            head.time = 1;
+        } else {
+            head.time += elapsed;
+        }
+        if (head.time < head.delay) {
+            return;
+        }
+        if (!head.start) {
+            head.start = {};
+            head.keys = {};
+            for (var key in head.end) {
+                if (typeof (start = node.pin(key)) === "number") {
+                    head.start[key] = start;
+                    head.keys[key] = key;
+                } else if (typeof (startX = node.pin(key + "X")) === "number" && typeof (startY = node.pin(key + "Y")) === "number") {
+                    head.start[key + "X"] = startX;
+                    head.keys[key + "X"] = key;
+                    head.start[key + "Y"] = startY;
+                    head.keys[key + "Y"] = key;
+                }
+            }
+        }
+        var p = (head.time - head.delay) / head.duration;
+        var over = p >= 1;
+        p = p > 1 ? 1 : p;
+        p = typeof head.easing == "function" ? head.easing(p) : p;
+        var q = 1 - p;
+        for (var key in head.keys) {
+            node.pin(key, head.start[key] * q + head.end[head.keys[key]] * p);
+        }
+        if (over) {
+            tween._queue.shift();
+            head.then && head.then.call(node);
+        }
+    }, true);
+}
+
+Tween.prototype.tween = function(duration, delay) {
+    this._next = {
+        id: ++iid,
+        end: {},
+        duration: duration || 400,
+        delay: delay || 0
+    };
+    return this;
+};
+
+Tween.prototype.pin = function(a, b) {
+    if (this._next !== this._queue[this._queue.length - 1]) {
+        this._owner.touch();
+        this._queue.push(this._next);
+    }
+    var end = this._next.end;
+    if (typeof a === "object") {
+        for (var attr in a) {
+            end[attr] = a[attr];
+        }
+    } else if (typeof b !== "undefined") {
+        end[a] = b;
+    }
+    return this;
+};
+
+Tween.prototype.clear = function(forward) {
+    var tween;
+    while (tween = this._queue.shift()) {
+        forward && this._owner.pin(tween.end);
+    }
+    return this;
+};
 
-require("../lib/loader.cordova");
+Tween.prototype.then = function(then) {
+    this._next.then = then;
+    return this;
+};
 
-module.exports._extend = require("../lib/util/extend");
+Tween.prototype.ease = function(easing) {
+    this._next.easing = Easing(easing);
+    return this;
+};
 
-module.exports._create = require("../lib/util/create");
-},{"../lib/":7,"../lib/loader.cordova":8,"../lib/mouse":10,"../lib/tween":14,"../lib/util/create":16,"../lib/util/extend":17,"../lib/util/math":19}],2:[function(require,module,exports){
+module.exports = Tween;
+
+
+},{"../core":8,"../pin":16,"./easing":2}],5:[function(require,module,exports){
+var Cut = require("./core");
+
+require("./pin");
+
+require("./render");
+
+var create = require("./util/create");
+
+var math = require("./util/math");
+
+Cut.anim = function(frames, fps) {
+    var anim = new Anim();
+    anim.frames(frames).gotoFrame(0);
+    fps && anim.fps(fps);
+    return anim;
+};
+
+Anim._super = Cut;
+
+Anim.prototype = create(Anim._super.prototype);
+
+// TODO: replace with atlas fps or texture time
+Cut.Anim = {
+    FPS: 15
+};
+
+function Anim() {
+    Anim._super.call(this);
+    this.label("Anim");
+    this._textures = [];
+    this._fps = Cut.Anim.FPS;
+    this._ft = 1e3 / this._fps;
+    this._time = -1;
+    this._repeat = 0;
+    this._index = 0;
+    this._frames = [];
+    var lastTime = 0;
+    this.tick(function(t, now, last) {
+        if (this._time < 0 || this._frames.length <= 1) {
+            return;
+        }
+        // ignore old elapsed
+        var ignore = lastTime != last;
+        lastTime = now;
+        if (ignore) {
+            return true;
+        }
+        this._time += t;
+        if (this._time < this._ft) {
+            return true;
+        }
+        var n = this._time / this._ft | 0;
+        this._time -= n * this._ft;
+        this.moveFrame(n);
+        if (this._repeat > 0 && (this._repeat -= n) <= 0) {
+            this.stop();
+            this._callback && this._callback();
+            return false;
+        }
+        return true;
+    }, false);
+}
+
+Anim.prototype.fps = function(fps) {
+    if (typeof fps === "undefined") {
+        return this._fps;
+    }
+    this._fps = fps > 0 ? fps : Cut.Anim.FPS;
+    this._ft = 1e3 / this._fps;
+    return this;
+};
+
+/**
+ * @deprecated Use frames
+ */
+Anim.prototype.setFrames = function(a, b, c) {
+    return this.frames(a, b, c);
+};
+
+Anim.prototype.frames = function(frames) {
+    this._index = 0;
+    this._frames = Cut.texture(frames).array();
+    this.touch();
+    return this;
+};
+
+Anim.prototype.length = function() {
+    return this._frames ? this._frames.length : 0;
+};
+
+Anim.prototype.gotoFrame = function(frame, resize) {
+    this._index = math.rotate(frame, this._frames.length) | 0;
+    resize = resize || !this._textures[0];
+    this._textures[0] = this._frames[this._index];
+    if (resize) {
+        this.pin("width", this._textures[0].width);
+        this.pin("height", this._textures[0].height);
+    }
+    this.touch();
+    return this;
+};
+
+Anim.prototype.moveFrame = function(move) {
+    return this.gotoFrame(this._index + move);
+};
+
+Anim.prototype.repeat = function(repeat, callback) {
+    this._repeat = repeat * this._frames.length - 1;
+    this._callback = callback;
+    this.play();
+    return this;
+};
+
+Anim.prototype.play = function(frame) {
+    if (typeof frame !== "undefined") {
+        this.gotoFrame(frame);
+        this._time = 0;
+    } else if (this._time < 0) {
+        this._time = 0;
+    }
+    this.touch();
+    return this;
+};
+
+Anim.prototype.stop = function(frame) {
+    this._time = -1;
+    if (typeof frame !== "undefined") {
+        this.gotoFrame(frame);
+    }
+    return this;
+};
+
+
+},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/math":24}],6:[function(require,module,exports){
 var Cut = require("./core");
 
 var Texture = require("./texture");
@@ -41,6 +672,7 @@ var _atlases_arr = [];
 // TODO: return entire atlas as texture
 // TODO: select atlas itself, call texture function
 // TODO: print subquery not found error
+// TODO: cache and clone or index textures
 Cut.atlas = function(def) {
     var atlas = is.fn(def.draw) ? def : new Atlas(def);
     if (def.name) {
@@ -200,7 +832,6 @@ function Selection(result, find, make) {
     };
 }
 
-// TODO: cache and clone
 Cut.texture = function(query) {
     if (!is.string(query)) {
         return new Selection(query);
@@ -228,7 +859,7 @@ function deprecated(hash, name, msg) {
 module.exports = Atlas;
 
 
-},{"./core":4,"./texture":13,"./util/create":16,"./util/extend":17,"./util/is":18,"./util/string":23}],3:[function(require,module,exports){
+},{"./core":8,"./texture":20,"./util/create":21,"./util/extend":22,"./util/is":23,"./util/string":28}],7:[function(require,module,exports){
 var Cut = require("./core");
 
 var Texture = require("./texture");
@@ -269,13 +900,13 @@ Cut.canvas = function(type, attributes, callback) {
         return this;
     };
     if (typeof callback === "function") {
-        callback.call(this, context);
+        callback.call(texture, context);
     }
     return texture;
 };
 
 
-},{"./core":4,"./texture":13}],4:[function(require,module,exports){
+},{"./core":8,"./texture":20}],8:[function(require,module,exports){
 if (typeof DEBUG === "undefined") DEBUG = true;
 
 var stats = require("./util/stats");
@@ -409,286 +1040,290 @@ Cut.create = function() {
 module.exports = Cut;
 
 
-},{"./util/extend":17,"./util/is":18,"./util/once":20,"./util/stats":22}],5:[function(require,module,exports){
-function _identity(x) {
-    return x;
+},{"./util/extend":22,"./util/is":23,"./util/once":25,"./util/stats":27}],9:[function(require,module,exports){
+var Cut = require("./core");
+
+var is = require("./util/is");
+
+Cut.prototype._listeners = null;
+
+Cut.prototype.on = Cut.prototype.listen = function(types, listener) {
+    if (types = _check(this, types, listener, true)) {
+        for (var i = 0; i < types.length; i++) {
+            var type = types[i];
+            this._listeners[type] = this._listeners[type] || [];
+            this._listeners[type].push(listener);
+            this._flag(type, true);
+        }
+    }
+    return this;
+};
+
+Cut.prototype.off = function(types, listener) {
+    if (types = _check(this, types, listener, false)) {
+        for (var i = 0; i < types.length; i++) {
+            var type = types[i], all = this._listeners[type], index;
+            if (all && (index = all.indexOf(listener)) >= 0) {
+                all.splice(index, 1);
+                if (!all.length) {
+                    delete this._listeners[type];
+                }
+                this._flag(type, false);
+            }
+        }
+    }
+    return this;
+};
+
+function _check(node, types, listener, create) {
+    if (!types || !types.length || typeof listener !== "function") {
+        return false;
+    }
+    if (!(types = (is.array(types) ? types.join(" ") : types).match(/\S+/g))) {
+        return false;
+    }
+    if (node._listeners === null) {
+        if (create) {
+            node._listeners = {};
+        } else {
+            return false;
+        }
+    }
+    return types;
+}
+
+Cut.prototype.listeners = function(type) {
+    return this._listeners && this._listeners[type];
+};
+
+Cut.prototype.publish = function(name, args) {
+    var listeners = this.listeners(name);
+    if (!listeners || !listeners.length) {
+        return 0;
+    }
+    for (var l = 0; l < listeners.length; l++) {
+        listeners[l].apply(this, args);
+    }
+    return listeners.length;
+};
+
+Cut.prototype.trigger = function(name, args) {
+    this.publish(name, args);
+    return this;
+};
+
+
+},{"./core":8,"./util/is":23}],10:[function(require,module,exports){
+var Cut = require("./core");
+
+require("./pin");
+
+require("./render");
+
+var repeat = require("./util/repeat");
+
+var create = require("./util/create");
+
+Cut.image = function(image) {
+    var img = new Image();
+    image && img.image(image);
+    return img;
+};
+
+Image._super = Cut;
+
+Image.prototype = create(Image._super.prototype);
+
+function Image() {
+    Image._super.call(this);
+    this.label("Image");
+    this._textures = [];
+    this._image = null;
 }
 
-var _cache = {};
+/**
+ * @deprecated Use image
+ */
+Image.prototype.setImage = function(a, b, c) {
+    return this.image(a, b, c);
+};
 
-var _modes = {};
+Image.prototype.image = function(image) {
+    this._image = Cut.texture(image).one();
+    this.pin("width", this._image ? this._image.width : 0);
+    this.pin("height", this._image ? this._image.height : 0);
+    this._textures[0] = this._image.pipe();
+    this._textures.length = 1;
+    return this;
+};
 
-var _easings = {};
+Image.prototype.tile = function(inner) {
+    this._repeat(false, inner);
+    return this;
+};
 
-function Easing(token) {
-    if (typeof token === "function") {
-        return token;
-    }
-    if (typeof token !== "string") {
-        return _identity;
-    }
-    var fn = _cache[token];
-    if (fn) {
-        return fn;
-    }
-    var match = /^(\w+)(-(in|out|in-out|out-in))?(\((.*)\))?$/i.exec(token);
-    if (!match || !match.length) {
-        return _identity;
-    }
-    easing = _easings[match[1]];
-    mode = _modes[match[3]];
-    params = match[5];
-    if (easing && easing.fn) {
-        fn = easing.fn;
-    } else if (easing && easing.fc) {
-        fn = easing.fc.apply(easing.fc, params && params.replace(/\s+/, "").split(","));
-    } else {
-        fn = _identity;
-    }
-    if (mode) {
-        fn = mode.fn(fn);
-    }
-    // TODO: It can be a memory leak with different `params`.
-    _cache[token] = fn;
-    return fn;
-}
+Image.prototype.stretch = function(inner) {
+    this._repeat(true, inner);
+    return this;
+};
 
-Easing.add = function(data) {
-    var names = (data.name || data.mode).split(/\s+/);
-    for (var i = 0; i < names.length; i++) {
-        var name = names[i];
-        if (name) {
-            (data.name ? _easings : _modes)[name] = data;
+Image.prototype._repeat = function(stretch, inner) {
+    var self = this;
+    this.untick(this._repeatTicker);
+    this.tick(this._repeatTicker = function() {
+        if (this._mo_stretch == this._pin._ts_transform) {
+            return;
         }
+        this._mo_stretch = this._pin._ts_transform;
+        var width = this.pin("width");
+        var height = this.pin("height");
+        this._textures.length = repeat(this._image, width, height, stretch, inner, insert);
+    });
+    function insert(i, sx, sy, sw, sh, dx, dy, dw, dh) {
+        var repeat = self._textures.length > i ? self._textures[i] : self._textures[i] = self._image.pipe();
+        repeat.src(sx, sy, sw, sh);
+        repeat.dest(dx, dy, dw, dh);
     }
 };
 
-Easing.add({
-    mode: "in",
-    fn: function(f) {
-        return f;
-    }
-});
-
-Easing.add({
-    mode: "out",
-    fn: function(f) {
-        return function(t) {
-            return 1 - f(1 - t);
-        };
-    }
-});
 
-Easing.add({
-    mode: "in-out",
-    fn: function(f) {
-        return function(t) {
-            return t < .5 ? f(2 * t) / 2 : 1 - f(2 * (1 - t)) / 2;
-        };
-    }
-});
+},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/repeat":26}],11:[function(require,module,exports){
+module.exports = require("./core");
 
-Easing.add({
-    mode: "out-in",
-    fn: function(f) {
-        return function(t) {
-            return t < .5 ? 1 - f(2 * (1 - t)) / 2 : f(2 * t) / 2;
-        };
-    }
-});
+module.exports.Matrix = require("./matrix");
 
-Easing.add({
-    name: "linear",
-    fn: function(t) {
-        return t;
-    }
-});
+module.exports.Texture = require("./texture");
 
-Easing.add({
-    name: "quad",
-    fn: function(t) {
-        return t * t;
-    }
-});
+require("./atlas");
 
-Easing.add({
-    name: "cubic",
-    fn: function(t) {
-        return t * t * t;
-    }
-});
+require("./node");
 
-Easing.add({
-    name: "quart",
-    fn: function(t) {
-        return t * t * t * t;
-    }
-});
+require("./event");
 
-Easing.add({
-    name: "quint",
-    fn: function(t) {
-        return t * t * t * t * t;
-    }
-});
+require("./pin");
 
-Easing.add({
-    name: "sin sine",
-    fn: function(t) {
-        return 1 - Math.cos(t * Math.PI / 2);
-    }
-});
+require("./render");
 
-Easing.add({
-    name: "exp",
-    fn: function(t) {
-        return t == 0 ? 0 : Math.pow(2, 10 * (t - 1));
-    }
-});
+require("./root");
 
-Easing.add({
-    name: "circle circ",
-    fn: function(t) {
-        return 1 - Math.sqrt(1 - t * t);
-    }
-});
 
-Easing.add({
-    name: "bounce",
-    fn: function(t) {
-        return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
-    }
-});
+},{"./atlas":6,"./core":8,"./event":9,"./matrix":14,"./node":15,"./pin":16,"./render":17,"./root":18,"./texture":20}],12:[function(require,module,exports){
+var Cut = require("./core");
 
-Easing.add({
-    name: "poly",
-    fc: function(e) {
-        return function(t) {
-            return Math.pow(t, e);
-        };
-    }
-});
+require("./pin");
 
-Easing.add({
-    name: "elastic",
-    fc: function(a, p) {
-        p = p || .45;
-        a = a || 1;
-        var s = p / (2 * Math.PI) * Math.asin(1 / a);
-        return function(t) {
-            return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p);
-        };
-    }
-});
+require("./render");
 
-Easing.add({
-    name: "back",
-    fc: function(s) {
-        s = typeof s !== "undefined" ? s : 1.70158;
-        return function(t) {
-            return t * t * ((s + 1) * t - s);
-        };
-    }
-});
+var create = require("./util/create");
 
-module.exports = Easing;
+Cut.row = function(align) {
+    return Cut.create().row(align);
+};
 
+Cut.prototype.row = function(align) {
+    this.sequence("row", align);
+    return this;
+};
 
-},{}],6:[function(require,module,exports){
-var Cut = require("./core");
+Cut.column = function(align) {
+    return Cut.create().column(align);
+};
 
-var is = require("./util/is");
+Cut.prototype.column = function(align) {
+    this.sequence("column", align);
+    return this;
+};
 
-Cut.prototype._listeners = null;
+Cut.sequence = function(type, align) {
+    return Cut.create().sequence(type, align);
+};
 
-Cut.prototype.on = Cut.prototype.listen = function(types, listener) {
-    if (types = _check(this, types, listener, true)) {
-        for (var i = 0; i < types.length; i++) {
-            var type = types[i];
-            this._listeners[type] = this._listeners[type] || [];
-            this._listeners[type].push(listener);
-            this._flag(type, true);
+Cut.prototype.sequence = function(type, align) {
+    this._padding = this._padding || 0;
+    this._spacing = this._spacing || 0;
+    this.untick(this._sequenceTicker);
+    this.tick(this._sequenceTicker = function() {
+        if (this._mo_seq == this._ts_touch) {
+            return;
+        }
+        this._mo_seq = this._ts_touch;
+        var alignChildren = this._mo_seqAlign != this._ts_children;
+        this._mo_seqAlign = this._ts_children;
+        var width = 0, height = 0;
+        var child, next = this.first(true);
+        var first = true;
+        while (child = next) {
+            next = child.next(true);
+            child._pin.relativeMatrix();
+            var w = child.pin("boxWidth");
+            var h = child.pin("boxHeight");
+            if (type == "column") {
+                !first && (height += this._spacing);
+                child.pin("offsetY") != height && child.pin("offsetY", height);
+                width = Math.max(width, w);
+                height = height + h;
+                alignChildren && child.pin("alignX", align);
+            } else if (type == "row") {
+                !first && (width += this._spacing);
+                child.pin("offsetX") != width && child.pin("offsetX", width);
+                width = width + w;
+                height = Math.max(height, h);
+                alignChildren && child.pin("alignY", align);
+            }
+            first = false;
         }
-    }
+        width += 2 * this._padding;
+        height += 2 * this._padding;
+        this.pin("width") != width && this.pin("width", width);
+        this.pin("height") != height && this.pin("height", height);
+    });
     return this;
 };
 
-Cut.prototype.off = function(types, listener) {
-    if (types = _check(this, types, listener, false)) {
-        for (var i = 0; i < types.length; i++) {
-            var type = types[i], all = this._listeners[type], index;
-            if (all && (index = all.indexOf(listener)) >= 0) {
-                all.splice(index, 1);
-                if (!all.length) {
-                    delete this._listeners[type];
-                }
-                this._flag(type, false);
-            }
-        }
-    }
-    return this;
+Cut.box = function() {
+    return Cut.create().box();
 };
 
-function _check(node, types, listener, create) {
-    if (!types || !types.length || typeof listener !== "function") {
-        return false;
-    }
-    if (!(types = (is.array(types) ? types.join(" ") : types).match(/\S+/g))) {
-        return false;
-    }
-    if (node._listeners === null) {
-        if (create) {
-            node._listeners = {};
-        } else {
-            return false;
+Cut.prototype.box = function() {
+    if (this._boxTicker) return this;
+    this._padding = this._padding || 0;
+    this.tick(this._boxTicker = function() {
+        if (this._mo_box == this._ts_touch) {
+            return;
         }
-    }
-    return types;
-}
-
-Cut.prototype.listeners = function(type) {
-    return this._listeners && this._listeners[type];
+        this._mo_box = this._ts_touch;
+        var width = 0, height = 0;
+        var child, next = this.first(true);
+        while (child = next) {
+            next = child.next(true);
+            child._pin.relativeMatrix();
+            var w = child.pin("boxWidth");
+            var h = child.pin("boxHeight");
+            width = Math.max(width, w);
+            height = Math.max(height, h);
+        }
+        width += 2 * this._padding;
+        height += 2 * this._padding;
+        this.pin("width") != width && this.pin("width", width);
+        this.pin("height") != height && this.pin("height", height);
+    });
+    return this;
 };
 
-Cut.prototype.publish = function(name, args) {
-    var listeners = this.listeners(name);
-    if (!listeners || !listeners.length) {
-        return 0;
-    }
-    for (var l = 0; l < listeners.length; l++) {
-        listeners[l].apply(this, args);
-    }
-    return listeners.length;
+// TODO: move padding to pin
+Cut.prototype.padding = function(pad) {
+    this._padding = pad;
+    return this;
 };
 
-Cut.prototype.trigger = function(name, args) {
-    this.publish(name, args);
+Cut.prototype.spacing = function(space) {
+    this._spacing = space;
     return this;
 };
 
 
-},{"./core":4,"./util/is":18}],7:[function(require,module,exports){
-module.exports = require("./core");
-
-module.exports.Matrix = require("./matrix");
-
-module.exports.Texture = require("./texture");
-
-require("./atlas");
-
-require("./canvas");
-
-require("./node");
-
-require("./event");
-
-require("./pin");
-
-require("./ui");
-
-
-},{"./atlas":2,"./canvas":3,"./core":4,"./event":6,"./matrix":9,"./node":11,"./pin":12,"./texture":13,"./ui":15}],8:[function(require,module,exports){
-var Cut = require("./core");
+},{"./core":8,"./pin":16,"./render":17,"./util/create":21}],13:[function(require,module,exports){
+var Cut = require("../core");
 
 if (typeof DEBUG === "undefined") DEBUG = true;
 
@@ -816,7 +1451,7 @@ function ImageLoader(src, success, error) {
 }
 
 
-},{"./core":4}],9:[function(require,module,exports){
+},{"../core":8}],14:[function(require,module,exports){
 function Matrix(a, b, c, d, e, f) {
     this._dirty = true;
     this.a = a || 1;
@@ -964,205 +1599,23 @@ Matrix.prototype.reverse = function() {
 
 Matrix.prototype.map = function(p, q) {
     q = q || {};
-    q.x = this.a * p.x + this.c * p.y + this.e;
-    q.y = this.b * p.x + this.d * p.y + this.f;
-    return q;
-};
-
-Matrix.prototype.mapX = function(x, y) {
-    return this.a * x + this.c * y + this.e;
-};
-
-Matrix.prototype.mapY = function(x, y) {
-    return this.b * x + this.d * y + this.f;
-};
-
-module.exports = Matrix;
-
-
-},{}],10:[function(require,module,exports){
-if (typeof DEBUG === "undefined") DEBUG = true;
-
-function Mouse() {
-    Mouse.subscribe.apply(Mouse, arguments);
-}
-
-Mouse.CLICK = "click";
-
-Mouse.START = "touchstart mousedown";
-
-Mouse.MOVE = "touchmove mousemove";
-
-Mouse.END = "touchend mouseup";
-
-Mouse.CANCEL = "touchcancel";
-
-Mouse.subscribe = function(root, elem) {
-    var visitor = null, data = {}, abs = null, rel = null, clicked = [];
-    elem = elem || document;
-    // click events are synthesized from start/end events on same nodes
-    // elem.addEventListener('click', handleClick);
-    elem.addEventListener("touchstart", handleStart);
-    elem.addEventListener("touchend", handleEnd);
-    elem.addEventListener("touchmove", handleMove);
-    elem.addEventListener("touchcancel", handleCancel);
-    elem.addEventListener("mousedown", handleStart);
-    elem.addEventListener("mouseup", handleEnd);
-    elem.addEventListener("mousemove", handleMove);
-    function handleStart(event) {
-        Mouse._xy(root, elem, event, abs);
-        DEBUG && console.log("Mouse Start: " + event.type + " " + abs);
-        event.preventDefault();
-        publish(event.type, event);
-        findClicks();
-    }
-    function handleEnd(event) {
-        // New xy is not valid/available, last xy is used instead.
-        DEBUG && console.log("Mouse End: " + event.type + " " + abs);
-        event.preventDefault();
-        publish(event.type, event);
-        if (clicked.length) {
-            DEBUG && console.log("Mouse Click: " + clicked.length);
-            fireClicks(event);
-        }
-    }
-    function handleCancel(event) {
-        DEBUG && console.log("Mouse Cancel: " + event.type);
-        event.preventDefault();
-        publish(event.type, event);
-    }
-    function handleMove(event) {
-        Mouse._xy(root, elem, event, abs);
-        // DEBUG && console.log('Mouse Move: ' + event.type + ' ' +
-        // abs);
-        if (!root._flag(event.type)) {
-            return;
-        }
-        event.preventDefault();
-        publish(event.type, event);
-    }
-    function findClicks() {
-        while (clicked.length) {
-            clicked.pop();
-        }
-        publish("click", null, clicked);
-    }
-    function fireClicks(event) {
-        data.event = event;
-        data.type = "click";
-        data.root = root;
-        data.collect = false;
-        var cancel = false;
-        while (clicked.length) {
-            var node = clicked.shift();
-            if (cancel) {
-                continue;
-            }
-            cancel = visitor.end(node, data) ? true : cancel;
-        }
-    }
-    function publish(type, event, collect) {
-        rel.x = abs.x;
-        rel.y = abs.y;
-        data.event = event;
-        data.type = type;
-        data.root = /* root._capture || */ root;
-        data.collect = collect;
-        data.root.visit(visitor, data);
-    }
-    visitor = {
-        reverse: true,
-        visible: true,
-        start: function(node, data) {
-            return !node._flag(data.type);
-        },
-        end: function(node, data) {
-            // data: event, type, root, collect
-            rel.raw = data.event;
-            rel.type = data.type;
-            var listeners = node.listeners(data.type);
-            if (!listeners) {
-                return;
-            }
-            node.matrix().reverse().map(abs, rel);
-            if (!(node === data.root || node.attr("spy") || Mouse._isInside(node, rel))) {
-                return;
-            }
-            if (data.collect) {
-                data.collect.push(node);
-                return;
-            }
-            var cancel = false;
-            for (var l = 0; l < listeners.length; l++) {
-                cancel = listeners[l].call(node, rel) ? true : cancel;
-            }
-            return cancel;
-        }
-    };
-    abs = {
-        x: 0,
-        y: 0,
-        toString: function() {
-            return (this.x | 0) + "x" + (this.y | 0);
-        }
-    };
-    rel = {
-        x: 0,
-        y: 0,
-        toString: function() {
-            return abs + " / " + (this.x | 0) + "x" + (this.y | 0);
-        }
-    };
+    q.x = this.a * p.x + this.c * p.y + this.e;
+    q.y = this.b * p.x + this.d * p.y + this.f;
+    return q;
 };
 
-Mouse._isInside = function(node, point) {
-    return point.x >= 0 && point.x <= node._pin._width && point.y >= 0 && point.y <= node._pin._height;
+Matrix.prototype.mapX = function(x, y) {
+    return this.a * x + this.c * y + this.e;
 };
 
-Mouse._xy = function(root, elem, event, point) {
-    var isTouch = false;
-    // touch screen events
-    if (event.touches) {
-        if (event.touches.length) {
-            isTouch = true;
-            point.x = event.touches[0].pageX;
-            point.y = event.touches[0].pageY;
-        } else {
-            return;
-        }
-    } else {
-        // mouse events
-        point.x = event.clientX;
-        point.y = event.clientY;
-        // See http://goo.gl/JuVnF2
-        if (document.body.scrollLeft || document.body.scrollTop) {} else if (document.documentElement) {
-            point.x += document.documentElement.scrollLeft;
-            point.y += document.documentElement.scrollTop;
-        }
-    }
-    // accounts for border
-    point.x -= elem.clientLeft || 0;
-    point.y -= elem.clientTop || 0;
-    var par = elem;
-    while (par) {
-        point.x -= par.offsetLeft || 0;
-        point.y -= par.offsetTop || 0;
-        if (!isTouch) {
-            // touch events offset scrolling with pageX/Y
-            // so scroll offset not needed for them
-            point.x += par.scrollLeft || 0;
-            point.y += par.scrollTop || 0;
-        }
-        par = par.offsetParent;
-    }
-    point.x *= root.viewport().ratio || 1;
-    point.y *= root.viewport().ratio || 1;
+Matrix.prototype.mapY = function(x, y) {
+    return this.b * x + this.d * y + this.f;
 };
 
-module.exports = Mouse;
+module.exports = Matrix;
 
 
-},{}],11:[function(require,module,exports){
+},{}],15:[function(require,module,exports){
 var Cut = require("./core");
 
 var iid = 0;
@@ -1483,7 +1936,7 @@ function _ensure(obj) {
 module.exports = Cut;
 
 
-},{"./core":4}],12:[function(require,module,exports){
+},{"./core":8}],16:[function(require,module,exports){
 var Cut = require("./core");
 
 var Matrix = require("./matrix");
@@ -1931,250 +2384,26 @@ Pin.prototype._scaleTo = function(width, height, mode) {
             pin._scaleX = pin._scaleY = Math.max(pin._scaleX, pin._scaleY);
         } else if (mode == "in" || mode == "in-pad") {
             pin._scaleX = pin._scaleY = Math.min(pin._scaleX, pin._scaleY);
-        }
-        if (mode == "out-crop" || mode == "in-pad") {
-            pin._width = width / pin._scaleX;
-            pin._height = height / pin._scaleY;
-        }
-    }
-};
-
-module.exports = Pin;
-
-
-},{"./core":4,"./matrix":9}],13:[function(require,module,exports){
-var stats = require("./util/stats");
-
-var math = require("./util/math");
-
-function Texture(image, ratio) {
-    if (typeof image === "object") {
-        this.src(image, ratio);
-    }
-}
-
-Texture.prototype.pipe = function() {
-    return new Texture(this);
-};
-
-/**
- * Signatures: (image), (x, y, w, h), (w, h)
- */
-Texture.prototype.src = function(x, y, w, h) {
-    if (typeof x === "object") {
-        var image = x, ratio = y || 1;
-        this._image = image;
-        this._sx = this._dx = 0;
-        this._sy = this._dy = 0;
-        this._sw = this._dw = image.width / ratio;
-        this._sh = this._dh = image.height / ratio;
-        this.width = image.width / ratio;
-        this.height = image.height / ratio;
-        this.ratio = ratio;
-    } else {
-        if (typeof w === "undefined") {
-            w = x, h = y;
-        } else {
-            this._sx = x, this._sy = y;
-        }
-        this._sw = this._dw = w;
-        this._sh = this._dh = h;
-        this.width = w;
-        this.height = h;
-    }
-    return this;
-};
-
-/**
- * Signatures: (x, y, w, h), (x, y)
- */
-Texture.prototype.dest = function(x, y, w, h) {
-    this._dx = x, this._dy = y;
-    this._dx = x, this._dy = y;
-    if (typeof w !== "undefined") {
-        this._dw = w, this._dh = h;
-        this.width = w, this.height = h;
-    }
-    return this;
-};
-
-Texture.prototype.draw = function(context, x1, y1, x2, y2, x3, y3, x4, y4) {
-    var image = this._image;
-    if (image === null || typeof image !== "object") {
-        return;
-    }
-    var sx = this._sx, sy = this._sy;
-    var sw = this._sw, sh = this._sh;
-    var dx = this._dx, dy = this._dy;
-    var dw = this._dw, dh = this._dh;
-    if (typeof x3 !== "undefined") {
-        x1 = math.limit(x1, 0, this._sw), x2 = math.limit(x2, 0, this._sw - x1);
-        y1 = math.limit(y1, 0, this._sh), y2 = math.limit(y2, 0, this._sh - y1);
-        sx += x1, sy += y1, sw = x2, sh = y2;
-        dx = x3, dy = y3, dw = x4, dh = y4;
-    } else if (typeof x2 !== "undefined") {
-        dx = x1, dy = y1, dw = x2, dh = y2;
-    } else if (typeof x1 !== "undefined") {
-        dw = x1, dh = y1;
-    }
-    var ratio = this.ratio || 1;
-    sx *= ratio, sy *= ratio, sw *= ratio, sh *= ratio;
-    try {
-        if (typeof image.draw === "function") {
-            image.draw(context, sx, sy, sw, sh, dx, dy, dw, dh);
-        } else {
-            stats.draw++;
-            context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
-        }
-    } catch (ex) {
-        if (!image._draw_failed) {
-            console.log("Unable to draw: ", image);
-            console.log(ex);
-            image._draw_failed = true;
-        }
-    }
-};
-
-module.exports = Texture;
-
-
-},{"./util/math":19,"./util/stats":22}],14:[function(require,module,exports){
-var Easing = require("./easing");
-
-var Cut = require("./core");
-
-var Pin = require("./pin");
-
-Cut.prototype.tween = function(duration, delay) {
-    if (!this._tween) {
-        this._tween = new Tween(this);
-    }
-    return this._tween.tween(duration, delay);
-};
-
-var iid = 0;
-
-function Tween(node) {
-    // TODO: reuse head.start/keys/end
-    var tween = this;
-    this._owner = node;
-    this._queue = [];
-    this._next = null;
-    var lastTime = 0;
-    node.tick(function(elapsed, now, last) {
-        if (!tween._queue.length) {
-            return;
-        }
-        // ignore old elapsed
-        var ignore = lastTime != last;
-        lastTime = now;
-        this.touch();
-        if (ignore) {
-            return;
-        }
-        var head = tween._queue[0];
-        if (!head.time) {
-            head.time = 1;
-        } else {
-            head.time += elapsed;
-        }
-        if (head.time < head.delay) {
-            return;
-        }
-        if (!head.start) {
-            head.start = {};
-            head.keys = {};
-            for (var key in head.end) {
-                if (typeof (start = node.pin(key)) === "number") {
-                    head.start[key] = start;
-                    head.keys[key] = key;
-                } else if (typeof (startX = node.pin(key + "X")) === "number" && typeof (startY = node.pin(key + "Y")) === "number") {
-                    head.start[key + "X"] = startX;
-                    head.keys[key + "X"] = key;
-                    head.start[key + "Y"] = startY;
-                    head.keys[key + "Y"] = key;
-                }
-            }
-        }
-        var p = (head.time - head.delay) / head.duration;
-        var over = p >= 1;
-        p = p > 1 ? 1 : p;
-        p = typeof head.easing == "function" ? head.easing(p) : p;
-        var q = 1 - p;
-        for (var key in head.keys) {
-            node.pin(key, head.start[key] * q + head.end[head.keys[key]] * p);
-        }
-        if (over) {
-            tween._queue.shift();
-            head.then && head.then.call(node);
-        }
-    }, true);
-}
-
-Tween.prototype.tween = function(duration, delay) {
-    this._next = {
-        id: ++iid,
-        end: {},
-        duration: duration || 400,
-        delay: delay || 0
-    };
-    return this;
-};
-
-Tween.prototype.pin = function(a, b) {
-    if (this._next !== this._queue[this._queue.length - 1]) {
-        this._owner.touch();
-        this._queue.push(this._next);
-    }
-    var end = this._next.end;
-    if (typeof a === "object") {
-        for (var attr in a) {
-            end[attr] = a[attr];
-        }
-    } else if (typeof b !== "undefined") {
-        end[a] = b;
-    }
-    return this;
-};
-
-Tween.prototype.clear = function(forward) {
-    var tween;
-    while (tween = this._queue.shift()) {
-        forward && this._owner.pin(tween.end);
+        }
+        if (mode == "out-crop" || mode == "in-pad") {
+            pin._width = width / pin._scaleX;
+            pin._height = height / pin._scaleY;
+        }
     }
-    return this;
-};
-
-Tween.prototype.then = function(then) {
-    this._next.then = then;
-    return this;
-};
-
-Tween.prototype.ease = function(easing) {
-    this._next.easing = Easing(easing);
-    return this;
 };
 
-module.exports = Tween;
+module.exports = Pin;
 
 
-},{"./core":4,"./easing":5,"./pin":12}],15:[function(require,module,exports){
+},{"./core":8,"./matrix":14}],17:[function(require,module,exports){
 var Cut = require("./core");
 
-var Pin = require("./pin");
+require("./pin");
 
 var stats = require("./util/stats");
 
-var repeat = require("./util/repeat");
-
 var create = require("./util/create");
 
-var extend = require("./util/extend");
-
-var math = require("./util/math");
-
-var is = require("./util/is");
-
 Cut.prototype._textures = null;
 
 Cut.prototype._tickBefore = null;
@@ -2274,6 +2503,20 @@ Cut.prototype.untick = function(ticker) {
     }
 };
 
+
+},{"./core":8,"./pin":16,"./util/create":21,"./util/stats":27}],18:[function(require,module,exports){
+var Cut = require("./core");
+
+require("./pin");
+
+require("./render");
+
+var stats = require("./util/stats");
+
+var create = require("./util/create");
+
+var extend = require("./util/extend");
+
 Root._super = Cut;
 
 Root.prototype = create(Root._super.prototype);
@@ -2317,260 +2560,91 @@ Root.prototype.start = function() {
     return this.resume();
 };
 
-Root.prototype.resume = function(force) {
-    if (this._paused || force) {
-        this._paused = false;
-        this.request();
-    }
-    return this;
-};
-
-Root.prototype.pause = function() {
-    this._paused = true;
-    return this;
-};
-
-Root.prototype.touch = function() {
-    this.resume();
-    return Root._super.prototype.touch.call(this);
-};
-
-Root.prototype.background = function(color) {
-    // to be implemented by loaders
-    return this;
-};
-
-Root.prototype.viewport = function(width, height, ratio) {
-    if (typeof width === "undefined") {
-        return extend({}, this._viewport);
-    }
-    this._viewport = {
-        width: width,
-        height: height,
-        ratio: ratio || 1
-    };
-    this._updateViewbox();
-    var data = extend({}, this._viewport);
-    this.visit({
-        start: function(node) {
-            if (!node._flag("viewport")) {
-                return true;
-            }
-            node.publish("viewport", [ data ]);
-        }
-    });
-    return this;
-};
-
-// TODO: static/fixed viewbox
-Root.prototype.viewbox = function(width, height, mode) {
-    this._viewbox = {
-        width: width,
-        height: height,
-        mode: /^(in|out|in-pad|out-crop)$/.test(mode) ? mode : "in-pad"
-    };
-    this._updateViewbox();
-    return this;
-};
-
-Root.prototype._updateViewbox = function() {
-    var box = this._viewbox;
-    var size = this._viewport;
-    if (size && box) {
-        this.pin({
-            width: box.width,
-            height: box.height
-        });
-        this._pin._scaleTo(size.width, size.height, box.mode);
-    } else if (size) {
-        this.pin({
-            width: size.width,
-            height: size.height
-        });
-    }
-};
-
-Cut.image = function(image) {
-    var img = new Image();
-    image && img.image(image);
-    return img;
-};
-
-Image._super = Cut;
-
-Image.prototype = create(Image._super.prototype);
-
-function Image() {
-    Image._super.call(this);
-    this.label("Image");
-    this._textures = [];
-    this._image = null;
-}
-
-/**
- * @deprecated Use image
- */
-Image.prototype.setImage = function(a, b, c) {
-    return this.image(a, b, c);
-};
-
-Image.prototype.image = function(image) {
-    this._image = Cut.texture(image).one();
-    this.pin("width", this._image ? this._image.width : 0);
-    this.pin("height", this._image ? this._image.height : 0);
-    this._textures[0] = this._image.pipe();
-    this._textures.length = 1;
-    return this;
-};
-
-Image.prototype.tile = function(inner) {
-    this._repeat(false, inner);
-    return this;
-};
-
-Image.prototype.stretch = function(inner) {
-    this._repeat(true, inner);
-    return this;
-};
-
-Image.prototype._repeat = function(stretch, inner) {
-    var self = this;
-    this.untick(this._repeatTicker);
-    this.tick(this._repeatTicker = function() {
-        if (this._mo_stretch == this._pin._ts_transform) {
-            return;
-        }
-        this._mo_stretch = this._pin._ts_transform;
-        var width = this.pin("width");
-        var height = this.pin("height");
-        this._textures.length = repeat(this._image, width, height, stretch, inner, insert);
-    });
-    function insert(i, sx, sy, sw, sh, dx, dy, dw, dh) {
-        var repeat = self._textures.length > i ? self._textures[i] : self._textures[i] = self._image.pipe();
-        repeat.src(sx, sy, sw, sh);
-        repeat.dest(dx, dy, dw, dh);
-    }
-};
-
-Cut.anim = function(frames, fps) {
-    var anim = new Anim();
-    anim.frames(frames).gotoFrame(0);
-    fps && anim.fps(fps);
-    return anim;
-};
-
-Anim._super = Cut;
-
-Anim.prototype = create(Anim._super.prototype);
-
-Anim.FPS = 12;
-
-function Anim() {
-    Anim._super.call(this);
-    this.label("Anim");
-    this._textures = [];
-    this._fps = Anim.FPS;
-    this._ft = 1e3 / this._fps;
-    this._time = -1;
-    this._repeat = 0;
-    this._index = 0;
-    this._frames = [];
-    var lastTime = 0;
-    this.tick(function(t, now, last) {
-        if (this._time < 0 || this._frames.length <= 1) {
-            return;
-        }
-        // ignore old elapsed
-        var ignore = lastTime != last;
-        lastTime = now;
-        if (ignore) {
-            return true;
-        }
-        this._time += t;
-        if (this._time < this._ft) {
-            return true;
-        }
-        var n = this._time / this._ft | 0;
-        this._time -= n * this._ft;
-        this.moveFrame(n);
-        if (this._repeat > 0 && (this._repeat -= n) <= 0) {
-            this.stop();
-            this._callback && this._callback();
-            return false;
-        }
-        return true;
-    }, false);
-}
-
-Anim.prototype.fps = function(fps) {
-    if (typeof fps === "undefined") {
-        return this._fps;
-    }
-    this._fps = fps > 0 ? fps : Cut.Anim.FPS;
-    this._ft = 1e3 / this._fps;
-    return this;
-};
-
-/**
- * @deprecated Use frames
- */
-Anim.prototype.setFrames = function(a, b, c) {
-    return this.frames(a, b, c);
-};
-
-Anim.prototype.frames = function(frames) {
-    this._index = 0;
-    this._frames = Cut.texture(frames).array();
-    this.touch();
-    return this;
-};
-
-Anim.prototype.length = function() {
-    return this._frames ? this._frames.length : 0;
-};
-
-Anim.prototype.gotoFrame = function(frame, resize) {
-    this._index = math.rotate(frame, this._frames.length) | 0;
-    resize = resize || !this._textures[0];
-    this._textures[0] = this._frames[this._index];
-    if (resize) {
-        this.pin("width", this._textures[0].width);
-        this.pin("height", this._textures[0].height);
+Root.prototype.resume = function(force) {
+    if (this._paused || force) {
+        this._paused = false;
+        this.request();
     }
-    this.touch();
     return this;
 };
 
-Anim.prototype.moveFrame = function(move) {
-    return this.gotoFrame(this._index + move);
+Root.prototype.pause = function() {
+    this._paused = true;
+    return this;
 };
 
-Anim.prototype.repeat = function(repeat, callback) {
-    this._repeat = repeat * this._frames.length - 1;
-    this._callback = callback;
-    this.play();
+Root.prototype.touch = function() {
+    this.resume();
+    return Root._super.prototype.touch.call(this);
+};
+
+Root.prototype.background = function(color) {
+    // to be implemented by loaders
     return this;
 };
 
-Anim.prototype.play = function(frame) {
-    if (typeof frame !== "undefined") {
-        this.gotoFrame(frame);
-        this._time = 0;
-    } else if (this._time < 0) {
-        this._time = 0;
+Root.prototype.viewport = function(width, height, ratio) {
+    if (typeof width === "undefined") {
+        return extend({}, this._viewport);
     }
-    this.touch();
+    this._viewport = {
+        width: width,
+        height: height,
+        ratio: ratio || 1
+    };
+    this._updateViewbox();
+    var data = extend({}, this._viewport);
+    this.visit({
+        start: function(node) {
+            if (!node._flag("viewport")) {
+                return true;
+            }
+            node.publish("viewport", [ data ]);
+        }
+    });
     return this;
 };
 
-Anim.prototype.stop = function(frame) {
-    this._time = -1;
-    if (typeof frame !== "undefined") {
-        this.gotoFrame(frame);
-    }
+// TODO: static/fixed viewbox
+Root.prototype.viewbox = function(width, height, mode) {
+    this._viewbox = {
+        width: width,
+        height: height,
+        mode: /^(in|out|in-pad|out-crop)$/.test(mode) ? mode : "in-pad"
+    };
+    this._updateViewbox();
     return this;
 };
 
+Root.prototype._updateViewbox = function() {
+    var box = this._viewbox;
+    var size = this._viewport;
+    if (size && box) {
+        this.pin({
+            width: box.width,
+            height: box.height
+        });
+        this._pin._scaleTo(size.width, size.height, box.mode);
+    } else if (size) {
+        this.pin({
+            width: size.width,
+            height: size.height
+        });
+    }
+};
+
+
+},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/extend":22,"./util/stats":27}],19:[function(require,module,exports){
+var Cut = require("./core");
+
+require("./pin");
+
+require("./render");
+
+var create = require("./util/create");
+
+var is = require("./util/is");
+
 Cut.string = function(frames) {
     return new Str().frames(frames);
 };
@@ -2644,113 +2718,104 @@ Str.prototype.value = function(value) {
     return this;
 };
 
-Cut.row = function(align) {
-    return Cut.create().row(align);
-};
 
-Cut.prototype.row = function(align) {
-    this.sequence("row", align);
-    return this;
-};
+},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/is":23}],20:[function(require,module,exports){
+var stats = require("./util/stats");
 
-Cut.column = function(align) {
-    return Cut.create().column(align);
-};
+var math = require("./util/math");
 
-Cut.prototype.column = function(align) {
-    this.sequence("column", align);
-    return this;
-};
+function Texture(image, ratio) {
+    if (typeof image === "object") {
+        this.src(image, ratio);
+    }
+}
 
-Cut.sequence = function(type, align) {
-    return Cut.create().sequence(type, align);
+Texture.prototype.pipe = function() {
+    return new Texture(this);
 };
 
-Cut.prototype.sequence = function(type, align) {
-    this._padding = this._padding || 0;
-    this._spacing = this._spacing || 0;
-    this.untick(this._sequenceTicker);
-    this.tick(this._sequenceTicker = function() {
-        if (this._mo_seq == this._ts_touch) {
-            return;
-        }
-        this._mo_seq = this._ts_touch;
-        var alignChildren = this._mo_seqAlign != this._ts_children;
-        this._mo_seqAlign = this._ts_children;
-        var width = 0, height = 0;
-        var child, next = this.first(true);
-        var first = true;
-        while (child = next) {
-            next = child.next(true);
-            child._pin.relativeMatrix();
-            var w = child.pin("boxWidth");
-            var h = child.pin("boxHeight");
-            if (type == "column") {
-                !first && (height += this._spacing);
-                child.pin("offsetY") != height && child.pin("offsetY", height);
-                width = Math.max(width, w);
-                height = height + h;
-                alignChildren && child.pin("alignX", align);
-            } else if (type == "row") {
-                !first && (width += this._spacing);
-                child.pin("offsetX") != width && child.pin("offsetX", width);
-                width = width + w;
-                height = Math.max(height, h);
-                alignChildren && child.pin("alignY", align);
-            }
-            first = false;
+/**
+ * Signatures: (image), (x, y, w, h), (w, h)
+ */
+Texture.prototype.src = function(x, y, w, h) {
+    if (typeof x === "object") {
+        var image = x, ratio = y || 1;
+        this._image = image;
+        this._sx = this._dx = 0;
+        this._sy = this._dy = 0;
+        this._sw = this._dw = image.width / ratio;
+        this._sh = this._dh = image.height / ratio;
+        this.width = image.width / ratio;
+        this.height = image.height / ratio;
+        this.ratio = ratio;
+    } else {
+        if (typeof w === "undefined") {
+            w = x, h = y;
+        } else {
+            this._sx = x, this._sy = y;
         }
-        width += 2 * this._padding;
-        height += 2 * this._padding;
-        this.pin("width") != width && this.pin("width", width);
-        this.pin("height") != height && this.pin("height", height);
-    });
+        this._sw = this._dw = w;
+        this._sh = this._dh = h;
+        this.width = w;
+        this.height = h;
+    }
     return this;
 };
 
-Cut.box = function() {
-    return Cut.create().box();
+/**
+ * Signatures: (x, y, w, h), (x, y)
+ */
+Texture.prototype.dest = function(x, y, w, h) {
+    this._dx = x, this._dy = y;
+    this._dx = x, this._dy = y;
+    if (typeof w !== "undefined") {
+        this._dw = w, this._dh = h;
+        this.width = w, this.height = h;
+    }
+    return this;
 };
 
-Cut.prototype.box = function() {
-    if (this._boxTicker) return this;
-    this._padding = this._padding || 0;
-    this.tick(this._boxTicker = function() {
-        if (this._mo_box == this._ts_touch) {
-            return;
+Texture.prototype.draw = function(context, x1, y1, x2, y2, x3, y3, x4, y4) {
+    var image = this._image;
+    if (image === null || typeof image !== "object") {
+        return;
+    }
+    var sx = this._sx, sy = this._sy;
+    var sw = this._sw, sh = this._sh;
+    var dx = this._dx, dy = this._dy;
+    var dw = this._dw, dh = this._dh;
+    if (typeof x3 !== "undefined") {
+        x1 = math.limit(x1, 0, this._sw), x2 = math.limit(x2, 0, this._sw - x1);
+        y1 = math.limit(y1, 0, this._sh), y2 = math.limit(y2, 0, this._sh - y1);
+        sx += x1, sy += y1, sw = x2, sh = y2;
+        dx = x3, dy = y3, dw = x4, dh = y4;
+    } else if (typeof x2 !== "undefined") {
+        dx = x1, dy = y1, dw = x2, dh = y2;
+    } else if (typeof x1 !== "undefined") {
+        dw = x1, dh = y1;
+    }
+    var ratio = this.ratio || 1;
+    sx *= ratio, sy *= ratio, sw *= ratio, sh *= ratio;
+    try {
+        if (typeof image.draw === "function") {
+            image.draw(context, sx, sy, sw, sh, dx, dy, dw, dh);
+        } else {
+            stats.draw++;
+            context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
         }
-        this._mo_box = this._ts_touch;
-        var width = 0, height = 0;
-        var child, next = this.first(true);
-        while (child = next) {
-            next = child.next(true);
-            child._pin.relativeMatrix();
-            var w = child.pin("boxWidth");
-            var h = child.pin("boxHeight");
-            width = Math.max(width, w);
-            height = Math.max(height, h);
+    } catch (ex) {
+        if (!image._draw_failed) {
+            console.log("Unable to draw: ", image);
+            console.log(ex);
+            image._draw_failed = true;
         }
-        width += 2 * this._padding;
-        height += 2 * this._padding;
-        this.pin("width") != width && this.pin("width", width);
-        this.pin("height") != height && this.pin("height", height);
-    });
-    return this;
-};
-
-// TODO: move padding to pin
-Cut.prototype.padding = function(pad) {
-    this._padding = pad;
-    return this;
+    }
 };
 
-Cut.prototype.spacing = function(space) {
-    this._spacing = space;
-    return this;
-};
+module.exports = Texture;
 
 
-},{"./core":4,"./pin":12,"./util/create":16,"./util/extend":17,"./util/is":18,"./util/math":19,"./util/repeat":21,"./util/stats":22}],16:[function(require,module,exports){
+},{"./util/math":24,"./util/stats":27}],21:[function(require,module,exports){
 if (typeof Object.create == "function") {
     module.exports = function(proto, props) {
         return Object.create.call(Object, proto, props);
@@ -2766,7 +2831,7 @@ if (typeof Object.create == "function") {
 }
 
 
-},{}],17:[function(require,module,exports){
+},{}],22:[function(require,module,exports){
 module.exports = function(base) {
     for (var i = 1; i < arguments.length; i++) {
         var obj = arguments[i];
@@ -2780,7 +2845,7 @@ module.exports = function(base) {
 };
 
 
-},{}],18:[function(require,module,exports){
+},{}],23:[function(require,module,exports){
 var objProto = Object.prototype;
 
 var owns = objProto.hasOwnProperty;
@@ -2931,7 +2996,7 @@ is.hex = function(value) {
 };
 
 
-},{}],19:[function(require,module,exports){
+},{}],24:[function(require,module,exports){
 module.exports.random = function(min, max) {
     if (typeof min === "undefined") {
         max = 1, min = 0;
@@ -2971,7 +3036,7 @@ module.exports.length = function(x, y) {
 };
 
 
-},{}],20:[function(require,module,exports){
+},{}],25:[function(require,module,exports){
 module.exports = function(fn, ctx) {
     var called = false;
     return function() {
@@ -2983,7 +3048,7 @@ module.exports = function(fn, ctx) {
 };
 
 
-},{}],21:[function(require,module,exports){
+},{}],26:[function(require,module,exports){
 module.exports = function(img, owidth, oheight, stretch, inner, insert) {
     var width = img.width;
     var height = img.height;
@@ -3037,11 +3102,11 @@ module.exports = function(img, owidth, oheight, stretch, inner, insert) {
 };
 
 
-},{}],22:[function(require,module,exports){
+},{}],27:[function(require,module,exports){
 module.exports = {};
 
 
-},{}],23:[function(require,module,exports){
+},{}],28:[function(require,module,exports){
 module.exports.startsWith = function(str, sub) {
     return typeof str === "string" && typeof sub === "string" && str.substring(0, sub.length) == sub;
 };
diff --git a/dist/cut.cordova.min.js b/dist/cut.cordova.min.js
index f5ef39c..feff8b8 100644
--- a/dist/cut.cordova.min.js
+++ b/dist/cut.cordova.min.js
@@ -1,8 +1,8 @@
 /*
- * CutJS 0.5.0-beta.4
+ * CutJS 0.5.0-beta.5
  * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
  * Available under the MIT license
  * @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;"undefined"!=typeof window?e=window:"undefined"!=typeof global?e=global:"undefined"!=typeof self&&(e=self),e.Cut=t()}}(function(){return function t(e,i,n){function r(o,h){if(!i[o]){if(!e[o]){var a="function"==typeof require&&require;if(!h&&a)return a(o,!0);if(s)return s(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var f=i[o]={exports:{}};e[o][0].call(f.exports,function(t){var i=e[o][1][t];return r(i?i:t)},f,f.exports,t,e,i,n)}return i[o].exports}for(var s="function"==typeof require&&require,o=0;o<n.length;o++)r(n[o]);return r}({1:[function(t,e){e.exports=t("../lib/"),e.exports.Mouse=t("../lib/mouse"),e.exports.Math=t("../lib/util/math"),t("../lib/tween"),t("../lib/loader.cordova"),e.exports._extend=t("../lib/util/extend"),e.exports._create=t("../lib/util/create")},{"../lib/":7,"../lib/loader.cordova":8,"../lib/mouse":10,"../lib/tween":14,"../lib/util/create":16,"../lib/util/extend":17,"../lib/util/math":19}],2:[function(t,e){function i(t){function e(t){if(!t||u.fn(t.draw))return t;t=h({},t),u.fn(a)&&(t=a(t)),1!=c&&(t.x*=c,t.y*=c,t.width*=c,t.height*=c,t.top*=c,t.bottom*=c,t.left*=c,t.right*=c),0!=p&&(t.x+=p,t.y+=p,t.width-=2*p,t.height-=2*p,t.top-=p,t.bottom-=p,t.left-=p,t.right-=p);var e=o.pipe();return e.top=t.top,e.bottom=t.bottom,e.left=t.left,e.right=t.right,e.src(t.x,t.y,t.width,t.height),e}function s(t){if(_){if(u.fn(_))return _(t);if(u.hash(_))return _[t]}if(d){for(var e=null,i=0,n=0;n<d.length;n++)f.startsWith(d[n].name,t)&&(0===i?e=d[n]:1===i?e=[e,d[n]]:e.push(d[n]),i++);return 0===i&&u.fn(l)&&(e=function(e){return l(t+(e?e:""))}),e}}i._super.call(this);var o=this;r(t,"filter"),r(t,"cutouts"),r(t,"sprites"),r(t,"factory");var a=t.map||t.filter,c=t.ppu||t.ratio||1,p=t.trim||0,_=t.textures,l=t.factory,d=t.cutouts||t.sprites;this.select=function(t){var i=s(t);return i?new n(i,s,e):void 0}}function n(t,e,i){function n(t,r){return t?u.fn(t.draw)?t:u.hash(t)&&u.number(t.width)&&u.number(t.height)&&u.fn(i)?i(t):u.hash(t)&&u.defined(r)?n(t[r]):u.fn(t)?n(t(r)):u.array(t)?n(t[0]):u.string(t)&&u.fn(e)?n(e(t)):void 0:_}this.one=function(e){return n(t,e)},this.array=function(e){var i=u.array(e)?e:[];if(u.array(t))for(var r=0;r<t.length;r++)i[r]=n(t[r]);else i[0]=n(t);return i}}function r(t,e,i){e in t&&console.log(i?i.replace("%name",e):"'"+e+"' field of texture atlas is deprecated.")}var s=t("./core"),o=t("./texture"),h=t("./util/extend"),a=t("./util/create"),u=t("./util/is"),f=t("./util/string"),c={},p=[];s.atlas=function(t){var e=u.fn(t.draw)?t:new i(t);t.name&&(c[t.name]=e),p.push(e),r(t,"imagePath"),r(t,"imageRatio");var n=t.imagePath,o=t.imageRatio||1;return u.string(t.image)?n=t.image:u.hash(t.image)&&(n=t.image.url,o=t.image.ratio||o),n&&s.preload(function(t){DEBUG&&console.log("Loading image: "+n);var i=s.config("image-loader");i(n,function(i){DEBUG&&console.log("Image loaded: "+n),e.src(i,o),t()},function(e){DEBUG&&console.log("Error loading image: "+n,e),t()})}),e},i._super=o,i.prototype=a(i._super.prototype);var _=new o;_.x=_.y=_.width=_.height=0,_.pipe=_.src=_.dest=function(){return this},_.draw=function(){};var l=new n(_);s.texture=function(t){if(!u.string(t))return new n(t);var e=null,i=t.indexOf(":");if(i>0&&t.length>i+1){var r=c[t.slice(0,i)];e=r&&r.select(t.slice(i+1))}for(var i=0;!e&&i<p.length;i++)e=p[i].select(t);return e||(console.error("Texture not found: "+t),e=l),e},e.exports=i},{"./core":4,"./texture":13,"./util/create":16,"./util/extend":17,"./util/is":18,"./util/string":23}],3:[function(t){var e=t("./core"),i=t("./texture");e.canvas=function(t,e,n){"string"==typeof t?"object"==typeof e||("function"==typeof e&&(n=e),e={}):("function"==typeof t&&(n=t),e={},t="2d");var r=document.createElement("canvas"),s=r.getContext(t,e),o=new i(r);return o.context=function(){return s},o.size=function(t,e,i){return r.width=t*i,r.height=e*i,this.src(r,i),this},o.canvas=function(t){return"function"==typeof t?t.call(this,s):"undefined"==typeof t&&"function"==typeof n&&n.call(this,s),this},"function"==typeof n&&n.call(this,s),o}},{"./core":4,"./texture":13}],4:[function(t,e){function i(t){if(!(this instanceof i))return o.fn(t)?i.app.apply(i,arguments):o.object(t)?i.atlas.apply(i,arguments):t;n.create++;for(var e=0;e<h.length;e++)h[e].call(this)}"undefined"==typeof DEBUG&&(DEBUG=!0);var n=t("./util/stats"),r=t("./util/extend"),s=t("./util/once"),o=t("./util/is");n.create=0;var h=[];i._init=function(t){h.push(t)};var a={};i.config=function(){return 1===arguments.length&&o.string(arguments[0])?a[arguments[0]]:(1===arguments.length&&o.object(arguments[0])&&r(a,arguments[0]),void(2===arguments.length&&o.string(arguments[0])&&a[(arguments[0],arguments[1])]))};var u=[],f=[],c=[],p=!1,_=!1;i.app=function(t,e){if(!p)return void u.push(arguments);DEBUG&&console.log("Creating app...");var n=i.config("app-loader");n(function(e,i){DEBUG&&console.log("Initing app..."),t(e,i),c.push(e),DEBUG&&console.log("Starting app..."),e.start()},e)},i.preload=function(t){return p?void t(function(){}):void f.push(t)},i.start=function(t){function e(){if(--n<=0)for(DEBUG&&console.log("Loading apps..."),p=!0;u.length;){var t=u.shift();i.app.apply(i,t)}}DEBUG&&console.log("Starting..."),i.config(t),DEBUG&&console.log("Preloading...");var n=0;if(f.length)for(;f.length;){var r=f.shift();r(s(e)),n++}else e()},i.pause=function(){if(!_){_=!0;for(var t=c.length-1;t>=0;t--)c[t].pause()}},i.resume=function(){if(_){_=!1;for(var t=c.length-1;t>=0;t--)c[t].resume()}},i.create=function(){return new i},e.exports=i},{"./util/extend":17,"./util/is":18,"./util/once":20,"./util/stats":22}],5:[function(t,e){function i(t){return t}function n(t){if("function"==typeof t)return t;if("string"!=typeof t)return i;var e=r[t];if(e)return e;var n=/^(\w+)(-(in|out|in-out|out-in))?(\((.*)\))?$/i.exec(t);return n&&n.length?(easing=o[n[1]],mode=s[n[3]],params=n[5],e=easing&&easing.fn?easing.fn:easing&&easing.fc?easing.fc.apply(easing.fc,params&&params.replace(/\s+/,"").split(",")):i,mode&&(e=mode.fn(e)),r[t]=e,e):i}var r={},s={},o={};n.add=function(t){for(var e=(t.name||t.mode).split(/\s+/),i=0;i<e.length;i++){var n=e[i];n&&((t.name?o:s)[n]=t)}},n.add({mode:"in",fn:function(t){return t}}),n.add({mode:"out",fn:function(t){return function(e){return 1-t(1-e)}}}),n.add({mode:"in-out",fn:function(t){return function(e){return.5>e?t(2*e)/2:1-t(2*(1-e))/2}}}),n.add({mode:"out-in",fn:function(t){return function(e){return.5>e?1-t(2*(1-e))/2:t(2*e)/2}}}),n.add({name:"linear",fn:function(t){return t}}),n.add({name:"quad",fn:function(t){return t*t}}),n.add({name:"cubic",fn:function(t){return t*t*t}}),n.add({name:"quart",fn:function(t){return t*t*t*t}}),n.add({name:"quint",fn:function(t){return t*t*t*t*t}}),n.add({name:"sin sine",fn:function(t){return 1-Math.cos(t*Math.PI/2)}}),n.add({name:"exp",fn:function(t){return 0==t?0:Math.pow(2,10*(t-1))}}),n.add({name:"circle circ",fn:function(t){return 1-Math.sqrt(1-t*t)}}),n.add({name:"bounce",fn:function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}}),n.add({name:"poly",fc:function(t){return function(e){return Math.pow(e,t)}}}),n.add({name:"elastic",fc:function(t,e){e=e||.45,t=t||1;var i=e/(2*Math.PI)*Math.asin(1/t);return function(n){return 1+t*Math.pow(2,-10*n)*Math.sin(2*(n-i)*Math.PI/e)}}}),n.add({name:"back",fc:function(t){return t="undefined"!=typeof t?t:1.70158,function(e){return e*e*((t+1)*e-t)}}}),e.exports=n},{}],6:[function(t){function e(t,e,i,r){if(!e||!e.length||"function"!=typeof i)return!1;if(!(e=(n.array(e)?e.join(" "):e).match(/\S+/g)))return!1;if(null===t._listeners){if(!r)return!1;t._listeners={}}return e}var i=t("./core"),n=t("./util/is");i.prototype._listeners=null,i.prototype.on=i.prototype.listen=function(t,i){if(t=e(this,t,i,!0))for(var n=0;n<t.length;n++){var r=t[n];this._listeners[r]=this._listeners[r]||[],this._listeners[r].push(i),this._flag(r,!0)}return this},i.prototype.off=function(t,i){if(t=e(this,t,i,!1))for(var n=0;n<t.length;n++){var r,s=t[n],o=this._listeners[s];o&&(r=o.indexOf(i))>=0&&(o.splice(r,1),o.length||delete this._listeners[s],this._flag(s,!1))}return this},i.prototype.listeners=function(t){return this._listeners&&this._listeners[t]},i.prototype.publish=function(t,e){var i=this.listeners(t);if(!i||!i.length)return 0;for(var n=0;n<i.length;n++)i[n].apply(this,e);return i.length},i.prototype.trigger=function(t,e){return this.publish(t,e),this}},{"./core":4,"./util/is":18}],7:[function(t,e){e.exports=t("./core"),e.exports.Matrix=t("./matrix"),e.exports.Texture=t("./texture"),t("./atlas"),t("./canvas"),t("./node"),t("./event"),t("./pin"),t("./ui")},{"./atlas":2,"./canvas":3,"./core":4,"./event":6,"./matrix":9,"./node":11,"./pin":12,"./texture":13,"./ui":15}],8:[function(t){function e(t,e){function i(){o.isFast?(o.clear(),o.setTransform(1,0,0,1,0,0)):(o.setTransform(1,0,0,1,0,0),o.clearRect(0,0,a,u)),d.render(o)}function r(){h?(a=window.innerWidth>0?window.innerWidth:screen.width,u=window.innerHeight>0?window.innerHeight:screen.height,s.style.width=a+"px",s.style.height=u+"px"):(a=s.clientWidth,u=s.clientHeight),a*=f,u*=f,(s.width!==a||s.height!==u)&&(s.width=a,s.height=u,DEBUG&&console.log("Resize: "+a+" x "+u+" / "+f),d.viewport(a,u,f),i())}e=e||{};var s=e.canvas,o=null,h=!1,a=0,u=0,f=1;if("string"==typeof s&&(s=document.getElementById(s)),s||(s=document.getElementById("cutjs")),!s){h=!0,DEBUG&&console.log("Creating Canvas..."),s=document.createElement("canvas"),s.style.position="absolute";var c=document.body;c.insertBefore(s,c.firstChild)}o=s.getContext("2d",{fastcontext:!0}),o.isFast=!!o.isFast,h=h||o.isFast,DEBUG&&console.log("FastContext: "+o.isFast);var p=window.devicePixelRatio||1,_=o.webkitBackingStorePixelRatio||o.mozBackingStorePixelRatio||o.msBackingStorePixelRatio||o.oBackingStorePixelRatio||o.backingStorePixelRatio||1;f=p/_;var l=window.requestAnimationFrame||window.msRequestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.oRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)};DEBUG&&console.log("Creating root...");var d=n.root(l,i);d.background=function(t){return o.isFast?o.setBackgroundColor&&o.setBackgroundColor(t):s.style.backgroundColor=t,this},t(d,s),r(),window.addEventListener("resize",r,!1),window.addEventListener("orientationchange",r,!1)}function i(t,e,i){function n(){e(r)}DEBUG&&console.log("Loading image: "+t);var r;FastContext?r=FastContext.createImage(t,n,i):(r=new Image,r.onload=n,r.onerror=i,r.src=t)}var n=t("./core");"undefined"==typeof DEBUG&&(DEBUG=!0),"undefined"==typeof FastContext&&(FastContext=window.FastContext),window.addEventListener("load",function(){DEBUG&&console.log("On load."),document.addEventListener("deviceready",function(){DEBUG&&console.log("On deviceready."),n.start({"app-loader":e,"image-loader":i})},!1),document.addEventListener("pause",function(){n.pause()},!1),document.addEventListener("resume",function(){n.resume()},!1)},!1)},{"./core":4}],9:[function(t,e){function i(t,e,i,n,r,s){this._dirty=!0,this.a=t||1,this.b=e||0,this.c=i||0,this.d=n||1,this.e=r||0,this.f=s||0}i.prototype.toString=function(){return"["+this.a+", "+this.b+", "+this.c+", "+this.d+", "+this.e+", "+this.f+"]"},i.prototype.clone=function(){return new i(this.a,this.b,this.c,this.d,this.e,this.f)},i.prototype.copyTo=function(t){return t.copyFrom(this),this},i.prototype.copyFrom=function(t){return this._dirty=!0,this.a=t.a,this.b=t.b,this.c=t.c,this.d=t.d,this.e=t.e,this.f=t.f,this},i.prototype.identity=function(){return this._dirty=!0,this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0,this},i.prototype.rotate=function(t){if(!t)return this;this._dirty=!0;var e=t?Math.cos(t):1,i=t?Math.sin(t):0,n=e*this.a-i*this.b,r=e*this.b+i*this.a,s=e*this.c-i*this.d,o=e*this.d+i*this.c,h=e*this.e-i*this.f,a=e*this.f+i*this.e;return this.a=n,this.b=r,this.c=s,this.d=o,this.e=h,this.f=a,this},i.prototype.translate=function(t,e){return t||e?(this._dirty=!0,this.e+=t,this.f+=e,this):this},i.prototype.scale=function(t,e){return t-1||e-1?(this._dirty=!0,this.a*=t,this.b*=e,this.c*=t,this.d*=e,this.e*=t,this.f*=e,this):this},i.prototype.skew=function(t,e){if(!t&&!e)return this;this._dirty=!0;var i=this.a+this.b*t,n=this.b+this.a*e,r=this.c+this.d*t,s=this.d+this.c*e,o=this.e+this.f*t,h=this.f+this.e*e;return this.a=i,this.b=n,this.c=r,this.d=s,this.e=o,this.f=h,this},i.prototype.concat=function(t){this._dirty=!0;var e=this,i=e.a*t.a+e.b*t.c,n=e.b*t.d+e.a*t.b,r=e.c*t.a+e.d*t.c,s=e.d*t.d+e.c*t.b,o=e.e*t.a+t.e+e.f*t.c,h=e.f*t.d+t.f+e.e*t.b;return this.a=i,this.b=n,this.c=r,this.d=s,this.e=o,this.f=h,this},i.prototype.reverse=function(){if(this._dirty){this._dirty=!1,this.reversed=this.reversed||new i;var t=this.a*this.d-this.b*this.c;this.reversed.a=this.d/t,this.reversed.b=-this.b/t,this.reversed.c=-this.c/t,this.reversed.d=this.a/t,this.reversed.e=(this.c*this.f-this.e*this.d)/t,this.reversed.f=(this.e*this.b-this.a*this.f)/t}return this.reversed},i.prototype.map=function(t,e){return e=e||{},e.x=this.a*t.x+this.c*t.y+this.e,e.y=this.b*t.x+this.d*t.y+this.f,e},i.prototype.mapX=function(t,e){return this.a*t+this.c*e+this.e},i.prototype.mapY=function(t,e){return this.b*t+this.d*e+this.f},e.exports=i},{}],10:[function(t,e){function i(){i.subscribe.apply(i,arguments)}"undefined"==typeof DEBUG&&(DEBUG=!0),i.CLICK="click",i.START="touchstart mousedown",i.MOVE="touchmove mousemove",i.END="touchend mouseup",i.CANCEL="touchcancel",i.subscribe=function(t,e){function n(n){i._xy(t,e,n,p),DEBUG&&console.log("Mouse Start: "+n.type+" "+p),n.preventDefault(),u(n.type,n),h()}function r(t){DEBUG&&console.log("Mouse End: "+t.type+" "+p),t.preventDefault(),u(t.type,t),l.length&&(DEBUG&&console.log("Mouse Click: "+l.length),a(t))}function s(t){DEBUG&&console.log("Mouse Cancel: "+t.type),t.preventDefault(),u(t.type,t)}function o(n){i._xy(t,e,n,p),t._flag(n.type)&&(n.preventDefault(),u(n.type,n))}function h(){for(;l.length;)l.pop();u("click",null,l)}function a(e){c.event=e,c.type="click",c.root=t,c.collect=!1;for(var i=!1;l.length;){var n=l.shift();i||(i=f.end(n,c)?!0:i)}}function u(e,i,n){_.x=p.x,_.y=p.y,c.event=i,c.type=e,c.root=t,c.collect=n,c.root.visit(f,c)}var f=null,c={},p=null,_=null,l=[];e=e||document,e.addEventListener("touchstart",n),e.addEventListener("touchend",r),e.addEventListener("touchmove",o),e.addEventListener("touchcancel",s),e.addEventListener("mousedown",n),e.addEventListener("mouseup",r),e.addEventListener("mousemove",o),f={reverse:!0,visible:!0,start:function(t,e){return!t._flag(e.type)},end:function(t,e){_.raw=e.event,_.type=e.type;var n=t.listeners(e.type);if(n&&(t.matrix().reverse().map(p,_),t===e.root||t.attr("spy")||i._isInside(t,_))){if(e.collect)return void e.collect.push(t);for(var r=!1,s=0;s<n.length;s++)r=n[s].call(t,_)?!0:r;return r}}},p={x:0,y:0,toString:function(){return(0|this.x)+"x"+(0|this.y)}},_={x:0,y:0,toString:function(){return p+" / "+(0|this.x)+"x"+(0|this.y)}}},i._isInside=function(t,e){return e.x>=0&&e.x<=t._pin._width&&e.y>=0&&e.y<=t._pin._height},i._xy=function(t,e,i,n){var r=!1;if(i.touches){if(!i.touches.length)return;r=!0,n.x=i.touches[0].pageX,n.y=i.touches[0].pageY}else n.x=i.clientX,n.y=i.clientY,document.body.scrollLeft||document.body.scrollTop||document.documentElement&&(n.x+=document.documentElement.scrollLeft,n.y+=document.documentElement.scrollTop);n.x-=e.clientLeft||0,n.y-=e.clientTop||0;for(var s=e;s;)n.x-=s.offsetLeft||0,n.y-=s.offsetTop||0,r||(n.x+=s.scrollLeft||0,n.y+=s.scrollTop||0),s=s.offsetParent;n.x*=t.viewport().ratio||1,n.y*=t.viewport().ratio||1},e.exports=i},{}],11:[function(t,e){function i(t){if(t&&t instanceof n)return t;throw"Invalid node: "+t}var n=t("./core"),r=0;n.prototype._label="",n.prototype._visible=!0,n.prototype._parent=null,n.prototype._next=null,n.prototype._prev=null,n.prototype._first=null,n.prototype._last=null,n.prototype._attrs=null,n.prototype._flags=null,n.prototype.toString=function(){return"["+this._label+"]"},n.prototype.id=function(t){return this.label(t)},n.prototype.label=function(t){return"undefined"==typeof t?this._label:(this._label=t,this)},n.prototype.attr=function(t,e){return"undefined"==typeof e?null!==this._attrs?this._attrs[t]:void 0:((null!==this._attrs?this._attrs:this._attrs={})[t]=e,this)},n.prototype.visible=function(t){return"undefined"==typeof t?this._visible:(this._visible=t,this._parent&&(this._parent._ts_children=++r),this._ts_pin=++r,this.touch(),this)},n.prototype.hide=function(){return this.visible(!1)},n.prototype.show=function(){return this.visible(!0)},n.prototype.parent=function(){return this._parent},n.prototype.next=function(t){for(var e=this._next;e&&t&&!e._visible;)e=e._next;return e},n.prototype.prev=function(t){for(var e=this._prev;e&&t&&!e._visible;)e=e._prev;return e},n.prototype.first=function(t){for(var e=this._first;e&&t&&!e._visible;)e=e._next;return e},n.prototype.last=function(t){for(var e=this._last;e&&t&&!e._visible;)e=e._prev;return e},n.prototype.visit=function(t,e){var i=t.reverse,n=t.visible;if(!t.start||!t.start(this,e)){for(var r,s=i?this.last(n):this.first(n);r=s;)if(s=i?r.prev(n):r.next(n),r.visit(t,e))return!0;return t.end&&t.end(this,e)}},n.prototype.append=function(){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t].appendTo(this);return this},n.prototype.prepend=function(){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t].prependTo(this);return this},n.prototype.appendTo=function(t){return i(t),this.remove(),t._last&&(t._last._next=this,this._prev=t._last),this._parent=t,t._last=this,t._first||(t._first=this),this._parent._flag(this,!0),this._ts_parent=++r,t._ts_children=++r,t.touch(),this},n.prototype.prependTo=function(t){return i(t),this.remove(),t._first&&(t._first._prev=this,this._next=t._first),this._parent=t,t._first=this,t._last||(t._last=this),this._parent._flag(this,!0),this._ts_parent=++r,t._ts_children=++r,t.touch(),this},n.prototype.insertNext=function(){if(arguments.length)for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].insertAfter(this);return this},n.prototype.insertPrev=function(){if(arguments.length)for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].insertBefore(this);return this},n.prototype.insertBefore=function(t){i(t),this.remove();var e=t._parent,n=t._prev;return t._prev=this,n&&(n._next=this)||e&&(e._first=this),this._parent=e,this._prev=n,this._next=t,this._parent._flag(this,!0),this._ts_parent=++r,this.touch(),this},n.prototype.insertAfter=function(t){i(t),this.remove();var e=t._parent,n=t._next;return t._next=this,n&&(n._prev=this)||e&&(e._last=this),this._parent=e,this._prev=t,this._next=n,this._parent._flag(this,!0),this._ts_parent=++r,this.touch(),this},n.prototype.remove=function(){if(arguments.length){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].remove();return this}return this._prev&&(this._prev._next=this._next),this._next&&(this._next._prev=this._prev),this._parent&&(this._parent._first===this&&(this._parent._first=this._next),this._parent._last===this&&(this._parent._last=this._prev),this._parent._flag(this,!1),this._parent._ts_children=++r,this._parent.touch()),this._prev=this._next=this._parent=null,this._ts_parent=++r,this},n.prototype.empty=function(){for(var t,e=this._first;t=e;)e=t._next,t._prev=t._next=t._parent=null,this._flag(t,!1);return this._first=this._last=null,this._ts_children=++r,this.touch(),this},n.prototype.touch=function(){return this._ts_touch=++r,this._parent&&this._parent.touch(),this},n.prototype._flag=function(t,e){if("undefined"==typeof e)return null!==this._flags&&this._flags[t]||0;if("string"==typeof t&&(e?(this._flags=this._flags||{},!this._flags[t]&&this._parent&&this._parent._flag(t,!0),this._flags[t]=(this._flags[t]||0)+1):this._flags&&this._flags[t]>0&&(1==this._flags[t]&&this._parent&&this._parent._flag(t,!1),this._flags[t]=this._flags[t]-1)),"object"==typeof t&&t._flags)for(var i in t._flags)t._flags[i]>0&&this._flag(i,e);return this},e.exports=n},{"./core":4}],12:[function(t,e){function i(t){this._owner=t,this._parent=null,this._relativeMatrix=new r,this._absoluteMatrix=new r,this.reset()}var n=t("./core"),r=t("./matrix"),s=0;n._init(function(){this._pin=new i(this)}),n.prototype.matrix=function(){return this._pin.absoluteMatrix()},n.prototype.pin=function(t,e){return"object"==typeof t?(this._pin.set(t),this):"string"==typeof t?"undefined"==typeof e?this._pin.get(t):(this._pin.set(t,e),this):"undefined"==typeof t?this._pin:void 0},i.prototype.reset=function(){this._textureAlpha=1,this._alpha=1,this._width=0,this._height=0,this._scaleX=1,this._scaleY=1,this._skewX=0,this._skewY=0,this._rotation=0,this._pivoted=!1,this._pivotX=null,this._pivotY=null,this._handled=!1,this._handleX=0,this._handleY=0,this._aligned=!1,this._alignX=0,this._alignY=0,this._offsetX=0,this._offsetY=0,this._boxX=0,this._boxY=0,this._boxWidth=this._width,this._boxHeight=this._height,this._ts_translate=++s,this._ts_transform=++s,this._ts_matrix=++s},i.prototype._update=function(){return this._parent=this._owner._parent&&this._owner._parent._pin,this._handled&&this._mo_handle!=this._ts_transform&&(this._mo_handle=this._ts_transform,this._ts_translate=++s),this._aligned&&this._parent&&this._mo_align!=this._parent._ts_transform&&(this._mo_align=this._parent._ts_transform,this._ts_translate=++s),this},i.prototype.toString=function(){return this._owner+" ("+(this._parent?this._parent._owner:null)+")"},i.prototype.absoluteMatrix=function(){this._update();var t=Math.max(this._ts_transform,this._ts_translate,this._parent?this._parent._ts_matrix:0);if(this._mo_abs==t)return this._absoluteMatrix;this._mo_abs=t;var e=this._absoluteMatrix;return e.copyFrom(this.relativeMatrix()),this._parent&&e.concat(this._parent._absoluteMatrix),this._ts_matrix=++s,e},i.prototype.relativeMatrix=function(){this._update();var t=Math.max(this._ts_transform,this._ts_translate,this._parent?this._parent._ts_transform:0);if(this._mo_rel==t)return this._relativeMatrix;this._mo_rel=t;var e=this._relativeMatrix;if(e.identity(),this._pivoted&&e.translate(-this._pivotX*this._width,-this._pivotY*this._height),e.scale(this._scaleX,this._scaleY),e.skew(this._skewX,this._skewY),e.rotate(this._rotation),this._pivoted&&e.translate(this._pivotX*this._width,this._pivotY*this._height),this._pivoted)this._boxX=0,this._boxY=0,this._boxWidth=this._width,this._boxHeight=this._height;else{var i,n;e.a>0&&e.c>0||e.a<0&&e.c<0?(i=0,n=e.a*this._width+e.c*this._height):(i=e.a*this._width,n=e.c*this._height),i>n?(this._boxX=n,this._boxWidth=i-n):(this._boxX=i,this._boxWidth=n-i),e.b>0&&e.d>0||e.b<0&&e.d<0?(i=0,n=e.b*this._width+e.d*this._height):(i=e.b*this._width,n=e.d*this._height),i>n?(this._boxY=n,this._boxHeight=i-n):(this._boxY=i,this._boxHeight=n-i)}return this._x=this._offsetX,this._y=this._offsetY,this._x-=this._boxX+this._handleX*this._boxWidth,this._y-=this._boxY+this._handleY*this._boxHeight,this._aligned&&this._parent&&(this._parent.relativeMatrix(),this._x+=this._alignX*this._parent._width,this._y+=this._alignY*this._parent._height),e.translate(this._x,this._y),this._relativeMatrix},i.prototype.get=function(t){return i._get(this,t)},i.prototype.set=function(t,e){if("string"==typeof t)i._set(this,t,e);else if("object"==typeof t)for(e in t)i._set(this,e,t[e],t);return this._owner&&(this._owner._ts_pin=++s,this._owner.touch()),this},i._get=function(t,e){return"undefined"!=typeof(e=i._getters[e])?e.call(i._getters,t):void 0},i._set=function(t,e,n,r){"undefined"!=typeof(e=i._setters[e])&&"undefined"!=typeof n&&e.call(i._setters,t,n,r)},i._getters={alpha:function(t){return t._alpha},textureAlpha:function(t){return t._textureAlpha},width:function(t){return t._width},height:function(t){return t._height},boxWidth:function(t){return t._boxWidth},boxHeight:function(t){return t._boxHeight},scaleX:function(t){return t._scaleX},scaleY:function(t){return t._scaleY},skewX:function(t){return t._skewX},skewY:function(t){return t._skewY},rotation:function(t){return t._rotation},pivotX:function(t){return t._pivotX},pivotY:function(t){return t._pivotY},offsetX:function(t){return t._offsetX},offsetY:function(t){return t._offsetY},alignX:function(t){return t._alignX},alignY:function(t){return t._alignY},handleX:function(t){return t._handleX},handleY:function(t){return t._handleY}},i._setters={alpha:function(t,e){t._alpha=e},textureAlpha:function(t,e){t._textureAlpha=e},width:function(t,e){t._width_=e,t._width=e,t._ts_transform=++s},height:function(t,e){t._height_=e,t._height=e,t._ts_transform=++s},scale:function(t,e){t._scaleX=e,t._scaleY=e,t._ts_transform=++s},scaleX:function(t,e){t._scaleX=e,t._ts_transform=++s},scaleY:function(t,e){t._scaleY=e,t._ts_transform=++s},skew:function(t,e){t._skewX=e,t._skewY=e,t._ts_transform=++s},skewX:function(t,e){t._skewX=e,t._ts_transform=++s},skewY:function(t,e){t._skewY=e,t._ts_transform=++s},rotation:function(t,e){t._rotation=e,t._ts_transform=++s},pivot:function(t,e){t._pivotX=e,t._pivotY=e,t._pivoted=!0,t._ts_transform=++s},pivotX:function(t,e){t._pivotX=e,t._pivoted=!0,t._ts_transform=++s},pivotY:function(t,e){t._pivotY=e,t._pivoted=!0,t._ts_transform=++s},offset:function(t,e){t._offsetX=e,t._offsetY=e,t._ts_translate=++s},offsetX:function(t,e){t._offsetX=e,t._ts_translate=++s},offsetY:function(t,e){t._offsetY=e,t._ts_translate=++s},align:function(t,e){this.alignX(t,e),this.alignY(t,e)},alignX:function(t,e){t._alignX=e,t._aligned=!0,t._ts_translate=++s,this.handleX(t,e)},alignY:function(t,e){t._alignY=e,t._aligned=!0,t._ts_translate=++s,this.handleY(t,e)},handle:function(t,e){this.handleX(t,e),this.handleY(t,e)},handleX:function(t,e){t._handleX=e,t._handled=!0,t._ts_translate=++s},handleY:function(t,e){t._handleY=e,t._handled=!0,t._ts_translate=++s},resizeMode:function(t,e,i){i&&("in"==e?e="in-pad":"out"==e&&(e="out-crop"),t._scaleTo(i.resizeWidth,i.resizeHeight,e))},resizeWidth:function(t,e,i){i&&i.resizeMode||t._scaleTo(e,null)},resizeHeight:function(t,e,i){i&&i.resizeMode||t._scaleTo(null,e)},scaleMode:function(t,e,i){i&&t._scaleTo(i.scaleWidth,i.scaleHeight,e)},scaleWidth:function(t,e,i){i&&i.scaleMode||t._scaleTo(e,null)},scaleHeight:function(t,e,i){i&&i.scaleMode||t._scaleTo(null,e)},matrix:function(t,e){this.scaleX(t,e.a),this.skewX(t,e.c/e.d),this.skewY(t,e.b/e.a),this.scaleY(t,e.d),this.offsetX(t,e.e),this.offsetY(t,e.f),this.rotation(t,0)}},i.prototype._scaleTo=function(t,e,i){var n="number"==typeof t,r="number"==typeof e,o="string"==typeof i,h=this;h._ts_transform=++s,n&&(h._scaleX=t/h._width_,h._width=h._width_),r&&(h._scaleY=e/h._height_,h._height=h._height_),n&&r&&o&&("out"==i||"out-crop"==i?h._scaleX=h._scaleY=Math.max(h._scaleX,h._scaleY):("in"==i||"in-pad"==i)&&(h._scaleX=h._scaleY=Math.min(h._scaleX,h._scaleY)),("out-crop"==i||"in-pad"==i)&&(h._width=t/h._scaleX,h._height=e/h._scaleY))},e.exports=i},{"./core":4,"./matrix":9}],13:[function(t,e){function i(t,e){"object"==typeof t&&this.src(t,e)}var n=t("./util/stats"),r=t("./util/math");i.prototype.pipe=function(){return new i(this)},i.prototype.src=function(t,e,i,n){if("object"==typeof t){var r=t,s=e||1;this._image=r,this._sx=this._dx=0,this._sy=this._dy=0,this._sw=this._dw=r.width/s,this._sh=this._dh=r.height/s,this.width=r.width/s,this.height=r.height/s,this.ratio=s}else"undefined"==typeof i?(i=t,n=e):(this._sx=t,this._sy=e),this._sw=this._dw=i,this._sh=this._dh=n,this.width=i,this.height=n;return this},i.prototype.dest=function(t,e,i,n){return this._dx=t,this._dy=e,this._dx=t,this._dy=e,"undefined"!=typeof i&&(this._dw=i,this._dh=n,this.width=i,this.height=n),this},i.prototype.draw=function(t,e,i,s,o,h,a,u,f){var c=this._image;if(null!==c&&"object"==typeof c){var p=this._sx,_=this._sy,l=this._sw,d=this._sh,g=this._dx,m=this._dy,y=this._dw,v=this._dh;"undefined"!=typeof h?(e=r.limit(e,0,this._sw),s=r.limit(s,0,this._sw-e),i=r.limit(i,0,this._sh),o=r.limit(o,0,this._sh-i),p+=e,_+=i,l=s,d=o,g=h,m=a,y=u,v=f):"undefined"!=typeof s?(g=e,m=i,y=s,v=o):"undefined"!=typeof e&&(y=e,v=i);var x=this.ratio||1;p*=x,_*=x,l*=x,d*=x;try{"function"==typeof c.draw?c.draw(t,p,_,l,d,g,m,y,v):(n.draw++,t.drawImage(c,p,_,l,d,g,m,y,v))}catch(b){c._draw_failed||(console.log("Unable to draw: ",c),console.log(b),c._draw_failed=!0)}}},e.exports=i},{"./util/math":19,"./util/stats":22}],14:[function(t,e){function i(t){var e=this;this._owner=t,this._queue=[],this._next=null;var i=0;t.tick(function(n,r,s){if(e._queue.length){var o=i!=s;if(i=r,this.touch(),!o){var h=e._queue[0];if(h.time?h.time+=n:h.time=1,!(h.time<h.delay)){if(!h.start){h.start={},h.keys={};for(var a in h.end)"number"==typeof(start=t.pin(a))?(h.start[a]=start,h.keys[a]=a):"number"==typeof(startX=t.pin(a+"X"))&&"number"==typeof(startY=t.pin(a+"Y"))&&(h.start[a+"X"]=startX,h.keys[a+"X"]=a,h.start[a+"Y"]=startY,h.keys[a+"Y"]=a)}var u=(h.time-h.delay)/h.duration,f=u>=1;u=u>1?1:u,u="function"==typeof h.easing?h.easing(u):u;var c=1-u;for(var a in h.keys)t.pin(a,h.start[a]*c+h.end[h.keys[a]]*u);f&&(e._queue.shift(),h.then&&h.then.call(t))}}}},!0)}{var n=t("./easing"),r=t("./core");t("./pin")}r.prototype.tween=function(t,e){return this._tween||(this._tween=new i(this)),this._tween.tween(t,e)};var s=0;i.prototype.tween=function(t,e){return this._next={id:++s,end:{},duration:t||400,delay:e||0},this},i.prototype.pin=function(t,e){this._next!==this._queue[this._queue.length-1]&&(this._owner.touch(),this._queue.push(this._next));var i=this._next.end;if("object"==typeof t)for(var n in t)i[n]=t[n];else"undefined"!=typeof e&&(i[t]=e);return this},i.prototype.clear=function(t){for(var e;e=this._queue.shift();)t&&this._owner.pin(e.end);return this},i.prototype.then=function(t){return this._next.then=t,this},i.prototype.ease=function(t){return this._next.easing=n(t),this},e.exports=i},{"./core":4,"./easing":5,"./pin":12}],15:[function(t){function e(t,i){e._super.call(this),this.label("Root"),this._paused=!0;var n=this,r=0,s=function(t){if(n._paused!==!0){o.tick=o.node=o.draw=0;var e=r||t,s=t-e;r=t;var h=n._tick(s,t,e);n._mo_touch!=n._ts_touch?(n._mo_touch=n._ts_touch,i.call(n),n.request()):h?n.request():n.pause(),o.fps=s?1e3/s:0}};this.request=function(){t(s)}}function i(){i._super.call(this),this.label("Image"),this._textures=[],this._image=null}function n(){n._super.call(this),this.label("Anim"),this._textures=[],this._fps=n.FPS,this._ft=1e3/this._fps,this._time=-1,this._repeat=0,this._index=0,this._frames=[];var t=0;this.tick(function(e,i,n){if(!(this._time<0||this._frames.length<=1)){var r=t!=n;if(t=i,r)return!0;if(this._time+=e,this._time<this._ft)return!0;var s=this._time/this._ft|0;return this._time-=s*this._ft,this.moveFrame(s),this._repeat>0&&(this._repeat-=s)<=0?(this.stop(),this._callback&&this._callback(),!1):!0}},!1)}function r(){r._super.call(this),this.label("String"),this._textures=[]}var s=t("./core"),o=(t("./pin"),t("./util/stats")),h=t("./util/repeat"),a=t("./util/create"),u=t("./util/extend"),f=t("./util/math"),c=t("./util/is");s.prototype._textures=null,s.prototype._tickBefore=null,s.prototype._tickAfter=null,s.prototype._alpha=1,s.prototype.render=function(t){if(this._visible){o.node++;var e=this.matrix();t.setTransform(e.a,e.b,e.c,e.d,e.e,e.f),this._alpha=this._pin._alpha*(this._parent?this._parent._alpha:1);var i=this._pin._textureAlpha*this._alpha;if(t.globalAlpha!=i&&(t.globalAlpha=i),null!==this._textures)for(var n=0,r=this._textures.length;r>n;n++)this._textures[n].draw(t);t.globalAlpha!=this._alpha&&(t.globalAlpha=this._alpha);for(var s,h=this._first;s=h;)h=s._next,s.render(t)}},s.prototype.MAX_ELAPSE=1/0,s.prototype._tick=function(t,e,i){if(this._visible){t>this.MAX_ELAPSE&&(t=this.MAX_ELAPSE);var n=!1;if(null!==this._tickBefore)for(var r=0,s=this._tickBefore.length;s>r;r++)o.tick++,n=this._tickBefore[r].call(this,t,e,i)===!0||n;for(var h,a=this._first;h=a;)a=h._next,h._flag("_tick")&&(n=h._tick(t,e,i)===!0?!0:n);
-if(null!==this._tickAfter)for(var r=0,s=this._tickAfter.length;s>r;r++)o.tick++,n=this._tickAfter[r].call(this,t,e,i)===!0||n;return n}},s.prototype.tick=function(t,e){"function"==typeof t&&(e?(null===this._tickBefore&&(this._tickBefore=[]),this._tickBefore.push(t)):(null===this._tickAfter&&(this._tickAfter=[]),this._tickAfter.push(t)),this._flag("_tick",null!==this._tickAfter&&this._tickAfter.length>0||null!==this._tickBefore&&this._tickBefore.length>0))},s.prototype.untick=function(t){if("function"==typeof t){var e;null!==this._tickBefore&&(e=this._tickBefore.indexOf(t))>=0&&this._tickBefore.splice(e,1),null!==this._tickAfter&&(e=this._tickAfter.indexOf(t))>=0&&this._tickAfter.splice(e,1)}},e._super=s,e.prototype=a(e._super.prototype),s.root=function(t,i){return new e(t,i)},e.prototype.start=function(){return this.resume()},e.prototype.resume=function(t){return(this._paused||t)&&(this._paused=!1,this.request()),this},e.prototype.pause=function(){return this._paused=!0,this},e.prototype.touch=function(){return this.resume(),e._super.prototype.touch.call(this)},e.prototype.background=function(){return this},e.prototype.viewport=function(t,e,i){if("undefined"==typeof t)return u({},this._viewport);this._viewport={width:t,height:e,ratio:i||1},this._updateViewbox();var n=u({},this._viewport);return this.visit({start:function(t){return t._flag("viewport")?void t.publish("viewport",[n]):!0}}),this},e.prototype.viewbox=function(t,e,i){return this._viewbox={width:t,height:e,mode:/^(in|out|in-pad|out-crop)$/.test(i)?i:"in-pad"},this._updateViewbox(),this},e.prototype._updateViewbox=function(){var t=this._viewbox,e=this._viewport;e&&t?(this.pin({width:t.width,height:t.height}),this._pin._scaleTo(e.width,e.height,t.mode)):e&&this.pin({width:e.width,height:e.height})},s.image=function(t){var e=new i;return t&&e.image(t),e},i._super=s,i.prototype=a(i._super.prototype),i.prototype.setImage=function(t,e,i){return this.image(t,e,i)},i.prototype.image=function(t){return this._image=s.texture(t).one(),this.pin("width",this._image?this._image.width:0),this.pin("height",this._image?this._image.height:0),this._textures[0]=this._image.pipe(),this._textures.length=1,this},i.prototype.tile=function(t){return this._repeat(!1,t),this},i.prototype.stretch=function(t){return this._repeat(!0,t),this},i.prototype._repeat=function(t,e){function i(t,e,i,r,s,o,h,a,u){var f=n._textures.length>t?n._textures[t]:n._textures[t]=n._image.pipe();f.src(e,i,r,s),f.dest(o,h,a,u)}var n=this;this.untick(this._repeatTicker),this.tick(this._repeatTicker=function(){if(this._mo_stretch!=this._pin._ts_transform){this._mo_stretch=this._pin._ts_transform;var n=this.pin("width"),r=this.pin("height");this._textures.length=h(this._image,n,r,t,e,i)}})},s.anim=function(t,e){var i=new n;return i.frames(t).gotoFrame(0),e&&i.fps(e),i},n._super=s,n.prototype=a(n._super.prototype),n.FPS=12,n.prototype.fps=function(t){return"undefined"==typeof t?this._fps:(this._fps=t>0?t:s.Anim.FPS,this._ft=1e3/this._fps,this)},n.prototype.setFrames=function(t,e,i){return this.frames(t,e,i)},n.prototype.frames=function(t){return this._index=0,this._frames=s.texture(t).array(),this.touch(),this},n.prototype.length=function(){return this._frames?this._frames.length:0},n.prototype.gotoFrame=function(t,e){return this._index=0|f.rotate(t,this._frames.length),e=e||!this._textures[0],this._textures[0]=this._frames[this._index],e&&(this.pin("width",this._textures[0].width),this.pin("height",this._textures[0].height)),this.touch(),this},n.prototype.moveFrame=function(t){return this.gotoFrame(this._index+t)},n.prototype.repeat=function(t,e){return this._repeat=t*this._frames.length-1,this._callback=e,this.play(),this},n.prototype.play=function(t){return"undefined"!=typeof t?(this.gotoFrame(t),this._time=0):this._time<0&&(this._time=0),this.touch(),this},n.prototype.stop=function(t){return this._time=-1,"undefined"!=typeof t&&this.gotoFrame(t),this},s.string=function(t){return(new r).frames(t)},r._super=s,r.prototype=a(r._super.prototype),r.prototype.setFont=function(t,e,i){return this.frames(t,e,i)},r.prototype.frames=function(t){return this._textures=[],"string"==typeof t?(t=s.texture(t),this._item=function(e){return t.one(e)}):"object"==typeof t?this._item=function(e){return t[e]}:"function"==typeof t&&(this._item=t),this},r.prototype.setValue=function(t,e,i){return this.value(t,e,i)},r.prototype.value=function(t){if("undefined"==typeof t)return this._value;if(this._value===t)return this;this._value=t,null===t?t="":"string"==typeof t||c.array(t)||(t=t.toString()),this._spacing=this._spacing||0;for(var e=0,i=0,n=0;n<t.length;n++){var r=this._textures[n]=this._item(t[n]);e+=n>0?this._spacing:0,r.dest(e,0),e+=r.width,i=Math.max(i,r.height)}return this.pin("width",e),this.pin("height",i),this._textures.length=t.length,this},s.row=function(t){return s.create().row(t)},s.prototype.row=function(t){return this.sequence("row",t),this},s.column=function(t){return s.create().column(t)},s.prototype.column=function(t){return this.sequence("column",t),this},s.sequence=function(t,e){return s.create().sequence(t,e)},s.prototype.sequence=function(t,e){return this._padding=this._padding||0,this._spacing=this._spacing||0,this.untick(this._sequenceTicker),this.tick(this._sequenceTicker=function(){if(this._mo_seq!=this._ts_touch){this._mo_seq=this._ts_touch;var i=this._mo_seqAlign!=this._ts_children;this._mo_seqAlign=this._ts_children;for(var n,r=0,s=0,o=this.first(!0),h=!0;n=o;){o=n.next(!0),n._pin.relativeMatrix();var a=n.pin("boxWidth"),u=n.pin("boxHeight");"column"==t?(!h&&(s+=this._spacing),n.pin("offsetY")!=s&&n.pin("offsetY",s),r=Math.max(r,a),s+=u,i&&n.pin("alignX",e)):"row"==t&&(!h&&(r+=this._spacing),n.pin("offsetX")!=r&&n.pin("offsetX",r),r+=a,s=Math.max(s,u),i&&n.pin("alignY",e)),h=!1}r+=2*this._padding,s+=2*this._padding,this.pin("width")!=r&&this.pin("width",r),this.pin("height")!=s&&this.pin("height",s)}}),this},s.box=function(){return s.create().box()},s.prototype.box=function(){return this._boxTicker?this:(this._padding=this._padding||0,this.tick(this._boxTicker=function(){if(this._mo_box!=this._ts_touch){this._mo_box=this._ts_touch;for(var t,e=0,i=0,n=this.first(!0);t=n;){n=t.next(!0),t._pin.relativeMatrix();var r=t.pin("boxWidth"),s=t.pin("boxHeight");e=Math.max(e,r),i=Math.max(i,s)}e+=2*this._padding,i+=2*this._padding,this.pin("width")!=e&&this.pin("width",e),this.pin("height")!=i&&this.pin("height",i)}}),this)},s.prototype.padding=function(t){return this._padding=t,this},s.prototype.spacing=function(t){return this._spacing=t,this}},{"./core":4,"./pin":12,"./util/create":16,"./util/extend":17,"./util/is":18,"./util/math":19,"./util/repeat":21,"./util/stats":22}],16:[function(t,e){function i(){}e.exports="function"==typeof Object.create?function(t,e){return Object.create.call(Object,t,e)}:function(t,e){if(e)throw Error("Second argument is not supported!");if("object"!=typeof t||null===t)throw Error("Invalid prototype!");return i.prototype=t,new i}},{}],17:[function(t,e){e.exports=function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var n in i)i.hasOwnProperty(n)&&(t[n]=i[n])}return t}},{}],18:[function(t,e){var i=Object.prototype,n=i.hasOwnProperty,r=i.toString,s=/^[A-Fa-f0-9]+$/,o=e.exports={};o.a=o.an=o.type=function(t,e){return typeof t===e},o.defined=function(t){return"undefined"!=typeof t},o.empty=function(t){var e,i=r.call(t);if("[object Array]"===i||"[object Arguments]"===i||"[object String]"===i)return 0===t.length;if("[object Object]"===i){for(e in t)if(n.call(t,e))return!1;return!0}return!t},o.equal=function(t,e){if(t===e)return!0;var i,n=r.call(t);if(n!==r.call(e))return!1;if("[object Object]"===n){for(i in t)if(!(o.equal(t[i],e[i])&&i in e))return!1;for(i in e)if(!(o.equal(t[i],e[i])&&i in t))return!1;return!0}if("[object Array]"===n){if(i=t.length,i!==e.length)return!1;for(;--i;)if(!o.equal(t[i],e[i]))return!1;return!0}return"[object Function]"===n?t.prototype===e.prototype:"[object Date]"===n?t.getTime()===e.getTime():!1},o.instance=function(t,e){return t instanceof e},o.nil=function(t){return null===t},o.undef=function(t){return"undefined"==typeof t},o.array=function(t){return"[object Array]"===r.call(t)},o.emptyarray=function(t){return o.array(t)&&0===t.length},o.arraylike=function(t){return!!t&&!o["boolean"](t)&&n.call(t,"length")&&isFinite(t.length)&&o.number(t.length)&&t.length>=0},o["boolean"]=function(t){return"[object Boolean]"===r.call(t)},o.element=function(t){return void 0!==t&&"undefined"!=typeof HTMLElement&&t instanceof HTMLElement&&1===t.nodeType},o.fn=function(t){return"[object Function]"===r.call(t)},o.number=function(t){return"[object Number]"===r.call(t)},o.nan=function(t){return!o.number(t)||t!==t},o.object=function(t){return"[object Object]"===r.call(t)},o.hash=function(t){return o.object(t)&&t.constructor===Object&&!t.nodeType&&!t.setInterval},o.regexp=function(t){return"[object RegExp]"===r.call(t)},o.string=function(t){return"[object String]"===r.call(t)},o.hex=function(t){return o.string(t)&&(!t.length||s.test(t))}},{}],19:[function(t,e){e.exports.random=function(t,e){return"undefined"==typeof t?(e=1,t=0):"undefined"==typeof e&&(e=t,t=0),t==e?t:Math.random()*(e-t)+t},e.exports.rotate=function(t,e,i){return"undefined"==typeof e?(i=1,e=0):"undefined"==typeof i&&(i=e,e=0),i>e?(t=(t-e)%(i-e),t+(0>t?i:e)):(t=(t-i)%(e-i),t+(0>=t?e:i))},e.exports.limit=function(t,e,i){return e>t?e:t>i?i:t},e.exports.length=function(t,e){return Math.sqrt(t*t+e*e)}},{}],20:[function(t,e){e.exports=function(t,e){var i=!1;return function(){i||(i=!0,t.apply(e,arguments))}}},{}],21:[function(t,e){e.exports=function(t,e,i,n,r,s){var o=t.width,h=t.height,a=t.left,u=t.right,f=t.top,c=t.bottom;a="number"==typeof a&&a===a?a:0,u="number"==typeof u&&u===u?u:0,f="number"==typeof f&&f===f?f:0,c="number"==typeof c&&c===c?c:0,o=o-a-u,h=h-f-c,r||(e=Math.max(e-a-u,0),i=Math.max(i-f-c,0));var p=0;if(f>0&&a>0&&s(p++,0,0,a,f,0,0,a,f),c>0&&a>0&&s(p++,0,h+f,a,c,0,i+f,a,c),f>0&&u>0&&s(p++,o+a,0,u,f,e+a,0,u,f),c>0&&u>0&&s(p++,o+a,h+f,u,c,e+a,i+f,u,c),n)f>0&&s(p++,a,0,o,f,a,0,e,f),c>0&&s(p++,a,h+f,o,c,a,i+f,e,c),a>0&&s(p++,0,f,a,h,0,f,a,i),u>0&&s(p++,o+a,f,u,h,e+a,f,u,i),s(p++,a,f,o,h,a,f,e,i);else for(var _,l=a,d=e;d>0;){_=Math.min(o,d),d-=o;for(var g,m=f,y=i;y>0;)g=Math.min(h,y),y-=h,s(p++,a,f,_,g,l,m,_,g),0>=d&&(a&&s(p++,0,f,a,g,0,m,a,g),u&&s(p++,o+a,f,u,g,l+_,m,u,g)),m+=g;f&&s(p++,a,0,_,f,l,0,_,f),c&&s(p++,a,h+f,_,c,l,m,_,c),l+=_}return p}},{}],22:[function(t,e){e.exports={}},{}],23:[function(t,e){e.exports.startsWith=function(t,e){return"string"==typeof t&&"string"==typeof e&&t.substring(0,e.length)==e}},{}]},{},[1])(1)});
\ No newline at end of file
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;"undefined"!=typeof window?e=window:"undefined"!=typeof global?e=global:"undefined"!=typeof self&&(e=self),e.Cut=t()}}(function(){return function t(e,i,n){function r(o,h){if(!i[o]){if(!e[o]){var a="function"==typeof require&&require;if(!h&&a)return a(o,!0);if(s)return s(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var f=i[o]={exports:{}};e[o][0].call(f.exports,function(t){var i=e[o][1][t];return r(i?i:t)},f,f.exports,t,e,i,n)}return i[o].exports}for(var s="function"==typeof require&&require,o=0;o<n.length;o++)r(n[o]);return r}({1:[function(t,e){e.exports=t("../lib/"),t("../lib/canvas"),t("../lib/image"),t("../lib/anim"),t("../lib/str"),t("../lib/layout"),t("../lib/addon/tween"),e.exports.Mouse=t("../lib/addon/mouse"),e.exports.Math=t("../lib/util/math"),e.exports._extend=t("../lib/util/extend"),e.exports._create=t("../lib/util/create"),t("../lib/loader/cordova")},{"../lib/":11,"../lib/addon/mouse":3,"../lib/addon/tween":4,"../lib/anim":5,"../lib/canvas":7,"../lib/image":10,"../lib/layout":12,"../lib/loader/cordova":13,"../lib/str":19,"../lib/util/create":21,"../lib/util/extend":22,"../lib/util/math":24}],2:[function(t,e){function i(t){return t}function n(t){if("function"==typeof t)return t;if("string"!=typeof t)return i;var e=r[t];if(e)return e;var n=/^(\w+)(-(in|out|in-out|out-in))?(\((.*)\))?$/i.exec(t);return n&&n.length?(easing=o[n[1]],mode=s[n[3]],params=n[5],e=easing&&easing.fn?easing.fn:easing&&easing.fc?easing.fc.apply(easing.fc,params&&params.replace(/\s+/,"").split(",")):i,mode&&(e=mode.fn(e)),r[t]=e,e):i}var r={},s={},o={};n.add=function(t){for(var e=(t.name||t.mode).split(/\s+/),i=0;i<e.length;i++){var n=e[i];n&&((t.name?o:s)[n]=t)}},n.add({mode:"in",fn:function(t){return t}}),n.add({mode:"out",fn:function(t){return function(e){return 1-t(1-e)}}}),n.add({mode:"in-out",fn:function(t){return function(e){return.5>e?t(2*e)/2:1-t(2*(1-e))/2}}}),n.add({mode:"out-in",fn:function(t){return function(e){return.5>e?1-t(2*(1-e))/2:t(2*e)/2}}}),n.add({name:"linear",fn:function(t){return t}}),n.add({name:"quad",fn:function(t){return t*t}}),n.add({name:"cubic",fn:function(t){return t*t*t}}),n.add({name:"quart",fn:function(t){return t*t*t*t}}),n.add({name:"quint",fn:function(t){return t*t*t*t*t}}),n.add({name:"sin sine",fn:function(t){return 1-Math.cos(t*Math.PI/2)}}),n.add({name:"exp",fn:function(t){return 0==t?0:Math.pow(2,10*(t-1))}}),n.add({name:"circle circ",fn:function(t){return 1-Math.sqrt(1-t*t)}}),n.add({name:"bounce",fn:function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}}),n.add({name:"poly",fc:function(t){return function(e){return Math.pow(e,t)}}}),n.add({name:"elastic",fc:function(t,e){e=e||.45,t=t||1;var i=e/(2*Math.PI)*Math.asin(1/t);return function(n){return 1+t*Math.pow(2,-10*n)*Math.sin(2*(n-i)*Math.PI/e)}}}),n.add({name:"back",fc:function(t){return t="undefined"!=typeof t?t:1.70158,function(e){return e*e*((t+1)*e-t)}}}),e.exports=n},{}],3:[function(t,e){function i(){i.subscribe.apply(i,arguments)}"undefined"==typeof DEBUG&&(DEBUG=!0),i.CLICK="click",i.START="touchstart mousedown",i.MOVE="touchmove mousemove",i.END="touchend mouseup",i.CANCEL="touchcancel",i.subscribe=function(t,e){function n(n){i._xy(t,e,n,p),DEBUG&&console.log("Mouse Start: "+n.type+" "+p),n.preventDefault(),u(n.type,n),h()}function r(t){DEBUG&&console.log("Mouse End: "+t.type+" "+p),t.preventDefault(),u(t.type,t),l.length&&(DEBUG&&console.log("Mouse Click: "+l.length),a(t))}function s(t){DEBUG&&console.log("Mouse Cancel: "+t.type),t.preventDefault(),u(t.type,t)}function o(n){i._xy(t,e,n,p),t._flag(n.type)&&(n.preventDefault(),u(n.type,n))}function h(){for(;l.length;)l.pop();u("click",null,l)}function a(e){c.event=e,c.type="click",c.root=t,c.collect=!1;for(var i=!1;l.length;){var n=l.shift();i||(i=f.end(n,c)?!0:i)}}function u(e,i,n){_.x=p.x,_.y=p.y,c.event=i,c.type=e,c.root=t,c.collect=n,c.root.visit(f,c)}var f=null,c={},p=null,_=null,l=[];e=e||document,e.addEventListener("touchstart",n),e.addEventListener("touchend",r),e.addEventListener("touchmove",o),e.addEventListener("touchcancel",s),e.addEventListener("mousedown",n),e.addEventListener("mouseup",r),e.addEventListener("mousemove",o),f={reverse:!0,visible:!0,start:function(t,e){return!t._flag(e.type)},end:function(t,e){_.raw=e.event,_.type=e.type;var n=t.listeners(e.type);if(n&&(t.matrix().reverse().map(p,_),t===e.root||t.attr("spy")||i._isInside(t,_))){if(e.collect)return void e.collect.push(t);for(var r=!1,s=0;s<n.length;s++)r=n[s].call(t,_)?!0:r;return r}}},p={x:0,y:0,toString:function(){return(0|this.x)+"x"+(0|this.y)}},_={x:0,y:0,toString:function(){return p+" / "+(0|this.x)+"x"+(0|this.y)}}},i._isInside=function(t,e){return e.x>=0&&e.x<=t._pin._width&&e.y>=0&&e.y<=t._pin._height},i._xy=function(t,e,i,n){var r=!1;if(i.touches){if(!i.touches.length)return;r=!0,n.x=i.touches[0].pageX,n.y=i.touches[0].pageY}else n.x=i.clientX,n.y=i.clientY,document.body.scrollLeft||document.body.scrollTop||document.documentElement&&(n.x+=document.documentElement.scrollLeft,n.y+=document.documentElement.scrollTop);n.x-=e.clientLeft||0,n.y-=e.clientTop||0;for(var s=e;s;)n.x-=s.offsetLeft||0,n.y-=s.offsetTop||0,r||(n.x+=s.scrollLeft||0,n.y+=s.scrollTop||0),s=s.offsetParent;n.x*=t.viewport().ratio||1,n.y*=t.viewport().ratio||1},e.exports=i},{}],4:[function(t,e){function i(t){var e=this;this._owner=t,this._queue=[],this._next=null;var i=0;t.tick(function(n,r,s){if(e._queue.length){var o=i!=s;if(i=r,this.touch(),!o){var h=e._queue[0];if(h.time?h.time+=n:h.time=1,!(h.time<h.delay)){if(!h.start){h.start={},h.keys={};for(var a in h.end)"number"==typeof(start=t.pin(a))?(h.start[a]=start,h.keys[a]=a):"number"==typeof(startX=t.pin(a+"X"))&&"number"==typeof(startY=t.pin(a+"Y"))&&(h.start[a+"X"]=startX,h.keys[a+"X"]=a,h.start[a+"Y"]=startY,h.keys[a+"Y"]=a)}var u=(h.time-h.delay)/h.duration,f=u>=1;u=u>1?1:u,u="function"==typeof h.easing?h.easing(u):u;var c=1-u;for(var a in h.keys)t.pin(a,h.start[a]*c+h.end[h.keys[a]]*u);f&&(e._queue.shift(),h.then&&h.then.call(t))}}}},!0)}{var n=t("./easing"),r=t("../core");t("../pin")}r.prototype.tween=function(t,e){return this._tween||(this._tween=new i(this)),this._tween.tween(t,e)};var s=0;i.prototype.tween=function(t,e){return this._next={id:++s,end:{},duration:t||400,delay:e||0},this},i.prototype.pin=function(t,e){this._next!==this._queue[this._queue.length-1]&&(this._owner.touch(),this._queue.push(this._next));var i=this._next.end;if("object"==typeof t)for(var n in t)i[n]=t[n];else"undefined"!=typeof e&&(i[t]=e);return this},i.prototype.clear=function(t){for(var e;e=this._queue.shift();)t&&this._owner.pin(e.end);return this},i.prototype.then=function(t){return this._next.then=t,this},i.prototype.ease=function(t){return this._next.easing=n(t),this},e.exports=i},{"../core":8,"../pin":16,"./easing":2}],5:[function(t){function e(){e._super.call(this),this.label("Anim"),this._textures=[],this._fps=i.Anim.FPS,this._ft=1e3/this._fps,this._time=-1,this._repeat=0,this._index=0,this._frames=[];var t=0;this.tick(function(e,i,n){if(!(this._time<0||this._frames.length<=1)){var r=t!=n;if(t=i,r)return!0;if(this._time+=e,this._time<this._ft)return!0;var s=this._time/this._ft|0;return this._time-=s*this._ft,this.moveFrame(s),this._repeat>0&&(this._repeat-=s)<=0?(this.stop(),this._callback&&this._callback(),!1):!0}},!1)}var i=t("./core");t("./pin"),t("./render");var n=t("./util/create"),r=t("./util/math");i.anim=function(t,i){var n=new e;return n.frames(t).gotoFrame(0),i&&n.fps(i),n},e._super=i,e.prototype=n(e._super.prototype),i.Anim={FPS:15},e.prototype.fps=function(t){return"undefined"==typeof t?this._fps:(this._fps=t>0?t:i.Anim.FPS,this._ft=1e3/this._fps,this)},e.prototype.setFrames=function(t,e,i){return this.frames(t,e,i)},e.prototype.frames=function(t){return this._index=0,this._frames=i.texture(t).array(),this.touch(),this},e.prototype.length=function(){return this._frames?this._frames.length:0},e.prototype.gotoFrame=function(t,e){return this._index=0|r.rotate(t,this._frames.length),e=e||!this._textures[0],this._textures[0]=this._frames[this._index],e&&(this.pin("width",this._textures[0].width),this.pin("height",this._textures[0].height)),this.touch(),this},e.prototype.moveFrame=function(t){return this.gotoFrame(this._index+t)},e.prototype.repeat=function(t,e){return this._repeat=t*this._frames.length-1,this._callback=e,this.play(),this},e.prototype.play=function(t){return"undefined"!=typeof t?(this.gotoFrame(t),this._time=0):this._time<0&&(this._time=0),this.touch(),this},e.prototype.stop=function(t){return this._time=-1,"undefined"!=typeof t&&this.gotoFrame(t),this}},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/math":24}],6:[function(t,e){function i(t){function e(t){if(!t||u.fn(t.draw))return t;t=h({},t),u.fn(a)&&(t=a(t)),1!=c&&(t.x*=c,t.y*=c,t.width*=c,t.height*=c,t.top*=c,t.bottom*=c,t.left*=c,t.right*=c),0!=p&&(t.x+=p,t.y+=p,t.width-=2*p,t.height-=2*p,t.top-=p,t.bottom-=p,t.left-=p,t.right-=p);var e=o.pipe();return e.top=t.top,e.bottom=t.bottom,e.left=t.left,e.right=t.right,e.src(t.x,t.y,t.width,t.height),e}function s(t){if(_){if(u.fn(_))return _(t);if(u.hash(_))return _[t]}if(d){for(var e=null,i=0,n=0;n<d.length;n++)f.startsWith(d[n].name,t)&&(0===i?e=d[n]:1===i?e=[e,d[n]]:e.push(d[n]),i++);return 0===i&&u.fn(l)&&(e=function(e){return l(t+(e?e:""))}),e}}i._super.call(this);var o=this;r(t,"filter"),r(t,"cutouts"),r(t,"sprites"),r(t,"factory");var a=t.map||t.filter,c=t.ppu||t.ratio||1,p=t.trim||0,_=t.textures,l=t.factory,d=t.cutouts||t.sprites;this.select=function(t){var i=s(t);return i?new n(i,s,e):void 0}}function n(t,e,i){function n(t,r){return t?u.fn(t.draw)?t:u.hash(t)&&u.number(t.width)&&u.number(t.height)&&u.fn(i)?i(t):u.hash(t)&&u.defined(r)?n(t[r]):u.fn(t)?n(t(r)):u.array(t)?n(t[0]):u.string(t)&&u.fn(e)?n(e(t)):void 0:_}this.one=function(e){return n(t,e)},this.array=function(e){var i=u.array(e)?e:[];if(u.array(t))for(var r=0;r<t.length;r++)i[r]=n(t[r]);else i[0]=n(t);return i}}function r(t,e,i){e in t&&console.log(i?i.replace("%name",e):"'"+e+"' field of texture atlas is deprecated.")}var s=t("./core"),o=t("./texture"),h=t("./util/extend"),a=t("./util/create"),u=t("./util/is"),f=t("./util/string"),c={},p=[];s.atlas=function(t){var e=u.fn(t.draw)?t:new i(t);t.name&&(c[t.name]=e),p.push(e),r(t,"imagePath"),r(t,"imageRatio");var n=t.imagePath,o=t.imageRatio||1;return u.string(t.image)?n=t.image:u.hash(t.image)&&(n=t.image.url,o=t.image.ratio||o),n&&s.preload(function(t){DEBUG&&console.log("Loading image: "+n);var i=s.config("image-loader");i(n,function(i){DEBUG&&console.log("Image loaded: "+n),e.src(i,o),t()},function(e){DEBUG&&console.log("Error loading image: "+n,e),t()})}),e},i._super=o,i.prototype=a(i._super.prototype);var _=new o;_.x=_.y=_.width=_.height=0,_.pipe=_.src=_.dest=function(){return this},_.draw=function(){};var l=new n(_);s.texture=function(t){if(!u.string(t))return new n(t);var e=null,i=t.indexOf(":");if(i>0&&t.length>i+1){var r=c[t.slice(0,i)];e=r&&r.select(t.slice(i+1))}for(var i=0;!e&&i<p.length;i++)e=p[i].select(t);return e||(console.error("Texture not found: "+t),e=l),e},e.exports=i},{"./core":8,"./texture":20,"./util/create":21,"./util/extend":22,"./util/is":23,"./util/string":28}],7:[function(t){var e=t("./core"),i=t("./texture");e.canvas=function(t,e,n){"string"==typeof t?"object"==typeof e||("function"==typeof e&&(n=e),e={}):("function"==typeof t&&(n=t),e={},t="2d");var r=document.createElement("canvas"),s=r.getContext(t,e),o=new i(r);return o.context=function(){return s},o.size=function(t,e,i){return r.width=t*i,r.height=e*i,this.src(r,i),this},o.canvas=function(t){return"function"==typeof t?t.call(this,s):"undefined"==typeof t&&"function"==typeof n&&n.call(this,s),this},"function"==typeof n&&n.call(o,s),o}},{"./core":8,"./texture":20}],8:[function(t,e){function i(t){if(!(this instanceof i))return o.fn(t)?i.app.apply(i,arguments):o.object(t)?i.atlas.apply(i,arguments):t;n.create++;for(var e=0;e<h.length;e++)h[e].call(this)}"undefined"==typeof DEBUG&&(DEBUG=!0);var n=t("./util/stats"),r=t("./util/extend"),s=t("./util/once"),o=t("./util/is");n.create=0;var h=[];i._init=function(t){h.push(t)};var a={};i.config=function(){return 1===arguments.length&&o.string(arguments[0])?a[arguments[0]]:(1===arguments.length&&o.object(arguments[0])&&r(a,arguments[0]),void(2===arguments.length&&o.string(arguments[0])&&a[(arguments[0],arguments[1])]))};var u=[],f=[],c=[],p=!1,_=!1;i.app=function(t,e){if(!p)return void u.push(arguments);DEBUG&&console.log("Creating app...");var n=i.config("app-loader");n(function(e,i){DEBUG&&console.log("Initing app..."),t(e,i),c.push(e),DEBUG&&console.log("Starting app..."),e.start()},e)},i.preload=function(t){return p?void t(function(){}):void f.push(t)},i.start=function(t){function e(){if(--n<=0)for(DEBUG&&console.log("Loading apps..."),p=!0;u.length;){var t=u.shift();i.app.apply(i,t)}}DEBUG&&console.log("Starting..."),i.config(t),DEBUG&&console.log("Preloading...");var n=0;if(f.length)for(;f.length;){var r=f.shift();r(s(e)),n++}else e()},i.pause=function(){if(!_){_=!0;for(var t=c.length-1;t>=0;t--)c[t].pause()}},i.resume=function(){if(_){_=!1;for(var t=c.length-1;t>=0;t--)c[t].resume()}},i.create=function(){return new i},e.exports=i},{"./util/extend":22,"./util/is":23,"./util/once":25,"./util/stats":27}],9:[function(t){function e(t,e,i,r){if(!e||!e.length||"function"!=typeof i)return!1;if(!(e=(n.array(e)?e.join(" "):e).match(/\S+/g)))return!1;if(null===t._listeners){if(!r)return!1;t._listeners={}}return e}var i=t("./core"),n=t("./util/is");i.prototype._listeners=null,i.prototype.on=i.prototype.listen=function(t,i){if(t=e(this,t,i,!0))for(var n=0;n<t.length;n++){var r=t[n];this._listeners[r]=this._listeners[r]||[],this._listeners[r].push(i),this._flag(r,!0)}return this},i.prototype.off=function(t,i){if(t=e(this,t,i,!1))for(var n=0;n<t.length;n++){var r,s=t[n],o=this._listeners[s];o&&(r=o.indexOf(i))>=0&&(o.splice(r,1),o.length||delete this._listeners[s],this._flag(s,!1))}return this},i.prototype.listeners=function(t){return this._listeners&&this._listeners[t]},i.prototype.publish=function(t,e){var i=this.listeners(t);if(!i||!i.length)return 0;for(var n=0;n<i.length;n++)i[n].apply(this,e);return i.length},i.prototype.trigger=function(t,e){return this.publish(t,e),this}},{"./core":8,"./util/is":23}],10:[function(t){function e(){e._super.call(this),this.label("Image"),this._textures=[],this._image=null}var i=t("./core");t("./pin"),t("./render");var n=t("./util/repeat"),r=t("./util/create");i.image=function(t){var i=new e;return t&&i.image(t),i},e._super=i,e.prototype=r(e._super.prototype),e.prototype.setImage=function(t,e,i){return this.image(t,e,i)},e.prototype.image=function(t){return this._image=i.texture(t).one(),this.pin("width",this._image?this._image.width:0),this.pin("height",this._image?this._image.height:0),this._textures[0]=this._image.pipe(),this._textures.length=1,this},e.prototype.tile=function(t){return this._repeat(!1,t),this},e.prototype.stretch=function(t){return this._repeat(!0,t),this},e.prototype._repeat=function(t,e){function i(t,e,i,n,s,o,h,a,u){var f=r._textures.length>t?r._textures[t]:r._textures[t]=r._image.pipe();f.src(e,i,n,s),f.dest(o,h,a,u)}var r=this;this.untick(this._repeatTicker),this.tick(this._repeatTicker=function(){if(this._mo_stretch!=this._pin._ts_transform){this._mo_stretch=this._pin._ts_transform;var r=this.pin("width"),s=this.pin("height");this._textures.length=n(this._image,r,s,t,e,i)}})}},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/repeat":26}],11:[function(t,e){e.exports=t("./core"),e.exports.Matrix=t("./matrix"),e.exports.Texture=t("./texture"),t("./atlas"),t("./node"),t("./event"),t("./pin"),t("./render"),t("./root")},{"./atlas":6,"./core":8,"./event":9,"./matrix":14,"./node":15,"./pin":16,"./render":17,"./root":18,"./texture":20}],12:[function(t){var e=t("./core");t("./pin"),t("./render");t("./util/create");e.row=function(t){return e.create().row(t)},e.prototype.row=function(t){return this.sequence("row",t),this},e.column=function(t){return e.create().column(t)},e.prototype.column=function(t){return this.sequence("column",t),this},e.sequence=function(t,i){return e.create().sequence(t,i)},e.prototype.sequence=function(t,e){return this._padding=this._padding||0,this._spacing=this._spacing||0,this.untick(this._sequenceTicker),this.tick(this._sequenceTicker=function(){if(this._mo_seq!=this._ts_touch){this._mo_seq=this._ts_touch;var i=this._mo_seqAlign!=this._ts_children;this._mo_seqAlign=this._ts_children;for(var n,r=0,s=0,o=this.first(!0),h=!0;n=o;){o=n.next(!0),n._pin.relativeMatrix();var a=n.pin("boxWidth"),u=n.pin("boxHeight");"column"==t?(!h&&(s+=this._spacing),n.pin("offsetY")!=s&&n.pin("offsetY",s),r=Math.max(r,a),s+=u,i&&n.pin("alignX",e)):"row"==t&&(!h&&(r+=this._spacing),n.pin("offsetX")!=r&&n.pin("offsetX",r),r+=a,s=Math.max(s,u),i&&n.pin("alignY",e)),h=!1}r+=2*this._padding,s+=2*this._padding,this.pin("width")!=r&&this.pin("width",r),this.pin("height")!=s&&this.pin("height",s)}}),this},e.box=function(){return e.create().box()},e.prototype.box=function(){return this._boxTicker?this:(this._padding=this._padding||0,this.tick(this._boxTicker=function(){if(this._mo_box!=this._ts_touch){this._mo_box=this._ts_touch;for(var t,e=0,i=0,n=this.first(!0);t=n;){n=t.next(!0),t._pin.relativeMatrix();var r=t.pin("boxWidth"),s=t.pin("boxHeight");e=Math.max(e,r),i=Math.max(i,s)}e+=2*this._padding,i+=2*this._padding,this.pin("width")!=e&&this.pin("width",e),this.pin("height")!=i&&this.pin("height",i)}}),this)},e.prototype.padding=function(t){return this._padding=t,this},e.prototype.spacing=function(t){return this._spacing=t,this}},{"./core":8,"./pin":16,"./render":17,"./util/create":21}],13:[function(t){function e(t,e){function i(){o.isFast?(o.clear(),o.setTransform(1,0,0,1,0,0)):(o.setTransform(1,0,0,1,0,0),o.clearRect(0,0,a,u)),d.render(o)}function r(){h?(a=window.innerWidth>0?window.innerWidth:screen.width,u=window.innerHeight>0?window.innerHeight:screen.height,s.style.width=a+"px",s.style.height=u+"px"):(a=s.clientWidth,u=s.clientHeight),a*=f,u*=f,(s.width!==a||s.height!==u)&&(s.width=a,s.height=u,DEBUG&&console.log("Resize: "+a+" x "+u+" / "+f),d.viewport(a,u,f),i())}e=e||{};var s=e.canvas,o=null,h=!1,a=0,u=0,f=1;if("string"==typeof s&&(s=document.getElementById(s)),s||(s=document.getElementById("cutjs")),!s){h=!0,DEBUG&&console.log("Creating Canvas..."),s=document.createElement("canvas"),s.style.position="absolute";var c=document.body;c.insertBefore(s,c.firstChild)}o=s.getContext("2d",{fastcontext:!0}),o.isFast=!!o.isFast,h=h||o.isFast,DEBUG&&console.log("FastContext: "+o.isFast);var p=window.devicePixelRatio||1,_=o.webkitBackingStorePixelRatio||o.mozBackingStorePixelRatio||o.msBackingStorePixelRatio||o.oBackingStorePixelRatio||o.backingStorePixelRatio||1;f=p/_;var l=window.requestAnimationFrame||window.msRequestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.oRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)};DEBUG&&console.log("Creating root...");var d=n.root(l,i);d.background=function(t){return o.isFast?o.setBackgroundColor&&o.setBackgroundColor(t):s.style.backgroundColor=t,this},t(d,s),r(),window.addEventListener("resize",r,!1),window.addEventListener("orientationchange",r,!1)}function i(t,e,i){function n(){e(r)}DEBUG&&console.log("Loading image: "+t);var r;FastContext?r=FastContext.createImage(t,n,i):(r=new Image,r.onload=n,r.onerror=i,r.src=t)}var n=t("../core");"undefined"==typeof DEBUG&&(DEBUG=!0),"undefined"==typeof FastContext&&(FastContext=window.FastContext),window.addEventListener("load",function(){DEBUG&&console.log("On load."),document.addEventListener("deviceready",function(){DEBUG&&console.log("On deviceready."),n.start({"app-loader":e,"image-loader":i})},!1),document.addEventListener("pause",function(){n.pause()},!1),document.addEventListener("resume",function(){n.resume()},!1)},!1)},{"../core":8}],14:[function(t,e){function i(t,e,i,n,r,s){this._dirty=!0,this.a=t||1,this.b=e||0,this.c=i||0,this.d=n||1,this.e=r||0,this.f=s||0}i.prototype.toString=function(){return"["+this.a+", "+this.b+", "+this.c+", "+this.d+", "+this.e+", "+this.f+"]"},i.prototype.clone=function(){return new i(this.a,this.b,this.c,this.d,this.e,this.f)},i.prototype.copyTo=function(t){return t.copyFrom(this),this},i.prototype.copyFrom=function(t){return this._dirty=!0,this.a=t.a,this.b=t.b,this.c=t.c,this.d=t.d,this.e=t.e,this.f=t.f,this},i.prototype.identity=function(){return this._dirty=!0,this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0,this},i.prototype.rotate=function(t){if(!t)return this;this._dirty=!0;var e=t?Math.cos(t):1,i=t?Math.sin(t):0,n=e*this.a-i*this.b,r=e*this.b+i*this.a,s=e*this.c-i*this.d,o=e*this.d+i*this.c,h=e*this.e-i*this.f,a=e*this.f+i*this.e;return this.a=n,this.b=r,this.c=s,this.d=o,this.e=h,this.f=a,this},i.prototype.translate=function(t,e){return t||e?(this._dirty=!0,this.e+=t,this.f+=e,this):this},i.prototype.scale=function(t,e){return t-1||e-1?(this._dirty=!0,this.a*=t,this.b*=e,this.c*=t,this.d*=e,this.e*=t,this.f*=e,this):this},i.prototype.skew=function(t,e){if(!t&&!e)return this;this._dirty=!0;var i=this.a+this.b*t,n=this.b+this.a*e,r=this.c+this.d*t,s=this.d+this.c*e,o=this.e+this.f*t,h=this.f+this.e*e;return this.a=i,this.b=n,this.c=r,this.d=s,this.e=o,this.f=h,this},i.prototype.concat=function(t){this._dirty=!0;var e=this,i=e.a*t.a+e.b*t.c,n=e.b*t.d+e.a*t.b,r=e.c*t.a+e.d*t.c,s=e.d*t.d+e.c*t.b,o=e.e*t.a+t.e+e.f*t.c,h=e.f*t.d+t.f+e.e*t.b;return this.a=i,this.b=n,this.c=r,this.d=s,this.e=o,this.f=h,this},i.prototype.reverse=function(){if(this._dirty){this._dirty=!1,this.reversed=this.reversed||new i;var t=this.a*this.d-this.b*this.c;this.reversed.a=this.d/t,this.reversed.b=-this.b/t,this.reversed.c=-this.c/t,this.reversed.d=this.a/t,this.reversed.e=(this.c*this.f-this.e*this.d)/t,this.reversed.f=(this.e*this.b-this.a*this.f)/t}return this.reversed},i.prototype.map=function(t,e){return e=e||{},e.x=this.a*t.x+this.c*t.y+this.e,e.y=this.b*t.x+this.d*t.y+this.f,e},i.prototype.mapX=function(t,e){return this.a*t+this.c*e+this.e},i.prototype.mapY=function(t,e){return this.b*t+this.d*e+this.f},e.exports=i},{}],15:[function(t,e){function i(t){if(t&&t instanceof n)return t;throw"Invalid node: "+t}var n=t("./core"),r=0;n.prototype._label="",n.prototype._visible=!0,n.prototype._parent=null,n.prototype._next=null,n.prototype._prev=null,n.prototype._first=null,n.prototype._last=null,n.prototype._attrs=null,n.prototype._flags=null,n.prototype.toString=function(){return"["+this._label+"]"},n.prototype.id=function(t){return this.label(t)},n.prototype.label=function(t){return"undefined"==typeof t?this._label:(this._label=t,this)},n.prototype.attr=function(t,e){return"undefined"==typeof e?null!==this._attrs?this._attrs[t]:void 0:((null!==this._attrs?this._attrs:this._attrs={})[t]=e,this)},n.prototype.visible=function(t){return"undefined"==typeof t?this._visible:(this._visible=t,this._parent&&(this._parent._ts_children=++r),this._ts_pin=++r,this.touch(),this)},n.prototype.hide=function(){return this.visible(!1)},n.prototype.show=function(){return this.visible(!0)},n.prototype.parent=function(){return this._parent},n.prototype.next=function(t){for(var e=this._next;e&&t&&!e._visible;)e=e._next;return e},n.prototype.prev=function(t){for(var e=this._prev;e&&t&&!e._visible;)e=e._prev;return e},n.prototype.first=function(t){for(var e=this._first;e&&t&&!e._visible;)e=e._next;return e},n.prototype.last=function(t){for(var e=this._last;e&&t&&!e._visible;)e=e._prev;return e},n.prototype.visit=function(t,e){var i=t.reverse,n=t.visible;if(!t.start||!t.start(this,e)){for(var r,s=i?this.last(n):this.first(n);r=s;)if(s=i?r.prev(n):r.next(n),r.visit(t,e))return!0;return t.end&&t.end(this,e)}},n.prototype.append=function(){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t].appendTo(this);return this},n.prototype.prepend=function(){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t].prependTo(this);return this},n.prototype.appendTo=function(t){return i(t),this.remove(),t._last&&(t._last._next=this,this._prev=t._last),this._parent=t,t._last=this,t._first||(t._first=this),this._parent._flag(this,!0),this._ts_parent=++r,t._ts_children=++r,t.touch(),this},n.prototype.prependTo=function(t){return i(t),this.remove(),t._first&&(t._first._prev=this,this._next=t._first),this._parent=t,t._first=this,t._last||(t._last=this),this._parent._flag(this,!0),this._ts_parent=++r,t._ts_children=++r,t.touch(),this},n.prototype.insertNext=function(){if(arguments.length)for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].insertAfter(this);return this},n.prototype.insertPrev=function(){if(arguments.length)for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].insertBefore(this);return this},n.prototype.insertBefore=function(t){i(t),this.remove();var e=t._parent,n=t._prev;return t._prev=this,n&&(n._next=this)||e&&(e._first=this),this._parent=e,this._prev=n,this._next=t,this._parent._flag(this,!0),this._ts_parent=++r,this.touch(),this},n.prototype.insertAfter=function(t){i(t),this.remove();var e=t._parent,n=t._next;return t._next=this,n&&(n._prev=this)||e&&(e._last=this),this._parent=e,this._prev=t,this._next=n,this._parent._flag(this,!0),this._ts_parent=++r,this.touch(),this},n.prototype.remove=function(){if(arguments.length){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].remove();return this}return this._prev&&(this._prev._next=this._next),this._next&&(this._next._prev=this._prev),this._parent&&(this._parent._first===this&&(this._parent._first=this._next),this._parent._last===this&&(this._parent._last=this._prev),this._parent._flag(this,!1),this._parent._ts_children=++r,this._parent.touch()),this._prev=this._next=this._parent=null,this._ts_parent=++r,this},n.prototype.empty=function(){for(var t,e=this._first;t=e;)e=t._next,t._prev=t._next=t._parent=null,this._flag(t,!1);return this._first=this._last=null,this._ts_children=++r,this.touch(),this},n.prototype.touch=function(){return this._ts_touch=++r,this._parent&&this._parent.touch(),this},n.prototype._flag=function(t,e){if("undefined"==typeof e)return null!==this._flags&&this._flags[t]||0;if("string"==typeof t&&(e?(this._flags=this._flags||{},!this._flags[t]&&this._parent&&this._parent._flag(t,!0),this._flags[t]=(this._flags[t]||0)+1):this._flags&&this._flags[t]>0&&(1==this._flags[t]&&this._parent&&this._parent._flag(t,!1),this._flags[t]=this._flags[t]-1)),"object"==typeof t&&t._flags)for(var i in t._flags)t._flags[i]>0&&this._flag(i,e);return this},e.exports=n},{"./core":8}],16:[function(t,e){function i(t){this._owner=t,this._parent=null,this._relativeMatrix=new r,this._absoluteMatrix=new r,this.reset()}var n=t("./core"),r=t("./matrix"),s=0;n._init(function(){this._pin=new i(this)}),n.prototype.matrix=function(){return this._pin.absoluteMatrix()},n.prototype.pin=function(t,e){return"object"==typeof t?(this._pin.set(t),this):"string"==typeof t?"undefined"==typeof e?this._pin.get(t):(this._pin.set(t,e),this):"undefined"==typeof t?this._pin:void 0},i.prototype.reset=function(){this._textureAlpha=1,this._alpha=1,this._width=0,this._height=0,this._scaleX=1,this._scaleY=1,this._skewX=0,this._skewY=0,this._rotation=0,this._pivoted=!1,this._pivotX=null,this._pivotY=null,this._handled=!1,this._handleX=0,this._handleY=0,this._aligned=!1,this._alignX=0,this._alignY=0,this._offsetX=0,this._offsetY=0,this._boxX=0,this._boxY=0,this._boxWidth=this._width,this._boxHeight=this._height,this._ts_translate=++s,this._ts_transform=++s,this._ts_matrix=++s},i.prototype._update=function(){return this._parent=this._owner._parent&&this._owner._parent._pin,this._handled&&this._mo_handle!=this._ts_transform&&(this._mo_handle=this._ts_transform,this._ts_translate=++s),this._aligned&&this._parent&&this._mo_align!=this._parent._ts_transform&&(this._mo_align=this._parent._ts_transform,this._ts_translate=++s),this},i.prototype.toString=function(){return this._owner+" ("+(this._parent?this._parent._owner:null)+")"},i.prototype.absoluteMatrix=function(){this._update();var t=Math.max(this._ts_transform,this._ts_translate,this._parent?this._parent._ts_matrix:0);if(this._mo_abs==t)return this._absoluteMatrix;this._mo_abs=t;var e=this._absoluteMatrix;return e.copyFrom(this.relativeMatrix()),this._parent&&e.concat(this._parent._absoluteMatrix),this._ts_matrix=++s,e},i.prototype.relativeMatrix=function(){this._update();var t=Math.max(this._ts_transform,this._ts_translate,this._parent?this._parent._ts_transform:0);if(this._mo_rel==t)return this._relativeMatrix;this._mo_rel=t;var e=this._relativeMatrix;if(e.identity(),this._pivoted&&e.translate(-this._pivotX*this._width,-this._pivotY*this._height),e.scale(this._scaleX,this._scaleY),e.skew(this._skewX,this._skewY),e.rotate(this._rotation),this._pivoted&&e.translate(this._pivotX*this._width,this._pivotY*this._height),this._pivoted)this._boxX=0,this._boxY=0,this._boxWidth=this._width,this._boxHeight=this._height;else{var i,n;e.a>0&&e.c>0||e.a<0&&e.c<0?(i=0,n=e.a*this._width+e.c*this._height):(i=e.a*this._width,n=e.c*this._height),i>n?(this._boxX=n,this._boxWidth=i-n):(this._boxX=i,this._boxWidth=n-i),e.b>0&&e.d>0||e.b<0&&e.d<0?(i=0,n=e.b*this._width+e.d*this._height):(i=e.b*this._width,n=e.d*this._height),i>n?(this._boxY=n,this._boxHeight=i-n):(this._boxY=i,this._boxHeight=n-i)}return this._x=this._offsetX,this._y=this._offsetY,this._x-=this._boxX+this._handleX*this._boxWidth,this._y-=this._boxY+this._handleY*this._boxHeight,this._aligned&&this._parent&&(this._parent.relativeMatrix(),this._x+=this._alignX*this._parent._width,this._y+=this._alignY*this._parent._height),e.translate(this._x,this._y),this._relativeMatrix},i.prototype.get=function(t){return i._get(this,t)},i.prototype.set=function(t,e){if("string"==typeof t)i._set(this,t,e);else if("object"==typeof t)for(e in t)i._set(this,e,t[e],t);return this._owner&&(this._owner._ts_pin=++s,this._owner.touch()),this},i._get=function(t,e){return"undefined"!=typeof(e=i._getters[e])?e.call(i._getters,t):void 0},i._set=function(t,e,n,r){"undefined"!=typeof(e=i._setters[e])&&"undefined"!=typeof n&&e.call(i._setters,t,n,r)},i._getters={alpha:function(t){return t._alpha},textureAlpha:function(t){return t._textureAlpha},width:function(t){return t._width},height:function(t){return t._height},boxWidth:function(t){return t._boxWidth},boxHeight:function(t){return t._boxHeight},scaleX:function(t){return t._scaleX},scaleY:function(t){return t._scaleY},skewX:function(t){return t._skewX},skewY:function(t){return t._skewY},rotation:function(t){return t._rotation},pivotX:function(t){return t._pivotX},pivotY:function(t){return t._pivotY},offsetX:function(t){return t._offsetX},offsetY:function(t){return t._offsetY},alignX:function(t){return t._alignX},alignY:function(t){return t._alignY},handleX:function(t){return t._handleX},handleY:function(t){return t._handleY}},i._setters={alpha:function(t,e){t._alpha=e},textureAlpha:function(t,e){t._textureAlpha=e},width:function(t,e){t._width_=e,t._width=e,t._ts_transform=++s},height:function(t,e){t._height_=e,t._height=e,t._ts_transform=++s},scale:function(t,e){t._scaleX=e,t._scaleY=e,t._ts_transform=++s},scaleX:function(t,e){t._scaleX=e,t._ts_transform=++s},scaleY:function(t,e){t._scaleY=e,t._ts_transform=++s},skew:function(t,e){t._skewX=e,t._skewY=e,t._ts_transform=++s},skewX:function(t,e){t._skewX=e,t._ts_transform=++s},skewY:function(t,e){t._skewY=e,t._ts_transform=++s},rotation:function(t,e){t._rotation=e,t._ts_transform=++s},pivot:function(t,e){t._pivotX=e,t._pivotY=e,t._pivoted=!0,t._ts_transform=++s},pivotX:function(t,e){t._pivotX=e,t._pivoted=!0,t._ts_transform=++s
+},pivotY:function(t,e){t._pivotY=e,t._pivoted=!0,t._ts_transform=++s},offset:function(t,e){t._offsetX=e,t._offsetY=e,t._ts_translate=++s},offsetX:function(t,e){t._offsetX=e,t._ts_translate=++s},offsetY:function(t,e){t._offsetY=e,t._ts_translate=++s},align:function(t,e){this.alignX(t,e),this.alignY(t,e)},alignX:function(t,e){t._alignX=e,t._aligned=!0,t._ts_translate=++s,this.handleX(t,e)},alignY:function(t,e){t._alignY=e,t._aligned=!0,t._ts_translate=++s,this.handleY(t,e)},handle:function(t,e){this.handleX(t,e),this.handleY(t,e)},handleX:function(t,e){t._handleX=e,t._handled=!0,t._ts_translate=++s},handleY:function(t,e){t._handleY=e,t._handled=!0,t._ts_translate=++s},resizeMode:function(t,e,i){i&&("in"==e?e="in-pad":"out"==e&&(e="out-crop"),t._scaleTo(i.resizeWidth,i.resizeHeight,e))},resizeWidth:function(t,e,i){i&&i.resizeMode||t._scaleTo(e,null)},resizeHeight:function(t,e,i){i&&i.resizeMode||t._scaleTo(null,e)},scaleMode:function(t,e,i){i&&t._scaleTo(i.scaleWidth,i.scaleHeight,e)},scaleWidth:function(t,e,i){i&&i.scaleMode||t._scaleTo(e,null)},scaleHeight:function(t,e,i){i&&i.scaleMode||t._scaleTo(null,e)},matrix:function(t,e){this.scaleX(t,e.a),this.skewX(t,e.c/e.d),this.skewY(t,e.b/e.a),this.scaleY(t,e.d),this.offsetX(t,e.e),this.offsetY(t,e.f),this.rotation(t,0)}},i.prototype._scaleTo=function(t,e,i){var n="number"==typeof t,r="number"==typeof e,o="string"==typeof i,h=this;h._ts_transform=++s,n&&(h._scaleX=t/h._width_,h._width=h._width_),r&&(h._scaleY=e/h._height_,h._height=h._height_),n&&r&&o&&("out"==i||"out-crop"==i?h._scaleX=h._scaleY=Math.max(h._scaleX,h._scaleY):("in"==i||"in-pad"==i)&&(h._scaleX=h._scaleY=Math.min(h._scaleX,h._scaleY)),("out-crop"==i||"in-pad"==i)&&(h._width=t/h._scaleX,h._height=e/h._scaleY))},e.exports=i},{"./core":8,"./matrix":14}],17:[function(t){var e=t("./core");t("./pin");{var i=t("./util/stats");t("./util/create")}e.prototype._textures=null,e.prototype._tickBefore=null,e.prototype._tickAfter=null,e.prototype._alpha=1,e.prototype.render=function(t){if(this._visible){i.node++;var e=this.matrix();t.setTransform(e.a,e.b,e.c,e.d,e.e,e.f),this._alpha=this._pin._alpha*(this._parent?this._parent._alpha:1);var n=this._pin._textureAlpha*this._alpha;if(t.globalAlpha!=n&&(t.globalAlpha=n),null!==this._textures)for(var r=0,s=this._textures.length;s>r;r++)this._textures[r].draw(t);t.globalAlpha!=this._alpha&&(t.globalAlpha=this._alpha);for(var o,h=this._first;o=h;)h=o._next,o.render(t)}},e.prototype.MAX_ELAPSE=1/0,e.prototype._tick=function(t,e,n){if(this._visible){t>this.MAX_ELAPSE&&(t=this.MAX_ELAPSE);var r=!1;if(null!==this._tickBefore)for(var s=0,o=this._tickBefore.length;o>s;s++)i.tick++,r=this._tickBefore[s].call(this,t,e,n)===!0||r;for(var h,a=this._first;h=a;)a=h._next,h._flag("_tick")&&(r=h._tick(t,e,n)===!0?!0:r);if(null!==this._tickAfter)for(var s=0,o=this._tickAfter.length;o>s;s++)i.tick++,r=this._tickAfter[s].call(this,t,e,n)===!0||r;return r}},e.prototype.tick=function(t,e){"function"==typeof t&&(e?(null===this._tickBefore&&(this._tickBefore=[]),this._tickBefore.push(t)):(null===this._tickAfter&&(this._tickAfter=[]),this._tickAfter.push(t)),this._flag("_tick",null!==this._tickAfter&&this._tickAfter.length>0||null!==this._tickBefore&&this._tickBefore.length>0))},e.prototype.untick=function(t){if("function"==typeof t){var e;null!==this._tickBefore&&(e=this._tickBefore.indexOf(t))>=0&&this._tickBefore.splice(e,1),null!==this._tickAfter&&(e=this._tickAfter.indexOf(t))>=0&&this._tickAfter.splice(e,1)}}},{"./core":8,"./pin":16,"./util/create":21,"./util/stats":27}],18:[function(t){function e(t,i){e._super.call(this),this.label("Root"),this._paused=!0;var r=this,s=0,o=function(t){if(r._paused!==!0){n.tick=n.node=n.draw=0;var e=s||t,o=t-e;s=t;var h=r._tick(o,t,e);r._mo_touch!=r._ts_touch?(r._mo_touch=r._ts_touch,i.call(r),r.request()):h?r.request():r.pause(),n.fps=o?1e3/o:0}};this.request=function(){t(o)}}var i=t("./core");t("./pin"),t("./render");var n=t("./util/stats"),r=t("./util/create"),s=t("./util/extend");e._super=i,e.prototype=r(e._super.prototype),i.root=function(t,i){return new e(t,i)},e.prototype.start=function(){return this.resume()},e.prototype.resume=function(t){return(this._paused||t)&&(this._paused=!1,this.request()),this},e.prototype.pause=function(){return this._paused=!0,this},e.prototype.touch=function(){return this.resume(),e._super.prototype.touch.call(this)},e.prototype.background=function(){return this},e.prototype.viewport=function(t,e,i){if("undefined"==typeof t)return s({},this._viewport);this._viewport={width:t,height:e,ratio:i||1},this._updateViewbox();var n=s({},this._viewport);return this.visit({start:function(t){return t._flag("viewport")?void t.publish("viewport",[n]):!0}}),this},e.prototype.viewbox=function(t,e,i){return this._viewbox={width:t,height:e,mode:/^(in|out|in-pad|out-crop)$/.test(i)?i:"in-pad"},this._updateViewbox(),this},e.prototype._updateViewbox=function(){var t=this._viewbox,e=this._viewport;e&&t?(this.pin({width:t.width,height:t.height}),this._pin._scaleTo(e.width,e.height,t.mode)):e&&this.pin({width:e.width,height:e.height})}},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/extend":22,"./util/stats":27}],19:[function(t){function e(){e._super.call(this),this.label("String"),this._textures=[]}var i=t("./core");t("./pin"),t("./render");var n=t("./util/create"),r=t("./util/is");i.string=function(t){return(new e).frames(t)},e._super=i,e.prototype=n(e._super.prototype),e.prototype.setFont=function(t,e,i){return this.frames(t,e,i)},e.prototype.frames=function(t){return this._textures=[],"string"==typeof t?(t=i.texture(t),this._item=function(e){return t.one(e)}):"object"==typeof t?this._item=function(e){return t[e]}:"function"==typeof t&&(this._item=t),this},e.prototype.setValue=function(t,e,i){return this.value(t,e,i)},e.prototype.value=function(t){if("undefined"==typeof t)return this._value;if(this._value===t)return this;this._value=t,null===t?t="":"string"==typeof t||r.array(t)||(t=t.toString()),this._spacing=this._spacing||0;for(var e=0,i=0,n=0;n<t.length;n++){var s=this._textures[n]=this._item(t[n]);e+=n>0?this._spacing:0,s.dest(e,0),e+=s.width,i=Math.max(i,s.height)}return this.pin("width",e),this.pin("height",i),this._textures.length=t.length,this}},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/is":23}],20:[function(t,e){function i(t,e){"object"==typeof t&&this.src(t,e)}var n=t("./util/stats"),r=t("./util/math");i.prototype.pipe=function(){return new i(this)},i.prototype.src=function(t,e,i,n){if("object"==typeof t){var r=t,s=e||1;this._image=r,this._sx=this._dx=0,this._sy=this._dy=0,this._sw=this._dw=r.width/s,this._sh=this._dh=r.height/s,this.width=r.width/s,this.height=r.height/s,this.ratio=s}else"undefined"==typeof i?(i=t,n=e):(this._sx=t,this._sy=e),this._sw=this._dw=i,this._sh=this._dh=n,this.width=i,this.height=n;return this},i.prototype.dest=function(t,e,i,n){return this._dx=t,this._dy=e,this._dx=t,this._dy=e,"undefined"!=typeof i&&(this._dw=i,this._dh=n,this.width=i,this.height=n),this},i.prototype.draw=function(t,e,i,s,o,h,a,u,f){var c=this._image;if(null!==c&&"object"==typeof c){var p=this._sx,_=this._sy,l=this._sw,d=this._sh,g=this._dx,m=this._dy,y=this._dw,v=this._dh;"undefined"!=typeof h?(e=r.limit(e,0,this._sw),s=r.limit(s,0,this._sw-e),i=r.limit(i,0,this._sh),o=r.limit(o,0,this._sh-i),p+=e,_+=i,l=s,d=o,g=h,m=a,y=u,v=f):"undefined"!=typeof s?(g=e,m=i,y=s,v=o):"undefined"!=typeof e&&(y=e,v=i);var x=this.ratio||1;p*=x,_*=x,l*=x,d*=x;try{"function"==typeof c.draw?c.draw(t,p,_,l,d,g,m,y,v):(n.draw++,t.drawImage(c,p,_,l,d,g,m,y,v))}catch(b){c._draw_failed||(console.log("Unable to draw: ",c),console.log(b),c._draw_failed=!0)}}},e.exports=i},{"./util/math":24,"./util/stats":27}],21:[function(t,e){function i(){}e.exports="function"==typeof Object.create?function(t,e){return Object.create.call(Object,t,e)}:function(t,e){if(e)throw Error("Second argument is not supported!");if("object"!=typeof t||null===t)throw Error("Invalid prototype!");return i.prototype=t,new i}},{}],22:[function(t,e){e.exports=function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var n in i)i.hasOwnProperty(n)&&(t[n]=i[n])}return t}},{}],23:[function(t,e){var i=Object.prototype,n=i.hasOwnProperty,r=i.toString,s=/^[A-Fa-f0-9]+$/,o=e.exports={};o.a=o.an=o.type=function(t,e){return typeof t===e},o.defined=function(t){return"undefined"!=typeof t},o.empty=function(t){var e,i=r.call(t);if("[object Array]"===i||"[object Arguments]"===i||"[object String]"===i)return 0===t.length;if("[object Object]"===i){for(e in t)if(n.call(t,e))return!1;return!0}return!t},o.equal=function(t,e){if(t===e)return!0;var i,n=r.call(t);if(n!==r.call(e))return!1;if("[object Object]"===n){for(i in t)if(!(o.equal(t[i],e[i])&&i in e))return!1;for(i in e)if(!(o.equal(t[i],e[i])&&i in t))return!1;return!0}if("[object Array]"===n){if(i=t.length,i!==e.length)return!1;for(;--i;)if(!o.equal(t[i],e[i]))return!1;return!0}return"[object Function]"===n?t.prototype===e.prototype:"[object Date]"===n?t.getTime()===e.getTime():!1},o.instance=function(t,e){return t instanceof e},o.nil=function(t){return null===t},o.undef=function(t){return"undefined"==typeof t},o.array=function(t){return"[object Array]"===r.call(t)},o.emptyarray=function(t){return o.array(t)&&0===t.length},o.arraylike=function(t){return!!t&&!o["boolean"](t)&&n.call(t,"length")&&isFinite(t.length)&&o.number(t.length)&&t.length>=0},o["boolean"]=function(t){return"[object Boolean]"===r.call(t)},o.element=function(t){return void 0!==t&&"undefined"!=typeof HTMLElement&&t instanceof HTMLElement&&1===t.nodeType},o.fn=function(t){return"[object Function]"===r.call(t)},o.number=function(t){return"[object Number]"===r.call(t)},o.nan=function(t){return!o.number(t)||t!==t},o.object=function(t){return"[object Object]"===r.call(t)},o.hash=function(t){return o.object(t)&&t.constructor===Object&&!t.nodeType&&!t.setInterval},o.regexp=function(t){return"[object RegExp]"===r.call(t)},o.string=function(t){return"[object String]"===r.call(t)},o.hex=function(t){return o.string(t)&&(!t.length||s.test(t))}},{}],24:[function(t,e){e.exports.random=function(t,e){return"undefined"==typeof t?(e=1,t=0):"undefined"==typeof e&&(e=t,t=0),t==e?t:Math.random()*(e-t)+t},e.exports.rotate=function(t,e,i){return"undefined"==typeof e?(i=1,e=0):"undefined"==typeof i&&(i=e,e=0),i>e?(t=(t-e)%(i-e),t+(0>t?i:e)):(t=(t-i)%(e-i),t+(0>=t?e:i))},e.exports.limit=function(t,e,i){return e>t?e:t>i?i:t},e.exports.length=function(t,e){return Math.sqrt(t*t+e*e)}},{}],25:[function(t,e){e.exports=function(t,e){var i=!1;return function(){i||(i=!0,t.apply(e,arguments))}}},{}],26:[function(t,e){e.exports=function(t,e,i,n,r,s){var o=t.width,h=t.height,a=t.left,u=t.right,f=t.top,c=t.bottom;a="number"==typeof a&&a===a?a:0,u="number"==typeof u&&u===u?u:0,f="number"==typeof f&&f===f?f:0,c="number"==typeof c&&c===c?c:0,o=o-a-u,h=h-f-c,r||(e=Math.max(e-a-u,0),i=Math.max(i-f-c,0));var p=0;if(f>0&&a>0&&s(p++,0,0,a,f,0,0,a,f),c>0&&a>0&&s(p++,0,h+f,a,c,0,i+f,a,c),f>0&&u>0&&s(p++,o+a,0,u,f,e+a,0,u,f),c>0&&u>0&&s(p++,o+a,h+f,u,c,e+a,i+f,u,c),n)f>0&&s(p++,a,0,o,f,a,0,e,f),c>0&&s(p++,a,h+f,o,c,a,i+f,e,c),a>0&&s(p++,0,f,a,h,0,f,a,i),u>0&&s(p++,o+a,f,u,h,e+a,f,u,i),s(p++,a,f,o,h,a,f,e,i);else for(var _,l=a,d=e;d>0;){_=Math.min(o,d),d-=o;for(var g,m=f,y=i;y>0;)g=Math.min(h,y),y-=h,s(p++,a,f,_,g,l,m,_,g),0>=d&&(a&&s(p++,0,f,a,g,0,m,a,g),u&&s(p++,o+a,f,u,g,l+_,m,u,g)),m+=g;f&&s(p++,a,0,_,f,l,0,_,f),c&&s(p++,a,h+f,_,c,l,m,_,c),l+=_}return p}},{}],27:[function(t,e){e.exports={}},{}],28:[function(t,e){e.exports.startsWith=function(t,e){return"string"==typeof t&&"string"==typeof e&&t.substring(0,e.length)==e}},{}]},{},[1])(1)});
\ No newline at end of file
diff --git a/dist/cut.web.js b/dist/cut.web.js
index df17917..3392e87 100644
--- a/dist/cut.web.js
+++ b/dist/cut.web.js
@@ -1,5 +1,5 @@
 /*
- * CutJS 0.5.0-beta.4
+ * CutJS 0.5.0-beta.5
  * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
  * Available under the MIT license
  * @license
@@ -8,18 +8,649 @@
 !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Cut=e()}}(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){
 module.exports = require("../lib/");
 
-module.exports.Mouse = require("../lib/mouse");
+require("../lib/canvas");
+
+require("../lib/image");
+
+require("../lib/anim");
+
+require("../lib/str");
+
+require("../lib/layout");
+
+require("../lib/addon/tween");
+
+module.exports.Mouse = require("../lib/addon/mouse");
 
 module.exports.Math = require("../lib/util/math");
 
-require("../lib/tween");
+module.exports._extend = require("../lib/util/extend");
+
+module.exports._create = require("../lib/util/create");
+
+require("../lib/loader/web");
+},{"../lib/":11,"../lib/addon/mouse":3,"../lib/addon/tween":4,"../lib/anim":5,"../lib/canvas":7,"../lib/image":10,"../lib/layout":12,"../lib/loader/web":13,"../lib/str":19,"../lib/util/create":21,"../lib/util/extend":22,"../lib/util/math":24}],2:[function(require,module,exports){
+function _identity(x) {
+    return x;
+}
+
+var _cache = {};
+
+var _modes = {};
+
+var _easings = {};
+
+function Easing(token) {
+    if (typeof token === "function") {
+        return token;
+    }
+    if (typeof token !== "string") {
+        return _identity;
+    }
+    var fn = _cache[token];
+    if (fn) {
+        return fn;
+    }
+    var match = /^(\w+)(-(in|out|in-out|out-in))?(\((.*)\))?$/i.exec(token);
+    if (!match || !match.length) {
+        return _identity;
+    }
+    easing = _easings[match[1]];
+    mode = _modes[match[3]];
+    params = match[5];
+    if (easing && easing.fn) {
+        fn = easing.fn;
+    } else if (easing && easing.fc) {
+        fn = easing.fc.apply(easing.fc, params && params.replace(/\s+/, "").split(","));
+    } else {
+        fn = _identity;
+    }
+    if (mode) {
+        fn = mode.fn(fn);
+    }
+    // TODO: It can be a memory leak with different `params`.
+    _cache[token] = fn;
+    return fn;
+}
+
+Easing.add = function(data) {
+    var names = (data.name || data.mode).split(/\s+/);
+    for (var i = 0; i < names.length; i++) {
+        var name = names[i];
+        if (name) {
+            (data.name ? _easings : _modes)[name] = data;
+        }
+    }
+};
+
+Easing.add({
+    mode: "in",
+    fn: function(f) {
+        return f;
+    }
+});
+
+Easing.add({
+    mode: "out",
+    fn: function(f) {
+        return function(t) {
+            return 1 - f(1 - t);
+        };
+    }
+});
+
+Easing.add({
+    mode: "in-out",
+    fn: function(f) {
+        return function(t) {
+            return t < .5 ? f(2 * t) / 2 : 1 - f(2 * (1 - t)) / 2;
+        };
+    }
+});
+
+Easing.add({
+    mode: "out-in",
+    fn: function(f) {
+        return function(t) {
+            return t < .5 ? 1 - f(2 * (1 - t)) / 2 : f(2 * t) / 2;
+        };
+    }
+});
+
+Easing.add({
+    name: "linear",
+    fn: function(t) {
+        return t;
+    }
+});
+
+Easing.add({
+    name: "quad",
+    fn: function(t) {
+        return t * t;
+    }
+});
+
+Easing.add({
+    name: "cubic",
+    fn: function(t) {
+        return t * t * t;
+    }
+});
+
+Easing.add({
+    name: "quart",
+    fn: function(t) {
+        return t * t * t * t;
+    }
+});
+
+Easing.add({
+    name: "quint",
+    fn: function(t) {
+        return t * t * t * t * t;
+    }
+});
+
+Easing.add({
+    name: "sin sine",
+    fn: function(t) {
+        return 1 - Math.cos(t * Math.PI / 2);
+    }
+});
+
+Easing.add({
+    name: "exp",
+    fn: function(t) {
+        return t == 0 ? 0 : Math.pow(2, 10 * (t - 1));
+    }
+});
+
+Easing.add({
+    name: "circle circ",
+    fn: function(t) {
+        return 1 - Math.sqrt(1 - t * t);
+    }
+});
+
+Easing.add({
+    name: "bounce",
+    fn: function(t) {
+        return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
+    }
+});
+
+Easing.add({
+    name: "poly",
+    fc: function(e) {
+        return function(t) {
+            return Math.pow(t, e);
+        };
+    }
+});
+
+Easing.add({
+    name: "elastic",
+    fc: function(a, p) {
+        p = p || .45;
+        a = a || 1;
+        var s = p / (2 * Math.PI) * Math.asin(1 / a);
+        return function(t) {
+            return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p);
+        };
+    }
+});
+
+Easing.add({
+    name: "back",
+    fc: function(s) {
+        s = typeof s !== "undefined" ? s : 1.70158;
+        return function(t) {
+            return t * t * ((s + 1) * t - s);
+        };
+    }
+});
+
+module.exports = Easing;
+
+
+},{}],3:[function(require,module,exports){
+if (typeof DEBUG === "undefined") DEBUG = true;
+
+function Mouse() {
+    Mouse.subscribe.apply(Mouse, arguments);
+}
+
+Mouse.CLICK = "click";
+
+Mouse.START = "touchstart mousedown";
+
+Mouse.MOVE = "touchmove mousemove";
+
+Mouse.END = "touchend mouseup";
+
+Mouse.CANCEL = "touchcancel";
+
+Mouse.subscribe = function(root, elem) {
+    var visitor = null, data = {}, abs = null, rel = null, clicked = [];
+    elem = elem || document;
+    // click events are synthesized from start/end events on same nodes
+    // elem.addEventListener('click', handleClick);
+    elem.addEventListener("touchstart", handleStart);
+    elem.addEventListener("touchend", handleEnd);
+    elem.addEventListener("touchmove", handleMove);
+    elem.addEventListener("touchcancel", handleCancel);
+    elem.addEventListener("mousedown", handleStart);
+    elem.addEventListener("mouseup", handleEnd);
+    elem.addEventListener("mousemove", handleMove);
+    function handleStart(event) {
+        Mouse._xy(root, elem, event, abs);
+        DEBUG && console.log("Mouse Start: " + event.type + " " + abs);
+        event.preventDefault();
+        publish(event.type, event);
+        findClicks();
+    }
+    function handleEnd(event) {
+        // New xy is not valid/available, last xy is used instead.
+        DEBUG && console.log("Mouse End: " + event.type + " " + abs);
+        event.preventDefault();
+        publish(event.type, event);
+        if (clicked.length) {
+            DEBUG && console.log("Mouse Click: " + clicked.length);
+            fireClicks(event);
+        }
+    }
+    function handleCancel(event) {
+        DEBUG && console.log("Mouse Cancel: " + event.type);
+        event.preventDefault();
+        publish(event.type, event);
+    }
+    function handleMove(event) {
+        Mouse._xy(root, elem, event, abs);
+        // DEBUG && console.log('Mouse Move: ' + event.type + ' ' +
+        // abs);
+        if (!root._flag(event.type)) {
+            return;
+        }
+        event.preventDefault();
+        publish(event.type, event);
+    }
+    function findClicks() {
+        while (clicked.length) {
+            clicked.pop();
+        }
+        publish("click", null, clicked);
+    }
+    function fireClicks(event) {
+        data.event = event;
+        data.type = "click";
+        data.root = root;
+        data.collect = false;
+        var cancel = false;
+        while (clicked.length) {
+            var node = clicked.shift();
+            if (cancel) {
+                continue;
+            }
+            cancel = visitor.end(node, data) ? true : cancel;
+        }
+    }
+    function publish(type, event, collect) {
+        rel.x = abs.x;
+        rel.y = abs.y;
+        data.event = event;
+        data.type = type;
+        data.root = /* root._capture || */ root;
+        data.collect = collect;
+        data.root.visit(visitor, data);
+    }
+    visitor = {
+        reverse: true,
+        visible: true,
+        start: function(node, data) {
+            return !node._flag(data.type);
+        },
+        end: function(node, data) {
+            // data: event, type, root, collect
+            rel.raw = data.event;
+            rel.type = data.type;
+            var listeners = node.listeners(data.type);
+            if (!listeners) {
+                return;
+            }
+            node.matrix().reverse().map(abs, rel);
+            if (!(node === data.root || node.attr("spy") || Mouse._isInside(node, rel))) {
+                return;
+            }
+            if (data.collect) {
+                data.collect.push(node);
+                return;
+            }
+            var cancel = false;
+            for (var l = 0; l < listeners.length; l++) {
+                cancel = listeners[l].call(node, rel) ? true : cancel;
+            }
+            return cancel;
+        }
+    };
+    abs = {
+        x: 0,
+        y: 0,
+        toString: function() {
+            return (this.x | 0) + "x" + (this.y | 0);
+        }
+    };
+    rel = {
+        x: 0,
+        y: 0,
+        toString: function() {
+            return abs + " / " + (this.x | 0) + "x" + (this.y | 0);
+        }
+    };
+};
+
+Mouse._isInside = function(node, point) {
+    return point.x >= 0 && point.x <= node._pin._width && point.y >= 0 && point.y <= node._pin._height;
+};
+
+Mouse._xy = function(root, elem, event, point) {
+    var isTouch = false;
+    // touch screen events
+    if (event.touches) {
+        if (event.touches.length) {
+            isTouch = true;
+            point.x = event.touches[0].pageX;
+            point.y = event.touches[0].pageY;
+        } else {
+            return;
+        }
+    } else {
+        // mouse events
+        point.x = event.clientX;
+        point.y = event.clientY;
+        // See http://goo.gl/JuVnF2
+        if (document.body.scrollLeft || document.body.scrollTop) {} else if (document.documentElement) {
+            point.x += document.documentElement.scrollLeft;
+            point.y += document.documentElement.scrollTop;
+        }
+    }
+    // accounts for border
+    point.x -= elem.clientLeft || 0;
+    point.y -= elem.clientTop || 0;
+    var par = elem;
+    while (par) {
+        point.x -= par.offsetLeft || 0;
+        point.y -= par.offsetTop || 0;
+        if (!isTouch) {
+            // touch events offset scrolling with pageX/Y
+            // so scroll offset not needed for them
+            point.x += par.scrollLeft || 0;
+            point.y += par.scrollTop || 0;
+        }
+        par = par.offsetParent;
+    }
+    point.x *= root.viewport().ratio || 1;
+    point.y *= root.viewport().ratio || 1;
+};
+
+module.exports = Mouse;
+
+
+},{}],4:[function(require,module,exports){
+var Easing = require("./easing");
+
+var Cut = require("../core");
+
+var Pin = require("../pin");
+
+Cut.prototype.tween = function(duration, delay) {
+    if (!this._tween) {
+        this._tween = new Tween(this);
+    }
+    return this._tween.tween(duration, delay);
+};
+
+var iid = 0;
+
+function Tween(node) {
+    // TODO: reuse head.start/keys/end
+    var tween = this;
+    this._owner = node;
+    this._queue = [];
+    this._next = null;
+    var lastTime = 0;
+    node.tick(function(elapsed, now, last) {
+        if (!tween._queue.length) {
+            return;
+        }
+        // ignore old elapsed
+        var ignore = lastTime != last;
+        lastTime = now;
+        this.touch();
+        if (ignore) {
+            return;
+        }
+        var head = tween._queue[0];
+        if (!head.time) {
+            head.time = 1;
+        } else {
+            head.time += elapsed;
+        }
+        if (head.time < head.delay) {
+            return;
+        }
+        if (!head.start) {
+            head.start = {};
+            head.keys = {};
+            for (var key in head.end) {
+                if (typeof (start = node.pin(key)) === "number") {
+                    head.start[key] = start;
+                    head.keys[key] = key;
+                } else if (typeof (startX = node.pin(key + "X")) === "number" && typeof (startY = node.pin(key + "Y")) === "number") {
+                    head.start[key + "X"] = startX;
+                    head.keys[key + "X"] = key;
+                    head.start[key + "Y"] = startY;
+                    head.keys[key + "Y"] = key;
+                }
+            }
+        }
+        var p = (head.time - head.delay) / head.duration;
+        var over = p >= 1;
+        p = p > 1 ? 1 : p;
+        p = typeof head.easing == "function" ? head.easing(p) : p;
+        var q = 1 - p;
+        for (var key in head.keys) {
+            node.pin(key, head.start[key] * q + head.end[head.keys[key]] * p);
+        }
+        if (over) {
+            tween._queue.shift();
+            head.then && head.then.call(node);
+        }
+    }, true);
+}
+
+Tween.prototype.tween = function(duration, delay) {
+    this._next = {
+        id: ++iid,
+        end: {},
+        duration: duration || 400,
+        delay: delay || 0
+    };
+    return this;
+};
+
+Tween.prototype.pin = function(a, b) {
+    if (this._next !== this._queue[this._queue.length - 1]) {
+        this._owner.touch();
+        this._queue.push(this._next);
+    }
+    var end = this._next.end;
+    if (typeof a === "object") {
+        for (var attr in a) {
+            end[attr] = a[attr];
+        }
+    } else if (typeof b !== "undefined") {
+        end[a] = b;
+    }
+    return this;
+};
+
+Tween.prototype.clear = function(forward) {
+    var tween;
+    while (tween = this._queue.shift()) {
+        forward && this._owner.pin(tween.end);
+    }
+    return this;
+};
 
-require("../lib/loader.web");
+Tween.prototype.then = function(then) {
+    this._next.then = then;
+    return this;
+};
 
-module.exports._extend = require("../lib/util/extend");
+Tween.prototype.ease = function(easing) {
+    this._next.easing = Easing(easing);
+    return this;
+};
 
-module.exports._create = require("../lib/util/create");
-},{"../lib/":7,"../lib/loader.web":8,"../lib/mouse":10,"../lib/tween":14,"../lib/util/create":16,"../lib/util/extend":17,"../lib/util/math":19}],2:[function(require,module,exports){
+module.exports = Tween;
+
+
+},{"../core":8,"../pin":16,"./easing":2}],5:[function(require,module,exports){
+var Cut = require("./core");
+
+require("./pin");
+
+require("./render");
+
+var create = require("./util/create");
+
+var math = require("./util/math");
+
+Cut.anim = function(frames, fps) {
+    var anim = new Anim();
+    anim.frames(frames).gotoFrame(0);
+    fps && anim.fps(fps);
+    return anim;
+};
+
+Anim._super = Cut;
+
+Anim.prototype = create(Anim._super.prototype);
+
+// TODO: replace with atlas fps or texture time
+Cut.Anim = {
+    FPS: 15
+};
+
+function Anim() {
+    Anim._super.call(this);
+    this.label("Anim");
+    this._textures = [];
+    this._fps = Cut.Anim.FPS;
+    this._ft = 1e3 / this._fps;
+    this._time = -1;
+    this._repeat = 0;
+    this._index = 0;
+    this._frames = [];
+    var lastTime = 0;
+    this.tick(function(t, now, last) {
+        if (this._time < 0 || this._frames.length <= 1) {
+            return;
+        }
+        // ignore old elapsed
+        var ignore = lastTime != last;
+        lastTime = now;
+        if (ignore) {
+            return true;
+        }
+        this._time += t;
+        if (this._time < this._ft) {
+            return true;
+        }
+        var n = this._time / this._ft | 0;
+        this._time -= n * this._ft;
+        this.moveFrame(n);
+        if (this._repeat > 0 && (this._repeat -= n) <= 0) {
+            this.stop();
+            this._callback && this._callback();
+            return false;
+        }
+        return true;
+    }, false);
+}
+
+Anim.prototype.fps = function(fps) {
+    if (typeof fps === "undefined") {
+        return this._fps;
+    }
+    this._fps = fps > 0 ? fps : Cut.Anim.FPS;
+    this._ft = 1e3 / this._fps;
+    return this;
+};
+
+/**
+ * @deprecated Use frames
+ */
+Anim.prototype.setFrames = function(a, b, c) {
+    return this.frames(a, b, c);
+};
+
+Anim.prototype.frames = function(frames) {
+    this._index = 0;
+    this._frames = Cut.texture(frames).array();
+    this.touch();
+    return this;
+};
+
+Anim.prototype.length = function() {
+    return this._frames ? this._frames.length : 0;
+};
+
+Anim.prototype.gotoFrame = function(frame, resize) {
+    this._index = math.rotate(frame, this._frames.length) | 0;
+    resize = resize || !this._textures[0];
+    this._textures[0] = this._frames[this._index];
+    if (resize) {
+        this.pin("width", this._textures[0].width);
+        this.pin("height", this._textures[0].height);
+    }
+    this.touch();
+    return this;
+};
+
+Anim.prototype.moveFrame = function(move) {
+    return this.gotoFrame(this._index + move);
+};
+
+Anim.prototype.repeat = function(repeat, callback) {
+    this._repeat = repeat * this._frames.length - 1;
+    this._callback = callback;
+    this.play();
+    return this;
+};
+
+Anim.prototype.play = function(frame) {
+    if (typeof frame !== "undefined") {
+        this.gotoFrame(frame);
+        this._time = 0;
+    } else if (this._time < 0) {
+        this._time = 0;
+    }
+    this.touch();
+    return this;
+};
+
+Anim.prototype.stop = function(frame) {
+    this._time = -1;
+    if (typeof frame !== "undefined") {
+        this.gotoFrame(frame);
+    }
+    return this;
+};
+
+
+},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/math":24}],6:[function(require,module,exports){
 var Cut = require("./core");
 
 var Texture = require("./texture");
@@ -41,6 +672,7 @@ var _atlases_arr = [];
 // TODO: return entire atlas as texture
 // TODO: select atlas itself, call texture function
 // TODO: print subquery not found error
+// TODO: cache and clone or index textures
 Cut.atlas = function(def) {
     var atlas = is.fn(def.draw) ? def : new Atlas(def);
     if (def.name) {
@@ -200,7 +832,6 @@ function Selection(result, find, make) {
     };
 }
 
-// TODO: cache and clone
 Cut.texture = function(query) {
     if (!is.string(query)) {
         return new Selection(query);
@@ -228,7 +859,7 @@ function deprecated(hash, name, msg) {
 module.exports = Atlas;
 
 
-},{"./core":4,"./texture":13,"./util/create":16,"./util/extend":17,"./util/is":18,"./util/string":23}],3:[function(require,module,exports){
+},{"./core":8,"./texture":20,"./util/create":21,"./util/extend":22,"./util/is":23,"./util/string":28}],7:[function(require,module,exports){
 var Cut = require("./core");
 
 var Texture = require("./texture");
@@ -269,13 +900,13 @@ Cut.canvas = function(type, attributes, callback) {
         return this;
     };
     if (typeof callback === "function") {
-        callback.call(this, context);
+        callback.call(texture, context);
     }
     return texture;
 };
 
 
-},{"./core":4,"./texture":13}],4:[function(require,module,exports){
+},{"./core":8,"./texture":20}],8:[function(require,module,exports){
 if (typeof DEBUG === "undefined") DEBUG = true;
 
 var stats = require("./util/stats");
@@ -409,286 +1040,290 @@ Cut.create = function() {
 module.exports = Cut;
 
 
-},{"./util/extend":17,"./util/is":18,"./util/once":20,"./util/stats":22}],5:[function(require,module,exports){
-function _identity(x) {
-    return x;
+},{"./util/extend":22,"./util/is":23,"./util/once":25,"./util/stats":27}],9:[function(require,module,exports){
+var Cut = require("./core");
+
+var is = require("./util/is");
+
+Cut.prototype._listeners = null;
+
+Cut.prototype.on = Cut.prototype.listen = function(types, listener) {
+    if (types = _check(this, types, listener, true)) {
+        for (var i = 0; i < types.length; i++) {
+            var type = types[i];
+            this._listeners[type] = this._listeners[type] || [];
+            this._listeners[type].push(listener);
+            this._flag(type, true);
+        }
+    }
+    return this;
+};
+
+Cut.prototype.off = function(types, listener) {
+    if (types = _check(this, types, listener, false)) {
+        for (var i = 0; i < types.length; i++) {
+            var type = types[i], all = this._listeners[type], index;
+            if (all && (index = all.indexOf(listener)) >= 0) {
+                all.splice(index, 1);
+                if (!all.length) {
+                    delete this._listeners[type];
+                }
+                this._flag(type, false);
+            }
+        }
+    }
+    return this;
+};
+
+function _check(node, types, listener, create) {
+    if (!types || !types.length || typeof listener !== "function") {
+        return false;
+    }
+    if (!(types = (is.array(types) ? types.join(" ") : types).match(/\S+/g))) {
+        return false;
+    }
+    if (node._listeners === null) {
+        if (create) {
+            node._listeners = {};
+        } else {
+            return false;
+        }
+    }
+    return types;
+}
+
+Cut.prototype.listeners = function(type) {
+    return this._listeners && this._listeners[type];
+};
+
+Cut.prototype.publish = function(name, args) {
+    var listeners = this.listeners(name);
+    if (!listeners || !listeners.length) {
+        return 0;
+    }
+    for (var l = 0; l < listeners.length; l++) {
+        listeners[l].apply(this, args);
+    }
+    return listeners.length;
+};
+
+Cut.prototype.trigger = function(name, args) {
+    this.publish(name, args);
+    return this;
+};
+
+
+},{"./core":8,"./util/is":23}],10:[function(require,module,exports){
+var Cut = require("./core");
+
+require("./pin");
+
+require("./render");
+
+var repeat = require("./util/repeat");
+
+var create = require("./util/create");
+
+Cut.image = function(image) {
+    var img = new Image();
+    image && img.image(image);
+    return img;
+};
+
+Image._super = Cut;
+
+Image.prototype = create(Image._super.prototype);
+
+function Image() {
+    Image._super.call(this);
+    this.label("Image");
+    this._textures = [];
+    this._image = null;
 }
 
-var _cache = {};
+/**
+ * @deprecated Use image
+ */
+Image.prototype.setImage = function(a, b, c) {
+    return this.image(a, b, c);
+};
 
-var _modes = {};
+Image.prototype.image = function(image) {
+    this._image = Cut.texture(image).one();
+    this.pin("width", this._image ? this._image.width : 0);
+    this.pin("height", this._image ? this._image.height : 0);
+    this._textures[0] = this._image.pipe();
+    this._textures.length = 1;
+    return this;
+};
 
-var _easings = {};
+Image.prototype.tile = function(inner) {
+    this._repeat(false, inner);
+    return this;
+};
 
-function Easing(token) {
-    if (typeof token === "function") {
-        return token;
-    }
-    if (typeof token !== "string") {
-        return _identity;
-    }
-    var fn = _cache[token];
-    if (fn) {
-        return fn;
-    }
-    var match = /^(\w+)(-(in|out|in-out|out-in))?(\((.*)\))?$/i.exec(token);
-    if (!match || !match.length) {
-        return _identity;
-    }
-    easing = _easings[match[1]];
-    mode = _modes[match[3]];
-    params = match[5];
-    if (easing && easing.fn) {
-        fn = easing.fn;
-    } else if (easing && easing.fc) {
-        fn = easing.fc.apply(easing.fc, params && params.replace(/\s+/, "").split(","));
-    } else {
-        fn = _identity;
-    }
-    if (mode) {
-        fn = mode.fn(fn);
-    }
-    // TODO: It can be a memory leak with different `params`.
-    _cache[token] = fn;
-    return fn;
-}
+Image.prototype.stretch = function(inner) {
+    this._repeat(true, inner);
+    return this;
+};
 
-Easing.add = function(data) {
-    var names = (data.name || data.mode).split(/\s+/);
-    for (var i = 0; i < names.length; i++) {
-        var name = names[i];
-        if (name) {
-            (data.name ? _easings : _modes)[name] = data;
+Image.prototype._repeat = function(stretch, inner) {
+    var self = this;
+    this.untick(this._repeatTicker);
+    this.tick(this._repeatTicker = function() {
+        if (this._mo_stretch == this._pin._ts_transform) {
+            return;
         }
+        this._mo_stretch = this._pin._ts_transform;
+        var width = this.pin("width");
+        var height = this.pin("height");
+        this._textures.length = repeat(this._image, width, height, stretch, inner, insert);
+    });
+    function insert(i, sx, sy, sw, sh, dx, dy, dw, dh) {
+        var repeat = self._textures.length > i ? self._textures[i] : self._textures[i] = self._image.pipe();
+        repeat.src(sx, sy, sw, sh);
+        repeat.dest(dx, dy, dw, dh);
     }
 };
 
-Easing.add({
-    mode: "in",
-    fn: function(f) {
-        return f;
-    }
-});
-
-Easing.add({
-    mode: "out",
-    fn: function(f) {
-        return function(t) {
-            return 1 - f(1 - t);
-        };
-    }
-});
 
-Easing.add({
-    mode: "in-out",
-    fn: function(f) {
-        return function(t) {
-            return t < .5 ? f(2 * t) / 2 : 1 - f(2 * (1 - t)) / 2;
-        };
-    }
-});
+},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/repeat":26}],11:[function(require,module,exports){
+module.exports = require("./core");
 
-Easing.add({
-    mode: "out-in",
-    fn: function(f) {
-        return function(t) {
-            return t < .5 ? 1 - f(2 * (1 - t)) / 2 : f(2 * t) / 2;
-        };
-    }
-});
+module.exports.Matrix = require("./matrix");
 
-Easing.add({
-    name: "linear",
-    fn: function(t) {
-        return t;
-    }
-});
+module.exports.Texture = require("./texture");
 
-Easing.add({
-    name: "quad",
-    fn: function(t) {
-        return t * t;
-    }
-});
+require("./atlas");
 
-Easing.add({
-    name: "cubic",
-    fn: function(t) {
-        return t * t * t;
-    }
-});
+require("./node");
 
-Easing.add({
-    name: "quart",
-    fn: function(t) {
-        return t * t * t * t;
-    }
-});
+require("./event");
 
-Easing.add({
-    name: "quint",
-    fn: function(t) {
-        return t * t * t * t * t;
-    }
-});
+require("./pin");
 
-Easing.add({
-    name: "sin sine",
-    fn: function(t) {
-        return 1 - Math.cos(t * Math.PI / 2);
-    }
-});
+require("./render");
 
-Easing.add({
-    name: "exp",
-    fn: function(t) {
-        return t == 0 ? 0 : Math.pow(2, 10 * (t - 1));
-    }
-});
+require("./root");
 
-Easing.add({
-    name: "circle circ",
-    fn: function(t) {
-        return 1 - Math.sqrt(1 - t * t);
-    }
-});
 
-Easing.add({
-    name: "bounce",
-    fn: function(t) {
-        return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
-    }
-});
+},{"./atlas":6,"./core":8,"./event":9,"./matrix":14,"./node":15,"./pin":16,"./render":17,"./root":18,"./texture":20}],12:[function(require,module,exports){
+var Cut = require("./core");
 
-Easing.add({
-    name: "poly",
-    fc: function(e) {
-        return function(t) {
-            return Math.pow(t, e);
-        };
-    }
-});
+require("./pin");
 
-Easing.add({
-    name: "elastic",
-    fc: function(a, p) {
-        p = p || .45;
-        a = a || 1;
-        var s = p / (2 * Math.PI) * Math.asin(1 / a);
-        return function(t) {
-            return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p);
-        };
-    }
-});
+require("./render");
 
-Easing.add({
-    name: "back",
-    fc: function(s) {
-        s = typeof s !== "undefined" ? s : 1.70158;
-        return function(t) {
-            return t * t * ((s + 1) * t - s);
-        };
-    }
-});
+var create = require("./util/create");
 
-module.exports = Easing;
+Cut.row = function(align) {
+    return Cut.create().row(align);
+};
 
+Cut.prototype.row = function(align) {
+    this.sequence("row", align);
+    return this;
+};
 
-},{}],6:[function(require,module,exports){
-var Cut = require("./core");
+Cut.column = function(align) {
+    return Cut.create().column(align);
+};
 
-var is = require("./util/is");
+Cut.prototype.column = function(align) {
+    this.sequence("column", align);
+    return this;
+};
 
-Cut.prototype._listeners = null;
+Cut.sequence = function(type, align) {
+    return Cut.create().sequence(type, align);
+};
 
-Cut.prototype.on = Cut.prototype.listen = function(types, listener) {
-    if (types = _check(this, types, listener, true)) {
-        for (var i = 0; i < types.length; i++) {
-            var type = types[i];
-            this._listeners[type] = this._listeners[type] || [];
-            this._listeners[type].push(listener);
-            this._flag(type, true);
+Cut.prototype.sequence = function(type, align) {
+    this._padding = this._padding || 0;
+    this._spacing = this._spacing || 0;
+    this.untick(this._sequenceTicker);
+    this.tick(this._sequenceTicker = function() {
+        if (this._mo_seq == this._ts_touch) {
+            return;
+        }
+        this._mo_seq = this._ts_touch;
+        var alignChildren = this._mo_seqAlign != this._ts_children;
+        this._mo_seqAlign = this._ts_children;
+        var width = 0, height = 0;
+        var child, next = this.first(true);
+        var first = true;
+        while (child = next) {
+            next = child.next(true);
+            child._pin.relativeMatrix();
+            var w = child.pin("boxWidth");
+            var h = child.pin("boxHeight");
+            if (type == "column") {
+                !first && (height += this._spacing);
+                child.pin("offsetY") != height && child.pin("offsetY", height);
+                width = Math.max(width, w);
+                height = height + h;
+                alignChildren && child.pin("alignX", align);
+            } else if (type == "row") {
+                !first && (width += this._spacing);
+                child.pin("offsetX") != width && child.pin("offsetX", width);
+                width = width + w;
+                height = Math.max(height, h);
+                alignChildren && child.pin("alignY", align);
+            }
+            first = false;
         }
-    }
+        width += 2 * this._padding;
+        height += 2 * this._padding;
+        this.pin("width") != width && this.pin("width", width);
+        this.pin("height") != height && this.pin("height", height);
+    });
     return this;
 };
 
-Cut.prototype.off = function(types, listener) {
-    if (types = _check(this, types, listener, false)) {
-        for (var i = 0; i < types.length; i++) {
-            var type = types[i], all = this._listeners[type], index;
-            if (all && (index = all.indexOf(listener)) >= 0) {
-                all.splice(index, 1);
-                if (!all.length) {
-                    delete this._listeners[type];
-                }
-                this._flag(type, false);
-            }
-        }
-    }
-    return this;
+Cut.box = function() {
+    return Cut.create().box();
 };
 
-function _check(node, types, listener, create) {
-    if (!types || !types.length || typeof listener !== "function") {
-        return false;
-    }
-    if (!(types = (is.array(types) ? types.join(" ") : types).match(/\S+/g))) {
-        return false;
-    }
-    if (node._listeners === null) {
-        if (create) {
-            node._listeners = {};
-        } else {
-            return false;
+Cut.prototype.box = function() {
+    if (this._boxTicker) return this;
+    this._padding = this._padding || 0;
+    this.tick(this._boxTicker = function() {
+        if (this._mo_box == this._ts_touch) {
+            return;
         }
-    }
-    return types;
-}
-
-Cut.prototype.listeners = function(type) {
-    return this._listeners && this._listeners[type];
+        this._mo_box = this._ts_touch;
+        var width = 0, height = 0;
+        var child, next = this.first(true);
+        while (child = next) {
+            next = child.next(true);
+            child._pin.relativeMatrix();
+            var w = child.pin("boxWidth");
+            var h = child.pin("boxHeight");
+            width = Math.max(width, w);
+            height = Math.max(height, h);
+        }
+        width += 2 * this._padding;
+        height += 2 * this._padding;
+        this.pin("width") != width && this.pin("width", width);
+        this.pin("height") != height && this.pin("height", height);
+    });
+    return this;
 };
 
-Cut.prototype.publish = function(name, args) {
-    var listeners = this.listeners(name);
-    if (!listeners || !listeners.length) {
-        return 0;
-    }
-    for (var l = 0; l < listeners.length; l++) {
-        listeners[l].apply(this, args);
-    }
-    return listeners.length;
+// TODO: move padding to pin
+Cut.prototype.padding = function(pad) {
+    this._padding = pad;
+    return this;
 };
 
-Cut.prototype.trigger = function(name, args) {
-    this.publish(name, args);
+Cut.prototype.spacing = function(space) {
+    this._spacing = space;
     return this;
 };
 
 
-},{"./core":4,"./util/is":18}],7:[function(require,module,exports){
-module.exports = require("./core");
-
-module.exports.Matrix = require("./matrix");
-
-module.exports.Texture = require("./texture");
-
-require("./atlas");
-
-require("./canvas");
-
-require("./node");
-
-require("./event");
-
-require("./pin");
-
-require("./ui");
-
-
-},{"./atlas":2,"./canvas":3,"./core":4,"./event":6,"./matrix":9,"./node":11,"./pin":12,"./texture":13,"./ui":15}],8:[function(require,module,exports){
-var Cut = require("./core");
+},{"./core":8,"./pin":16,"./render":17,"./util/create":21}],13:[function(require,module,exports){
+var Cut = require("../core");
 
 if (typeof DEBUG === "undefined") DEBUG = true;
 
@@ -778,7 +1413,7 @@ function ImageLoader(src, success, error) {
 }
 
 
-},{"./core":4}],9:[function(require,module,exports){
+},{"../core":8}],14:[function(require,module,exports){
 function Matrix(a, b, c, d, e, f) {
     this._dirty = true;
     this.a = a || 1;
@@ -926,205 +1561,23 @@ Matrix.prototype.reverse = function() {
 
 Matrix.prototype.map = function(p, q) {
     q = q || {};
-    q.x = this.a * p.x + this.c * p.y + this.e;
-    q.y = this.b * p.x + this.d * p.y + this.f;
-    return q;
-};
-
-Matrix.prototype.mapX = function(x, y) {
-    return this.a * x + this.c * y + this.e;
-};
-
-Matrix.prototype.mapY = function(x, y) {
-    return this.b * x + this.d * y + this.f;
-};
-
-module.exports = Matrix;
-
-
-},{}],10:[function(require,module,exports){
-if (typeof DEBUG === "undefined") DEBUG = true;
-
-function Mouse() {
-    Mouse.subscribe.apply(Mouse, arguments);
-}
-
-Mouse.CLICK = "click";
-
-Mouse.START = "touchstart mousedown";
-
-Mouse.MOVE = "touchmove mousemove";
-
-Mouse.END = "touchend mouseup";
-
-Mouse.CANCEL = "touchcancel";
-
-Mouse.subscribe = function(root, elem) {
-    var visitor = null, data = {}, abs = null, rel = null, clicked = [];
-    elem = elem || document;
-    // click events are synthesized from start/end events on same nodes
-    // elem.addEventListener('click', handleClick);
-    elem.addEventListener("touchstart", handleStart);
-    elem.addEventListener("touchend", handleEnd);
-    elem.addEventListener("touchmove", handleMove);
-    elem.addEventListener("touchcancel", handleCancel);
-    elem.addEventListener("mousedown", handleStart);
-    elem.addEventListener("mouseup", handleEnd);
-    elem.addEventListener("mousemove", handleMove);
-    function handleStart(event) {
-        Mouse._xy(root, elem, event, abs);
-        DEBUG && console.log("Mouse Start: " + event.type + " " + abs);
-        event.preventDefault();
-        publish(event.type, event);
-        findClicks();
-    }
-    function handleEnd(event) {
-        // New xy is not valid/available, last xy is used instead.
-        DEBUG && console.log("Mouse End: " + event.type + " " + abs);
-        event.preventDefault();
-        publish(event.type, event);
-        if (clicked.length) {
-            DEBUG && console.log("Mouse Click: " + clicked.length);
-            fireClicks(event);
-        }
-    }
-    function handleCancel(event) {
-        DEBUG && console.log("Mouse Cancel: " + event.type);
-        event.preventDefault();
-        publish(event.type, event);
-    }
-    function handleMove(event) {
-        Mouse._xy(root, elem, event, abs);
-        // DEBUG && console.log('Mouse Move: ' + event.type + ' ' +
-        // abs);
-        if (!root._flag(event.type)) {
-            return;
-        }
-        event.preventDefault();
-        publish(event.type, event);
-    }
-    function findClicks() {
-        while (clicked.length) {
-            clicked.pop();
-        }
-        publish("click", null, clicked);
-    }
-    function fireClicks(event) {
-        data.event = event;
-        data.type = "click";
-        data.root = root;
-        data.collect = false;
-        var cancel = false;
-        while (clicked.length) {
-            var node = clicked.shift();
-            if (cancel) {
-                continue;
-            }
-            cancel = visitor.end(node, data) ? true : cancel;
-        }
-    }
-    function publish(type, event, collect) {
-        rel.x = abs.x;
-        rel.y = abs.y;
-        data.event = event;
-        data.type = type;
-        data.root = /* root._capture || */ root;
-        data.collect = collect;
-        data.root.visit(visitor, data);
-    }
-    visitor = {
-        reverse: true,
-        visible: true,
-        start: function(node, data) {
-            return !node._flag(data.type);
-        },
-        end: function(node, data) {
-            // data: event, type, root, collect
-            rel.raw = data.event;
-            rel.type = data.type;
-            var listeners = node.listeners(data.type);
-            if (!listeners) {
-                return;
-            }
-            node.matrix().reverse().map(abs, rel);
-            if (!(node === data.root || node.attr("spy") || Mouse._isInside(node, rel))) {
-                return;
-            }
-            if (data.collect) {
-                data.collect.push(node);
-                return;
-            }
-            var cancel = false;
-            for (var l = 0; l < listeners.length; l++) {
-                cancel = listeners[l].call(node, rel) ? true : cancel;
-            }
-            return cancel;
-        }
-    };
-    abs = {
-        x: 0,
-        y: 0,
-        toString: function() {
-            return (this.x | 0) + "x" + (this.y | 0);
-        }
-    };
-    rel = {
-        x: 0,
-        y: 0,
-        toString: function() {
-            return abs + " / " + (this.x | 0) + "x" + (this.y | 0);
-        }
-    };
+    q.x = this.a * p.x + this.c * p.y + this.e;
+    q.y = this.b * p.x + this.d * p.y + this.f;
+    return q;
 };
 
-Mouse._isInside = function(node, point) {
-    return point.x >= 0 && point.x <= node._pin._width && point.y >= 0 && point.y <= node._pin._height;
+Matrix.prototype.mapX = function(x, y) {
+    return this.a * x + this.c * y + this.e;
 };
 
-Mouse._xy = function(root, elem, event, point) {
-    var isTouch = false;
-    // touch screen events
-    if (event.touches) {
-        if (event.touches.length) {
-            isTouch = true;
-            point.x = event.touches[0].pageX;
-            point.y = event.touches[0].pageY;
-        } else {
-            return;
-        }
-    } else {
-        // mouse events
-        point.x = event.clientX;
-        point.y = event.clientY;
-        // See http://goo.gl/JuVnF2
-        if (document.body.scrollLeft || document.body.scrollTop) {} else if (document.documentElement) {
-            point.x += document.documentElement.scrollLeft;
-            point.y += document.documentElement.scrollTop;
-        }
-    }
-    // accounts for border
-    point.x -= elem.clientLeft || 0;
-    point.y -= elem.clientTop || 0;
-    var par = elem;
-    while (par) {
-        point.x -= par.offsetLeft || 0;
-        point.y -= par.offsetTop || 0;
-        if (!isTouch) {
-            // touch events offset scrolling with pageX/Y
-            // so scroll offset not needed for them
-            point.x += par.scrollLeft || 0;
-            point.y += par.scrollTop || 0;
-        }
-        par = par.offsetParent;
-    }
-    point.x *= root.viewport().ratio || 1;
-    point.y *= root.viewport().ratio || 1;
+Matrix.prototype.mapY = function(x, y) {
+    return this.b * x + this.d * y + this.f;
 };
 
-module.exports = Mouse;
+module.exports = Matrix;
 
 
-},{}],11:[function(require,module,exports){
+},{}],15:[function(require,module,exports){
 var Cut = require("./core");
 
 var iid = 0;
@@ -1445,7 +1898,7 @@ function _ensure(obj) {
 module.exports = Cut;
 
 
-},{"./core":4}],12:[function(require,module,exports){
+},{"./core":8}],16:[function(require,module,exports){
 var Cut = require("./core");
 
 var Matrix = require("./matrix");
@@ -1893,250 +2346,26 @@ Pin.prototype._scaleTo = function(width, height, mode) {
             pin._scaleX = pin._scaleY = Math.max(pin._scaleX, pin._scaleY);
         } else if (mode == "in" || mode == "in-pad") {
             pin._scaleX = pin._scaleY = Math.min(pin._scaleX, pin._scaleY);
-        }
-        if (mode == "out-crop" || mode == "in-pad") {
-            pin._width = width / pin._scaleX;
-            pin._height = height / pin._scaleY;
-        }
-    }
-};
-
-module.exports = Pin;
-
-
-},{"./core":4,"./matrix":9}],13:[function(require,module,exports){
-var stats = require("./util/stats");
-
-var math = require("./util/math");
-
-function Texture(image, ratio) {
-    if (typeof image === "object") {
-        this.src(image, ratio);
-    }
-}
-
-Texture.prototype.pipe = function() {
-    return new Texture(this);
-};
-
-/**
- * Signatures: (image), (x, y, w, h), (w, h)
- */
-Texture.prototype.src = function(x, y, w, h) {
-    if (typeof x === "object") {
-        var image = x, ratio = y || 1;
-        this._image = image;
-        this._sx = this._dx = 0;
-        this._sy = this._dy = 0;
-        this._sw = this._dw = image.width / ratio;
-        this._sh = this._dh = image.height / ratio;
-        this.width = image.width / ratio;
-        this.height = image.height / ratio;
-        this.ratio = ratio;
-    } else {
-        if (typeof w === "undefined") {
-            w = x, h = y;
-        } else {
-            this._sx = x, this._sy = y;
-        }
-        this._sw = this._dw = w;
-        this._sh = this._dh = h;
-        this.width = w;
-        this.height = h;
-    }
-    return this;
-};
-
-/**
- * Signatures: (x, y, w, h), (x, y)
- */
-Texture.prototype.dest = function(x, y, w, h) {
-    this._dx = x, this._dy = y;
-    this._dx = x, this._dy = y;
-    if (typeof w !== "undefined") {
-        this._dw = w, this._dh = h;
-        this.width = w, this.height = h;
-    }
-    return this;
-};
-
-Texture.prototype.draw = function(context, x1, y1, x2, y2, x3, y3, x4, y4) {
-    var image = this._image;
-    if (image === null || typeof image !== "object") {
-        return;
-    }
-    var sx = this._sx, sy = this._sy;
-    var sw = this._sw, sh = this._sh;
-    var dx = this._dx, dy = this._dy;
-    var dw = this._dw, dh = this._dh;
-    if (typeof x3 !== "undefined") {
-        x1 = math.limit(x1, 0, this._sw), x2 = math.limit(x2, 0, this._sw - x1);
-        y1 = math.limit(y1, 0, this._sh), y2 = math.limit(y2, 0, this._sh - y1);
-        sx += x1, sy += y1, sw = x2, sh = y2;
-        dx = x3, dy = y3, dw = x4, dh = y4;
-    } else if (typeof x2 !== "undefined") {
-        dx = x1, dy = y1, dw = x2, dh = y2;
-    } else if (typeof x1 !== "undefined") {
-        dw = x1, dh = y1;
-    }
-    var ratio = this.ratio || 1;
-    sx *= ratio, sy *= ratio, sw *= ratio, sh *= ratio;
-    try {
-        if (typeof image.draw === "function") {
-            image.draw(context, sx, sy, sw, sh, dx, dy, dw, dh);
-        } else {
-            stats.draw++;
-            context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
-        }
-    } catch (ex) {
-        if (!image._draw_failed) {
-            console.log("Unable to draw: ", image);
-            console.log(ex);
-            image._draw_failed = true;
-        }
-    }
-};
-
-module.exports = Texture;
-
-
-},{"./util/math":19,"./util/stats":22}],14:[function(require,module,exports){
-var Easing = require("./easing");
-
-var Cut = require("./core");
-
-var Pin = require("./pin");
-
-Cut.prototype.tween = function(duration, delay) {
-    if (!this._tween) {
-        this._tween = new Tween(this);
-    }
-    return this._tween.tween(duration, delay);
-};
-
-var iid = 0;
-
-function Tween(node) {
-    // TODO: reuse head.start/keys/end
-    var tween = this;
-    this._owner = node;
-    this._queue = [];
-    this._next = null;
-    var lastTime = 0;
-    node.tick(function(elapsed, now, last) {
-        if (!tween._queue.length) {
-            return;
-        }
-        // ignore old elapsed
-        var ignore = lastTime != last;
-        lastTime = now;
-        this.touch();
-        if (ignore) {
-            return;
-        }
-        var head = tween._queue[0];
-        if (!head.time) {
-            head.time = 1;
-        } else {
-            head.time += elapsed;
-        }
-        if (head.time < head.delay) {
-            return;
-        }
-        if (!head.start) {
-            head.start = {};
-            head.keys = {};
-            for (var key in head.end) {
-                if (typeof (start = node.pin(key)) === "number") {
-                    head.start[key] = start;
-                    head.keys[key] = key;
-                } else if (typeof (startX = node.pin(key + "X")) === "number" && typeof (startY = node.pin(key + "Y")) === "number") {
-                    head.start[key + "X"] = startX;
-                    head.keys[key + "X"] = key;
-                    head.start[key + "Y"] = startY;
-                    head.keys[key + "Y"] = key;
-                }
-            }
-        }
-        var p = (head.time - head.delay) / head.duration;
-        var over = p >= 1;
-        p = p > 1 ? 1 : p;
-        p = typeof head.easing == "function" ? head.easing(p) : p;
-        var q = 1 - p;
-        for (var key in head.keys) {
-            node.pin(key, head.start[key] * q + head.end[head.keys[key]] * p);
-        }
-        if (over) {
-            tween._queue.shift();
-            head.then && head.then.call(node);
-        }
-    }, true);
-}
-
-Tween.prototype.tween = function(duration, delay) {
-    this._next = {
-        id: ++iid,
-        end: {},
-        duration: duration || 400,
-        delay: delay || 0
-    };
-    return this;
-};
-
-Tween.prototype.pin = function(a, b) {
-    if (this._next !== this._queue[this._queue.length - 1]) {
-        this._owner.touch();
-        this._queue.push(this._next);
-    }
-    var end = this._next.end;
-    if (typeof a === "object") {
-        for (var attr in a) {
-            end[attr] = a[attr];
-        }
-    } else if (typeof b !== "undefined") {
-        end[a] = b;
-    }
-    return this;
-};
-
-Tween.prototype.clear = function(forward) {
-    var tween;
-    while (tween = this._queue.shift()) {
-        forward && this._owner.pin(tween.end);
+        }
+        if (mode == "out-crop" || mode == "in-pad") {
+            pin._width = width / pin._scaleX;
+            pin._height = height / pin._scaleY;
+        }
     }
-    return this;
-};
-
-Tween.prototype.then = function(then) {
-    this._next.then = then;
-    return this;
-};
-
-Tween.prototype.ease = function(easing) {
-    this._next.easing = Easing(easing);
-    return this;
 };
 
-module.exports = Tween;
+module.exports = Pin;
 
 
-},{"./core":4,"./easing":5,"./pin":12}],15:[function(require,module,exports){
+},{"./core":8,"./matrix":14}],17:[function(require,module,exports){
 var Cut = require("./core");
 
-var Pin = require("./pin");
+require("./pin");
 
 var stats = require("./util/stats");
 
-var repeat = require("./util/repeat");
-
 var create = require("./util/create");
 
-var extend = require("./util/extend");
-
-var math = require("./util/math");
-
-var is = require("./util/is");
-
 Cut.prototype._textures = null;
 
 Cut.prototype._tickBefore = null;
@@ -2236,6 +2465,20 @@ Cut.prototype.untick = function(ticker) {
     }
 };
 
+
+},{"./core":8,"./pin":16,"./util/create":21,"./util/stats":27}],18:[function(require,module,exports){
+var Cut = require("./core");
+
+require("./pin");
+
+require("./render");
+
+var stats = require("./util/stats");
+
+var create = require("./util/create");
+
+var extend = require("./util/extend");
+
 Root._super = Cut;
 
 Root.prototype = create(Root._super.prototype);
@@ -2279,260 +2522,91 @@ Root.prototype.start = function() {
     return this.resume();
 };
 
-Root.prototype.resume = function(force) {
-    if (this._paused || force) {
-        this._paused = false;
-        this.request();
-    }
-    return this;
-};
-
-Root.prototype.pause = function() {
-    this._paused = true;
-    return this;
-};
-
-Root.prototype.touch = function() {
-    this.resume();
-    return Root._super.prototype.touch.call(this);
-};
-
-Root.prototype.background = function(color) {
-    // to be implemented by loaders
-    return this;
-};
-
-Root.prototype.viewport = function(width, height, ratio) {
-    if (typeof width === "undefined") {
-        return extend({}, this._viewport);
-    }
-    this._viewport = {
-        width: width,
-        height: height,
-        ratio: ratio || 1
-    };
-    this._updateViewbox();
-    var data = extend({}, this._viewport);
-    this.visit({
-        start: function(node) {
-            if (!node._flag("viewport")) {
-                return true;
-            }
-            node.publish("viewport", [ data ]);
-        }
-    });
-    return this;
-};
-
-// TODO: static/fixed viewbox
-Root.prototype.viewbox = function(width, height, mode) {
-    this._viewbox = {
-        width: width,
-        height: height,
-        mode: /^(in|out|in-pad|out-crop)$/.test(mode) ? mode : "in-pad"
-    };
-    this._updateViewbox();
-    return this;
-};
-
-Root.prototype._updateViewbox = function() {
-    var box = this._viewbox;
-    var size = this._viewport;
-    if (size && box) {
-        this.pin({
-            width: box.width,
-            height: box.height
-        });
-        this._pin._scaleTo(size.width, size.height, box.mode);
-    } else if (size) {
-        this.pin({
-            width: size.width,
-            height: size.height
-        });
-    }
-};
-
-Cut.image = function(image) {
-    var img = new Image();
-    image && img.image(image);
-    return img;
-};
-
-Image._super = Cut;
-
-Image.prototype = create(Image._super.prototype);
-
-function Image() {
-    Image._super.call(this);
-    this.label("Image");
-    this._textures = [];
-    this._image = null;
-}
-
-/**
- * @deprecated Use image
- */
-Image.prototype.setImage = function(a, b, c) {
-    return this.image(a, b, c);
-};
-
-Image.prototype.image = function(image) {
-    this._image = Cut.texture(image).one();
-    this.pin("width", this._image ? this._image.width : 0);
-    this.pin("height", this._image ? this._image.height : 0);
-    this._textures[0] = this._image.pipe();
-    this._textures.length = 1;
-    return this;
-};
-
-Image.prototype.tile = function(inner) {
-    this._repeat(false, inner);
-    return this;
-};
-
-Image.prototype.stretch = function(inner) {
-    this._repeat(true, inner);
-    return this;
-};
-
-Image.prototype._repeat = function(stretch, inner) {
-    var self = this;
-    this.untick(this._repeatTicker);
-    this.tick(this._repeatTicker = function() {
-        if (this._mo_stretch == this._pin._ts_transform) {
-            return;
-        }
-        this._mo_stretch = this._pin._ts_transform;
-        var width = this.pin("width");
-        var height = this.pin("height");
-        this._textures.length = repeat(this._image, width, height, stretch, inner, insert);
-    });
-    function insert(i, sx, sy, sw, sh, dx, dy, dw, dh) {
-        var repeat = self._textures.length > i ? self._textures[i] : self._textures[i] = self._image.pipe();
-        repeat.src(sx, sy, sw, sh);
-        repeat.dest(dx, dy, dw, dh);
-    }
-};
-
-Cut.anim = function(frames, fps) {
-    var anim = new Anim();
-    anim.frames(frames).gotoFrame(0);
-    fps && anim.fps(fps);
-    return anim;
-};
-
-Anim._super = Cut;
-
-Anim.prototype = create(Anim._super.prototype);
-
-Anim.FPS = 12;
-
-function Anim() {
-    Anim._super.call(this);
-    this.label("Anim");
-    this._textures = [];
-    this._fps = Anim.FPS;
-    this._ft = 1e3 / this._fps;
-    this._time = -1;
-    this._repeat = 0;
-    this._index = 0;
-    this._frames = [];
-    var lastTime = 0;
-    this.tick(function(t, now, last) {
-        if (this._time < 0 || this._frames.length <= 1) {
-            return;
-        }
-        // ignore old elapsed
-        var ignore = lastTime != last;
-        lastTime = now;
-        if (ignore) {
-            return true;
-        }
-        this._time += t;
-        if (this._time < this._ft) {
-            return true;
-        }
-        var n = this._time / this._ft | 0;
-        this._time -= n * this._ft;
-        this.moveFrame(n);
-        if (this._repeat > 0 && (this._repeat -= n) <= 0) {
-            this.stop();
-            this._callback && this._callback();
-            return false;
-        }
-        return true;
-    }, false);
-}
-
-Anim.prototype.fps = function(fps) {
-    if (typeof fps === "undefined") {
-        return this._fps;
-    }
-    this._fps = fps > 0 ? fps : Cut.Anim.FPS;
-    this._ft = 1e3 / this._fps;
-    return this;
-};
-
-/**
- * @deprecated Use frames
- */
-Anim.prototype.setFrames = function(a, b, c) {
-    return this.frames(a, b, c);
-};
-
-Anim.prototype.frames = function(frames) {
-    this._index = 0;
-    this._frames = Cut.texture(frames).array();
-    this.touch();
-    return this;
-};
-
-Anim.prototype.length = function() {
-    return this._frames ? this._frames.length : 0;
-};
-
-Anim.prototype.gotoFrame = function(frame, resize) {
-    this._index = math.rotate(frame, this._frames.length) | 0;
-    resize = resize || !this._textures[0];
-    this._textures[0] = this._frames[this._index];
-    if (resize) {
-        this.pin("width", this._textures[0].width);
-        this.pin("height", this._textures[0].height);
+Root.prototype.resume = function(force) {
+    if (this._paused || force) {
+        this._paused = false;
+        this.request();
     }
-    this.touch();
     return this;
 };
 
-Anim.prototype.moveFrame = function(move) {
-    return this.gotoFrame(this._index + move);
+Root.prototype.pause = function() {
+    this._paused = true;
+    return this;
 };
 
-Anim.prototype.repeat = function(repeat, callback) {
-    this._repeat = repeat * this._frames.length - 1;
-    this._callback = callback;
-    this.play();
+Root.prototype.touch = function() {
+    this.resume();
+    return Root._super.prototype.touch.call(this);
+};
+
+Root.prototype.background = function(color) {
+    // to be implemented by loaders
     return this;
 };
 
-Anim.prototype.play = function(frame) {
-    if (typeof frame !== "undefined") {
-        this.gotoFrame(frame);
-        this._time = 0;
-    } else if (this._time < 0) {
-        this._time = 0;
+Root.prototype.viewport = function(width, height, ratio) {
+    if (typeof width === "undefined") {
+        return extend({}, this._viewport);
     }
-    this.touch();
+    this._viewport = {
+        width: width,
+        height: height,
+        ratio: ratio || 1
+    };
+    this._updateViewbox();
+    var data = extend({}, this._viewport);
+    this.visit({
+        start: function(node) {
+            if (!node._flag("viewport")) {
+                return true;
+            }
+            node.publish("viewport", [ data ]);
+        }
+    });
     return this;
 };
 
-Anim.prototype.stop = function(frame) {
-    this._time = -1;
-    if (typeof frame !== "undefined") {
-        this.gotoFrame(frame);
-    }
+// TODO: static/fixed viewbox
+Root.prototype.viewbox = function(width, height, mode) {
+    this._viewbox = {
+        width: width,
+        height: height,
+        mode: /^(in|out|in-pad|out-crop)$/.test(mode) ? mode : "in-pad"
+    };
+    this._updateViewbox();
     return this;
 };
 
+Root.prototype._updateViewbox = function() {
+    var box = this._viewbox;
+    var size = this._viewport;
+    if (size && box) {
+        this.pin({
+            width: box.width,
+            height: box.height
+        });
+        this._pin._scaleTo(size.width, size.height, box.mode);
+    } else if (size) {
+        this.pin({
+            width: size.width,
+            height: size.height
+        });
+    }
+};
+
+
+},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/extend":22,"./util/stats":27}],19:[function(require,module,exports){
+var Cut = require("./core");
+
+require("./pin");
+
+require("./render");
+
+var create = require("./util/create");
+
+var is = require("./util/is");
+
 Cut.string = function(frames) {
     return new Str().frames(frames);
 };
@@ -2606,113 +2680,104 @@ Str.prototype.value = function(value) {
     return this;
 };
 
-Cut.row = function(align) {
-    return Cut.create().row(align);
-};
 
-Cut.prototype.row = function(align) {
-    this.sequence("row", align);
-    return this;
-};
+},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/is":23}],20:[function(require,module,exports){
+var stats = require("./util/stats");
 
-Cut.column = function(align) {
-    return Cut.create().column(align);
-};
+var math = require("./util/math");
 
-Cut.prototype.column = function(align) {
-    this.sequence("column", align);
-    return this;
-};
+function Texture(image, ratio) {
+    if (typeof image === "object") {
+        this.src(image, ratio);
+    }
+}
 
-Cut.sequence = function(type, align) {
-    return Cut.create().sequence(type, align);
+Texture.prototype.pipe = function() {
+    return new Texture(this);
 };
 
-Cut.prototype.sequence = function(type, align) {
-    this._padding = this._padding || 0;
-    this._spacing = this._spacing || 0;
-    this.untick(this._sequenceTicker);
-    this.tick(this._sequenceTicker = function() {
-        if (this._mo_seq == this._ts_touch) {
-            return;
-        }
-        this._mo_seq = this._ts_touch;
-        var alignChildren = this._mo_seqAlign != this._ts_children;
-        this._mo_seqAlign = this._ts_children;
-        var width = 0, height = 0;
-        var child, next = this.first(true);
-        var first = true;
-        while (child = next) {
-            next = child.next(true);
-            child._pin.relativeMatrix();
-            var w = child.pin("boxWidth");
-            var h = child.pin("boxHeight");
-            if (type == "column") {
-                !first && (height += this._spacing);
-                child.pin("offsetY") != height && child.pin("offsetY", height);
-                width = Math.max(width, w);
-                height = height + h;
-                alignChildren && child.pin("alignX", align);
-            } else if (type == "row") {
-                !first && (width += this._spacing);
-                child.pin("offsetX") != width && child.pin("offsetX", width);
-                width = width + w;
-                height = Math.max(height, h);
-                alignChildren && child.pin("alignY", align);
-            }
-            first = false;
+/**
+ * Signatures: (image), (x, y, w, h), (w, h)
+ */
+Texture.prototype.src = function(x, y, w, h) {
+    if (typeof x === "object") {
+        var image = x, ratio = y || 1;
+        this._image = image;
+        this._sx = this._dx = 0;
+        this._sy = this._dy = 0;
+        this._sw = this._dw = image.width / ratio;
+        this._sh = this._dh = image.height / ratio;
+        this.width = image.width / ratio;
+        this.height = image.height / ratio;
+        this.ratio = ratio;
+    } else {
+        if (typeof w === "undefined") {
+            w = x, h = y;
+        } else {
+            this._sx = x, this._sy = y;
         }
-        width += 2 * this._padding;
-        height += 2 * this._padding;
-        this.pin("width") != width && this.pin("width", width);
-        this.pin("height") != height && this.pin("height", height);
-    });
+        this._sw = this._dw = w;
+        this._sh = this._dh = h;
+        this.width = w;
+        this.height = h;
+    }
     return this;
 };
 
-Cut.box = function() {
-    return Cut.create().box();
+/**
+ * Signatures: (x, y, w, h), (x, y)
+ */
+Texture.prototype.dest = function(x, y, w, h) {
+    this._dx = x, this._dy = y;
+    this._dx = x, this._dy = y;
+    if (typeof w !== "undefined") {
+        this._dw = w, this._dh = h;
+        this.width = w, this.height = h;
+    }
+    return this;
 };
 
-Cut.prototype.box = function() {
-    if (this._boxTicker) return this;
-    this._padding = this._padding || 0;
-    this.tick(this._boxTicker = function() {
-        if (this._mo_box == this._ts_touch) {
-            return;
+Texture.prototype.draw = function(context, x1, y1, x2, y2, x3, y3, x4, y4) {
+    var image = this._image;
+    if (image === null || typeof image !== "object") {
+        return;
+    }
+    var sx = this._sx, sy = this._sy;
+    var sw = this._sw, sh = this._sh;
+    var dx = this._dx, dy = this._dy;
+    var dw = this._dw, dh = this._dh;
+    if (typeof x3 !== "undefined") {
+        x1 = math.limit(x1, 0, this._sw), x2 = math.limit(x2, 0, this._sw - x1);
+        y1 = math.limit(y1, 0, this._sh), y2 = math.limit(y2, 0, this._sh - y1);
+        sx += x1, sy += y1, sw = x2, sh = y2;
+        dx = x3, dy = y3, dw = x4, dh = y4;
+    } else if (typeof x2 !== "undefined") {
+        dx = x1, dy = y1, dw = x2, dh = y2;
+    } else if (typeof x1 !== "undefined") {
+        dw = x1, dh = y1;
+    }
+    var ratio = this.ratio || 1;
+    sx *= ratio, sy *= ratio, sw *= ratio, sh *= ratio;
+    try {
+        if (typeof image.draw === "function") {
+            image.draw(context, sx, sy, sw, sh, dx, dy, dw, dh);
+        } else {
+            stats.draw++;
+            context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
         }
-        this._mo_box = this._ts_touch;
-        var width = 0, height = 0;
-        var child, next = this.first(true);
-        while (child = next) {
-            next = child.next(true);
-            child._pin.relativeMatrix();
-            var w = child.pin("boxWidth");
-            var h = child.pin("boxHeight");
-            width = Math.max(width, w);
-            height = Math.max(height, h);
+    } catch (ex) {
+        if (!image._draw_failed) {
+            console.log("Unable to draw: ", image);
+            console.log(ex);
+            image._draw_failed = true;
         }
-        width += 2 * this._padding;
-        height += 2 * this._padding;
-        this.pin("width") != width && this.pin("width", width);
-        this.pin("height") != height && this.pin("height", height);
-    });
-    return this;
-};
-
-// TODO: move padding to pin
-Cut.prototype.padding = function(pad) {
-    this._padding = pad;
-    return this;
+    }
 };
 
-Cut.prototype.spacing = function(space) {
-    this._spacing = space;
-    return this;
-};
+module.exports = Texture;
 
 
-},{"./core":4,"./pin":12,"./util/create":16,"./util/extend":17,"./util/is":18,"./util/math":19,"./util/repeat":21,"./util/stats":22}],16:[function(require,module,exports){
+},{"./util/math":24,"./util/stats":27}],21:[function(require,module,exports){
 if (typeof Object.create == "function") {
     module.exports = function(proto, props) {
         return Object.create.call(Object, proto, props);
@@ -2728,7 +2793,7 @@ if (typeof Object.create == "function") {
 }
 
 
-},{}],17:[function(require,module,exports){
+},{}],22:[function(require,module,exports){
 module.exports = function(base) {
     for (var i = 1; i < arguments.length; i++) {
         var obj = arguments[i];
@@ -2742,7 +2807,7 @@ module.exports = function(base) {
 };
 
 
-},{}],18:[function(require,module,exports){
+},{}],23:[function(require,module,exports){
 var objProto = Object.prototype;
 
 var owns = objProto.hasOwnProperty;
@@ -2893,7 +2958,7 @@ is.hex = function(value) {
 };
 
 
-},{}],19:[function(require,module,exports){
+},{}],24:[function(require,module,exports){
 module.exports.random = function(min, max) {
     if (typeof min === "undefined") {
         max = 1, min = 0;
@@ -2933,7 +2998,7 @@ module.exports.length = function(x, y) {
 };
 
 
-},{}],20:[function(require,module,exports){
+},{}],25:[function(require,module,exports){
 module.exports = function(fn, ctx) {
     var called = false;
     return function() {
@@ -2945,7 +3010,7 @@ module.exports = function(fn, ctx) {
 };
 
 
-},{}],21:[function(require,module,exports){
+},{}],26:[function(require,module,exports){
 module.exports = function(img, owidth, oheight, stretch, inner, insert) {
     var width = img.width;
     var height = img.height;
@@ -2999,11 +3064,11 @@ module.exports = function(img, owidth, oheight, stretch, inner, insert) {
 };
 
 
-},{}],22:[function(require,module,exports){
+},{}],27:[function(require,module,exports){
 module.exports = {};
 
 
-},{}],23:[function(require,module,exports){
+},{}],28:[function(require,module,exports){
 module.exports.startsWith = function(str, sub) {
     return typeof str === "string" && typeof sub === "string" && str.substring(0, sub.length) == sub;
 };
diff --git a/dist/cut.web.min.js b/dist/cut.web.min.js
index 32f2bd3..393b6ef 100644
--- a/dist/cut.web.min.js
+++ b/dist/cut.web.min.js
@@ -1,8 +1,8 @@
 /*
- * CutJS 0.5.0-beta.4
+ * CutJS 0.5.0-beta.5
  * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
  * Available under the MIT license
  * @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;"undefined"!=typeof window?e=window:"undefined"!=typeof global?e=global:"undefined"!=typeof self&&(e=self),e.Cut=t()}}(function(){return function t(e,i,n){function r(o,h){if(!i[o]){if(!e[o]){var a="function"==typeof require&&require;if(!h&&a)return a(o,!0);if(s)return s(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var f=i[o]={exports:{}};e[o][0].call(f.exports,function(t){var i=e[o][1][t];return r(i?i:t)},f,f.exports,t,e,i,n)}return i[o].exports}for(var s="function"==typeof require&&require,o=0;o<n.length;o++)r(n[o]);return r}({1:[function(t,e){e.exports=t("../lib/"),e.exports.Mouse=t("../lib/mouse"),e.exports.Math=t("../lib/util/math"),t("../lib/tween"),t("../lib/loader.web"),e.exports._extend=t("../lib/util/extend"),e.exports._create=t("../lib/util/create")},{"../lib/":7,"../lib/loader.web":8,"../lib/mouse":10,"../lib/tween":14,"../lib/util/create":16,"../lib/util/extend":17,"../lib/util/math":19}],2:[function(t,e){function i(t){function e(t){if(!t||u.fn(t.draw))return t;t=h({},t),u.fn(a)&&(t=a(t)),1!=c&&(t.x*=c,t.y*=c,t.width*=c,t.height*=c,t.top*=c,t.bottom*=c,t.left*=c,t.right*=c),0!=_&&(t.x+=_,t.y+=_,t.width-=2*_,t.height-=2*_,t.top-=_,t.bottom-=_,t.left-=_,t.right-=_);var e=o.pipe();return e.top=t.top,e.bottom=t.bottom,e.left=t.left,e.right=t.right,e.src(t.x,t.y,t.width,t.height),e}function s(t){if(p){if(u.fn(p))return p(t);if(u.hash(p))return p[t]}if(d){for(var e=null,i=0,n=0;n<d.length;n++)f.startsWith(d[n].name,t)&&(0===i?e=d[n]:1===i?e=[e,d[n]]:e.push(d[n]),i++);return 0===i&&u.fn(l)&&(e=function(e){return l(t+(e?e:""))}),e}}i._super.call(this);var o=this;r(t,"filter"),r(t,"cutouts"),r(t,"sprites"),r(t,"factory");var a=t.map||t.filter,c=t.ppu||t.ratio||1,_=t.trim||0,p=t.textures,l=t.factory,d=t.cutouts||t.sprites;this.select=function(t){var i=s(t);return i?new n(i,s,e):void 0}}function n(t,e,i){function n(t,r){return t?u.fn(t.draw)?t:u.hash(t)&&u.number(t.width)&&u.number(t.height)&&u.fn(i)?i(t):u.hash(t)&&u.defined(r)?n(t[r]):u.fn(t)?n(t(r)):u.array(t)?n(t[0]):u.string(t)&&u.fn(e)?n(e(t)):void 0:p}this.one=function(e){return n(t,e)},this.array=function(e){var i=u.array(e)?e:[];if(u.array(t))for(var r=0;r<t.length;r++)i[r]=n(t[r]);else i[0]=n(t);return i}}function r(t,e,i){e in t&&console.log(i?i.replace("%name",e):"'"+e+"' field of texture atlas is deprecated.")}var s=t("./core"),o=t("./texture"),h=t("./util/extend"),a=t("./util/create"),u=t("./util/is"),f=t("./util/string"),c={},_=[];s.atlas=function(t){var e=u.fn(t.draw)?t:new i(t);t.name&&(c[t.name]=e),_.push(e),r(t,"imagePath"),r(t,"imageRatio");var n=t.imagePath,o=t.imageRatio||1;return u.string(t.image)?n=t.image:u.hash(t.image)&&(n=t.image.url,o=t.image.ratio||o),n&&s.preload(function(t){DEBUG&&console.log("Loading image: "+n);var i=s.config("image-loader");i(n,function(i){DEBUG&&console.log("Image loaded: "+n),e.src(i,o),t()},function(e){DEBUG&&console.log("Error loading image: "+n,e),t()})}),e},i._super=o,i.prototype=a(i._super.prototype);var p=new o;p.x=p.y=p.width=p.height=0,p.pipe=p.src=p.dest=function(){return this},p.draw=function(){};var l=new n(p);s.texture=function(t){if(!u.string(t))return new n(t);var e=null,i=t.indexOf(":");if(i>0&&t.length>i+1){var r=c[t.slice(0,i)];e=r&&r.select(t.slice(i+1))}for(var i=0;!e&&i<_.length;i++)e=_[i].select(t);return e||(console.error("Texture not found: "+t),e=l),e},e.exports=i},{"./core":4,"./texture":13,"./util/create":16,"./util/extend":17,"./util/is":18,"./util/string":23}],3:[function(t){var e=t("./core"),i=t("./texture");e.canvas=function(t,e,n){"string"==typeof t?"object"==typeof e||("function"==typeof e&&(n=e),e={}):("function"==typeof t&&(n=t),e={},t="2d");var r=document.createElement("canvas"),s=r.getContext(t,e),o=new i(r);return o.context=function(){return s},o.size=function(t,e,i){return r.width=t*i,r.height=e*i,this.src(r,i),this},o.canvas=function(t){return"function"==typeof t?t.call(this,s):"undefined"==typeof t&&"function"==typeof n&&n.call(this,s),this},"function"==typeof n&&n.call(this,s),o}},{"./core":4,"./texture":13}],4:[function(t,e){function i(t){if(!(this instanceof i))return o.fn(t)?i.app.apply(i,arguments):o.object(t)?i.atlas.apply(i,arguments):t;n.create++;for(var e=0;e<h.length;e++)h[e].call(this)}"undefined"==typeof DEBUG&&(DEBUG=!0);var n=t("./util/stats"),r=t("./util/extend"),s=t("./util/once"),o=t("./util/is");n.create=0;var h=[];i._init=function(t){h.push(t)};var a={};i.config=function(){return 1===arguments.length&&o.string(arguments[0])?a[arguments[0]]:(1===arguments.length&&o.object(arguments[0])&&r(a,arguments[0]),void(2===arguments.length&&o.string(arguments[0])&&a[(arguments[0],arguments[1])]))};var u=[],f=[],c=[],_=!1,p=!1;i.app=function(t,e){if(!_)return void u.push(arguments);DEBUG&&console.log("Creating app...");var n=i.config("app-loader");n(function(e,i){DEBUG&&console.log("Initing app..."),t(e,i),c.push(e),DEBUG&&console.log("Starting app..."),e.start()},e)},i.preload=function(t){return _?void t(function(){}):void f.push(t)},i.start=function(t){function e(){if(--n<=0)for(DEBUG&&console.log("Loading apps..."),_=!0;u.length;){var t=u.shift();i.app.apply(i,t)}}DEBUG&&console.log("Starting..."),i.config(t),DEBUG&&console.log("Preloading...");var n=0;if(f.length)for(;f.length;){var r=f.shift();r(s(e)),n++}else e()},i.pause=function(){if(!p){p=!0;for(var t=c.length-1;t>=0;t--)c[t].pause()}},i.resume=function(){if(p){p=!1;for(var t=c.length-1;t>=0;t--)c[t].resume()}},i.create=function(){return new i},e.exports=i},{"./util/extend":17,"./util/is":18,"./util/once":20,"./util/stats":22}],5:[function(t,e){function i(t){return t}function n(t){if("function"==typeof t)return t;if("string"!=typeof t)return i;var e=r[t];if(e)return e;var n=/^(\w+)(-(in|out|in-out|out-in))?(\((.*)\))?$/i.exec(t);return n&&n.length?(easing=o[n[1]],mode=s[n[3]],params=n[5],e=easing&&easing.fn?easing.fn:easing&&easing.fc?easing.fc.apply(easing.fc,params&&params.replace(/\s+/,"").split(",")):i,mode&&(e=mode.fn(e)),r[t]=e,e):i}var r={},s={},o={};n.add=function(t){for(var e=(t.name||t.mode).split(/\s+/),i=0;i<e.length;i++){var n=e[i];n&&((t.name?o:s)[n]=t)}},n.add({mode:"in",fn:function(t){return t}}),n.add({mode:"out",fn:function(t){return function(e){return 1-t(1-e)}}}),n.add({mode:"in-out",fn:function(t){return function(e){return.5>e?t(2*e)/2:1-t(2*(1-e))/2}}}),n.add({mode:"out-in",fn:function(t){return function(e){return.5>e?1-t(2*(1-e))/2:t(2*e)/2}}}),n.add({name:"linear",fn:function(t){return t}}),n.add({name:"quad",fn:function(t){return t*t}}),n.add({name:"cubic",fn:function(t){return t*t*t}}),n.add({name:"quart",fn:function(t){return t*t*t*t}}),n.add({name:"quint",fn:function(t){return t*t*t*t*t}}),n.add({name:"sin sine",fn:function(t){return 1-Math.cos(t*Math.PI/2)}}),n.add({name:"exp",fn:function(t){return 0==t?0:Math.pow(2,10*(t-1))}}),n.add({name:"circle circ",fn:function(t){return 1-Math.sqrt(1-t*t)}}),n.add({name:"bounce",fn:function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}}),n.add({name:"poly",fc:function(t){return function(e){return Math.pow(e,t)}}}),n.add({name:"elastic",fc:function(t,e){e=e||.45,t=t||1;var i=e/(2*Math.PI)*Math.asin(1/t);return function(n){return 1+t*Math.pow(2,-10*n)*Math.sin(2*(n-i)*Math.PI/e)}}}),n.add({name:"back",fc:function(t){return t="undefined"!=typeof t?t:1.70158,function(e){return e*e*((t+1)*e-t)}}}),e.exports=n},{}],6:[function(t){function e(t,e,i,r){if(!e||!e.length||"function"!=typeof i)return!1;if(!(e=(n.array(e)?e.join(" "):e).match(/\S+/g)))return!1;if(null===t._listeners){if(!r)return!1;t._listeners={}}return e}var i=t("./core"),n=t("./util/is");i.prototype._listeners=null,i.prototype.on=i.prototype.listen=function(t,i){if(t=e(this,t,i,!0))for(var n=0;n<t.length;n++){var r=t[n];this._listeners[r]=this._listeners[r]||[],this._listeners[r].push(i),this._flag(r,!0)}return this},i.prototype.off=function(t,i){if(t=e(this,t,i,!1))for(var n=0;n<t.length;n++){var r,s=t[n],o=this._listeners[s];o&&(r=o.indexOf(i))>=0&&(o.splice(r,1),o.length||delete this._listeners[s],this._flag(s,!1))}return this},i.prototype.listeners=function(t){return this._listeners&&this._listeners[t]},i.prototype.publish=function(t,e){var i=this.listeners(t);if(!i||!i.length)return 0;for(var n=0;n<i.length;n++)i[n].apply(this,e);return i.length},i.prototype.trigger=function(t,e){return this.publish(t,e),this}},{"./core":4,"./util/is":18}],7:[function(t,e){e.exports=t("./core"),e.exports.Matrix=t("./matrix"),e.exports.Texture=t("./texture"),t("./atlas"),t("./canvas"),t("./node"),t("./event"),t("./pin"),t("./ui")},{"./atlas":2,"./canvas":3,"./core":4,"./event":6,"./matrix":9,"./node":11,"./pin":12,"./texture":13,"./ui":15}],8:[function(t){function e(t,e){function i(){o.setTransform(1,0,0,1,0,0),o.clearRect(0,0,a,u),d.render(o)}function r(){h?(a=window.innerWidth>0?window.innerWidth:screen.width,u=window.innerHeight>0?window.innerHeight:screen.height,s.style.width=a+"px",s.style.height=u+"px"):(a=s.clientWidth,u=s.clientHeight),a*=f,u*=f,(s.width!==a||s.height!==u)&&(s.width=a,s.height=u,DEBUG&&console.log("Resize: "+a+" x "+u+" / "+f),d.viewport(a,u,f),i())}e=e||{};var s=e.canvas,o=null,h=!1,a=0,u=0,f=1;if("string"==typeof s&&(s=document.getElementById(s)),s||(s=document.getElementById("cutjs")),!s){h=!0,DEBUG&&console.log("Creating Canvas..."),s=document.createElement("canvas"),s.style.position="absolute";var c=document.body;c.insertBefore(s,c.firstChild)}o=s.getContext("2d");var _=window.devicePixelRatio||1,p=o.webkitBackingStorePixelRatio||o.mozBackingStorePixelRatio||o.msBackingStorePixelRatio||o.oBackingStorePixelRatio||o.backingStorePixelRatio||1;f=_/p;var l=window.requestAnimationFrame||window.msRequestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.oRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)};DEBUG&&console.log("Creating root...");var d=n.root(l,i);d.background=function(t){return s.style.backgroundColor=t,this},t(d,s),r(),window.addEventListener("resize",r,!1),window.addEventListener("orientationchange",r,!1)}function i(t,e,i){DEBUG&&console.log("Loading image: "+t);var n=new Image;n.onload=function(){e(n)},n.onerror=i,n.src=t}var n=t("./core");"undefined"==typeof DEBUG&&(DEBUG=!0),window.addEventListener("load",function(){DEBUG&&console.log("On load."),n.start({"app-loader":e,"image-loader":i})},!1)},{"./core":4}],9:[function(t,e){function i(t,e,i,n,r,s){this._dirty=!0,this.a=t||1,this.b=e||0,this.c=i||0,this.d=n||1,this.e=r||0,this.f=s||0}i.prototype.toString=function(){return"["+this.a+", "+this.b+", "+this.c+", "+this.d+", "+this.e+", "+this.f+"]"},i.prototype.clone=function(){return new i(this.a,this.b,this.c,this.d,this.e,this.f)},i.prototype.copyTo=function(t){return t.copyFrom(this),this},i.prototype.copyFrom=function(t){return this._dirty=!0,this.a=t.a,this.b=t.b,this.c=t.c,this.d=t.d,this.e=t.e,this.f=t.f,this},i.prototype.identity=function(){return this._dirty=!0,this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0,this},i.prototype.rotate=function(t){if(!t)return this;this._dirty=!0;var e=t?Math.cos(t):1,i=t?Math.sin(t):0,n=e*this.a-i*this.b,r=e*this.b+i*this.a,s=e*this.c-i*this.d,o=e*this.d+i*this.c,h=e*this.e-i*this.f,a=e*this.f+i*this.e;return this.a=n,this.b=r,this.c=s,this.d=o,this.e=h,this.f=a,this},i.prototype.translate=function(t,e){return t||e?(this._dirty=!0,this.e+=t,this.f+=e,this):this},i.prototype.scale=function(t,e){return t-1||e-1?(this._dirty=!0,this.a*=t,this.b*=e,this.c*=t,this.d*=e,this.e*=t,this.f*=e,this):this},i.prototype.skew=function(t,e){if(!t&&!e)return this;this._dirty=!0;var i=this.a+this.b*t,n=this.b+this.a*e,r=this.c+this.d*t,s=this.d+this.c*e,o=this.e+this.f*t,h=this.f+this.e*e;return this.a=i,this.b=n,this.c=r,this.d=s,this.e=o,this.f=h,this},i.prototype.concat=function(t){this._dirty=!0;var e=this,i=e.a*t.a+e.b*t.c,n=e.b*t.d+e.a*t.b,r=e.c*t.a+e.d*t.c,s=e.d*t.d+e.c*t.b,o=e.e*t.a+t.e+e.f*t.c,h=e.f*t.d+t.f+e.e*t.b;return this.a=i,this.b=n,this.c=r,this.d=s,this.e=o,this.f=h,this},i.prototype.reverse=function(){if(this._dirty){this._dirty=!1,this.reversed=this.reversed||new i;var t=this.a*this.d-this.b*this.c;this.reversed.a=this.d/t,this.reversed.b=-this.b/t,this.reversed.c=-this.c/t,this.reversed.d=this.a/t,this.reversed.e=(this.c*this.f-this.e*this.d)/t,this.reversed.f=(this.e*this.b-this.a*this.f)/t}return this.reversed},i.prototype.map=function(t,e){return e=e||{},e.x=this.a*t.x+this.c*t.y+this.e,e.y=this.b*t.x+this.d*t.y+this.f,e},i.prototype.mapX=function(t,e){return this.a*t+this.c*e+this.e},i.prototype.mapY=function(t,e){return this.b*t+this.d*e+this.f},e.exports=i},{}],10:[function(t,e){function i(){i.subscribe.apply(i,arguments)}"undefined"==typeof DEBUG&&(DEBUG=!0),i.CLICK="click",i.START="touchstart mousedown",i.MOVE="touchmove mousemove",i.END="touchend mouseup",i.CANCEL="touchcancel",i.subscribe=function(t,e){function n(n){i._xy(t,e,n,_),DEBUG&&console.log("Mouse Start: "+n.type+" "+_),n.preventDefault(),u(n.type,n),h()}function r(t){DEBUG&&console.log("Mouse End: "+t.type+" "+_),t.preventDefault(),u(t.type,t),l.length&&(DEBUG&&console.log("Mouse Click: "+l.length),a(t))}function s(t){DEBUG&&console.log("Mouse Cancel: "+t.type),t.preventDefault(),u(t.type,t)}function o(n){i._xy(t,e,n,_),t._flag(n.type)&&(n.preventDefault(),u(n.type,n))}function h(){for(;l.length;)l.pop();u("click",null,l)}function a(e){c.event=e,c.type="click",c.root=t,c.collect=!1;for(var i=!1;l.length;){var n=l.shift();i||(i=f.end(n,c)?!0:i)}}function u(e,i,n){p.x=_.x,p.y=_.y,c.event=i,c.type=e,c.root=t,c.collect=n,c.root.visit(f,c)}var f=null,c={},_=null,p=null,l=[];e=e||document,e.addEventListener("touchstart",n),e.addEventListener("touchend",r),e.addEventListener("touchmove",o),e.addEventListener("touchcancel",s),e.addEventListener("mousedown",n),e.addEventListener("mouseup",r),e.addEventListener("mousemove",o),f={reverse:!0,visible:!0,start:function(t,e){return!t._flag(e.type)},end:function(t,e){p.raw=e.event,p.type=e.type;var n=t.listeners(e.type);if(n&&(t.matrix().reverse().map(_,p),t===e.root||t.attr("spy")||i._isInside(t,p))){if(e.collect)return void e.collect.push(t);for(var r=!1,s=0;s<n.length;s++)r=n[s].call(t,p)?!0:r;return r}}},_={x:0,y:0,toString:function(){return(0|this.x)+"x"+(0|this.y)}},p={x:0,y:0,toString:function(){return _+" / "+(0|this.x)+"x"+(0|this.y)}}},i._isInside=function(t,e){return e.x>=0&&e.x<=t._pin._width&&e.y>=0&&e.y<=t._pin._height},i._xy=function(t,e,i,n){var r=!1;if(i.touches){if(!i.touches.length)return;r=!0,n.x=i.touches[0].pageX,n.y=i.touches[0].pageY}else n.x=i.clientX,n.y=i.clientY,document.body.scrollLeft||document.body.scrollTop||document.documentElement&&(n.x+=document.documentElement.scrollLeft,n.y+=document.documentElement.scrollTop);n.x-=e.clientLeft||0,n.y-=e.clientTop||0;for(var s=e;s;)n.x-=s.offsetLeft||0,n.y-=s.offsetTop||0,r||(n.x+=s.scrollLeft||0,n.y+=s.scrollTop||0),s=s.offsetParent;n.x*=t.viewport().ratio||1,n.y*=t.viewport().ratio||1},e.exports=i},{}],11:[function(t,e){function i(t){if(t&&t instanceof n)return t;throw"Invalid node: "+t}var n=t("./core"),r=0;n.prototype._label="",n.prototype._visible=!0,n.prototype._parent=null,n.prototype._next=null,n.prototype._prev=null,n.prototype._first=null,n.prototype._last=null,n.prototype._attrs=null,n.prototype._flags=null,n.prototype.toString=function(){return"["+this._label+"]"},n.prototype.id=function(t){return this.label(t)},n.prototype.label=function(t){return"undefined"==typeof t?this._label:(this._label=t,this)},n.prototype.attr=function(t,e){return"undefined"==typeof e?null!==this._attrs?this._attrs[t]:void 0:((null!==this._attrs?this._attrs:this._attrs={})[t]=e,this)},n.prototype.visible=function(t){return"undefined"==typeof t?this._visible:(this._visible=t,this._parent&&(this._parent._ts_children=++r),this._ts_pin=++r,this.touch(),this)},n.prototype.hide=function(){return this.visible(!1)},n.prototype.show=function(){return this.visible(!0)},n.prototype.parent=function(){return this._parent},n.prototype.next=function(t){for(var e=this._next;e&&t&&!e._visible;)e=e._next;return e},n.prototype.prev=function(t){for(var e=this._prev;e&&t&&!e._visible;)e=e._prev;return e},n.prototype.first=function(t){for(var e=this._first;e&&t&&!e._visible;)e=e._next;return e},n.prototype.last=function(t){for(var e=this._last;e&&t&&!e._visible;)e=e._prev;return e},n.prototype.visit=function(t,e){var i=t.reverse,n=t.visible;if(!t.start||!t.start(this,e)){for(var r,s=i?this.last(n):this.first(n);r=s;)if(s=i?r.prev(n):r.next(n),r.visit(t,e))return!0;return t.end&&t.end(this,e)}},n.prototype.append=function(){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t].appendTo(this);return this},n.prototype.prepend=function(){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t].prependTo(this);return this},n.prototype.appendTo=function(t){return i(t),this.remove(),t._last&&(t._last._next=this,this._prev=t._last),this._parent=t,t._last=this,t._first||(t._first=this),this._parent._flag(this,!0),this._ts_parent=++r,t._ts_children=++r,t.touch(),this},n.prototype.prependTo=function(t){return i(t),this.remove(),t._first&&(t._first._prev=this,this._next=t._first),this._parent=t,t._first=this,t._last||(t._last=this),this._parent._flag(this,!0),this._ts_parent=++r,t._ts_children=++r,t.touch(),this},n.prototype.insertNext=function(){if(arguments.length)for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].insertAfter(this);return this},n.prototype.insertPrev=function(){if(arguments.length)for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].insertBefore(this);return this},n.prototype.insertBefore=function(t){i(t),this.remove();var e=t._parent,n=t._prev;return t._prev=this,n&&(n._next=this)||e&&(e._first=this),this._parent=e,this._prev=n,this._next=t,this._parent._flag(this,!0),this._ts_parent=++r,this.touch(),this},n.prototype.insertAfter=function(t){i(t),this.remove();var e=t._parent,n=t._next;return t._next=this,n&&(n._prev=this)||e&&(e._last=this),this._parent=e,this._prev=t,this._next=n,this._parent._flag(this,!0),this._ts_parent=++r,this.touch(),this},n.prototype.remove=function(){if(arguments.length){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].remove();return this}return this._prev&&(this._prev._next=this._next),this._next&&(this._next._prev=this._prev),this._parent&&(this._parent._first===this&&(this._parent._first=this._next),this._parent._last===this&&(this._parent._last=this._prev),this._parent._flag(this,!1),this._parent._ts_children=++r,this._parent.touch()),this._prev=this._next=this._parent=null,this._ts_parent=++r,this},n.prototype.empty=function(){for(var t,e=this._first;t=e;)e=t._next,t._prev=t._next=t._parent=null,this._flag(t,!1);return this._first=this._last=null,this._ts_children=++r,this.touch(),this},n.prototype.touch=function(){return this._ts_touch=++r,this._parent&&this._parent.touch(),this},n.prototype._flag=function(t,e){if("undefined"==typeof e)return null!==this._flags&&this._flags[t]||0;if("string"==typeof t&&(e?(this._flags=this._flags||{},!this._flags[t]&&this._parent&&this._parent._flag(t,!0),this._flags[t]=(this._flags[t]||0)+1):this._flags&&this._flags[t]>0&&(1==this._flags[t]&&this._parent&&this._parent._flag(t,!1),this._flags[t]=this._flags[t]-1)),"object"==typeof t&&t._flags)for(var i in t._flags)t._flags[i]>0&&this._flag(i,e);return this},e.exports=n},{"./core":4}],12:[function(t,e){function i(t){this._owner=t,this._parent=null,this._relativeMatrix=new r,this._absoluteMatrix=new r,this.reset()}var n=t("./core"),r=t("./matrix"),s=0;n._init(function(){this._pin=new i(this)}),n.prototype.matrix=function(){return this._pin.absoluteMatrix()},n.prototype.pin=function(t,e){return"object"==typeof t?(this._pin.set(t),this):"string"==typeof t?"undefined"==typeof e?this._pin.get(t):(this._pin.set(t,e),this):"undefined"==typeof t?this._pin:void 0},i.prototype.reset=function(){this._textureAlpha=1,this._alpha=1,this._width=0,this._height=0,this._scaleX=1,this._scaleY=1,this._skewX=0,this._skewY=0,this._rotation=0,this._pivoted=!1,this._pivotX=null,this._pivotY=null,this._handled=!1,this._handleX=0,this._handleY=0,this._aligned=!1,this._alignX=0,this._alignY=0,this._offsetX=0,this._offsetY=0,this._boxX=0,this._boxY=0,this._boxWidth=this._width,this._boxHeight=this._height,this._ts_translate=++s,this._ts_transform=++s,this._ts_matrix=++s},i.prototype._update=function(){return this._parent=this._owner._parent&&this._owner._parent._pin,this._handled&&this._mo_handle!=this._ts_transform&&(this._mo_handle=this._ts_transform,this._ts_translate=++s),this._aligned&&this._parent&&this._mo_align!=this._parent._ts_transform&&(this._mo_align=this._parent._ts_transform,this._ts_translate=++s),this},i.prototype.toString=function(){return this._owner+" ("+(this._parent?this._parent._owner:null)+")"},i.prototype.absoluteMatrix=function(){this._update();var t=Math.max(this._ts_transform,this._ts_translate,this._parent?this._parent._ts_matrix:0);if(this._mo_abs==t)return this._absoluteMatrix;this._mo_abs=t;var e=this._absoluteMatrix;return e.copyFrom(this.relativeMatrix()),this._parent&&e.concat(this._parent._absoluteMatrix),this._ts_matrix=++s,e},i.prototype.relativeMatrix=function(){this._update();var t=Math.max(this._ts_transform,this._ts_translate,this._parent?this._parent._ts_transform:0);if(this._mo_rel==t)return this._relativeMatrix;this._mo_rel=t;var e=this._relativeMatrix;if(e.identity(),this._pivoted&&e.translate(-this._pivotX*this._width,-this._pivotY*this._height),e.scale(this._scaleX,this._scaleY),e.skew(this._skewX,this._skewY),e.rotate(this._rotation),this._pivoted&&e.translate(this._pivotX*this._width,this._pivotY*this._height),this._pivoted)this._boxX=0,this._boxY=0,this._boxWidth=this._width,this._boxHeight=this._height;else{var i,n;e.a>0&&e.c>0||e.a<0&&e.c<0?(i=0,n=e.a*this._width+e.c*this._height):(i=e.a*this._width,n=e.c*this._height),i>n?(this._boxX=n,this._boxWidth=i-n):(this._boxX=i,this._boxWidth=n-i),e.b>0&&e.d>0||e.b<0&&e.d<0?(i=0,n=e.b*this._width+e.d*this._height):(i=e.b*this._width,n=e.d*this._height),i>n?(this._boxY=n,this._boxHeight=i-n):(this._boxY=i,this._boxHeight=n-i)}return this._x=this._offsetX,this._y=this._offsetY,this._x-=this._boxX+this._handleX*this._boxWidth,this._y-=this._boxY+this._handleY*this._boxHeight,this._aligned&&this._parent&&(this._parent.relativeMatrix(),this._x+=this._alignX*this._parent._width,this._y+=this._alignY*this._parent._height),e.translate(this._x,this._y),this._relativeMatrix},i.prototype.get=function(t){return i._get(this,t)},i.prototype.set=function(t,e){if("string"==typeof t)i._set(this,t,e);else if("object"==typeof t)for(e in t)i._set(this,e,t[e],t);return this._owner&&(this._owner._ts_pin=++s,this._owner.touch()),this},i._get=function(t,e){return"undefined"!=typeof(e=i._getters[e])?e.call(i._getters,t):void 0},i._set=function(t,e,n,r){"undefined"!=typeof(e=i._setters[e])&&"undefined"!=typeof n&&e.call(i._setters,t,n,r)},i._getters={alpha:function(t){return t._alpha},textureAlpha:function(t){return t._textureAlpha},width:function(t){return t._width},height:function(t){return t._height},boxWidth:function(t){return t._boxWidth},boxHeight:function(t){return t._boxHeight},scaleX:function(t){return t._scaleX},scaleY:function(t){return t._scaleY},skewX:function(t){return t._skewX},skewY:function(t){return t._skewY},rotation:function(t){return t._rotation},pivotX:function(t){return t._pivotX},pivotY:function(t){return t._pivotY},offsetX:function(t){return t._offsetX},offsetY:function(t){return t._offsetY},alignX:function(t){return t._alignX},alignY:function(t){return t._alignY},handleX:function(t){return t._handleX},handleY:function(t){return t._handleY}},i._setters={alpha:function(t,e){t._alpha=e},textureAlpha:function(t,e){t._textureAlpha=e},width:function(t,e){t._width_=e,t._width=e,t._ts_transform=++s},height:function(t,e){t._height_=e,t._height=e,t._ts_transform=++s},scale:function(t,e){t._scaleX=e,t._scaleY=e,t._ts_transform=++s},scaleX:function(t,e){t._scaleX=e,t._ts_transform=++s},scaleY:function(t,e){t._scaleY=e,t._ts_transform=++s},skew:function(t,e){t._skewX=e,t._skewY=e,t._ts_transform=++s},skewX:function(t,e){t._skewX=e,t._ts_transform=++s},skewY:function(t,e){t._skewY=e,t._ts_transform=++s},rotation:function(t,e){t._rotation=e,t._ts_transform=++s},pivot:function(t,e){t._pivotX=e,t._pivotY=e,t._pivoted=!0,t._ts_transform=++s},pivotX:function(t,e){t._pivotX=e,t._pivoted=!0,t._ts_transform=++s},pivotY:function(t,e){t._pivotY=e,t._pivoted=!0,t._ts_transform=++s},offset:function(t,e){t._offsetX=e,t._offsetY=e,t._ts_translate=++s},offsetX:function(t,e){t._offsetX=e,t._ts_translate=++s},offsetY:function(t,e){t._offsetY=e,t._ts_translate=++s},align:function(t,e){this.alignX(t,e),this.alignY(t,e)},alignX:function(t,e){t._alignX=e,t._aligned=!0,t._ts_translate=++s,this.handleX(t,e)},alignY:function(t,e){t._alignY=e,t._aligned=!0,t._ts_translate=++s,this.handleY(t,e)},handle:function(t,e){this.handleX(t,e),this.handleY(t,e)},handleX:function(t,e){t._handleX=e,t._handled=!0,t._ts_translate=++s},handleY:function(t,e){t._handleY=e,t._handled=!0,t._ts_translate=++s},resizeMode:function(t,e,i){i&&("in"==e?e="in-pad":"out"==e&&(e="out-crop"),t._scaleTo(i.resizeWidth,i.resizeHeight,e))},resizeWidth:function(t,e,i){i&&i.resizeMode||t._scaleTo(e,null)},resizeHeight:function(t,e,i){i&&i.resizeMode||t._scaleTo(null,e)},scaleMode:function(t,e,i){i&&t._scaleTo(i.scaleWidth,i.scaleHeight,e)},scaleWidth:function(t,e,i){i&&i.scaleMode||t._scaleTo(e,null)},scaleHeight:function(t,e,i){i&&i.scaleMode||t._scaleTo(null,e)},matrix:function(t,e){this.scaleX(t,e.a),this.skewX(t,e.c/e.d),this.skewY(t,e.b/e.a),this.scaleY(t,e.d),this.offsetX(t,e.e),this.offsetY(t,e.f),this.rotation(t,0)}},i.prototype._scaleTo=function(t,e,i){var n="number"==typeof t,r="number"==typeof e,o="string"==typeof i,h=this;h._ts_transform=++s,n&&(h._scaleX=t/h._width_,h._width=h._width_),r&&(h._scaleY=e/h._height_,h._height=h._height_),n&&r&&o&&("out"==i||"out-crop"==i?h._scaleX=h._scaleY=Math.max(h._scaleX,h._scaleY):("in"==i||"in-pad"==i)&&(h._scaleX=h._scaleY=Math.min(h._scaleX,h._scaleY)),("out-crop"==i||"in-pad"==i)&&(h._width=t/h._scaleX,h._height=e/h._scaleY))},e.exports=i},{"./core":4,"./matrix":9}],13:[function(t,e){function i(t,e){"object"==typeof t&&this.src(t,e)}var n=t("./util/stats"),r=t("./util/math");i.prototype.pipe=function(){return new i(this)},i.prototype.src=function(t,e,i,n){if("object"==typeof t){var r=t,s=e||1;this._image=r,this._sx=this._dx=0,this._sy=this._dy=0,this._sw=this._dw=r.width/s,this._sh=this._dh=r.height/s,this.width=r.width/s,this.height=r.height/s,this.ratio=s}else"undefined"==typeof i?(i=t,n=e):(this._sx=t,this._sy=e),this._sw=this._dw=i,this._sh=this._dh=n,this.width=i,this.height=n;return this},i.prototype.dest=function(t,e,i,n){return this._dx=t,this._dy=e,this._dx=t,this._dy=e,"undefined"!=typeof i&&(this._dw=i,this._dh=n,this.width=i,this.height=n),this},i.prototype.draw=function(t,e,i,s,o,h,a,u,f){var c=this._image;if(null!==c&&"object"==typeof c){var _=this._sx,p=this._sy,l=this._sw,d=this._sh,g=this._dx,m=this._dy,y=this._dw,v=this._dh;"undefined"!=typeof h?(e=r.limit(e,0,this._sw),s=r.limit(s,0,this._sw-e),i=r.limit(i,0,this._sh),o=r.limit(o,0,this._sh-i),_+=e,p+=i,l=s,d=o,g=h,m=a,y=u,v=f):"undefined"!=typeof s?(g=e,m=i,y=s,v=o):"undefined"!=typeof e&&(y=e,v=i);var x=this.ratio||1;_*=x,p*=x,l*=x,d*=x;try{"function"==typeof c.draw?c.draw(t,_,p,l,d,g,m,y,v):(n.draw++,t.drawImage(c,_,p,l,d,g,m,y,v))}catch(b){c._draw_failed||(console.log("Unable to draw: ",c),console.log(b),c._draw_failed=!0)}}},e.exports=i},{"./util/math":19,"./util/stats":22}],14:[function(t,e){function i(t){var e=this;this._owner=t,this._queue=[],this._next=null;var i=0;t.tick(function(n,r,s){if(e._queue.length){var o=i!=s;if(i=r,this.touch(),!o){var h=e._queue[0];if(h.time?h.time+=n:h.time=1,!(h.time<h.delay)){if(!h.start){h.start={},h.keys={};for(var a in h.end)"number"==typeof(start=t.pin(a))?(h.start[a]=start,h.keys[a]=a):"number"==typeof(startX=t.pin(a+"X"))&&"number"==typeof(startY=t.pin(a+"Y"))&&(h.start[a+"X"]=startX,h.keys[a+"X"]=a,h.start[a+"Y"]=startY,h.keys[a+"Y"]=a)}var u=(h.time-h.delay)/h.duration,f=u>=1;u=u>1?1:u,u="function"==typeof h.easing?h.easing(u):u;var c=1-u;for(var a in h.keys)t.pin(a,h.start[a]*c+h.end[h.keys[a]]*u);f&&(e._queue.shift(),h.then&&h.then.call(t))}}}},!0)}{var n=t("./easing"),r=t("./core");t("./pin")}r.prototype.tween=function(t,e){return this._tween||(this._tween=new i(this)),this._tween.tween(t,e)};var s=0;i.prototype.tween=function(t,e){return this._next={id:++s,end:{},duration:t||400,delay:e||0},this},i.prototype.pin=function(t,e){this._next!==this._queue[this._queue.length-1]&&(this._owner.touch(),this._queue.push(this._next));var i=this._next.end;if("object"==typeof t)for(var n in t)i[n]=t[n];else"undefined"!=typeof e&&(i[t]=e);return this},i.prototype.clear=function(t){for(var e;e=this._queue.shift();)t&&this._owner.pin(e.end);return this},i.prototype.then=function(t){return this._next.then=t,this},i.prototype.ease=function(t){return this._next.easing=n(t),this},e.exports=i},{"./core":4,"./easing":5,"./pin":12}],15:[function(t){function e(t,i){e._super.call(this),this.label("Root"),this._paused=!0;var n=this,r=0,s=function(t){if(n._paused!==!0){o.tick=o.node=o.draw=0;var e=r||t,s=t-e;r=t;var h=n._tick(s,t,e);n._mo_touch!=n._ts_touch?(n._mo_touch=n._ts_touch,i.call(n),n.request()):h?n.request():n.pause(),o.fps=s?1e3/s:0}};this.request=function(){t(s)}}function i(){i._super.call(this),this.label("Image"),this._textures=[],this._image=null}function n(){n._super.call(this),this.label("Anim"),this._textures=[],this._fps=n.FPS,this._ft=1e3/this._fps,this._time=-1,this._repeat=0,this._index=0,this._frames=[];var t=0;this.tick(function(e,i,n){if(!(this._time<0||this._frames.length<=1)){var r=t!=n;if(t=i,r)return!0;if(this._time+=e,this._time<this._ft)return!0;var s=this._time/this._ft|0;return this._time-=s*this._ft,this.moveFrame(s),this._repeat>0&&(this._repeat-=s)<=0?(this.stop(),this._callback&&this._callback(),!1):!0}},!1)}function r(){r._super.call(this),this.label("String"),this._textures=[]}var s=t("./core"),o=(t("./pin"),t("./util/stats")),h=t("./util/repeat"),a=t("./util/create"),u=t("./util/extend"),f=t("./util/math"),c=t("./util/is");s.prototype._textures=null,s.prototype._tickBefore=null,s.prototype._tickAfter=null,s.prototype._alpha=1,s.prototype.render=function(t){if(this._visible){o.node++;var e=this.matrix();t.setTransform(e.a,e.b,e.c,e.d,e.e,e.f),this._alpha=this._pin._alpha*(this._parent?this._parent._alpha:1);var i=this._pin._textureAlpha*this._alpha;if(t.globalAlpha!=i&&(t.globalAlpha=i),null!==this._textures)for(var n=0,r=this._textures.length;r>n;n++)this._textures[n].draw(t);t.globalAlpha!=this._alpha&&(t.globalAlpha=this._alpha);for(var s,h=this._first;s=h;)h=s._next,s.render(t)}},s.prototype.MAX_ELAPSE=1/0,s.prototype._tick=function(t,e,i){if(this._visible){t>this.MAX_ELAPSE&&(t=this.MAX_ELAPSE);var n=!1;if(null!==this._tickBefore)for(var r=0,s=this._tickBefore.length;s>r;r++)o.tick++,n=this._tickBefore[r].call(this,t,e,i)===!0||n;for(var h,a=this._first;h=a;)a=h._next,h._flag("_tick")&&(n=h._tick(t,e,i)===!0?!0:n);if(null!==this._tickAfter)for(var r=0,s=this._tickAfter.length;s>r;r++)o.tick++,n=this._tickAfter[r].call(this,t,e,i)===!0||n;return n}},s.prototype.tick=function(t,e){"function"==typeof t&&(e?(null===this._tickBefore&&(this._tickBefore=[]),this._tickBefore.push(t)):(null===this._tickAfter&&(this._tickAfter=[]),this._tickAfter.push(t)),this._flag("_tick",null!==this._tickAfter&&this._tickAfter.length>0||null!==this._tickBefore&&this._tickBefore.length>0))},s.prototype.untick=function(t){if("function"==typeof t){var e;
-null!==this._tickBefore&&(e=this._tickBefore.indexOf(t))>=0&&this._tickBefore.splice(e,1),null!==this._tickAfter&&(e=this._tickAfter.indexOf(t))>=0&&this._tickAfter.splice(e,1)}},e._super=s,e.prototype=a(e._super.prototype),s.root=function(t,i){return new e(t,i)},e.prototype.start=function(){return this.resume()},e.prototype.resume=function(t){return(this._paused||t)&&(this._paused=!1,this.request()),this},e.prototype.pause=function(){return this._paused=!0,this},e.prototype.touch=function(){return this.resume(),e._super.prototype.touch.call(this)},e.prototype.background=function(){return this},e.prototype.viewport=function(t,e,i){if("undefined"==typeof t)return u({},this._viewport);this._viewport={width:t,height:e,ratio:i||1},this._updateViewbox();var n=u({},this._viewport);return this.visit({start:function(t){return t._flag("viewport")?void t.publish("viewport",[n]):!0}}),this},e.prototype.viewbox=function(t,e,i){return this._viewbox={width:t,height:e,mode:/^(in|out|in-pad|out-crop)$/.test(i)?i:"in-pad"},this._updateViewbox(),this},e.prototype._updateViewbox=function(){var t=this._viewbox,e=this._viewport;e&&t?(this.pin({width:t.width,height:t.height}),this._pin._scaleTo(e.width,e.height,t.mode)):e&&this.pin({width:e.width,height:e.height})},s.image=function(t){var e=new i;return t&&e.image(t),e},i._super=s,i.prototype=a(i._super.prototype),i.prototype.setImage=function(t,e,i){return this.image(t,e,i)},i.prototype.image=function(t){return this._image=s.texture(t).one(),this.pin("width",this._image?this._image.width:0),this.pin("height",this._image?this._image.height:0),this._textures[0]=this._image.pipe(),this._textures.length=1,this},i.prototype.tile=function(t){return this._repeat(!1,t),this},i.prototype.stretch=function(t){return this._repeat(!0,t),this},i.prototype._repeat=function(t,e){function i(t,e,i,r,s,o,h,a,u){var f=n._textures.length>t?n._textures[t]:n._textures[t]=n._image.pipe();f.src(e,i,r,s),f.dest(o,h,a,u)}var n=this;this.untick(this._repeatTicker),this.tick(this._repeatTicker=function(){if(this._mo_stretch!=this._pin._ts_transform){this._mo_stretch=this._pin._ts_transform;var n=this.pin("width"),r=this.pin("height");this._textures.length=h(this._image,n,r,t,e,i)}})},s.anim=function(t,e){var i=new n;return i.frames(t).gotoFrame(0),e&&i.fps(e),i},n._super=s,n.prototype=a(n._super.prototype),n.FPS=12,n.prototype.fps=function(t){return"undefined"==typeof t?this._fps:(this._fps=t>0?t:s.Anim.FPS,this._ft=1e3/this._fps,this)},n.prototype.setFrames=function(t,e,i){return this.frames(t,e,i)},n.prototype.frames=function(t){return this._index=0,this._frames=s.texture(t).array(),this.touch(),this},n.prototype.length=function(){return this._frames?this._frames.length:0},n.prototype.gotoFrame=function(t,e){return this._index=0|f.rotate(t,this._frames.length),e=e||!this._textures[0],this._textures[0]=this._frames[this._index],e&&(this.pin("width",this._textures[0].width),this.pin("height",this._textures[0].height)),this.touch(),this},n.prototype.moveFrame=function(t){return this.gotoFrame(this._index+t)},n.prototype.repeat=function(t,e){return this._repeat=t*this._frames.length-1,this._callback=e,this.play(),this},n.prototype.play=function(t){return"undefined"!=typeof t?(this.gotoFrame(t),this._time=0):this._time<0&&(this._time=0),this.touch(),this},n.prototype.stop=function(t){return this._time=-1,"undefined"!=typeof t&&this.gotoFrame(t),this},s.string=function(t){return(new r).frames(t)},r._super=s,r.prototype=a(r._super.prototype),r.prototype.setFont=function(t,e,i){return this.frames(t,e,i)},r.prototype.frames=function(t){return this._textures=[],"string"==typeof t?(t=s.texture(t),this._item=function(e){return t.one(e)}):"object"==typeof t?this._item=function(e){return t[e]}:"function"==typeof t&&(this._item=t),this},r.prototype.setValue=function(t,e,i){return this.value(t,e,i)},r.prototype.value=function(t){if("undefined"==typeof t)return this._value;if(this._value===t)return this;this._value=t,null===t?t="":"string"==typeof t||c.array(t)||(t=t.toString()),this._spacing=this._spacing||0;for(var e=0,i=0,n=0;n<t.length;n++){var r=this._textures[n]=this._item(t[n]);e+=n>0?this._spacing:0,r.dest(e,0),e+=r.width,i=Math.max(i,r.height)}return this.pin("width",e),this.pin("height",i),this._textures.length=t.length,this},s.row=function(t){return s.create().row(t)},s.prototype.row=function(t){return this.sequence("row",t),this},s.column=function(t){return s.create().column(t)},s.prototype.column=function(t){return this.sequence("column",t),this},s.sequence=function(t,e){return s.create().sequence(t,e)},s.prototype.sequence=function(t,e){return this._padding=this._padding||0,this._spacing=this._spacing||0,this.untick(this._sequenceTicker),this.tick(this._sequenceTicker=function(){if(this._mo_seq!=this._ts_touch){this._mo_seq=this._ts_touch;var i=this._mo_seqAlign!=this._ts_children;this._mo_seqAlign=this._ts_children;for(var n,r=0,s=0,o=this.first(!0),h=!0;n=o;){o=n.next(!0),n._pin.relativeMatrix();var a=n.pin("boxWidth"),u=n.pin("boxHeight");"column"==t?(!h&&(s+=this._spacing),n.pin("offsetY")!=s&&n.pin("offsetY",s),r=Math.max(r,a),s+=u,i&&n.pin("alignX",e)):"row"==t&&(!h&&(r+=this._spacing),n.pin("offsetX")!=r&&n.pin("offsetX",r),r+=a,s=Math.max(s,u),i&&n.pin("alignY",e)),h=!1}r+=2*this._padding,s+=2*this._padding,this.pin("width")!=r&&this.pin("width",r),this.pin("height")!=s&&this.pin("height",s)}}),this},s.box=function(){return s.create().box()},s.prototype.box=function(){return this._boxTicker?this:(this._padding=this._padding||0,this.tick(this._boxTicker=function(){if(this._mo_box!=this._ts_touch){this._mo_box=this._ts_touch;for(var t,e=0,i=0,n=this.first(!0);t=n;){n=t.next(!0),t._pin.relativeMatrix();var r=t.pin("boxWidth"),s=t.pin("boxHeight");e=Math.max(e,r),i=Math.max(i,s)}e+=2*this._padding,i+=2*this._padding,this.pin("width")!=e&&this.pin("width",e),this.pin("height")!=i&&this.pin("height",i)}}),this)},s.prototype.padding=function(t){return this._padding=t,this},s.prototype.spacing=function(t){return this._spacing=t,this}},{"./core":4,"./pin":12,"./util/create":16,"./util/extend":17,"./util/is":18,"./util/math":19,"./util/repeat":21,"./util/stats":22}],16:[function(t,e){function i(){}e.exports="function"==typeof Object.create?function(t,e){return Object.create.call(Object,t,e)}:function(t,e){if(e)throw Error("Second argument is not supported!");if("object"!=typeof t||null===t)throw Error("Invalid prototype!");return i.prototype=t,new i}},{}],17:[function(t,e){e.exports=function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var n in i)i.hasOwnProperty(n)&&(t[n]=i[n])}return t}},{}],18:[function(t,e){var i=Object.prototype,n=i.hasOwnProperty,r=i.toString,s=/^[A-Fa-f0-9]+$/,o=e.exports={};o.a=o.an=o.type=function(t,e){return typeof t===e},o.defined=function(t){return"undefined"!=typeof t},o.empty=function(t){var e,i=r.call(t);if("[object Array]"===i||"[object Arguments]"===i||"[object String]"===i)return 0===t.length;if("[object Object]"===i){for(e in t)if(n.call(t,e))return!1;return!0}return!t},o.equal=function(t,e){if(t===e)return!0;var i,n=r.call(t);if(n!==r.call(e))return!1;if("[object Object]"===n){for(i in t)if(!(o.equal(t[i],e[i])&&i in e))return!1;for(i in e)if(!(o.equal(t[i],e[i])&&i in t))return!1;return!0}if("[object Array]"===n){if(i=t.length,i!==e.length)return!1;for(;--i;)if(!o.equal(t[i],e[i]))return!1;return!0}return"[object Function]"===n?t.prototype===e.prototype:"[object Date]"===n?t.getTime()===e.getTime():!1},o.instance=function(t,e){return t instanceof e},o.nil=function(t){return null===t},o.undef=function(t){return"undefined"==typeof t},o.array=function(t){return"[object Array]"===r.call(t)},o.emptyarray=function(t){return o.array(t)&&0===t.length},o.arraylike=function(t){return!!t&&!o["boolean"](t)&&n.call(t,"length")&&isFinite(t.length)&&o.number(t.length)&&t.length>=0},o["boolean"]=function(t){return"[object Boolean]"===r.call(t)},o.element=function(t){return void 0!==t&&"undefined"!=typeof HTMLElement&&t instanceof HTMLElement&&1===t.nodeType},o.fn=function(t){return"[object Function]"===r.call(t)},o.number=function(t){return"[object Number]"===r.call(t)},o.nan=function(t){return!o.number(t)||t!==t},o.object=function(t){return"[object Object]"===r.call(t)},o.hash=function(t){return o.object(t)&&t.constructor===Object&&!t.nodeType&&!t.setInterval},o.regexp=function(t){return"[object RegExp]"===r.call(t)},o.string=function(t){return"[object String]"===r.call(t)},o.hex=function(t){return o.string(t)&&(!t.length||s.test(t))}},{}],19:[function(t,e){e.exports.random=function(t,e){return"undefined"==typeof t?(e=1,t=0):"undefined"==typeof e&&(e=t,t=0),t==e?t:Math.random()*(e-t)+t},e.exports.rotate=function(t,e,i){return"undefined"==typeof e?(i=1,e=0):"undefined"==typeof i&&(i=e,e=0),i>e?(t=(t-e)%(i-e),t+(0>t?i:e)):(t=(t-i)%(e-i),t+(0>=t?e:i))},e.exports.limit=function(t,e,i){return e>t?e:t>i?i:t},e.exports.length=function(t,e){return Math.sqrt(t*t+e*e)}},{}],20:[function(t,e){e.exports=function(t,e){var i=!1;return function(){i||(i=!0,t.apply(e,arguments))}}},{}],21:[function(t,e){e.exports=function(t,e,i,n,r,s){var o=t.width,h=t.height,a=t.left,u=t.right,f=t.top,c=t.bottom;a="number"==typeof a&&a===a?a:0,u="number"==typeof u&&u===u?u:0,f="number"==typeof f&&f===f?f:0,c="number"==typeof c&&c===c?c:0,o=o-a-u,h=h-f-c,r||(e=Math.max(e-a-u,0),i=Math.max(i-f-c,0));var _=0;if(f>0&&a>0&&s(_++,0,0,a,f,0,0,a,f),c>0&&a>0&&s(_++,0,h+f,a,c,0,i+f,a,c),f>0&&u>0&&s(_++,o+a,0,u,f,e+a,0,u,f),c>0&&u>0&&s(_++,o+a,h+f,u,c,e+a,i+f,u,c),n)f>0&&s(_++,a,0,o,f,a,0,e,f),c>0&&s(_++,a,h+f,o,c,a,i+f,e,c),a>0&&s(_++,0,f,a,h,0,f,a,i),u>0&&s(_++,o+a,f,u,h,e+a,f,u,i),s(_++,a,f,o,h,a,f,e,i);else for(var p,l=a,d=e;d>0;){p=Math.min(o,d),d-=o;for(var g,m=f,y=i;y>0;)g=Math.min(h,y),y-=h,s(_++,a,f,p,g,l,m,p,g),0>=d&&(a&&s(_++,0,f,a,g,0,m,a,g),u&&s(_++,o+a,f,u,g,l+p,m,u,g)),m+=g;f&&s(_++,a,0,p,f,l,0,p,f),c&&s(_++,a,h+f,p,c,l,m,p,c),l+=p}return _}},{}],22:[function(t,e){e.exports={}},{}],23:[function(t,e){e.exports.startsWith=function(t,e){return"string"==typeof t&&"string"==typeof e&&t.substring(0,e.length)==e}},{}]},{},[1])(1)});
\ No newline at end of file
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;"undefined"!=typeof window?e=window:"undefined"!=typeof global?e=global:"undefined"!=typeof self&&(e=self),e.Cut=t()}}(function(){return function t(e,i,n){function r(o,h){if(!i[o]){if(!e[o]){var a="function"==typeof require&&require;if(!h&&a)return a(o,!0);if(s)return s(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var f=i[o]={exports:{}};e[o][0].call(f.exports,function(t){var i=e[o][1][t];return r(i?i:t)},f,f.exports,t,e,i,n)}return i[o].exports}for(var s="function"==typeof require&&require,o=0;o<n.length;o++)r(n[o]);return r}({1:[function(t,e){e.exports=t("../lib/"),t("../lib/canvas"),t("../lib/image"),t("../lib/anim"),t("../lib/str"),t("../lib/layout"),t("../lib/addon/tween"),e.exports.Mouse=t("../lib/addon/mouse"),e.exports.Math=t("../lib/util/math"),e.exports._extend=t("../lib/util/extend"),e.exports._create=t("../lib/util/create"),t("../lib/loader/web")},{"../lib/":11,"../lib/addon/mouse":3,"../lib/addon/tween":4,"../lib/anim":5,"../lib/canvas":7,"../lib/image":10,"../lib/layout":12,"../lib/loader/web":13,"../lib/str":19,"../lib/util/create":21,"../lib/util/extend":22,"../lib/util/math":24}],2:[function(t,e){function i(t){return t}function n(t){if("function"==typeof t)return t;if("string"!=typeof t)return i;var e=r[t];if(e)return e;var n=/^(\w+)(-(in|out|in-out|out-in))?(\((.*)\))?$/i.exec(t);return n&&n.length?(easing=o[n[1]],mode=s[n[3]],params=n[5],e=easing&&easing.fn?easing.fn:easing&&easing.fc?easing.fc.apply(easing.fc,params&&params.replace(/\s+/,"").split(",")):i,mode&&(e=mode.fn(e)),r[t]=e,e):i}var r={},s={},o={};n.add=function(t){for(var e=(t.name||t.mode).split(/\s+/),i=0;i<e.length;i++){var n=e[i];n&&((t.name?o:s)[n]=t)}},n.add({mode:"in",fn:function(t){return t}}),n.add({mode:"out",fn:function(t){return function(e){return 1-t(1-e)}}}),n.add({mode:"in-out",fn:function(t){return function(e){return.5>e?t(2*e)/2:1-t(2*(1-e))/2}}}),n.add({mode:"out-in",fn:function(t){return function(e){return.5>e?1-t(2*(1-e))/2:t(2*e)/2}}}),n.add({name:"linear",fn:function(t){return t}}),n.add({name:"quad",fn:function(t){return t*t}}),n.add({name:"cubic",fn:function(t){return t*t*t}}),n.add({name:"quart",fn:function(t){return t*t*t*t}}),n.add({name:"quint",fn:function(t){return t*t*t*t*t}}),n.add({name:"sin sine",fn:function(t){return 1-Math.cos(t*Math.PI/2)}}),n.add({name:"exp",fn:function(t){return 0==t?0:Math.pow(2,10*(t-1))}}),n.add({name:"circle circ",fn:function(t){return 1-Math.sqrt(1-t*t)}}),n.add({name:"bounce",fn:function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}}),n.add({name:"poly",fc:function(t){return function(e){return Math.pow(e,t)}}}),n.add({name:"elastic",fc:function(t,e){e=e||.45,t=t||1;var i=e/(2*Math.PI)*Math.asin(1/t);return function(n){return 1+t*Math.pow(2,-10*n)*Math.sin(2*(n-i)*Math.PI/e)}}}),n.add({name:"back",fc:function(t){return t="undefined"!=typeof t?t:1.70158,function(e){return e*e*((t+1)*e-t)}}}),e.exports=n},{}],3:[function(t,e){function i(){i.subscribe.apply(i,arguments)}"undefined"==typeof DEBUG&&(DEBUG=!0),i.CLICK="click",i.START="touchstart mousedown",i.MOVE="touchmove mousemove",i.END="touchend mouseup",i.CANCEL="touchcancel",i.subscribe=function(t,e){function n(n){i._xy(t,e,n,p),DEBUG&&console.log("Mouse Start: "+n.type+" "+p),n.preventDefault(),u(n.type,n),h()}function r(t){DEBUG&&console.log("Mouse End: "+t.type+" "+p),t.preventDefault(),u(t.type,t),l.length&&(DEBUG&&console.log("Mouse Click: "+l.length),a(t))}function s(t){DEBUG&&console.log("Mouse Cancel: "+t.type),t.preventDefault(),u(t.type,t)}function o(n){i._xy(t,e,n,p),t._flag(n.type)&&(n.preventDefault(),u(n.type,n))}function h(){for(;l.length;)l.pop();u("click",null,l)}function a(e){c.event=e,c.type="click",c.root=t,c.collect=!1;for(var i=!1;l.length;){var n=l.shift();i||(i=f.end(n,c)?!0:i)}}function u(e,i,n){_.x=p.x,_.y=p.y,c.event=i,c.type=e,c.root=t,c.collect=n,c.root.visit(f,c)}var f=null,c={},p=null,_=null,l=[];e=e||document,e.addEventListener("touchstart",n),e.addEventListener("touchend",r),e.addEventListener("touchmove",o),e.addEventListener("touchcancel",s),e.addEventListener("mousedown",n),e.addEventListener("mouseup",r),e.addEventListener("mousemove",o),f={reverse:!0,visible:!0,start:function(t,e){return!t._flag(e.type)},end:function(t,e){_.raw=e.event,_.type=e.type;var n=t.listeners(e.type);if(n&&(t.matrix().reverse().map(p,_),t===e.root||t.attr("spy")||i._isInside(t,_))){if(e.collect)return void e.collect.push(t);for(var r=!1,s=0;s<n.length;s++)r=n[s].call(t,_)?!0:r;return r}}},p={x:0,y:0,toString:function(){return(0|this.x)+"x"+(0|this.y)}},_={x:0,y:0,toString:function(){return p+" / "+(0|this.x)+"x"+(0|this.y)}}},i._isInside=function(t,e){return e.x>=0&&e.x<=t._pin._width&&e.y>=0&&e.y<=t._pin._height},i._xy=function(t,e,i,n){var r=!1;if(i.touches){if(!i.touches.length)return;r=!0,n.x=i.touches[0].pageX,n.y=i.touches[0].pageY}else n.x=i.clientX,n.y=i.clientY,document.body.scrollLeft||document.body.scrollTop||document.documentElement&&(n.x+=document.documentElement.scrollLeft,n.y+=document.documentElement.scrollTop);n.x-=e.clientLeft||0,n.y-=e.clientTop||0;for(var s=e;s;)n.x-=s.offsetLeft||0,n.y-=s.offsetTop||0,r||(n.x+=s.scrollLeft||0,n.y+=s.scrollTop||0),s=s.offsetParent;n.x*=t.viewport().ratio||1,n.y*=t.viewport().ratio||1},e.exports=i},{}],4:[function(t,e){function i(t){var e=this;this._owner=t,this._queue=[],this._next=null;var i=0;t.tick(function(n,r,s){if(e._queue.length){var o=i!=s;if(i=r,this.touch(),!o){var h=e._queue[0];if(h.time?h.time+=n:h.time=1,!(h.time<h.delay)){if(!h.start){h.start={},h.keys={};for(var a in h.end)"number"==typeof(start=t.pin(a))?(h.start[a]=start,h.keys[a]=a):"number"==typeof(startX=t.pin(a+"X"))&&"number"==typeof(startY=t.pin(a+"Y"))&&(h.start[a+"X"]=startX,h.keys[a+"X"]=a,h.start[a+"Y"]=startY,h.keys[a+"Y"]=a)}var u=(h.time-h.delay)/h.duration,f=u>=1;u=u>1?1:u,u="function"==typeof h.easing?h.easing(u):u;var c=1-u;for(var a in h.keys)t.pin(a,h.start[a]*c+h.end[h.keys[a]]*u);f&&(e._queue.shift(),h.then&&h.then.call(t))}}}},!0)}{var n=t("./easing"),r=t("../core");t("../pin")}r.prototype.tween=function(t,e){return this._tween||(this._tween=new i(this)),this._tween.tween(t,e)};var s=0;i.prototype.tween=function(t,e){return this._next={id:++s,end:{},duration:t||400,delay:e||0},this},i.prototype.pin=function(t,e){this._next!==this._queue[this._queue.length-1]&&(this._owner.touch(),this._queue.push(this._next));var i=this._next.end;if("object"==typeof t)for(var n in t)i[n]=t[n];else"undefined"!=typeof e&&(i[t]=e);return this},i.prototype.clear=function(t){for(var e;e=this._queue.shift();)t&&this._owner.pin(e.end);return this},i.prototype.then=function(t){return this._next.then=t,this},i.prototype.ease=function(t){return this._next.easing=n(t),this},e.exports=i},{"../core":8,"../pin":16,"./easing":2}],5:[function(t){function e(){e._super.call(this),this.label("Anim"),this._textures=[],this._fps=i.Anim.FPS,this._ft=1e3/this._fps,this._time=-1,this._repeat=0,this._index=0,this._frames=[];var t=0;this.tick(function(e,i,n){if(!(this._time<0||this._frames.length<=1)){var r=t!=n;if(t=i,r)return!0;if(this._time+=e,this._time<this._ft)return!0;var s=this._time/this._ft|0;return this._time-=s*this._ft,this.moveFrame(s),this._repeat>0&&(this._repeat-=s)<=0?(this.stop(),this._callback&&this._callback(),!1):!0}},!1)}var i=t("./core");t("./pin"),t("./render");var n=t("./util/create"),r=t("./util/math");i.anim=function(t,i){var n=new e;return n.frames(t).gotoFrame(0),i&&n.fps(i),n},e._super=i,e.prototype=n(e._super.prototype),i.Anim={FPS:15},e.prototype.fps=function(t){return"undefined"==typeof t?this._fps:(this._fps=t>0?t:i.Anim.FPS,this._ft=1e3/this._fps,this)},e.prototype.setFrames=function(t,e,i){return this.frames(t,e,i)},e.prototype.frames=function(t){return this._index=0,this._frames=i.texture(t).array(),this.touch(),this},e.prototype.length=function(){return this._frames?this._frames.length:0},e.prototype.gotoFrame=function(t,e){return this._index=0|r.rotate(t,this._frames.length),e=e||!this._textures[0],this._textures[0]=this._frames[this._index],e&&(this.pin("width",this._textures[0].width),this.pin("height",this._textures[0].height)),this.touch(),this},e.prototype.moveFrame=function(t){return this.gotoFrame(this._index+t)},e.prototype.repeat=function(t,e){return this._repeat=t*this._frames.length-1,this._callback=e,this.play(),this},e.prototype.play=function(t){return"undefined"!=typeof t?(this.gotoFrame(t),this._time=0):this._time<0&&(this._time=0),this.touch(),this},e.prototype.stop=function(t){return this._time=-1,"undefined"!=typeof t&&this.gotoFrame(t),this}},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/math":24}],6:[function(t,e){function i(t){function e(t){if(!t||u.fn(t.draw))return t;t=h({},t),u.fn(a)&&(t=a(t)),1!=c&&(t.x*=c,t.y*=c,t.width*=c,t.height*=c,t.top*=c,t.bottom*=c,t.left*=c,t.right*=c),0!=p&&(t.x+=p,t.y+=p,t.width-=2*p,t.height-=2*p,t.top-=p,t.bottom-=p,t.left-=p,t.right-=p);var e=o.pipe();return e.top=t.top,e.bottom=t.bottom,e.left=t.left,e.right=t.right,e.src(t.x,t.y,t.width,t.height),e}function s(t){if(_){if(u.fn(_))return _(t);if(u.hash(_))return _[t]}if(d){for(var e=null,i=0,n=0;n<d.length;n++)f.startsWith(d[n].name,t)&&(0===i?e=d[n]:1===i?e=[e,d[n]]:e.push(d[n]),i++);return 0===i&&u.fn(l)&&(e=function(e){return l(t+(e?e:""))}),e}}i._super.call(this);var o=this;r(t,"filter"),r(t,"cutouts"),r(t,"sprites"),r(t,"factory");var a=t.map||t.filter,c=t.ppu||t.ratio||1,p=t.trim||0,_=t.textures,l=t.factory,d=t.cutouts||t.sprites;this.select=function(t){var i=s(t);return i?new n(i,s,e):void 0}}function n(t,e,i){function n(t,r){return t?u.fn(t.draw)?t:u.hash(t)&&u.number(t.width)&&u.number(t.height)&&u.fn(i)?i(t):u.hash(t)&&u.defined(r)?n(t[r]):u.fn(t)?n(t(r)):u.array(t)?n(t[0]):u.string(t)&&u.fn(e)?n(e(t)):void 0:_}this.one=function(e){return n(t,e)},this.array=function(e){var i=u.array(e)?e:[];if(u.array(t))for(var r=0;r<t.length;r++)i[r]=n(t[r]);else i[0]=n(t);return i}}function r(t,e,i){e in t&&console.log(i?i.replace("%name",e):"'"+e+"' field of texture atlas is deprecated.")}var s=t("./core"),o=t("./texture"),h=t("./util/extend"),a=t("./util/create"),u=t("./util/is"),f=t("./util/string"),c={},p=[];s.atlas=function(t){var e=u.fn(t.draw)?t:new i(t);t.name&&(c[t.name]=e),p.push(e),r(t,"imagePath"),r(t,"imageRatio");var n=t.imagePath,o=t.imageRatio||1;return u.string(t.image)?n=t.image:u.hash(t.image)&&(n=t.image.url,o=t.image.ratio||o),n&&s.preload(function(t){DEBUG&&console.log("Loading image: "+n);var i=s.config("image-loader");i(n,function(i){DEBUG&&console.log("Image loaded: "+n),e.src(i,o),t()},function(e){DEBUG&&console.log("Error loading image: "+n,e),t()})}),e},i._super=o,i.prototype=a(i._super.prototype);var _=new o;_.x=_.y=_.width=_.height=0,_.pipe=_.src=_.dest=function(){return this},_.draw=function(){};var l=new n(_);s.texture=function(t){if(!u.string(t))return new n(t);var e=null,i=t.indexOf(":");if(i>0&&t.length>i+1){var r=c[t.slice(0,i)];e=r&&r.select(t.slice(i+1))}for(var i=0;!e&&i<p.length;i++)e=p[i].select(t);return e||(console.error("Texture not found: "+t),e=l),e},e.exports=i},{"./core":8,"./texture":20,"./util/create":21,"./util/extend":22,"./util/is":23,"./util/string":28}],7:[function(t){var e=t("./core"),i=t("./texture");e.canvas=function(t,e,n){"string"==typeof t?"object"==typeof e||("function"==typeof e&&(n=e),e={}):("function"==typeof t&&(n=t),e={},t="2d");var r=document.createElement("canvas"),s=r.getContext(t,e),o=new i(r);return o.context=function(){return s},o.size=function(t,e,i){return r.width=t*i,r.height=e*i,this.src(r,i),this},o.canvas=function(t){return"function"==typeof t?t.call(this,s):"undefined"==typeof t&&"function"==typeof n&&n.call(this,s),this},"function"==typeof n&&n.call(o,s),o}},{"./core":8,"./texture":20}],8:[function(t,e){function i(t){if(!(this instanceof i))return o.fn(t)?i.app.apply(i,arguments):o.object(t)?i.atlas.apply(i,arguments):t;n.create++;for(var e=0;e<h.length;e++)h[e].call(this)}"undefined"==typeof DEBUG&&(DEBUG=!0);var n=t("./util/stats"),r=t("./util/extend"),s=t("./util/once"),o=t("./util/is");n.create=0;var h=[];i._init=function(t){h.push(t)};var a={};i.config=function(){return 1===arguments.length&&o.string(arguments[0])?a[arguments[0]]:(1===arguments.length&&o.object(arguments[0])&&r(a,arguments[0]),void(2===arguments.length&&o.string(arguments[0])&&a[(arguments[0],arguments[1])]))};var u=[],f=[],c=[],p=!1,_=!1;i.app=function(t,e){if(!p)return void u.push(arguments);DEBUG&&console.log("Creating app...");var n=i.config("app-loader");n(function(e,i){DEBUG&&console.log("Initing app..."),t(e,i),c.push(e),DEBUG&&console.log("Starting app..."),e.start()},e)},i.preload=function(t){return p?void t(function(){}):void f.push(t)},i.start=function(t){function e(){if(--n<=0)for(DEBUG&&console.log("Loading apps..."),p=!0;u.length;){var t=u.shift();i.app.apply(i,t)}}DEBUG&&console.log("Starting..."),i.config(t),DEBUG&&console.log("Preloading...");var n=0;if(f.length)for(;f.length;){var r=f.shift();r(s(e)),n++}else e()},i.pause=function(){if(!_){_=!0;for(var t=c.length-1;t>=0;t--)c[t].pause()}},i.resume=function(){if(_){_=!1;for(var t=c.length-1;t>=0;t--)c[t].resume()}},i.create=function(){return new i},e.exports=i},{"./util/extend":22,"./util/is":23,"./util/once":25,"./util/stats":27}],9:[function(t){function e(t,e,i,r){if(!e||!e.length||"function"!=typeof i)return!1;if(!(e=(n.array(e)?e.join(" "):e).match(/\S+/g)))return!1;if(null===t._listeners){if(!r)return!1;t._listeners={}}return e}var i=t("./core"),n=t("./util/is");i.prototype._listeners=null,i.prototype.on=i.prototype.listen=function(t,i){if(t=e(this,t,i,!0))for(var n=0;n<t.length;n++){var r=t[n];this._listeners[r]=this._listeners[r]||[],this._listeners[r].push(i),this._flag(r,!0)}return this},i.prototype.off=function(t,i){if(t=e(this,t,i,!1))for(var n=0;n<t.length;n++){var r,s=t[n],o=this._listeners[s];o&&(r=o.indexOf(i))>=0&&(o.splice(r,1),o.length||delete this._listeners[s],this._flag(s,!1))}return this},i.prototype.listeners=function(t){return this._listeners&&this._listeners[t]},i.prototype.publish=function(t,e){var i=this.listeners(t);if(!i||!i.length)return 0;for(var n=0;n<i.length;n++)i[n].apply(this,e);return i.length},i.prototype.trigger=function(t,e){return this.publish(t,e),this}},{"./core":8,"./util/is":23}],10:[function(t){function e(){e._super.call(this),this.label("Image"),this._textures=[],this._image=null}var i=t("./core");t("./pin"),t("./render");var n=t("./util/repeat"),r=t("./util/create");i.image=function(t){var i=new e;return t&&i.image(t),i},e._super=i,e.prototype=r(e._super.prototype),e.prototype.setImage=function(t,e,i){return this.image(t,e,i)},e.prototype.image=function(t){return this._image=i.texture(t).one(),this.pin("width",this._image?this._image.width:0),this.pin("height",this._image?this._image.height:0),this._textures[0]=this._image.pipe(),this._textures.length=1,this},e.prototype.tile=function(t){return this._repeat(!1,t),this},e.prototype.stretch=function(t){return this._repeat(!0,t),this},e.prototype._repeat=function(t,e){function i(t,e,i,n,s,o,h,a,u){var f=r._textures.length>t?r._textures[t]:r._textures[t]=r._image.pipe();f.src(e,i,n,s),f.dest(o,h,a,u)}var r=this;this.untick(this._repeatTicker),this.tick(this._repeatTicker=function(){if(this._mo_stretch!=this._pin._ts_transform){this._mo_stretch=this._pin._ts_transform;var r=this.pin("width"),s=this.pin("height");this._textures.length=n(this._image,r,s,t,e,i)}})}},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/repeat":26}],11:[function(t,e){e.exports=t("./core"),e.exports.Matrix=t("./matrix"),e.exports.Texture=t("./texture"),t("./atlas"),t("./node"),t("./event"),t("./pin"),t("./render"),t("./root")},{"./atlas":6,"./core":8,"./event":9,"./matrix":14,"./node":15,"./pin":16,"./render":17,"./root":18,"./texture":20}],12:[function(t){var e=t("./core");t("./pin"),t("./render");t("./util/create");e.row=function(t){return e.create().row(t)},e.prototype.row=function(t){return this.sequence("row",t),this},e.column=function(t){return e.create().column(t)},e.prototype.column=function(t){return this.sequence("column",t),this},e.sequence=function(t,i){return e.create().sequence(t,i)},e.prototype.sequence=function(t,e){return this._padding=this._padding||0,this._spacing=this._spacing||0,this.untick(this._sequenceTicker),this.tick(this._sequenceTicker=function(){if(this._mo_seq!=this._ts_touch){this._mo_seq=this._ts_touch;var i=this._mo_seqAlign!=this._ts_children;this._mo_seqAlign=this._ts_children;for(var n,r=0,s=0,o=this.first(!0),h=!0;n=o;){o=n.next(!0),n._pin.relativeMatrix();var a=n.pin("boxWidth"),u=n.pin("boxHeight");"column"==t?(!h&&(s+=this._spacing),n.pin("offsetY")!=s&&n.pin("offsetY",s),r=Math.max(r,a),s+=u,i&&n.pin("alignX",e)):"row"==t&&(!h&&(r+=this._spacing),n.pin("offsetX")!=r&&n.pin("offsetX",r),r+=a,s=Math.max(s,u),i&&n.pin("alignY",e)),h=!1}r+=2*this._padding,s+=2*this._padding,this.pin("width")!=r&&this.pin("width",r),this.pin("height")!=s&&this.pin("height",s)}}),this},e.box=function(){return e.create().box()},e.prototype.box=function(){return this._boxTicker?this:(this._padding=this._padding||0,this.tick(this._boxTicker=function(){if(this._mo_box!=this._ts_touch){this._mo_box=this._ts_touch;for(var t,e=0,i=0,n=this.first(!0);t=n;){n=t.next(!0),t._pin.relativeMatrix();var r=t.pin("boxWidth"),s=t.pin("boxHeight");e=Math.max(e,r),i=Math.max(i,s)}e+=2*this._padding,i+=2*this._padding,this.pin("width")!=e&&this.pin("width",e),this.pin("height")!=i&&this.pin("height",i)}}),this)},e.prototype.padding=function(t){return this._padding=t,this},e.prototype.spacing=function(t){return this._spacing=t,this}},{"./core":8,"./pin":16,"./render":17,"./util/create":21}],13:[function(t){function e(t,e){function i(){o.setTransform(1,0,0,1,0,0),o.clearRect(0,0,a,u),d.render(o)}function r(){h?(a=window.innerWidth>0?window.innerWidth:screen.width,u=window.innerHeight>0?window.innerHeight:screen.height,s.style.width=a+"px",s.style.height=u+"px"):(a=s.clientWidth,u=s.clientHeight),a*=f,u*=f,(s.width!==a||s.height!==u)&&(s.width=a,s.height=u,DEBUG&&console.log("Resize: "+a+" x "+u+" / "+f),d.viewport(a,u,f),i())}e=e||{};var s=e.canvas,o=null,h=!1,a=0,u=0,f=1;if("string"==typeof s&&(s=document.getElementById(s)),s||(s=document.getElementById("cutjs")),!s){h=!0,DEBUG&&console.log("Creating Canvas..."),s=document.createElement("canvas"),s.style.position="absolute";var c=document.body;c.insertBefore(s,c.firstChild)}o=s.getContext("2d");var p=window.devicePixelRatio||1,_=o.webkitBackingStorePixelRatio||o.mozBackingStorePixelRatio||o.msBackingStorePixelRatio||o.oBackingStorePixelRatio||o.backingStorePixelRatio||1;f=p/_;var l=window.requestAnimationFrame||window.msRequestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.oRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)};DEBUG&&console.log("Creating root...");var d=n.root(l,i);d.background=function(t){return s.style.backgroundColor=t,this},t(d,s),r(),window.addEventListener("resize",r,!1),window.addEventListener("orientationchange",r,!1)}function i(t,e,i){DEBUG&&console.log("Loading image: "+t);var n=new Image;n.onload=function(){e(n)},n.onerror=i,n.src=t}var n=t("../core");"undefined"==typeof DEBUG&&(DEBUG=!0),window.addEventListener("load",function(){DEBUG&&console.log("On load."),n.start({"app-loader":e,"image-loader":i})},!1)},{"../core":8}],14:[function(t,e){function i(t,e,i,n,r,s){this._dirty=!0,this.a=t||1,this.b=e||0,this.c=i||0,this.d=n||1,this.e=r||0,this.f=s||0}i.prototype.toString=function(){return"["+this.a+", "+this.b+", "+this.c+", "+this.d+", "+this.e+", "+this.f+"]"},i.prototype.clone=function(){return new i(this.a,this.b,this.c,this.d,this.e,this.f)},i.prototype.copyTo=function(t){return t.copyFrom(this),this},i.prototype.copyFrom=function(t){return this._dirty=!0,this.a=t.a,this.b=t.b,this.c=t.c,this.d=t.d,this.e=t.e,this.f=t.f,this},i.prototype.identity=function(){return this._dirty=!0,this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0,this},i.prototype.rotate=function(t){if(!t)return this;this._dirty=!0;var e=t?Math.cos(t):1,i=t?Math.sin(t):0,n=e*this.a-i*this.b,r=e*this.b+i*this.a,s=e*this.c-i*this.d,o=e*this.d+i*this.c,h=e*this.e-i*this.f,a=e*this.f+i*this.e;return this.a=n,this.b=r,this.c=s,this.d=o,this.e=h,this.f=a,this},i.prototype.translate=function(t,e){return t||e?(this._dirty=!0,this.e+=t,this.f+=e,this):this},i.prototype.scale=function(t,e){return t-1||e-1?(this._dirty=!0,this.a*=t,this.b*=e,this.c*=t,this.d*=e,this.e*=t,this.f*=e,this):this},i.prototype.skew=function(t,e){if(!t&&!e)return this;this._dirty=!0;var i=this.a+this.b*t,n=this.b+this.a*e,r=this.c+this.d*t,s=this.d+this.c*e,o=this.e+this.f*t,h=this.f+this.e*e;return this.a=i,this.b=n,this.c=r,this.d=s,this.e=o,this.f=h,this},i.prototype.concat=function(t){this._dirty=!0;var e=this,i=e.a*t.a+e.b*t.c,n=e.b*t.d+e.a*t.b,r=e.c*t.a+e.d*t.c,s=e.d*t.d+e.c*t.b,o=e.e*t.a+t.e+e.f*t.c,h=e.f*t.d+t.f+e.e*t.b;return this.a=i,this.b=n,this.c=r,this.d=s,this.e=o,this.f=h,this},i.prototype.reverse=function(){if(this._dirty){this._dirty=!1,this.reversed=this.reversed||new i;var t=this.a*this.d-this.b*this.c;this.reversed.a=this.d/t,this.reversed.b=-this.b/t,this.reversed.c=-this.c/t,this.reversed.d=this.a/t,this.reversed.e=(this.c*this.f-this.e*this.d)/t,this.reversed.f=(this.e*this.b-this.a*this.f)/t}return this.reversed},i.prototype.map=function(t,e){return e=e||{},e.x=this.a*t.x+this.c*t.y+this.e,e.y=this.b*t.x+this.d*t.y+this.f,e},i.prototype.mapX=function(t,e){return this.a*t+this.c*e+this.e},i.prototype.mapY=function(t,e){return this.b*t+this.d*e+this.f},e.exports=i},{}],15:[function(t,e){function i(t){if(t&&t instanceof n)return t;throw"Invalid node: "+t}var n=t("./core"),r=0;n.prototype._label="",n.prototype._visible=!0,n.prototype._parent=null,n.prototype._next=null,n.prototype._prev=null,n.prototype._first=null,n.prototype._last=null,n.prototype._attrs=null,n.prototype._flags=null,n.prototype.toString=function(){return"["+this._label+"]"},n.prototype.id=function(t){return this.label(t)},n.prototype.label=function(t){return"undefined"==typeof t?this._label:(this._label=t,this)},n.prototype.attr=function(t,e){return"undefined"==typeof e?null!==this._attrs?this._attrs[t]:void 0:((null!==this._attrs?this._attrs:this._attrs={})[t]=e,this)},n.prototype.visible=function(t){return"undefined"==typeof t?this._visible:(this._visible=t,this._parent&&(this._parent._ts_children=++r),this._ts_pin=++r,this.touch(),this)},n.prototype.hide=function(){return this.visible(!1)},n.prototype.show=function(){return this.visible(!0)},n.prototype.parent=function(){return this._parent},n.prototype.next=function(t){for(var e=this._next;e&&t&&!e._visible;)e=e._next;return e},n.prototype.prev=function(t){for(var e=this._prev;e&&t&&!e._visible;)e=e._prev;return e},n.prototype.first=function(t){for(var e=this._first;e&&t&&!e._visible;)e=e._next;return e},n.prototype.last=function(t){for(var e=this._last;e&&t&&!e._visible;)e=e._prev;return e},n.prototype.visit=function(t,e){var i=t.reverse,n=t.visible;if(!t.start||!t.start(this,e)){for(var r,s=i?this.last(n):this.first(n);r=s;)if(s=i?r.prev(n):r.next(n),r.visit(t,e))return!0;return t.end&&t.end(this,e)}},n.prototype.append=function(){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t].appendTo(this);return this},n.prototype.prepend=function(){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t].prependTo(this);return this},n.prototype.appendTo=function(t){return i(t),this.remove(),t._last&&(t._last._next=this,this._prev=t._last),this._parent=t,t._last=this,t._first||(t._first=this),this._parent._flag(this,!0),this._ts_parent=++r,t._ts_children=++r,t.touch(),this},n.prototype.prependTo=function(t){return i(t),this.remove(),t._first&&(t._first._prev=this,this._next=t._first),this._parent=t,t._first=this,t._last||(t._last=this),this._parent._flag(this,!0),this._ts_parent=++r,t._ts_children=++r,t.touch(),this},n.prototype.insertNext=function(){if(arguments.length)for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].insertAfter(this);return this},n.prototype.insertPrev=function(){if(arguments.length)for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].insertBefore(this);return this},n.prototype.insertBefore=function(t){i(t),this.remove();var e=t._parent,n=t._prev;return t._prev=this,n&&(n._next=this)||e&&(e._first=this),this._parent=e,this._prev=n,this._next=t,this._parent._flag(this,!0),this._ts_parent=++r,this.touch(),this},n.prototype.insertAfter=function(t){i(t),this.remove();var e=t._parent,n=t._next;return t._next=this,n&&(n._prev=this)||e&&(e._last=this),this._parent=e,this._prev=t,this._next=n,this._parent._flag(this,!0),this._ts_parent=++r,this.touch(),this},n.prototype.remove=function(){if(arguments.length){for(var t=0;t<arguments.length;t++)i(arguments[t]),arguments[t]&&arguments[t].remove();return this}return this._prev&&(this._prev._next=this._next),this._next&&(this._next._prev=this._prev),this._parent&&(this._parent._first===this&&(this._parent._first=this._next),this._parent._last===this&&(this._parent._last=this._prev),this._parent._flag(this,!1),this._parent._ts_children=++r,this._parent.touch()),this._prev=this._next=this._parent=null,this._ts_parent=++r,this},n.prototype.empty=function(){for(var t,e=this._first;t=e;)e=t._next,t._prev=t._next=t._parent=null,this._flag(t,!1);return this._first=this._last=null,this._ts_children=++r,this.touch(),this},n.prototype.touch=function(){return this._ts_touch=++r,this._parent&&this._parent.touch(),this},n.prototype._flag=function(t,e){if("undefined"==typeof e)return null!==this._flags&&this._flags[t]||0;if("string"==typeof t&&(e?(this._flags=this._flags||{},!this._flags[t]&&this._parent&&this._parent._flag(t,!0),this._flags[t]=(this._flags[t]||0)+1):this._flags&&this._flags[t]>0&&(1==this._flags[t]&&this._parent&&this._parent._flag(t,!1),this._flags[t]=this._flags[t]-1)),"object"==typeof t&&t._flags)for(var i in t._flags)t._flags[i]>0&&this._flag(i,e);return this},e.exports=n},{"./core":8}],16:[function(t,e){function i(t){this._owner=t,this._parent=null,this._relativeMatrix=new r,this._absoluteMatrix=new r,this.reset()}var n=t("./core"),r=t("./matrix"),s=0;n._init(function(){this._pin=new i(this)}),n.prototype.matrix=function(){return this._pin.absoluteMatrix()},n.prototype.pin=function(t,e){return"object"==typeof t?(this._pin.set(t),this):"string"==typeof t?"undefined"==typeof e?this._pin.get(t):(this._pin.set(t,e),this):"undefined"==typeof t?this._pin:void 0},i.prototype.reset=function(){this._textureAlpha=1,this._alpha=1,this._width=0,this._height=0,this._scaleX=1,this._scaleY=1,this._skewX=0,this._skewY=0,this._rotation=0,this._pivoted=!1,this._pivotX=null,this._pivotY=null,this._handled=!1,this._handleX=0,this._handleY=0,this._aligned=!1,this._alignX=0,this._alignY=0,this._offsetX=0,this._offsetY=0,this._boxX=0,this._boxY=0,this._boxWidth=this._width,this._boxHeight=this._height,this._ts_translate=++s,this._ts_transform=++s,this._ts_matrix=++s},i.prototype._update=function(){return this._parent=this._owner._parent&&this._owner._parent._pin,this._handled&&this._mo_handle!=this._ts_transform&&(this._mo_handle=this._ts_transform,this._ts_translate=++s),this._aligned&&this._parent&&this._mo_align!=this._parent._ts_transform&&(this._mo_align=this._parent._ts_transform,this._ts_translate=++s),this},i.prototype.toString=function(){return this._owner+" ("+(this._parent?this._parent._owner:null)+")"},i.prototype.absoluteMatrix=function(){this._update();var t=Math.max(this._ts_transform,this._ts_translate,this._parent?this._parent._ts_matrix:0);if(this._mo_abs==t)return this._absoluteMatrix;this._mo_abs=t;var e=this._absoluteMatrix;return e.copyFrom(this.relativeMatrix()),this._parent&&e.concat(this._parent._absoluteMatrix),this._ts_matrix=++s,e},i.prototype.relativeMatrix=function(){this._update();var t=Math.max(this._ts_transform,this._ts_translate,this._parent?this._parent._ts_transform:0);if(this._mo_rel==t)return this._relativeMatrix;this._mo_rel=t;var e=this._relativeMatrix;if(e.identity(),this._pivoted&&e.translate(-this._pivotX*this._width,-this._pivotY*this._height),e.scale(this._scaleX,this._scaleY),e.skew(this._skewX,this._skewY),e.rotate(this._rotation),this._pivoted&&e.translate(this._pivotX*this._width,this._pivotY*this._height),this._pivoted)this._boxX=0,this._boxY=0,this._boxWidth=this._width,this._boxHeight=this._height;else{var i,n;e.a>0&&e.c>0||e.a<0&&e.c<0?(i=0,n=e.a*this._width+e.c*this._height):(i=e.a*this._width,n=e.c*this._height),i>n?(this._boxX=n,this._boxWidth=i-n):(this._boxX=i,this._boxWidth=n-i),e.b>0&&e.d>0||e.b<0&&e.d<0?(i=0,n=e.b*this._width+e.d*this._height):(i=e.b*this._width,n=e.d*this._height),i>n?(this._boxY=n,this._boxHeight=i-n):(this._boxY=i,this._boxHeight=n-i)}return this._x=this._offsetX,this._y=this._offsetY,this._x-=this._boxX+this._handleX*this._boxWidth,this._y-=this._boxY+this._handleY*this._boxHeight,this._aligned&&this._parent&&(this._parent.relativeMatrix(),this._x+=this._alignX*this._parent._width,this._y+=this._alignY*this._parent._height),e.translate(this._x,this._y),this._relativeMatrix},i.prototype.get=function(t){return i._get(this,t)},i.prototype.set=function(t,e){if("string"==typeof t)i._set(this,t,e);else if("object"==typeof t)for(e in t)i._set(this,e,t[e],t);return this._owner&&(this._owner._ts_pin=++s,this._owner.touch()),this},i._get=function(t,e){return"undefined"!=typeof(e=i._getters[e])?e.call(i._getters,t):void 0},i._set=function(t,e,n,r){"undefined"!=typeof(e=i._setters[e])&&"undefined"!=typeof n&&e.call(i._setters,t,n,r)},i._getters={alpha:function(t){return t._alpha},textureAlpha:function(t){return t._textureAlpha},width:function(t){return t._width},height:function(t){return t._height},boxWidth:function(t){return t._boxWidth},boxHeight:function(t){return t._boxHeight},scaleX:function(t){return t._scaleX},scaleY:function(t){return t._scaleY},skewX:function(t){return t._skewX},skewY:function(t){return t._skewY},rotation:function(t){return t._rotation},pivotX:function(t){return t._pivotX},pivotY:function(t){return t._pivotY},offsetX:function(t){return t._offsetX},offsetY:function(t){return t._offsetY},alignX:function(t){return t._alignX},alignY:function(t){return t._alignY},handleX:function(t){return t._handleX},handleY:function(t){return t._handleY}},i._setters={alpha:function(t,e){t._alpha=e},textureAlpha:function(t,e){t._textureAlpha=e},width:function(t,e){t._width_=e,t._width=e,t._ts_transform=++s},height:function(t,e){t._height_=e,t._height=e,t._ts_transform=++s},scale:function(t,e){t._scaleX=e,t._scaleY=e,t._ts_transform=++s},scaleX:function(t,e){t._scaleX=e,t._ts_transform=++s},scaleY:function(t,e){t._scaleY=e,t._ts_transform=++s},skew:function(t,e){t._skewX=e,t._skewY=e,t._ts_transform=++s},skewX:function(t,e){t._skewX=e,t._ts_transform=++s},skewY:function(t,e){t._skewY=e,t._ts_transform=++s},rotation:function(t,e){t._rotation=e,t._ts_transform=++s},pivot:function(t,e){t._pivotX=e,t._pivotY=e,t._pivoted=!0,t._ts_transform=++s},pivotX:function(t,e){t._pivotX=e,t._pivoted=!0,t._ts_transform=++s},pivotY:function(t,e){t._pivotY=e,t._pivoted=!0,t._ts_transform=++s},offset:function(t,e){t._offsetX=e,t._offsetY=e,t._ts_translate=++s},offsetX:function(t,e){t._offsetX=e,t._ts_translate=++s},offsetY:function(t,e){t._offsetY=e,t._ts_translate=++s},align:function(t,e){this.alignX(t,e),this.alignY(t,e)},alignX:function(t,e){t._alignX=e,t._aligned=!0,t._ts_translate=++s,this.handleX(t,e)},alignY:function(t,e){t._alignY=e,t._aligned=!0,t._ts_translate=++s,this.handleY(t,e)},handle:function(t,e){this.handleX(t,e),this.handleY(t,e)},handleX:function(t,e){t._handleX=e,t._handled=!0,t._ts_translate=++s
+},handleY:function(t,e){t._handleY=e,t._handled=!0,t._ts_translate=++s},resizeMode:function(t,e,i){i&&("in"==e?e="in-pad":"out"==e&&(e="out-crop"),t._scaleTo(i.resizeWidth,i.resizeHeight,e))},resizeWidth:function(t,e,i){i&&i.resizeMode||t._scaleTo(e,null)},resizeHeight:function(t,e,i){i&&i.resizeMode||t._scaleTo(null,e)},scaleMode:function(t,e,i){i&&t._scaleTo(i.scaleWidth,i.scaleHeight,e)},scaleWidth:function(t,e,i){i&&i.scaleMode||t._scaleTo(e,null)},scaleHeight:function(t,e,i){i&&i.scaleMode||t._scaleTo(null,e)},matrix:function(t,e){this.scaleX(t,e.a),this.skewX(t,e.c/e.d),this.skewY(t,e.b/e.a),this.scaleY(t,e.d),this.offsetX(t,e.e),this.offsetY(t,e.f),this.rotation(t,0)}},i.prototype._scaleTo=function(t,e,i){var n="number"==typeof t,r="number"==typeof e,o="string"==typeof i,h=this;h._ts_transform=++s,n&&(h._scaleX=t/h._width_,h._width=h._width_),r&&(h._scaleY=e/h._height_,h._height=h._height_),n&&r&&o&&("out"==i||"out-crop"==i?h._scaleX=h._scaleY=Math.max(h._scaleX,h._scaleY):("in"==i||"in-pad"==i)&&(h._scaleX=h._scaleY=Math.min(h._scaleX,h._scaleY)),("out-crop"==i||"in-pad"==i)&&(h._width=t/h._scaleX,h._height=e/h._scaleY))},e.exports=i},{"./core":8,"./matrix":14}],17:[function(t){var e=t("./core");t("./pin");{var i=t("./util/stats");t("./util/create")}e.prototype._textures=null,e.prototype._tickBefore=null,e.prototype._tickAfter=null,e.prototype._alpha=1,e.prototype.render=function(t){if(this._visible){i.node++;var e=this.matrix();t.setTransform(e.a,e.b,e.c,e.d,e.e,e.f),this._alpha=this._pin._alpha*(this._parent?this._parent._alpha:1);var n=this._pin._textureAlpha*this._alpha;if(t.globalAlpha!=n&&(t.globalAlpha=n),null!==this._textures)for(var r=0,s=this._textures.length;s>r;r++)this._textures[r].draw(t);t.globalAlpha!=this._alpha&&(t.globalAlpha=this._alpha);for(var o,h=this._first;o=h;)h=o._next,o.render(t)}},e.prototype.MAX_ELAPSE=1/0,e.prototype._tick=function(t,e,n){if(this._visible){t>this.MAX_ELAPSE&&(t=this.MAX_ELAPSE);var r=!1;if(null!==this._tickBefore)for(var s=0,o=this._tickBefore.length;o>s;s++)i.tick++,r=this._tickBefore[s].call(this,t,e,n)===!0||r;for(var h,a=this._first;h=a;)a=h._next,h._flag("_tick")&&(r=h._tick(t,e,n)===!0?!0:r);if(null!==this._tickAfter)for(var s=0,o=this._tickAfter.length;o>s;s++)i.tick++,r=this._tickAfter[s].call(this,t,e,n)===!0||r;return r}},e.prototype.tick=function(t,e){"function"==typeof t&&(e?(null===this._tickBefore&&(this._tickBefore=[]),this._tickBefore.push(t)):(null===this._tickAfter&&(this._tickAfter=[]),this._tickAfter.push(t)),this._flag("_tick",null!==this._tickAfter&&this._tickAfter.length>0||null!==this._tickBefore&&this._tickBefore.length>0))},e.prototype.untick=function(t){if("function"==typeof t){var e;null!==this._tickBefore&&(e=this._tickBefore.indexOf(t))>=0&&this._tickBefore.splice(e,1),null!==this._tickAfter&&(e=this._tickAfter.indexOf(t))>=0&&this._tickAfter.splice(e,1)}}},{"./core":8,"./pin":16,"./util/create":21,"./util/stats":27}],18:[function(t){function e(t,i){e._super.call(this),this.label("Root"),this._paused=!0;var r=this,s=0,o=function(t){if(r._paused!==!0){n.tick=n.node=n.draw=0;var e=s||t,o=t-e;s=t;var h=r._tick(o,t,e);r._mo_touch!=r._ts_touch?(r._mo_touch=r._ts_touch,i.call(r),r.request()):h?r.request():r.pause(),n.fps=o?1e3/o:0}};this.request=function(){t(o)}}var i=t("./core");t("./pin"),t("./render");var n=t("./util/stats"),r=t("./util/create"),s=t("./util/extend");e._super=i,e.prototype=r(e._super.prototype),i.root=function(t,i){return new e(t,i)},e.prototype.start=function(){return this.resume()},e.prototype.resume=function(t){return(this._paused||t)&&(this._paused=!1,this.request()),this},e.prototype.pause=function(){return this._paused=!0,this},e.prototype.touch=function(){return this.resume(),e._super.prototype.touch.call(this)},e.prototype.background=function(){return this},e.prototype.viewport=function(t,e,i){if("undefined"==typeof t)return s({},this._viewport);this._viewport={width:t,height:e,ratio:i||1},this._updateViewbox();var n=s({},this._viewport);return this.visit({start:function(t){return t._flag("viewport")?void t.publish("viewport",[n]):!0}}),this},e.prototype.viewbox=function(t,e,i){return this._viewbox={width:t,height:e,mode:/^(in|out|in-pad|out-crop)$/.test(i)?i:"in-pad"},this._updateViewbox(),this},e.prototype._updateViewbox=function(){var t=this._viewbox,e=this._viewport;e&&t?(this.pin({width:t.width,height:t.height}),this._pin._scaleTo(e.width,e.height,t.mode)):e&&this.pin({width:e.width,height:e.height})}},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/extend":22,"./util/stats":27}],19:[function(t){function e(){e._super.call(this),this.label("String"),this._textures=[]}var i=t("./core");t("./pin"),t("./render");var n=t("./util/create"),r=t("./util/is");i.string=function(t){return(new e).frames(t)},e._super=i,e.prototype=n(e._super.prototype),e.prototype.setFont=function(t,e,i){return this.frames(t,e,i)},e.prototype.frames=function(t){return this._textures=[],"string"==typeof t?(t=i.texture(t),this._item=function(e){return t.one(e)}):"object"==typeof t?this._item=function(e){return t[e]}:"function"==typeof t&&(this._item=t),this},e.prototype.setValue=function(t,e,i){return this.value(t,e,i)},e.prototype.value=function(t){if("undefined"==typeof t)return this._value;if(this._value===t)return this;this._value=t,null===t?t="":"string"==typeof t||r.array(t)||(t=t.toString()),this._spacing=this._spacing||0;for(var e=0,i=0,n=0;n<t.length;n++){var s=this._textures[n]=this._item(t[n]);e+=n>0?this._spacing:0,s.dest(e,0),e+=s.width,i=Math.max(i,s.height)}return this.pin("width",e),this.pin("height",i),this._textures.length=t.length,this}},{"./core":8,"./pin":16,"./render":17,"./util/create":21,"./util/is":23}],20:[function(t,e){function i(t,e){"object"==typeof t&&this.src(t,e)}var n=t("./util/stats"),r=t("./util/math");i.prototype.pipe=function(){return new i(this)},i.prototype.src=function(t,e,i,n){if("object"==typeof t){var r=t,s=e||1;this._image=r,this._sx=this._dx=0,this._sy=this._dy=0,this._sw=this._dw=r.width/s,this._sh=this._dh=r.height/s,this.width=r.width/s,this.height=r.height/s,this.ratio=s}else"undefined"==typeof i?(i=t,n=e):(this._sx=t,this._sy=e),this._sw=this._dw=i,this._sh=this._dh=n,this.width=i,this.height=n;return this},i.prototype.dest=function(t,e,i,n){return this._dx=t,this._dy=e,this._dx=t,this._dy=e,"undefined"!=typeof i&&(this._dw=i,this._dh=n,this.width=i,this.height=n),this},i.prototype.draw=function(t,e,i,s,o,h,a,u,f){var c=this._image;if(null!==c&&"object"==typeof c){var p=this._sx,_=this._sy,l=this._sw,d=this._sh,g=this._dx,m=this._dy,y=this._dw,v=this._dh;"undefined"!=typeof h?(e=r.limit(e,0,this._sw),s=r.limit(s,0,this._sw-e),i=r.limit(i,0,this._sh),o=r.limit(o,0,this._sh-i),p+=e,_+=i,l=s,d=o,g=h,m=a,y=u,v=f):"undefined"!=typeof s?(g=e,m=i,y=s,v=o):"undefined"!=typeof e&&(y=e,v=i);var x=this.ratio||1;p*=x,_*=x,l*=x,d*=x;try{"function"==typeof c.draw?c.draw(t,p,_,l,d,g,m,y,v):(n.draw++,t.drawImage(c,p,_,l,d,g,m,y,v))}catch(b){c._draw_failed||(console.log("Unable to draw: ",c),console.log(b),c._draw_failed=!0)}}},e.exports=i},{"./util/math":24,"./util/stats":27}],21:[function(t,e){function i(){}e.exports="function"==typeof Object.create?function(t,e){return Object.create.call(Object,t,e)}:function(t,e){if(e)throw Error("Second argument is not supported!");if("object"!=typeof t||null===t)throw Error("Invalid prototype!");return i.prototype=t,new i}},{}],22:[function(t,e){e.exports=function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var n in i)i.hasOwnProperty(n)&&(t[n]=i[n])}return t}},{}],23:[function(t,e){var i=Object.prototype,n=i.hasOwnProperty,r=i.toString,s=/^[A-Fa-f0-9]+$/,o=e.exports={};o.a=o.an=o.type=function(t,e){return typeof t===e},o.defined=function(t){return"undefined"!=typeof t},o.empty=function(t){var e,i=r.call(t);if("[object Array]"===i||"[object Arguments]"===i||"[object String]"===i)return 0===t.length;if("[object Object]"===i){for(e in t)if(n.call(t,e))return!1;return!0}return!t},o.equal=function(t,e){if(t===e)return!0;var i,n=r.call(t);if(n!==r.call(e))return!1;if("[object Object]"===n){for(i in t)if(!(o.equal(t[i],e[i])&&i in e))return!1;for(i in e)if(!(o.equal(t[i],e[i])&&i in t))return!1;return!0}if("[object Array]"===n){if(i=t.length,i!==e.length)return!1;for(;--i;)if(!o.equal(t[i],e[i]))return!1;return!0}return"[object Function]"===n?t.prototype===e.prototype:"[object Date]"===n?t.getTime()===e.getTime():!1},o.instance=function(t,e){return t instanceof e},o.nil=function(t){return null===t},o.undef=function(t){return"undefined"==typeof t},o.array=function(t){return"[object Array]"===r.call(t)},o.emptyarray=function(t){return o.array(t)&&0===t.length},o.arraylike=function(t){return!!t&&!o["boolean"](t)&&n.call(t,"length")&&isFinite(t.length)&&o.number(t.length)&&t.length>=0},o["boolean"]=function(t){return"[object Boolean]"===r.call(t)},o.element=function(t){return void 0!==t&&"undefined"!=typeof HTMLElement&&t instanceof HTMLElement&&1===t.nodeType},o.fn=function(t){return"[object Function]"===r.call(t)},o.number=function(t){return"[object Number]"===r.call(t)},o.nan=function(t){return!o.number(t)||t!==t},o.object=function(t){return"[object Object]"===r.call(t)},o.hash=function(t){return o.object(t)&&t.constructor===Object&&!t.nodeType&&!t.setInterval},o.regexp=function(t){return"[object RegExp]"===r.call(t)},o.string=function(t){return"[object String]"===r.call(t)},o.hex=function(t){return o.string(t)&&(!t.length||s.test(t))}},{}],24:[function(t,e){e.exports.random=function(t,e){return"undefined"==typeof t?(e=1,t=0):"undefined"==typeof e&&(e=t,t=0),t==e?t:Math.random()*(e-t)+t},e.exports.rotate=function(t,e,i){return"undefined"==typeof e?(i=1,e=0):"undefined"==typeof i&&(i=e,e=0),i>e?(t=(t-e)%(i-e),t+(0>t?i:e)):(t=(t-i)%(e-i),t+(0>=t?e:i))},e.exports.limit=function(t,e,i){return e>t?e:t>i?i:t},e.exports.length=function(t,e){return Math.sqrt(t*t+e*e)}},{}],25:[function(t,e){e.exports=function(t,e){var i=!1;return function(){i||(i=!0,t.apply(e,arguments))}}},{}],26:[function(t,e){e.exports=function(t,e,i,n,r,s){var o=t.width,h=t.height,a=t.left,u=t.right,f=t.top,c=t.bottom;a="number"==typeof a&&a===a?a:0,u="number"==typeof u&&u===u?u:0,f="number"==typeof f&&f===f?f:0,c="number"==typeof c&&c===c?c:0,o=o-a-u,h=h-f-c,r||(e=Math.max(e-a-u,0),i=Math.max(i-f-c,0));var p=0;if(f>0&&a>0&&s(p++,0,0,a,f,0,0,a,f),c>0&&a>0&&s(p++,0,h+f,a,c,0,i+f,a,c),f>0&&u>0&&s(p++,o+a,0,u,f,e+a,0,u,f),c>0&&u>0&&s(p++,o+a,h+f,u,c,e+a,i+f,u,c),n)f>0&&s(p++,a,0,o,f,a,0,e,f),c>0&&s(p++,a,h+f,o,c,a,i+f,e,c),a>0&&s(p++,0,f,a,h,0,f,a,i),u>0&&s(p++,o+a,f,u,h,e+a,f,u,i),s(p++,a,f,o,h,a,f,e,i);else for(var _,l=a,d=e;d>0;){_=Math.min(o,d),d-=o;for(var g,m=f,y=i;y>0;)g=Math.min(h,y),y-=h,s(p++,a,f,_,g,l,m,_,g),0>=d&&(a&&s(p++,0,f,a,g,0,m,a,g),u&&s(p++,o+a,f,u,g,l+_,m,u,g)),m+=g;f&&s(p++,a,0,_,f,l,0,_,f),c&&s(p++,a,h+f,_,c,l,m,_,c),l+=_}return p}},{}],27:[function(t,e){e.exports={}},{}],28:[function(t,e){e.exports.startsWith=function(t,e){return"string"==typeof t&&"string"==typeof e&&t.substring(0,e.length)==e}},{}]},{},[1])(1)});
\ No newline at end of file
diff --git a/lib/addon/easing.js b/lib/addon/easing.js
new file mode 100644
index 0000000..55e9a6d
--- /dev/null
+++ b/lib/addon/easing.js
@@ -0,0 +1,191 @@
+/*
+ * CutJS
+ * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
+ * Available under the MIT license
+ * @license
+ */
+
+function _identity(x) {
+  return x;
+};
+var _cache = {};
+var _modes = {};
+var _easings = {};
+
+function Easing(token) {
+  if (typeof token === 'function') {
+    return token;
+  }
+  if (typeof token !== 'string') {
+    return _identity;
+  }
+  var fn = _cache[token];
+  if (fn) {
+    return fn;
+  }
+  var match = /^(\w+)(-(in|out|in-out|out-in))?(\((.*)\))?$/i.exec(token);
+  if (!match || !match.length) {
+    return _identity;
+  }
+  easing = _easings[match[1]];
+  mode = _modes[match[3]];
+  params = match[5];
+  if (easing && easing.fn) {
+    fn = easing.fn;
+  } else if (easing && easing.fc) {
+    fn = easing.fc.apply(easing.fc, params
+        && params.replace(/\s+/, '').split(','));
+  } else {
+    fn = _identity;
+  }
+  if (mode) {
+    fn = mode.fn(fn);
+  }
+  // TODO: It can be a memory leak with different `params`.
+  _cache[token] = fn;
+  return fn;
+};
+
+Easing.add = function(data) {
+  var names = (data.name || data.mode).split(/\s+/);
+  for (var i = 0; i < names.length; i++) {
+    var name = names[i];
+    if (name) {
+      (data.name ? _easings : _modes)[name] = data;
+    }
+  }
+};
+
+Easing.add({
+  mode : 'in',
+  fn : function(f) {
+    return f;
+  }
+});
+
+Easing.add({
+  mode : 'out',
+  fn : function(f) {
+    return function(t) {
+      return 1 - f(1 - t);
+    };
+  }
+});
+
+Easing.add({
+  mode : 'in-out',
+  fn : function(f) {
+    return function(t) {
+      return (t < 0.5) ? (f(2 * t) / 2) : (1 - f(2 * (1 - t)) / 2);
+    };
+  }
+});
+
+Easing.add({
+  mode : 'out-in',
+  fn : function(f) {
+    return function(t) {
+      return (t < 0.5) ? (1 - f(2 * (1 - t)) / 2) : (f(2 * t) / 2);
+    };
+  }
+});
+
+Easing.add({
+  name : 'linear',
+  fn : function(t) {
+    return t;
+  }
+});
+
+Easing.add({
+  name : 'quad',
+  fn : function(t) {
+    return t * t;
+  }
+});
+
+Easing.add({
+  name : 'cubic',
+  fn : function(t) {
+    return t * t * t;
+  }
+});
+
+Easing.add({
+  name : 'quart',
+  fn : function(t) {
+    return t * t * t * t;
+  }
+});
+
+Easing.add({
+  name : 'quint',
+  fn : function(t) {
+    return t * t * t * t * t;
+  }
+});
+
+Easing.add({
+  name : 'sin sine',
+  fn : function(t) {
+    return 1 - Math.cos(t * Math.PI / 2);
+  }
+});
+
+Easing.add({
+  name : 'exp',
+  fn : function(t) {
+    return t == 0 ? 0 : Math.pow(2, 10 * (t - 1));
+  }
+});
+
+Easing.add({
+  name : 'circle circ',
+  fn : function(t) {
+    return 1 - Math.sqrt(1 - t * t);
+  }
+});
+
+Easing.add({
+  name : 'bounce',
+  fn : function(t) {
+    return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625
+        * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625
+        * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t
+        + .984375;
+  }
+});
+
+Easing.add({
+  name : 'poly',
+  fc : function(e) {
+    return function(t) {
+      return Math.pow(t, e);
+    };
+  }
+});
+
+Easing.add({
+  name : 'elastic',
+  fc : function(a, p) {
+    p = p || 0.45;
+    a = a || 1;
+    var s = p / (2 * Math.PI) * Math.asin(1 / a);
+    return function(t) {
+      return 1 + a * Math.pow(2, -10 * t)
+          * Math.sin((t - s) * (2 * Math.PI) / p);
+    };
+  }
+});
+
+Easing.add({
+  name : 'back',
+  fc : function(s) {
+    s = typeof s !== 'undefined' ? s : 1.70158;
+    return function(t) {
+      return t * t * ((s + 1) * t - s);
+    };
+  }
+});
+
+module.exports = Easing;
diff --git a/lib/addon/mouse.js b/lib/addon/mouse.js
new file mode 100644
index 0000000..96eee53
--- /dev/null
+++ b/lib/addon/mouse.js
@@ -0,0 +1,212 @@
+/*
+ * CutJS
+ * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
+ * Available under the MIT license
+ * @license
+ */
+
+if (typeof DEBUG === 'undefined')
+  DEBUG = true;
+
+function Mouse() {
+  Mouse.subscribe.apply(Mouse, arguments);
+};
+
+Mouse.CLICK = 'click';
+Mouse.START = 'touchstart mousedown';
+Mouse.MOVE = 'touchmove mousemove';
+Mouse.END = 'touchend mouseup';
+Mouse.CANCEL = 'touchcancel';
+
+Mouse.subscribe = function(root, elem) {
+  var visitor = null, data = {}, abs = null, rel = null, clicked = [];
+
+  elem = elem || document;
+
+  // click events are synthesized from start/end events on same nodes
+  // elem.addEventListener('click', handleClick);
+
+  elem.addEventListener('touchstart', handleStart);
+  elem.addEventListener('touchend', handleEnd);
+  elem.addEventListener('touchmove', handleMove);
+  elem.addEventListener('touchcancel', handleCancel);
+
+  elem.addEventListener('mousedown', handleStart);
+  elem.addEventListener('mouseup', handleEnd);
+  elem.addEventListener('mousemove', handleMove);
+
+  function handleStart(event) {
+    Mouse._xy(root, elem, event, abs);
+    DEBUG && console.log('Mouse Start: ' + event.type + ' ' + abs);
+    event.preventDefault();
+    publish(event.type, event);
+
+    findClicks();
+  }
+
+  function handleEnd(event) {
+    // New xy is not valid/available, last xy is used instead.
+    DEBUG && console.log('Mouse End: ' + event.type + ' ' + abs);
+    event.preventDefault();
+    publish(event.type, event);
+
+    if (clicked.length) {
+      DEBUG && console.log('Mouse Click: ' + clicked.length);
+      fireClicks(event);
+    }
+  }
+
+  function handleCancel(event) {
+    DEBUG && console.log('Mouse Cancel: ' + event.type);
+    event.preventDefault();
+    publish(event.type, event);
+  }
+
+  function handleMove(event) {
+    Mouse._xy(root, elem, event, abs);
+    // DEBUG && console.log('Mouse Move: ' + event.type + ' ' +
+    // abs);
+    if (!root._flag(event.type)) {
+      return;
+    }
+    event.preventDefault();
+    publish(event.type, event);
+  }
+
+  function findClicks() {
+    while (clicked.length) {
+      clicked.pop();
+    }
+    publish('click', null, clicked);
+  }
+
+  function fireClicks(event) {
+    data.event = event;
+    data.type = 'click';
+    data.root = root;
+    data.collect = false;
+
+    var cancel = false;
+    while (clicked.length) {
+      var node = clicked.shift();
+      if (cancel) {
+        continue;
+      }
+      cancel = visitor.end(node, data) ? true : cancel;
+    }
+  }
+
+  function publish(type, event, collect) {
+    rel.x = abs.x;
+    rel.y = abs.y;
+
+    data.event = event;
+    data.type = type;
+    data.root = /* root._capture || */root;
+    data.collect = collect;
+
+    data.root.visit(visitor, data);
+  }
+
+  visitor = {
+    reverse : true,
+    visible : true,
+    start : function(node, data) {
+      return !node._flag(data.type);
+    },
+    end : function(node, data) {
+      // data: event, type, root, collect
+      rel.raw = data.event;
+      rel.type = data.type;
+      var listeners = node.listeners(data.type);
+      if (!listeners) {
+        return;
+      }
+      node.matrix().reverse().map(abs, rel);
+      if (!(node === data.root || node.attr('spy') || Mouse._isInside(node, rel))) {
+        return;
+      }
+      if (data.collect) {
+        data.collect.push(node);
+        return;
+      }
+      var cancel = false;
+      for (var l = 0; l < listeners.length; l++) {
+        cancel = listeners[l].call(node, rel) ? true : cancel;
+      }
+      return cancel;
+    }
+  };
+
+  abs = {
+    x : 0,
+    y : 0,
+    toString : function() {
+      return (this.x | 0) + 'x' + (this.y | 0);
+    }
+  };
+
+  rel = {
+    x : 0,
+    y : 0,
+    toString : function() {
+      return abs + ' / ' + (this.x | 0) + 'x' + (this.y | 0);
+    }
+  };
+
+};
+
+Mouse._isInside = function(node, point) {
+  return point.x >= 0 && point.x <= node._pin._width && point.y >= 0
+      && point.y <= node._pin._height;
+};
+
+Mouse._xy = function(root, elem, event, point) {
+
+  var isTouch = false;
+
+  // touch screen events
+  if (event.touches) {
+    if (event.touches.length) {
+      isTouch = true;
+      point.x = event.touches[0].pageX;
+      point.y = event.touches[0].pageY;
+    } else {
+      return;
+    }
+  } else {
+    // mouse events
+    point.x = event.clientX;
+    point.y = event.clientY;
+    // See http://goo.gl/JuVnF2
+    if (document.body.scrollLeft || document.body.scrollTop) {
+      // body is added as offsetParent
+    } else if (document.documentElement) {
+      point.x += document.documentElement.scrollLeft;
+      point.y += document.documentElement.scrollTop;
+    }
+  }
+
+  // accounts for border
+  point.x -= elem.clientLeft || 0;
+  point.y -= elem.clientTop || 0;
+
+  var par = elem;
+  while (par) {
+    point.x -= par.offsetLeft || 0;
+    point.y -= par.offsetTop || 0;
+    if (!isTouch) {
+      // touch events offset scrolling with pageX/Y
+      // so scroll offset not needed for them
+      point.x += par.scrollLeft || 0;
+      point.y += par.scrollTop || 0;
+    }
+
+    par = par.offsetParent;
+  }
+
+  point.x *= root.viewport().ratio || 1;
+  point.y *= root.viewport().ratio || 1;
+};
+
+module.exports = Mouse;
diff --git a/lib/addon/tween.js b/lib/addon/tween.js
new file mode 100644
index 0000000..bee4e1d
--- /dev/null
+++ b/lib/addon/tween.js
@@ -0,0 +1,135 @@
+/*
+ * CutJS
+ * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
+ * Available under the MIT license
+ * @license
+ */
+
+var Easing = require('./easing');
+var Cut = require('../core');
+var Pin = require('../pin');
+
+Cut.prototype.tween = function(duration, delay) {
+  if (!this._tween) {
+    this._tween = new Tween(this);
+  }
+  return this._tween.tween(duration, delay);
+};
+
+var iid = 0;
+
+function Tween(node) {
+  // TODO: reuse head.start/keys/end
+
+  var tween = this;
+  this._owner = node;
+  this._queue = [];
+  this._next = null;
+
+  var lastTime = 0;
+  node.tick(function(elapsed, now, last) {
+    if (!tween._queue.length) {
+      return;
+    }
+
+    // ignore old elapsed
+    var ignore = lastTime != last;
+    lastTime = now;
+    this.touch();
+    if (ignore) {
+      return;
+    }
+
+    var head = tween._queue[0];
+
+    if (!head.time) {
+      head.time = 1;
+    } else {
+      head.time += elapsed;
+    }
+
+    if (head.time < head.delay) {
+      return;
+    }
+
+    if (!head.start) {
+      head.start = {};
+      head.keys = {};
+      for ( var key in head.end) {
+        if (typeof (start = node.pin(key)) === 'number') {
+          head.start[key] = start;
+          head.keys[key] = key;
+        } else if (typeof (startX = node.pin(key + 'X')) === 'number'
+            && typeof (startY = node.pin(key + 'Y')) === 'number') {
+          head.start[key + 'X'] = startX;
+          head.keys[key + 'X'] = key;
+          head.start[key + 'Y'] = startY;
+          head.keys[key + 'Y'] = key;
+        }
+      }
+    }
+
+    var p = (head.time - head.delay) / head.duration;
+    var over = p >= 1;
+    p = p > 1 ? 1 : p;
+    p = typeof head.easing == 'function' ? head.easing(p) : p;
+    var q = 1 - p;
+
+    for ( var key in head.keys) {
+      node.pin(key, head.start[key] * q + head.end[head.keys[key]] * p);
+    }
+
+    if (over) {
+      tween._queue.shift();
+      head.then && head.then.call(node);
+    }
+
+  }, true);
+};
+
+Tween.prototype.tween = function(duration, delay) {
+  this._next = {
+    id : ++iid,
+    end : {},
+    duration : duration || 400,
+    delay : delay || 0
+  };
+  return this;
+};
+
+Tween.prototype.pin = function(a, b) {
+  if (this._next !== this._queue[this._queue.length - 1]) {
+    this._owner.touch();
+    this._queue.push(this._next);
+  }
+
+  var end = this._next.end;
+  if (typeof a === 'object') {
+    for ( var attr in a) {
+      end[attr] = a[attr];
+    }
+  } else if (typeof b !== 'undefined') {
+    end[a] = b;
+  }
+  return this;
+};
+
+Tween.prototype.clear = function(forward) {
+  var tween;
+  while (tween = this._queue.shift()) {
+    forward && this._owner.pin(tween.end);
+  }
+  return this;
+};
+
+Tween.prototype.then = function(then) {
+  this._next.then = then;
+  return this;
+};
+
+Tween.prototype.ease = function(easing) {
+  this._next.easing = Easing(easing);
+  return this;
+};
+
+module.exports = Tween;
diff --git a/lib/anim.js b/lib/anim.js
new file mode 100644
index 0000000..bbc8c1d
--- /dev/null
+++ b/lib/anim.js
@@ -0,0 +1,142 @@
+/*
+ * CutJS
+ * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
+ * Available under the MIT license
+ * @license
+ */
+
+var Cut = require('./core');
+require('./pin');
+require('./render');
+
+var create = require('./util/create');
+var math = require('./util/math');
+
+Cut.anim = function(frames, fps) {
+  var anim = new Anim();
+  anim.frames(frames).gotoFrame(0);
+  fps && anim.fps(fps);
+  return anim;
+};
+
+Anim._super = Cut;
+Anim.prototype = create(Anim._super.prototype);
+
+// TODO: replace with atlas fps or texture time
+Cut.Anim = {
+  FPS : 15
+};
+
+function Anim() {
+  Anim._super.call(this);
+  this.label('Anim');
+
+  this._textures = [];
+
+  this._fps = Cut.Anim.FPS;
+  this._ft = 1000 / this._fps;
+
+  this._time = -1;
+  this._repeat = 0;
+
+  this._index = 0;
+  this._frames = [];
+
+  var lastTime = 0;
+  this.tick(function(t, now, last) {
+    if (this._time < 0 || this._frames.length <= 1) {
+      return;
+    }
+
+    // ignore old elapsed
+    var ignore = lastTime != last;
+    lastTime = now;
+    if (ignore) {
+      return true;
+    }
+
+    this._time += t;
+    if (this._time < this._ft) {
+      return true;
+    }
+    var n = this._time / this._ft | 0;
+    this._time -= n * this._ft;
+    this.moveFrame(n);
+    if (this._repeat > 0 && (this._repeat -= n) <= 0) {
+      this.stop();
+      this._callback && this._callback();
+      return false;
+    }
+    return true;
+  }, false);
+};
+
+Anim.prototype.fps = function(fps) {
+  if (typeof fps === 'undefined') {
+    return this._fps;
+  }
+  this._fps = fps > 0 ? fps : Cut.Anim.FPS;
+  this._ft = 1000 / this._fps;
+  return this;
+};
+
+/**
+ * @deprecated Use frames
+ */
+Anim.prototype.setFrames = function(a, b, c) {
+  return this.frames(a, b, c);
+};
+
+Anim.prototype.frames = function(frames) {
+  this._index = 0;
+  this._frames = Cut.texture(frames).array();
+  this.touch();
+  return this;
+};
+
+Anim.prototype.length = function() {
+  return this._frames ? this._frames.length : 0;
+};
+
+Anim.prototype.gotoFrame = function(frame, resize) {
+  this._index = math.rotate(frame, this._frames.length) | 0;
+  resize = resize || !this._textures[0];
+  this._textures[0] = this._frames[this._index];
+  if (resize) {
+    this.pin('width', this._textures[0].width);
+    this.pin('height', this._textures[0].height);
+  }
+  this.touch();
+  return this;
+};
+
+Anim.prototype.moveFrame = function(move) {
+  return this.gotoFrame(this._index + move);
+};
+
+Anim.prototype.repeat = function(repeat, callback) {
+  this._repeat = repeat * this._frames.length - 1;
+  this._callback = callback;
+  this.play();
+  return this;
+};
+
+Anim.prototype.play = function(frame) {
+  if (typeof frame !== 'undefined') {
+    this.gotoFrame(frame);
+    this._time = 0;
+  } else if (this._time < 0) {
+    this._time = 0;
+  }
+
+  this.touch();
+  return this;
+};
+
+Anim.prototype.stop = function(frame) {
+  this._time = -1;
+  if (typeof frame !== 'undefined') {
+    this.gotoFrame(frame);
+  }
+  return this;
+};
diff --git a/lib/canvas.js b/lib/canvas.js
index 29e9d39..bc6efd2 100644
--- a/lib/canvas.js
+++ b/lib/canvas.js
@@ -50,7 +50,7 @@ Cut.canvas = function(type, attributes, callback) {
   };
 
   if (typeof callback === 'function') {
-    callback.call(this, context);
+    callback.call(texture, context);
   }
 
   return texture;
diff --git a/lib/easing.js b/lib/easing.js
deleted file mode 100644
index 55e9a6d..0000000
--- a/lib/easing.js
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * CutJS
- * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
- * Available under the MIT license
- * @license
- */
-
-function _identity(x) {
-  return x;
-};
-var _cache = {};
-var _modes = {};
-var _easings = {};
-
-function Easing(token) {
-  if (typeof token === 'function') {
-    return token;
-  }
-  if (typeof token !== 'string') {
-    return _identity;
-  }
-  var fn = _cache[token];
-  if (fn) {
-    return fn;
-  }
-  var match = /^(\w+)(-(in|out|in-out|out-in))?(\((.*)\))?$/i.exec(token);
-  if (!match || !match.length) {
-    return _identity;
-  }
-  easing = _easings[match[1]];
-  mode = _modes[match[3]];
-  params = match[5];
-  if (easing && easing.fn) {
-    fn = easing.fn;
-  } else if (easing && easing.fc) {
-    fn = easing.fc.apply(easing.fc, params
-        && params.replace(/\s+/, '').split(','));
-  } else {
-    fn = _identity;
-  }
-  if (mode) {
-    fn = mode.fn(fn);
-  }
-  // TODO: It can be a memory leak with different `params`.
-  _cache[token] = fn;
-  return fn;
-};
-
-Easing.add = function(data) {
-  var names = (data.name || data.mode).split(/\s+/);
-  for (var i = 0; i < names.length; i++) {
-    var name = names[i];
-    if (name) {
-      (data.name ? _easings : _modes)[name] = data;
-    }
-  }
-};
-
-Easing.add({
-  mode : 'in',
-  fn : function(f) {
-    return f;
-  }
-});
-
-Easing.add({
-  mode : 'out',
-  fn : function(f) {
-    return function(t) {
-      return 1 - f(1 - t);
-    };
-  }
-});
-
-Easing.add({
-  mode : 'in-out',
-  fn : function(f) {
-    return function(t) {
-      return (t < 0.5) ? (f(2 * t) / 2) : (1 - f(2 * (1 - t)) / 2);
-    };
-  }
-});
-
-Easing.add({
-  mode : 'out-in',
-  fn : function(f) {
-    return function(t) {
-      return (t < 0.5) ? (1 - f(2 * (1 - t)) / 2) : (f(2 * t) / 2);
-    };
-  }
-});
-
-Easing.add({
-  name : 'linear',
-  fn : function(t) {
-    return t;
-  }
-});
-
-Easing.add({
-  name : 'quad',
-  fn : function(t) {
-    return t * t;
-  }
-});
-
-Easing.add({
-  name : 'cubic',
-  fn : function(t) {
-    return t * t * t;
-  }
-});
-
-Easing.add({
-  name : 'quart',
-  fn : function(t) {
-    return t * t * t * t;
-  }
-});
-
-Easing.add({
-  name : 'quint',
-  fn : function(t) {
-    return t * t * t * t * t;
-  }
-});
-
-Easing.add({
-  name : 'sin sine',
-  fn : function(t) {
-    return 1 - Math.cos(t * Math.PI / 2);
-  }
-});
-
-Easing.add({
-  name : 'exp',
-  fn : function(t) {
-    return t == 0 ? 0 : Math.pow(2, 10 * (t - 1));
-  }
-});
-
-Easing.add({
-  name : 'circle circ',
-  fn : function(t) {
-    return 1 - Math.sqrt(1 - t * t);
-  }
-});
-
-Easing.add({
-  name : 'bounce',
-  fn : function(t) {
-    return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625
-        * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625
-        * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t
-        + .984375;
-  }
-});
-
-Easing.add({
-  name : 'poly',
-  fc : function(e) {
-    return function(t) {
-      return Math.pow(t, e);
-    };
-  }
-});
-
-Easing.add({
-  name : 'elastic',
-  fc : function(a, p) {
-    p = p || 0.45;
-    a = a || 1;
-    var s = p / (2 * Math.PI) * Math.asin(1 / a);
-    return function(t) {
-      return 1 + a * Math.pow(2, -10 * t)
-          * Math.sin((t - s) * (2 * Math.PI) / p);
-    };
-  }
-});
-
-Easing.add({
-  name : 'back',
-  fc : function(s) {
-    s = typeof s !== 'undefined' ? s : 1.70158;
-    return function(t) {
-      return t * t * ((s + 1) * t - s);
-    };
-  }
-});
-
-module.exports = Easing;
diff --git a/lib/image.js b/lib/image.js
new file mode 100644
index 0000000..0098090
--- /dev/null
+++ b/lib/image.js
@@ -0,0 +1,77 @@
+/*
+ * CutJS
+ * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
+ * Available under the MIT license
+ * @license
+ */
+
+var Cut = require('./core');
+require('./pin');
+require('./render');
+
+var repeat = require('./util/repeat');
+var create = require('./util/create');
+
+Cut.image = function(image) {
+  var img = new Image();
+  image && img.image(image);
+  return img;
+};
+
+Image._super = Cut;
+Image.prototype = create(Image._super.prototype);
+
+function Image() {
+  Image._super.call(this);
+  this.label('Image');
+  this._textures = [];
+  this._image = null;
+};
+
+/**
+ * @deprecated Use image
+ */
+Image.prototype.setImage = function(a, b, c) {
+  return this.image(a, b, c);
+};
+
+Image.prototype.image = function(image) {
+  this._image = Cut.texture(image).one();
+  this.pin('width', this._image ? this._image.width : 0);
+  this.pin('height', this._image ? this._image.height : 0);
+  this._textures[0] = this._image.pipe();
+  this._textures.length = 1;
+  return this;
+};
+
+Image.prototype.tile = function(inner) {
+  this._repeat(false, inner);
+  return this;
+};
+
+Image.prototype.stretch = function(inner) {
+  this._repeat(true, inner);
+  return this;
+};
+
+Image.prototype._repeat = function(stretch, inner) {
+  var self = this;
+  this.untick(this._repeatTicker);
+  this.tick(this._repeatTicker = function() {
+    if (this._mo_stretch == this._pin._ts_transform) {
+      return;
+    }
+    this._mo_stretch = this._pin._ts_transform;
+    var width = this.pin('width');
+    var height = this.pin('height');
+    this._textures.length = repeat(this._image, width, height, stretch, inner,
+        insert);
+  });
+
+  function insert(i, sx, sy, sw, sh, dx, dy, dw, dh) {
+    var repeat = self._textures.length > i ? self._textures[i]
+        : self._textures[i] = self._image.pipe();
+    repeat.src(sx, sy, sw, sh);
+    repeat.dest(dx, dy, dw, dh);
+  }
+};
diff --git a/lib/index.js b/lib/index.js
index 2da2fea..75eadae 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -1,10 +1,10 @@
 module.exports = require('./core');
-
 module.exports.Matrix = require('./matrix');
-module.exports.Texture =require('./texture');
+module.exports.Texture = require('./texture');
 require('./atlas');
-require('./canvas');
 require('./node');
 require('./event');
 require('./pin');
-require('./ui');
+
+require('./render');
+require('./root');
\ No newline at end of file
diff --git a/lib/layout.js b/lib/layout.js
new file mode 100644
index 0000000..914071b
--- /dev/null
+++ b/lib/layout.js
@@ -0,0 +1,129 @@
+/*
+ * CutJS
+ * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
+ * Available under the MIT license
+ * @license
+ */
+
+var Cut = require('./core');
+require('./pin');
+require('./render');
+
+var create = require('./util/create');
+
+Cut.row = function(align) {
+  return Cut.create().row(align);
+};
+
+Cut.prototype.row = function(align) {
+  this.sequence('row', align);
+  return this;
+};
+
+Cut.column = function(align) {
+  return Cut.create().column(align);
+};
+
+Cut.prototype.column = function(align) {
+  this.sequence('column', align);
+  return this;
+};
+
+Cut.sequence = function(type, align) {
+  return Cut.create().sequence(type, align);
+};
+
+Cut.prototype.sequence = function(type, align) {
+
+  this._padding = this._padding || 0;
+  this._spacing = this._spacing || 0;
+
+  this.untick(this._sequenceTicker);
+  this.tick(this._sequenceTicker = function() {
+    if (this._mo_seq == this._ts_touch) {
+      return;
+    }
+    this._mo_seq = this._ts_touch;
+
+    var alignChildren = (this._mo_seqAlign != this._ts_children);
+    this._mo_seqAlign = this._ts_children;
+
+    var width = 0, height = 0;
+
+    var child, next = this.first(true);
+    var first = true;
+    while (child = next) {
+      next = child.next(true);
+
+      child._pin.relativeMatrix();
+      var w = child.pin('boxWidth');
+      var h = child.pin('boxHeight');
+
+      if (type == 'column') {
+        !first && (height += this._spacing);
+        child.pin('offsetY') != height && child.pin('offsetY', height);
+        width = Math.max(width, w);
+        height = height + h;
+        alignChildren && child.pin('alignX', align);
+
+      } else if (type == 'row') {
+        !first && (width += this._spacing);
+        child.pin('offsetX') != width && child.pin('offsetX', width);
+        width = width + w;
+        height = Math.max(height, h);
+        alignChildren && child.pin('alignY', align);
+      }
+      first = false;
+    }
+    width += 2 * this._padding;
+    height += 2 * this._padding;
+    this.pin('width') != width && this.pin('width', width);
+    this.pin('height') != height && this.pin('height', height);
+  });
+  return this;
+};
+
+Cut.box = function() {
+  return Cut.create().box();
+};
+
+Cut.prototype.box = function() {
+  if (this._boxTicker)
+    return this;
+
+  this._padding = this._padding || 0;
+
+  this.tick(this._boxTicker = function() {
+    if (this._mo_box == this._ts_touch) {
+      return;
+    }
+    this._mo_box = this._ts_touch;
+
+    var width = 0, height = 0;
+    var child, next = this.first(true);
+    while (child = next) {
+      next = child.next(true);
+      child._pin.relativeMatrix();
+      var w = child.pin('boxWidth');
+      var h = child.pin('boxHeight');
+      width = Math.max(width, w);
+      height = Math.max(height, h);
+    }
+    width += 2 * this._padding;
+    height += 2 * this._padding;
+    this.pin('width') != width && this.pin('width', width);
+    this.pin('height') != height && this.pin('height', height);
+  });
+  return this;
+};
+
+// TODO: move padding to pin
+Cut.prototype.padding = function(pad) {
+  this._padding = pad;
+  return this;
+};
+
+Cut.prototype.spacing = function(space) {
+  this._spacing = space;
+  return this;
+};
diff --git a/lib/loader.cordova.js b/lib/loader.cordova.js
deleted file mode 100644
index 7cdd2b7..0000000
--- a/lib/loader.cordova.js
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * CutJS
- * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
- * Available under the MIT license
- * @license
- */
-
-var Cut = require('./core');
-
-if (typeof DEBUG === 'undefined')
-  DEBUG = true;
-
-/**
- * Cordova/PhoneGap loader with FastContext support.
- */
-
-if (typeof FastContext === 'undefined') {
-  FastContext = window.FastContext;
-}
-
-window.addEventListener('load', function() {
-  DEBUG && console.log('On load.');
-  // var readyTimeout = setTimeout(function() {
-  // DEBUG && console.log('On deviceready timeout.');
-  // Cut.start();
-  // }, 2000);
-
-  document.addEventListener('deviceready', function() {
-    DEBUG && console.log('On deviceready.');
-    // clearTimeout(readyTimeout);
-    Cut.start({
-      'app-loader' : AppLoader,
-      'image-loader' : ImageLoader
-    });
-  }, false);
-
-  document.addEventListener('pause', function() {
-    Cut.pause();
-  }, false);
-
-  document.addEventListener('resume', function() {
-    Cut.resume();
-  }, false);
-}, false);
-
-function AppLoader(app, configs) {
-  configs = configs || {};
-  var canvas = configs.canvas, context = null, full = false;
-  var width = 0, height = 0, ratio = 1;
-
-  if (typeof canvas === 'string') {
-    canvas = document.getElementById(canvas);
-  }
-
-  if (!canvas) {
-    canvas = document.getElementById('cutjs');
-  }
-
-  if (!canvas) {
-    full = true;
-    DEBUG && console.log('Creating Canvas...');
-    canvas = document.createElement('canvas');
-    canvas.style.position = 'absolute';
-    var body = document.body;
-    body.insertBefore(canvas, body.firstChild);
-  }
-
-  context = canvas.getContext('2d', {
-    fastcontext : true
-  });
-
-  context.isFast = !!context.isFast;
-
-  full = full || context.isFast;
-
-  DEBUG && console.log('FastContext: ' + context.isFast);
-
-  var devicePixelRatio = window.devicePixelRatio || 1;
-  var backingStoreRatio = context.webkitBackingStorePixelRatio
-      || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio
-      || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
-  ratio = devicePixelRatio / backingStoreRatio;
-
-  var requestAnimationFrame = window.requestAnimationFrame
-      || window.msRequestAnimationFrame || window.mozRequestAnimationFrame
-      || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame
-      || function(callback) {
-        return window.setTimeout(callback, 1000 / 60);
-      };
-
-  DEBUG && console.log('Creating root...');
-  var root = Cut.root(requestAnimationFrame, render);
-
-  function render() {
-    if (context.isFast) {
-      context.clear();
-      context.setTransform(1, 0, 0, 1, 0, 0);
-    } else {
-      context.setTransform(1, 0, 0, 1, 0, 0);
-      context.clearRect(0, 0, width, height);
-    }
-    root.render(context);
-  }
-
-  root.background = function(color) {
-    if (context.isFast) {
-      context.setBackgroundColor && context.setBackgroundColor(color);
-    } else {
-      canvas.style.backgroundColor = color;
-    }
-    return this;
-  };
-
-  app(root, canvas);
-
-  resize();
-  window.addEventListener('resize', resize, false);
-  window.addEventListener('orientationchange', resize, false);
-
-  function resize() {
-
-    if (full) {
-      // screen.availWidth/Height?
-      width = (window.innerWidth > 0 ? window.innerWidth : screen.width);
-      height = (window.innerHeight > 0 ? window.innerHeight : screen.height);
-
-      canvas.style.width = width + 'px';
-      canvas.style.height = height + 'px';
-
-    } else {
-      width = canvas.clientWidth;
-      height = canvas.clientHeight;
-    }
-
-    width *= ratio;
-    height *= ratio;
-
-    if (canvas.width === width && canvas.height === height) {
-      return;
-    }
-
-    canvas.width = width;
-    canvas.height = height;
-
-    DEBUG && console.log('Resize: ' + width + ' x ' + height + ' / ' + ratio);
-
-    root.viewport(width, height, ratio);
-
-    render();
-  }
-}
-
-function ImageLoader(src, success, error) {
-  DEBUG && console.log('Loading image: ' + src);
-  var image;
-  if (FastContext) {
-    image = FastContext.createImage(src, loaded, error);
-  } else {
-    image = new Image();
-    image.onload = loaded;
-    image.onerror = error;
-    image.src = src;
-  }
-  function loaded() {
-    success(image);
-  }
-}
diff --git a/lib/loader.web.js b/lib/loader.web.js
deleted file mode 100644
index e84da5b..0000000
--- a/lib/loader.web.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * CutJS
- * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
- * Available under the MIT license
- * @license
- */
-
-var Cut = require('./core');
-
-if (typeof DEBUG === 'undefined')
-  DEBUG = true;
-
-/**
- * Default loader for web.
- */
-
-window.addEventListener('load', function() {
-  DEBUG && console.log('On load.');
-  Cut.start({
-    'app-loader' : AppLoader,
-    'image-loader' : ImageLoader,
-  });
-}, false);
-
-function AppLoader(app, configs) {
-  configs = configs || {};
-  var canvas = configs.canvas, context = null, full = false;
-  var width = 0, height = 0, ratio = 1;
-
-  if (typeof canvas === 'string') {
-    canvas = document.getElementById(canvas);
-  }
-
-  if (!canvas) {
-    canvas = document.getElementById('cutjs');
-  }
-
-  if (!canvas) {
-    full = true;
-    DEBUG && console.log('Creating Canvas...');
-    canvas = document.createElement('canvas');
-    canvas.style.position = 'absolute';
-    var body = document.body;
-    body.insertBefore(canvas, body.firstChild);
-  }
-
-  context = canvas.getContext('2d');
-
-  var devicePixelRatio = window.devicePixelRatio || 1;
-  var backingStoreRatio = context.webkitBackingStorePixelRatio
-      || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio
-      || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
-  ratio = devicePixelRatio / backingStoreRatio;
-
-  var requestAnimationFrame = window.requestAnimationFrame
-      || window.msRequestAnimationFrame || window.mozRequestAnimationFrame
-      || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame
-      || function(callback) {
-        return window.setTimeout(callback, 1000 / 60);
-      };
-
-  DEBUG && console.log('Creating root...');
-  var root = Cut.root(requestAnimationFrame, render);
-
-  function render() {
-    context.setTransform(1, 0, 0, 1, 0, 0);
-    context.clearRect(0, 0, width, height);
-    root.render(context);
-  }
-
-  root.background = function(color) {
-    canvas.style.backgroundColor = color;
-    return this;
-  };
-
-  app(root, canvas);
-
-  resize();
-  window.addEventListener('resize', resize, false);
-  window.addEventListener('orientationchange', resize, false);
-
-  function resize() {
-
-    if (full) {
-      // screen.availWidth/Height?
-      width = (window.innerWidth > 0 ? window.innerWidth : screen.width);
-      height = (window.innerHeight > 0 ? window.innerHeight : screen.height);
-
-      canvas.style.width = width + 'px';
-      canvas.style.height = height + 'px';
-
-    } else {
-      width = canvas.clientWidth;
-      height = canvas.clientHeight;
-    }
-
-    width *= ratio;
-    height *= ratio;
-
-    if (canvas.width === width && canvas.height === height) {
-      return;
-    }
-
-    canvas.width = width;
-    canvas.height = height;
-
-    DEBUG && console.log('Resize: ' + width + ' x ' + height + ' / ' + ratio);
-
-    root.viewport(width, height, ratio);
-
-    render();
-  }
-}
-
-function ImageLoader(src, success, error) {
-  DEBUG && console.log('Loading image: ' + src);
-  var image = new Image();
-  image.onload = function() {
-    success(image);
-  };
-  image.onerror = error;
-  image.src = src;
-}
diff --git a/lib/loader/cordova.js b/lib/loader/cordova.js
new file mode 100644
index 0000000..5454274
--- /dev/null
+++ b/lib/loader/cordova.js
@@ -0,0 +1,167 @@
+/*
+ * CutJS
+ * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
+ * Available under the MIT license
+ * @license
+ */
+
+var Cut = require('../core');
+
+if (typeof DEBUG === 'undefined')
+  DEBUG = true;
+
+/**
+ * Cordova/PhoneGap loader with FastContext support.
+ */
+
+if (typeof FastContext === 'undefined') {
+  FastContext = window.FastContext;
+}
+
+window.addEventListener('load', function() {
+  DEBUG && console.log('On load.');
+  // var readyTimeout = setTimeout(function() {
+  // DEBUG && console.log('On deviceready timeout.');
+  // Cut.start();
+  // }, 2000);
+
+  document.addEventListener('deviceready', function() {
+    DEBUG && console.log('On deviceready.');
+    // clearTimeout(readyTimeout);
+    Cut.start({
+      'app-loader' : AppLoader,
+      'image-loader' : ImageLoader
+    });
+  }, false);
+
+  document.addEventListener('pause', function() {
+    Cut.pause();
+  }, false);
+
+  document.addEventListener('resume', function() {
+    Cut.resume();
+  }, false);
+}, false);
+
+function AppLoader(app, configs) {
+  configs = configs || {};
+  var canvas = configs.canvas, context = null, full = false;
+  var width = 0, height = 0, ratio = 1;
+
+  if (typeof canvas === 'string') {
+    canvas = document.getElementById(canvas);
+  }
+
+  if (!canvas) {
+    canvas = document.getElementById('cutjs');
+  }
+
+  if (!canvas) {
+    full = true;
+    DEBUG && console.log('Creating Canvas...');
+    canvas = document.createElement('canvas');
+    canvas.style.position = 'absolute';
+    var body = document.body;
+    body.insertBefore(canvas, body.firstChild);
+  }
+
+  context = canvas.getContext('2d', {
+    fastcontext : true
+  });
+
+  context.isFast = !!context.isFast;
+
+  full = full || context.isFast;
+
+  DEBUG && console.log('FastContext: ' + context.isFast);
+
+  var devicePixelRatio = window.devicePixelRatio || 1;
+  var backingStoreRatio = context.webkitBackingStorePixelRatio
+      || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio
+      || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
+  ratio = devicePixelRatio / backingStoreRatio;
+
+  var requestAnimationFrame = window.requestAnimationFrame
+      || window.msRequestAnimationFrame || window.mozRequestAnimationFrame
+      || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame
+      || function(callback) {
+        return window.setTimeout(callback, 1000 / 60);
+      };
+
+  DEBUG && console.log('Creating root...');
+  var root = Cut.root(requestAnimationFrame, render);
+
+  function render() {
+    if (context.isFast) {
+      context.clear();
+      context.setTransform(1, 0, 0, 1, 0, 0);
+    } else {
+      context.setTransform(1, 0, 0, 1, 0, 0);
+      context.clearRect(0, 0, width, height);
+    }
+    root.render(context);
+  }
+
+  root.background = function(color) {
+    if (context.isFast) {
+      context.setBackgroundColor && context.setBackgroundColor(color);
+    } else {
+      canvas.style.backgroundColor = color;
+    }
+    return this;
+  };
+
+  app(root, canvas);
+
+  resize();
+  window.addEventListener('resize', resize, false);
+  window.addEventListener('orientationchange', resize, false);
+
+  function resize() {
+
+    if (full) {
+      // screen.availWidth/Height?
+      width = (window.innerWidth > 0 ? window.innerWidth : screen.width);
+      height = (window.innerHeight > 0 ? window.innerHeight : screen.height);
+
+      canvas.style.width = width + 'px';
+      canvas.style.height = height + 'px';
+
+    } else {
+      width = canvas.clientWidth;
+      height = canvas.clientHeight;
+    }
+
+    width *= ratio;
+    height *= ratio;
+
+    if (canvas.width === width && canvas.height === height) {
+      return;
+    }
+
+    canvas.width = width;
+    canvas.height = height;
+
+    DEBUG && console.log('Resize: ' + width + ' x ' + height + ' / ' + ratio);
+
+    root.viewport(width, height, ratio);
+
+    render();
+  }
+}
+
+function ImageLoader(src, success, error) {
+  DEBUG && console.log('Loading image: ' + src);
+  var image;
+  if (FastContext) {
+    image = FastContext.createImage(src, loaded, error);
+  } else {
+    image = new Image();
+    image.onload = loaded;
+    image.onerror = error;
+    image.src = src;
+  }
+  function loaded() {
+    success(image);
+  }
+}
diff --git a/lib/loader/web.js b/lib/loader/web.js
new file mode 100644
index 0000000..1867efa
--- /dev/null
+++ b/lib/loader/web.js
@@ -0,0 +1,123 @@
+/*
+ * CutJS
+ * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
+ * Available under the MIT license
+ * @license
+ */
+
+var Cut = require('../core');
+
+if (typeof DEBUG === 'undefined')
+  DEBUG = true;
+
+/**
+ * Default loader for web.
+ */
+
+window.addEventListener('load', function() {
+  DEBUG && console.log('On load.');
+  Cut.start({
+    'app-loader' : AppLoader,
+    'image-loader' : ImageLoader,
+  });
+}, false);
+
+function AppLoader(app, configs) {
+  configs = configs || {};
+  var canvas = configs.canvas, context = null, full = false;
+  var width = 0, height = 0, ratio = 1;
+
+  if (typeof canvas === 'string') {
+    canvas = document.getElementById(canvas);
+  }
+
+  if (!canvas) {
+    canvas = document.getElementById('cutjs');
+  }
+
+  if (!canvas) {
+    full = true;
+    DEBUG && console.log('Creating Canvas...');
+    canvas = document.createElement('canvas');
+    canvas.style.position = 'absolute';
+    var body = document.body;
+    body.insertBefore(canvas, body.firstChild);
+  }
+
+  context = canvas.getContext('2d');
+
+  var devicePixelRatio = window.devicePixelRatio || 1;
+  var backingStoreRatio = context.webkitBackingStorePixelRatio
+      || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio
+      || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
+  ratio = devicePixelRatio / backingStoreRatio;
+
+  var requestAnimationFrame = window.requestAnimationFrame
+      || window.msRequestAnimationFrame || window.mozRequestAnimationFrame
+      || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame
+      || function(callback) {
+        return window.setTimeout(callback, 1000 / 60);
+      };
+
+  DEBUG && console.log('Creating root...');
+  var root = Cut.root(requestAnimationFrame, render);
+
+  function render() {
+    context.setTransform(1, 0, 0, 1, 0, 0);
+    context.clearRect(0, 0, width, height);
+    root.render(context);
+  }
+
+  root.background = function(color) {
+    canvas.style.backgroundColor = color;
+    return this;
+  };
+
+  app(root, canvas);
+
+  resize();
+  window.addEventListener('resize', resize, false);
+  window.addEventListener('orientationchange', resize, false);
+
+  function resize() {
+
+    if (full) {
+      // screen.availWidth/Height?
+      width = (window.innerWidth > 0 ? window.innerWidth : screen.width);
+      height = (window.innerHeight > 0 ? window.innerHeight : screen.height);
+
+      canvas.style.width = width + 'px';
+      canvas.style.height = height + 'px';
+
+    } else {
+      width = canvas.clientWidth;
+      height = canvas.clientHeight;
+    }
+
+    width *= ratio;
+    height *= ratio;
+
+    if (canvas.width === width && canvas.height === height) {
+      return;
+    }
+
+    canvas.width = width;
+    canvas.height = height;
+
+    DEBUG && console.log('Resize: ' + width + ' x ' + height + ' / ' + ratio);
+
+    root.viewport(width, height, ratio);
+
+    render();
+  }
+}
+
+function ImageLoader(src, success, error) {
+  DEBUG && console.log('Loading image: ' + src);
+  var image = new Image();
+  image.onload = function() {
+    success(image);
+  };
+  image.onerror = error;
+  image.src = src;
+}
diff --git a/lib/mouse.js b/lib/mouse.js
deleted file mode 100644
index 96eee53..0000000
--- a/lib/mouse.js
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * CutJS
- * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
- * Available under the MIT license
- * @license
- */
-
-if (typeof DEBUG === 'undefined')
-  DEBUG = true;
-
-function Mouse() {
-  Mouse.subscribe.apply(Mouse, arguments);
-};
-
-Mouse.CLICK = 'click';
-Mouse.START = 'touchstart mousedown';
-Mouse.MOVE = 'touchmove mousemove';
-Mouse.END = 'touchend mouseup';
-Mouse.CANCEL = 'touchcancel';
-
-Mouse.subscribe = function(root, elem) {
-  var visitor = null, data = {}, abs = null, rel = null, clicked = [];
-
-  elem = elem || document;
-
-  // click events are synthesized from start/end events on same nodes
-  // elem.addEventListener('click', handleClick);
-
-  elem.addEventListener('touchstart', handleStart);
-  elem.addEventListener('touchend', handleEnd);
-  elem.addEventListener('touchmove', handleMove);
-  elem.addEventListener('touchcancel', handleCancel);
-
-  elem.addEventListener('mousedown', handleStart);
-  elem.addEventListener('mouseup', handleEnd);
-  elem.addEventListener('mousemove', handleMove);
-
-  function handleStart(event) {
-    Mouse._xy(root, elem, event, abs);
-    DEBUG && console.log('Mouse Start: ' + event.type + ' ' + abs);
-    event.preventDefault();
-    publish(event.type, event);
-
-    findClicks();
-  }
-
-  function handleEnd(event) {
-    // New xy is not valid/available, last xy is used instead.
-    DEBUG && console.log('Mouse End: ' + event.type + ' ' + abs);
-    event.preventDefault();
-    publish(event.type, event);
-
-    if (clicked.length) {
-      DEBUG && console.log('Mouse Click: ' + clicked.length);
-      fireClicks(event);
-    }
-  }
-
-  function handleCancel(event) {
-    DEBUG && console.log('Mouse Cancel: ' + event.type);
-    event.preventDefault();
-    publish(event.type, event);
-  }
-
-  function handleMove(event) {
-    Mouse._xy(root, elem, event, abs);
-    // DEBUG && console.log('Mouse Move: ' + event.type + ' ' +
-    // abs);
-    if (!root._flag(event.type)) {
-      return;
-    }
-    event.preventDefault();
-    publish(event.type, event);
-  }
-
-  function findClicks() {
-    while (clicked.length) {
-      clicked.pop();
-    }
-    publish('click', null, clicked);
-  }
-
-  function fireClicks(event) {
-    data.event = event;
-    data.type = 'click';
-    data.root = root;
-    data.collect = false;
-
-    var cancel = false;
-    while (clicked.length) {
-      var node = clicked.shift();
-      if (cancel) {
-        continue;
-      }
-      cancel = visitor.end(node, data) ? true : cancel;
-    }
-  }
-
-  function publish(type, event, collect) {
-    rel.x = abs.x;
-    rel.y = abs.y;
-
-    data.event = event;
-    data.type = type;
-    data.root = /* root._capture || */root;
-    data.collect = collect;
-
-    data.root.visit(visitor, data);
-  }
-
-  visitor = {
-    reverse : true,
-    visible : true,
-    start : function(node, data) {
-      return !node._flag(data.type);
-    },
-    end : function(node, data) {
-      // data: event, type, root, collect
-      rel.raw = data.event;
-      rel.type = data.type;
-      var listeners = node.listeners(data.type);
-      if (!listeners) {
-        return;
-      }
-      node.matrix().reverse().map(abs, rel);
-      if (!(node === data.root || node.attr('spy') || Mouse._isInside(node, rel))) {
-        return;
-      }
-      if (data.collect) {
-        data.collect.push(node);
-        return;
-      }
-      var cancel = false;
-      for (var l = 0; l < listeners.length; l++) {
-        cancel = listeners[l].call(node, rel) ? true : cancel;
-      }
-      return cancel;
-    }
-  };
-
-  abs = {
-    x : 0,
-    y : 0,
-    toString : function() {
-      return (this.x | 0) + 'x' + (this.y | 0);
-    }
-  };
-
-  rel = {
-    x : 0,
-    y : 0,
-    toString : function() {
-      return abs + ' / ' + (this.x | 0) + 'x' + (this.y | 0);
-    }
-  };
-
-};
-
-Mouse._isInside = function(node, point) {
-  return point.x >= 0 && point.x <= node._pin._width && point.y >= 0
-      && point.y <= node._pin._height;
-};
-
-Mouse._xy = function(root, elem, event, point) {
-
-  var isTouch = false;
-
-  // touch screen events
-  if (event.touches) {
-    if (event.touches.length) {
-      isTouch = true;
-      point.x = event.touches[0].pageX;
-      point.y = event.touches[0].pageY;
-    } else {
-      return;
-    }
-  } else {
-    // mouse events
-    point.x = event.clientX;
-    point.y = event.clientY;
-    // See http://goo.gl/JuVnF2
-    if (document.body.scrollLeft || document.body.scrollTop) {
-      // body is added as offsetParent
-    } else if (document.documentElement) {
-      point.x += document.documentElement.scrollLeft;
-      point.y += document.documentElement.scrollTop;
-    }
-  }
-
-  // accounts for border
-  point.x -= elem.clientLeft || 0;
-  point.y -= elem.clientTop || 0;
-
-  var par = elem;
-  while (par) {
-    point.x -= par.offsetLeft || 0;
-    point.y -= par.offsetTop || 0;
-    if (!isTouch) {
-      // touch events offset scrolling with pageX/Y
-      // so scroll offset not needed for them
-      point.x += par.scrollLeft || 0;
-      point.y += par.scrollTop || 0;
-    }
-
-    par = par.offsetParent;
-  }
-
-  point.x *= root.viewport().ratio || 1;
-  point.y *= root.viewport().ratio || 1;
-};
-
-module.exports = Mouse;
diff --git a/lib/render.js b/lib/render.js
new file mode 100644
index 0000000..a104a89
--- /dev/null
+++ b/lib/render.js
@@ -0,0 +1,123 @@
+/*
+ * CutJS
+ * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
+ * Available under the MIT license
+ * @license
+ */
+
+var Cut = require('./core');
+require('./pin');
+
+var stats = require('./util/stats');
+var create = require('./util/create');
+
+Cut.prototype._textures = null;
+Cut.prototype._tickBefore = null;
+Cut.prototype._tickAfter = null;
+Cut.prototype._alpha = 1;
+
+Cut.prototype.render = function(context) {
+  if (!this._visible) {
+    return;
+  }
+  stats.node++;
+
+  var m = this.matrix();
+  context.setTransform(m.a, m.b, m.c, m.d, m.e, m.f);
+
+  // move this elsewhere!
+  this._alpha = this._pin._alpha * (this._parent ? this._parent._alpha : 1);
+  var alpha = this._pin._textureAlpha * this._alpha;
+
+  if (context.globalAlpha != alpha) {
+    context.globalAlpha = alpha;
+  }
+
+  if (this._textures !== null) {
+    for (var i = 0, n = this._textures.length; i < n; i++) {
+      this._textures[i].draw(context);
+    }
+  }
+
+  if (context.globalAlpha != this._alpha) {
+    context.globalAlpha = this._alpha;
+  }
+
+  var child, next = this._first;
+  while (child = next) {
+    next = child._next;
+    child.render(context);
+  }
+};
+
+Cut.prototype.MAX_ELAPSE = Infinity;
+
+Cut.prototype._tick = function(elapsed, now, last) {
+  if (!this._visible) {
+    return;
+  }
+
+  if (elapsed > this.MAX_ELAPSE) {
+    elapsed = this.MAX_ELAPSE;
+  }
+
+  var ticked = false;
+
+  if (this._tickBefore !== null) {
+    for (var i = 0, n = this._tickBefore.length; i < n; i++) {
+      stats.tick++;
+      ticked = this._tickBefore[i].call(this, elapsed, now, last) === true
+          || ticked;
+    }
+  }
+
+  var child, next = this._first;
+  while (child = next) {
+    next = child._next;
+    if (child._flag('_tick')) {
+      ticked = child._tick(elapsed, now, last) === true ? true : ticked;
+    }
+  }
+
+  if (this._tickAfter !== null) {
+    for (var i = 0, n = this._tickAfter.length; i < n; i++) {
+      stats.tick++;
+      ticked = this._tickAfter[i].call(this, elapsed, now, last) === true
+          || ticked;
+    }
+  }
+
+  return ticked;
+};
+
+Cut.prototype.tick = function(ticker, before) {
+  if (typeof ticker !== 'function') {
+    return;
+  }
+  if (before) {
+    if (this._tickBefore === null) {
+      this._tickBefore = [];
+    }
+    this._tickBefore.push(ticker);
+  } else {
+    if (this._tickAfter === null) {
+      this._tickAfter = [];
+    }
+    this._tickAfter.push(ticker);
+  }
+  this._flag('_tick', this._tickAfter !== null && this._tickAfter.length > 0
+      || this._tickBefore !== null && this._tickBefore.length > 0);
+};
+
+Cut.prototype.untick = function(ticker) {
+  if (typeof ticker !== 'function') {
+    return;
+  }
+  var i;
+  if (this._tickBefore !== null && (i = this._tickBefore.indexOf(ticker)) >= 0) {
+    this._tickBefore.splice(i, 1);
+  }
+  if (this._tickAfter !== null && (i = this._tickAfter.indexOf(ticker)) >= 0) {
+    this._tickAfter.splice(i, 1);
+  }
+};
diff --git a/lib/root.js b/lib/root.js
new file mode 100644
index 0000000..953942c
--- /dev/null
+++ b/lib/root.js
@@ -0,0 +1,136 @@
+/*
+ * CutJS
+ * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
+ * Available under the MIT license
+ * @license
+ */
+
+var Cut = require('./core');
+require('./pin');
+require('./render');
+
+var stats = require('./util/stats');
+var create = require('./util/create');
+var extend = require('./util/extend');
+
+Root._super = Cut;
+Root.prototype = create(Root._super.prototype);
+
+Cut.root = function(request, render) {
+  return new Root(request, render);
+};
+
+function Root(request, render) {
+  Root._super.call(this);
+  this.label('Root');
+
+  this._paused = true;
+
+  var self = this;
+  var lastTime = 0;
+  var loop = function(now) {
+    if (self._paused === true) {
+      return;
+    }
+
+    stats.tick = stats.node = stats.draw = 0;
+
+    var last = lastTime || now;
+    var elapsed = now - last;
+    lastTime = now;
+
+    var ticked = self._tick(elapsed, now, last);
+    if (self._mo_touch != self._ts_touch) {
+      self._mo_touch = self._ts_touch;
+      render.call(self);
+      self.request();
+    } else if (ticked) {
+      self.request();
+    } else {
+      self.pause();
+    }
+
+    stats.fps = elapsed ? 1000 / elapsed : 0;
+  };
+
+  this.request = function() {
+    request(loop);
+  };
+};
+
+Root.prototype.start = function() {
+  return this.resume();
+};
+
+Root.prototype.resume = function(force) {
+  if (this._paused || force) {
+    this._paused = false;
+    this.request();
+  }
+  return this;
+};
+
+Root.prototype.pause = function() {
+  this._paused = true;
+  return this;
+};
+
+Root.prototype.touch = function() {
+  this.resume();
+  return Root._super.prototype.touch.call(this);
+};
+
+Root.prototype.background = function(color) {
+  // to be implemented by loaders
+  return this;
+};
+
+Root.prototype.viewport = function(width, height, ratio) {
+  if (typeof width === 'undefined') {
+    return extend({}, this._viewport);
+  }
+  this._viewport = {
+    width : width,
+    height : height,
+    ratio : ratio || 1
+  };
+  this._updateViewbox();
+  var data = extend({}, this._viewport);
+  this.visit({
+    start : function(node) {
+      if (!node._flag('viewport')) {
+        return true;
+      }
+      node.publish('viewport', [ data ]);
+    }
+  });
+  return this;
+};
+
+// TODO: static/fixed viewbox
+Root.prototype.viewbox = function(width, height, mode) {
+  this._viewbox = {
+    width : width,
+    height : height,
+    mode : /^(in|out|in-pad|out-crop)$/.test(mode) ? mode : 'in-pad'
+  };
+  this._updateViewbox();
+  return this;
+};
+
+Root.prototype._updateViewbox = function() {
+  var box = this._viewbox;
+  var size = this._viewport;
+  if (size && box) {
+    this.pin({
+      width : box.width,
+      height : box.height
+    });
+    this._pin._scaleTo(size.width, size.height, box.mode);
+  } else if (size) {
+    this.pin({
+      width : size.width,
+      height : size.height
+    });
+  }
+};
diff --git a/lib/str.js b/lib/str.js
new file mode 100644
index 0000000..c697520
--- /dev/null
+++ b/lib/str.js
@@ -0,0 +1,88 @@
+/*
+ * CutJS
+ * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
+ * Available under the MIT license
+ * @license
+ */
+
+var Cut = require('./core');
+require('./pin');
+require('./render');
+
+var create = require('./util/create');
+var is = require('./util/is');
+
+Cut.string = function(frames) {
+  return new Str().frames(frames);
+};
+
+Str._super = Cut;
+Str.prototype = create(Str._super.prototype);
+
+function Str() {
+  Str._super.call(this);
+  this.label('String');
+  this._textures = [];
+};
+
+/**
+ * @deprecated Use frames
+ */
+Str.prototype.setFont = function(a, b, c) {
+  return this.frames(a, b, c);
+};
+
+Str.prototype.frames = function(frames) {
+  this._textures = [];
+  if (typeof frames == 'string') {
+    frames = Cut.texture(frames);
+    this._item = function(value) {
+      return frames.one(value);
+    };
+  } else if (typeof frames === 'object') {
+    this._item = function(value) {
+      return frames[value];
+    };
+  } else if (typeof frames === 'function') {
+    this._item = frames;
+  }
+  return this;
+};
+
+/**
+ * @deprecated Use value
+ */
+Str.prototype.setValue = function(a, b, c) {
+  return this.value(a, b, c);
+};
+
+Str.prototype.value = function(value) {
+  if (typeof value === 'undefined') {
+    return this._value;
+  }
+  if (this._value === value) {
+    return this;
+  }
+  this._value = value;
+
+  if (value === null) {
+    value = '';
+  } else if (typeof value !== 'string' && !is.array(value)) {
+    value = value.toString();
+  }
+
+  this._spacing = this._spacing || 0;
+
+  var width = 0, height = 0;
+  for (var i = 0; i < value.length; i++) {
+    var image = this._textures[i] = this._item(value[i]);
+    width += i > 0 ? this._spacing : 0;
+    image.dest(width, 0);
+    width = width + image.width;
+    height = Math.max(height, image.height);
+  }
+  this.pin('width', width);
+  this.pin('height', height);
+  this._textures.length = value.length;
+  return this;
+};
diff --git a/lib/tween.js b/lib/tween.js
deleted file mode 100644
index af93088..0000000
--- a/lib/tween.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * CutJS
- * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
- * Available under the MIT license
- * @license
- */
-
-var Easing = require('./easing');
-var Cut = require('./core');
-var Pin = require('./pin');
-
-Cut.prototype.tween = function(duration, delay) {
-  if (!this._tween) {
-    this._tween = new Tween(this);
-  }
-  return this._tween.tween(duration, delay);
-};
-
-var iid = 0;
-
-function Tween(node) {
-  // TODO: reuse head.start/keys/end
-
-  var tween = this;
-  this._owner = node;
-  this._queue = [];
-  this._next = null;
-
-  var lastTime = 0;
-  node.tick(function(elapsed, now, last) {
-    if (!tween._queue.length) {
-      return;
-    }
-
-    // ignore old elapsed
-    var ignore = lastTime != last;
-    lastTime = now;
-    this.touch();
-    if (ignore) {
-      return;
-    }
-
-    var head = tween._queue[0];
-
-    if (!head.time) {
-      head.time = 1;
-    } else {
-      head.time += elapsed;
-    }
-
-    if (head.time < head.delay) {
-      return;
-    }
-
-    if (!head.start) {
-      head.start = {};
-      head.keys = {};
-      for ( var key in head.end) {
-        if (typeof (start = node.pin(key)) === 'number') {
-          head.start[key] = start;
-          head.keys[key] = key;
-        } else if (typeof (startX = node.pin(key + 'X')) === 'number'
-            && typeof (startY = node.pin(key + 'Y')) === 'number') {
-          head.start[key + 'X'] = startX;
-          head.keys[key + 'X'] = key;
-          head.start[key + 'Y'] = startY;
-          head.keys[key + 'Y'] = key;
-        }
-      }
-    }
-
-    var p = (head.time - head.delay) / head.duration;
-    var over = p >= 1;
-    p = p > 1 ? 1 : p;
-    p = typeof head.easing == 'function' ? head.easing(p) : p;
-    var q = 1 - p;
-
-    for ( var key in head.keys) {
-      node.pin(key, head.start[key] * q + head.end[head.keys[key]] * p);
-    }
-
-    if (over) {
-      tween._queue.shift();
-      head.then && head.then.call(node);
-    }
-
-  }, true);
-};
-
-Tween.prototype.tween = function(duration, delay) {
-  this._next = {
-    id : ++iid,
-    end : {},
-    duration : duration || 400,
-    delay : delay || 0
-  };
-  return this;
-};
-
-Tween.prototype.pin = function(a, b) {
-  if (this._next !== this._queue[this._queue.length - 1]) {
-    this._owner.touch();
-    this._queue.push(this._next);
-  }
-
-  var end = this._next.end;
-  if (typeof a === 'object') {
-    for ( var attr in a) {
-      end[attr] = a[attr];
-    }
-  } else if (typeof b !== 'undefined') {
-    end[a] = b;
-  }
-  return this;
-};
-
-Tween.prototype.clear = function(forward) {
-  var tween;
-  while (tween = this._queue.shift()) {
-    forward && this._owner.pin(tween.end);
-  }
-  return this;
-};
-
-Tween.prototype.then = function(then) {
-  this._next.then = then;
-  return this;
-};
-
-Tween.prototype.ease = function(easing) {
-  this._next.easing = Easing(easing);
-  return this;
-};
-
-module.exports = Tween;
diff --git a/lib/ui.js b/lib/ui.js
deleted file mode 100644
index 8531df0..0000000
--- a/lib/ui.js
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * CutJS
- * Copyright (c) 2015 Ali Shakiba, Piqnt LLC
- * Available under the MIT license
- * @license
- */
-
-var Cut = require('./core');
-var Pin = require('./pin');
-
-var stats = require('./util/stats');
-var repeat = require('./util/repeat');
-var create = require('./util/create');
-var extend = require('./util/extend');
-var math = require('./util/math');
-var is = require('./util/is');
-
-Cut.prototype._textures = null;
-Cut.prototype._tickBefore = null;
-Cut.prototype._tickAfter = null;
-Cut.prototype._alpha = 1;
-
-Cut.prototype.render = function(context) {
-  if (!this._visible) {
-    return;
-  }
-  stats.node++;
-
-  var m = this.matrix();
-  context.setTransform(m.a, m.b, m.c, m.d, m.e, m.f);
-
-  // move this elsewhere!
-  this._alpha = this._pin._alpha * (this._parent ? this._parent._alpha : 1);
-  var alpha = this._pin._textureAlpha * this._alpha;
-
-  if (context.globalAlpha != alpha) {
-    context.globalAlpha = alpha;
-  }
-
-  if (this._textures !== null) {
-    for (var i = 0, n = this._textures.length; i < n; i++) {
-      this._textures[i].draw(context);
-    }
-  }
-
-  if (context.globalAlpha != this._alpha) {
-    context.globalAlpha = this._alpha;
-  }
-
-  var child, next = this._first;
-  while (child = next) {
-    next = child._next;
-    child.render(context);
-  }
-};
-
-Cut.prototype.MAX_ELAPSE = Infinity;
-
-Cut.prototype._tick = function(elapsed, now, last) {
-  if (!this._visible) {
-    return;
-  }
-
-  if (elapsed > this.MAX_ELAPSE) {
-    elapsed = this.MAX_ELAPSE;
-  }
-
-  var ticked = false;
-
-  if (this._tickBefore !== null) {
-    for (var i = 0, n = this._tickBefore.length; i < n; i++) {
-      stats.tick++;
-      ticked = this._tickBefore[i].call(this, elapsed, now, last) === true
-          || ticked;
-    }
-  }
-
-  var child, next = this._first;
-  while (child = next) {
-    next = child._next;
-    if (child._flag('_tick')) {
-      ticked = child._tick(elapsed, now, last) === true ? true : ticked;
-    }
-  }
-
-  if (this._tickAfter !== null) {
-    for (var i = 0, n = this._tickAfter.length; i < n; i++) {
-      stats.tick++;
-      ticked = this._tickAfter[i].call(this, elapsed, now, last) === true
-          || ticked;
-    }
-  }
-
-  return ticked;
-};
-
-Cut.prototype.tick = function(ticker, before) {
-  if (typeof ticker !== 'function') {
-    return;
-  }
-  if (before) {
-    if (this._tickBefore === null) {
-      this._tickBefore = [];
-    }
-    this._tickBefore.push(ticker);
-  } else {
-    if (this._tickAfter === null) {
-      this._tickAfter = [];
-    }
-    this._tickAfter.push(ticker);
-  }
-  this._flag('_tick', this._tickAfter !== null && this._tickAfter.length > 0
-      || this._tickBefore !== null && this._tickBefore.length > 0);
-};
-
-Cut.prototype.untick = function(ticker) {
-  if (typeof ticker !== 'function') {
-    return;
-  }
-  var i;
-  if (this._tickBefore !== null && (i = this._tickBefore.indexOf(ticker)) >= 0) {
-    this._tickBefore.splice(i, 1);
-  }
-  if (this._tickAfter !== null && (i = this._tickAfter.indexOf(ticker)) >= 0) {
-    this._tickAfter.splice(i, 1);
-  }
-};
-
-Root._super = Cut;
-Root.prototype = create(Root._super.prototype);
-
-Cut.root = function(request, render) {
-  return new Root(request, render);
-};
-
-function Root(request, render) {
-  Root._super.call(this);
-  this.label('Root');
-
-  this._paused = true;
-
-  var self = this;
-  var lastTime = 0;
-  var loop = function(now) {
-    if (self._paused === true) {
-      return;
-    }
-
-    stats.tick = stats.node = stats.draw = 0;
-
-    var last = lastTime || now;
-    var elapsed = now - last;
-    lastTime = now;
-
-    var ticked = self._tick(elapsed, now, last);
-    if (self._mo_touch != self._ts_touch) {
-      self._mo_touch = self._ts_touch;
-      render.call(self);
-      self.request();
-    } else if (ticked) {
-      self.request();
-    } else {
-      self.pause();
-    }
-
-    stats.fps = elapsed ? 1000 / elapsed : 0;
-  };
-
-  this.request = function() {
-    request(loop);
-  };
-};
-
-Root.prototype.start = function() {
-  return this.resume();
-};
-
-Root.prototype.resume = function(force) {
-  if (this._paused || force) {
-    this._paused = false;
-    this.request();
-  }
-  return this;
-};
-
-Root.prototype.pause = function() {
-  this._paused = true;
-  return this;
-};
-
-Root.prototype.touch = function() {
-  this.resume();
-  return Root._super.prototype.touch.call(this);
-};
-
-Root.prototype.background = function(color) {
-  // to be implemented by loaders
-  return this;
-};
-
-Root.prototype.viewport = function(width, height, ratio) {
-  if (typeof width === 'undefined') {
-    return extend({}, this._viewport);
-  }
-  this._viewport = {
-    width : width,
-    height : height,
-    ratio : ratio || 1
-  };
-  this._updateViewbox();
-  var data = extend({}, this._viewport);
-  this.visit({
-    start : function(node) {
-      if (!node._flag('viewport')) {
-        return true;
-      }
-      node.publish('viewport', [ data ]);
-    }
-  });
-  return this;
-};
-
-// TODO: static/fixed viewbox
-Root.prototype.viewbox = function(width, height, mode) {
-  this._viewbox = {
-    width : width,
-    height : height,
-    mode : /^(in|out|in-pad|out-crop)$/.test(mode) ? mode : 'in-pad'
-  };
-  this._updateViewbox();
-  return this;
-};
-
-Root.prototype._updateViewbox = function() {
-  var box = this._viewbox;
-  var size = this._viewport;
-  if (size && box) {
-    this.pin({
-      width : box.width,
-      height : box.height
-    });
-    this._pin._scaleTo(size.width, size.height, box.mode);
-  } else if (size) {
-    this.pin({
-      width : size.width,
-      height : size.height
-    });
-  }
-};
-
-Cut.image = function(image) {
-  var img = new Image();
-  image && img.image(image);
-  return img;
-};
-
-Image._super = Cut;
-Image.prototype = create(Image._super.prototype);
-
-function Image() {
-  Image._super.call(this);
-  this.label('Image');
-  this._textures = [];
-  this._image = null;
-};
-
-/**
- * @deprecated Use image
- */
-Image.prototype.setImage = function(a, b, c) {
-  return this.image(a, b, c);
-};
-
-Image.prototype.image = function(image) {
-  this._image = Cut.texture(image).one();
-  this.pin('width', this._image ? this._image.width : 0);
-  this.pin('height', this._image ? this._image.height : 0);
-  this._textures[0] = this._image.pipe();
-  this._textures.length = 1;
-  return this;
-};
-
-Image.prototype.tile = function(inner) {
-  this._repeat(false, inner);
-  return this;
-};
-
-Image.prototype.stretch = function(inner) {
-  this._repeat(true, inner);
-  return this;
-};
-
-Image.prototype._repeat = function(stretch, inner) {
-  var self = this;
-  this.untick(this._repeatTicker);
-  this.tick(this._repeatTicker = function() {
-    if (this._mo_stretch == this._pin._ts_transform) {
-      return;
-    }
-    this._mo_stretch = this._pin._ts_transform;
-    var width = this.pin('width');
-    var height = this.pin('height');
-    this._textures.length = repeat(this._image, width, height, stretch, inner,
-        insert);
-  });
-
-  function insert(i, sx, sy, sw, sh, dx, dy, dw, dh) {
-    var repeat = self._textures.length > i ? self._textures[i]
-        : self._textures[i] = self._image.pipe();
-    repeat.src(sx, sy, sw, sh);
-    repeat.dest(dx, dy, dw, dh);
-  }
-};
-
-Cut.anim = function(frames, fps) {
-  var anim = new Anim();
-  anim.frames(frames).gotoFrame(0);
-  fps && anim.fps(fps);
-  return anim;
-};
-
-Anim._super = Cut;
-Anim.prototype = create(Anim._super.prototype);
-
-Anim.FPS = 12;
-
-function Anim() {
-  Anim._super.call(this);
-  this.label('Anim');
-
-  this._textures = [];
-
-  this._fps = Anim.FPS;
-  this._ft = 1000 / this._fps;
-
-  this._time = -1;
-  this._repeat = 0;
-
-  this._index = 0;
-  this._frames = [];
-
-  var lastTime = 0;
-  this.tick(function(t, now, last) {
-    if (this._time < 0 || this._frames.length <= 1) {
-      return;
-    }
-
-    // ignore old elapsed
-    var ignore = lastTime != last;
-    lastTime = now;
-    if (ignore) {
-      return true;
-    }
-
-    this._time += t;
-    if (this._time < this._ft) {
-      return true;
-    }
-    var n = this._time / this._ft | 0;
-    this._time -= n * this._ft;
-    this.moveFrame(n);
-    if (this._repeat > 0 && (this._repeat -= n) <= 0) {
-      this.stop();
-      this._callback && this._callback();
-      return false;
-    }
-    return true;
-  }, false);
-};
-
-Anim.prototype.fps = function(fps) {
-  if (typeof fps === 'undefined') {
-    return this._fps;
-  }
-  this._fps = fps > 0 ? fps : Cut.Anim.FPS;
-  this._ft = 1000 / this._fps;
-  return this;
-};
-
-/**
- * @deprecated Use frames
- */
-Anim.prototype.setFrames = function(a, b, c) {
-  return this.frames(a, b, c);
-};
-
-Anim.prototype.frames = function(frames) {
-  this._index = 0;
-  this._frames = Cut.texture(frames).array();
-  this.touch();
-  return this;
-};
-
-Anim.prototype.length = function() {
-  return this._frames ? this._frames.length : 0;
-};
-
-Anim.prototype.gotoFrame = function(frame, resize) {
-  this._index = math.rotate(frame, this._frames.length) | 0;
-  resize = resize || !this._textures[0];
-  this._textures[0] = this._frames[this._index];
-  if (resize) {
-    this.pin('width', this._textures[0].width);
-    this.pin('height', this._textures[0].height);
-  }
-  this.touch();
-  return this;
-};
-
-Anim.prototype.moveFrame = function(move) {
-  return this.gotoFrame(this._index + move);
-};
-
-Anim.prototype.repeat = function(repeat, callback) {
-  this._repeat = repeat * this._frames.length - 1;
-  this._callback = callback;
-  this.play();
-  return this;
-};
-
-Anim.prototype.play = function(frame) {
-  if (typeof frame !== 'undefined') {
-    this.gotoFrame(frame);
-    this._time = 0;
-  } else if (this._time < 0) {
-    this._time = 0;
-  }
-
-  this.touch();
-  return this;
-};
-
-Anim.prototype.stop = function(frame) {
-  this._time = -1;
-  if (typeof frame !== 'undefined') {
-    this.gotoFrame(frame);
-  }
-  return this;
-};
-
-Cut.string = function(frames) {
-  return new Str().frames(frames);
-};
-
-Str._super = Cut;
-Str.prototype = create(Str._super.prototype);
-
-function Str() {
-  Str._super.call(this);
-  this.label('String');
-  this._textures = [];
-};
-
-/**
- * @deprecated Use frames
- */
-Str.prototype.setFont = function(a, b, c) {
-  return this.frames(a, b, c);
-};
-
-Str.prototype.frames = function(frames) {
-  this._textures = [];
-  if (typeof frames == 'string') {
-    frames = Cut.texture(frames);
-    this._item = function(value) {
-      return frames.one(value);
-    };
-  } else if (typeof frames === 'object') {
-    this._item = function(value) {
-      return frames[value];
-    };
-  } else if (typeof frames === 'function') {
-    this._item = frames;
-  }
-  return this;
-};
-
-/**
- * @deprecated Use value
- */
-Str.prototype.setValue = function(a, b, c) {
-  return this.value(a, b, c);
-};
-
-Str.prototype.value = function(value) {
-  if (typeof value === 'undefined') {
-    return this._value;
-  }
-  if (this._value === value) {
-    return this;
-  }
-  this._value = value;
-
-  if (value === null) {
-    value = '';
-  } else if (typeof value !== 'string' && !is.array(value)) {
-    value = value.toString();
-  }
-
-  this._spacing = this._spacing || 0;
-
-  var width = 0, height = 0;
-  for (var i = 0; i < value.length; i++) {
-    var image = this._textures[i] = this._item(value[i]);
-    width += i > 0 ? this._spacing : 0;
-    image.dest(width, 0);
-    width = width + image.width;
-    height = Math.max(height, image.height);
-  }
-  this.pin('width', width);
-  this.pin('height', height);
-  this._textures.length = value.length;
-  return this;
-};
-
-Cut.row = function(align) {
-  return Cut.create().row(align);
-};
-
-Cut.prototype.row = function(align) {
-  this.sequence('row', align);
-  return this;
-};
-
-Cut.column = function(align) {
-  return Cut.create().column(align);
-};
-
-Cut.prototype.column = function(align) {
-  this.sequence('column', align);
-  return this;
-};
-
-Cut.sequence = function(type, align) {
-  return Cut.create().sequence(type, align);
-};
-
-Cut.prototype.sequence = function(type, align) {
-
-  this._padding = this._padding || 0;
-  this._spacing = this._spacing || 0;
-
-  this.untick(this._sequenceTicker);
-  this.tick(this._sequenceTicker = function() {
-    if (this._mo_seq == this._ts_touch) {
-      return;
-    }
-    this._mo_seq = this._ts_touch;
-
-    var alignChildren = (this._mo_seqAlign != this._ts_children);
-    this._mo_seqAlign = this._ts_children;
-
-    var width = 0, height = 0;
-
-    var child, next = this.first(true);
-    var first = true;
-    while (child = next) {
-      next = child.next(true);
-
-      child._pin.relativeMatrix();
-      var w = child.pin('boxWidth');
-      var h = child.pin('boxHeight');
-
-      if (type == 'column') {
-        !first && (height += this._spacing);
-        child.pin('offsetY') != height && child.pin('offsetY', height);
-        width = Math.max(width, w);
-        height = height + h;
-        alignChildren && child.pin('alignX', align);
-
-      } else if (type == 'row') {
-        !first && (width += this._spacing);
-        child.pin('offsetX') != width && child.pin('offsetX', width);
-        width = width + w;
-        height = Math.max(height, h);
-        alignChildren && child.pin('alignY', align);
-      }
-      first = false;
-    }
-    width += 2 * this._padding;
-    height += 2 * this._padding;
-    this.pin('width') != width && this.pin('width', width);
-    this.pin('height') != height && this.pin('height', height);
-  });
-  return this;
-};
-
-Cut.box = function() {
-  return Cut.create().box();
-};
-
-Cut.prototype.box = function() {
-  if (this._boxTicker)
-    return this;
-
-  this._padding = this._padding || 0;
-
-  this.tick(this._boxTicker = function() {
-    if (this._mo_box == this._ts_touch) {
-      return;
-    }
-    this._mo_box = this._ts_touch;
-
-    var width = 0, height = 0;
-    var child, next = this.first(true);
-    while (child = next) {
-      next = child.next(true);
-      child._pin.relativeMatrix();
-      var w = child.pin('boxWidth');
-      var h = child.pin('boxHeight');
-      width = Math.max(width, w);
-      height = Math.max(height, h);
-    }
-    width += 2 * this._padding;
-    height += 2 * this._padding;
-    this.pin('width') != width && this.pin('width', width);
-    this.pin('height') != height && this.pin('height', height);
-  });
-  return this;
-};
-
-// TODO: move padding to pin
-Cut.prototype.padding = function(pad) {
-  this._padding = pad;
-  return this;
-};
-
-Cut.prototype.spacing = function(space) {
-  this._spacing = space;
-  return this;
-};
diff --git a/package.json b/package.json
index b13ad4b..406f512 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "cutjs",
-  "version": "0.5.0-beta.4",
+  "version": "0.5.0-beta.5",
   "description": "Lightweight, fast, interactable 2D HTML5 rendering engine for cross-platform game development.",
   "homepage": "http://cutjs.org/",
   "keywords": [
diff --git a/platform/cordova.js b/platform/cordova.js
index 703ae5d..cc78146 100644
--- a/platform/cordova.js
+++ b/platform/cordova.js
@@ -1,8 +1,14 @@
 module.exports = require('../lib/');
-module.exports.Mouse = require('../lib/mouse');
-module.exports.Math = require('../lib/util/math');
-require('../lib/tween');
-require('../lib/loader.cordova');
 
+require('../lib/canvas');
+require('../lib/image');
+require('../lib/anim');
+require('../lib/str');
+require('../lib/layout');
+require('../lib/addon/tween');
+module.exports.Mouse = require('../lib/addon/mouse');
+module.exports.Math = require('../lib/util/math');
 module.exports._extend = require('../lib/util/extend');
-module.exports._create = require('../lib/util/create');
\ No newline at end of file
+module.exports._create = require('../lib/util/create');
+
+require('../lib/loader/cordova');
\ No newline at end of file
diff --git a/platform/web.js b/platform/web.js
index 1563a41..a8b9d25 100644
--- a/platform/web.js
+++ b/platform/web.js
@@ -1,8 +1,14 @@
 module.exports = require('../lib/');
-module.exports.Mouse = require('../lib/mouse');
-module.exports.Math = require('../lib/util/math');
-require('../lib/tween');
-require('../lib/loader.web');
 
+require('../lib/canvas');
+require('../lib/image');
+require('../lib/anim');
+require('../lib/str');
+require('../lib/layout');
+require('../lib/addon/tween');
+module.exports.Mouse = require('../lib/addon/mouse');
+module.exports.Math = require('../lib/util/math');
 module.exports._extend = require('../lib/util/extend');
-module.exports._create = require('../lib/util/create');
\ No newline at end of file
+module.exports._create = require('../lib/util/create');
+
+require('../lib/loader/web');
\ No newline at end of file
diff --git a/test/main-test.js b/test/main-test.js
index b0b50ee..dba0779 100644
--- a/test/main-test.js
+++ b/test/main-test.js
@@ -13,7 +13,10 @@ it('static methods', function() {
   expect(Cut.atlas).be.a('function');
 
   expect(Cut.create).be.a('function');
-  expect(Cut.image).be.a('function');
-  expect(Cut.anim).be.a('function');
-  expect(Cut.string).be.a('function');
+
+  // expect(Cut.root).be.a('function');
+  // expect(Cut.image).be.a('function');
+  // expect(Cut.anim).be.a('function');
+  // expect(Cut.string).be.a('function');
+  // expect(Cut.canvas).be.a('function');
 });
diff --git a/test/mouse-test.js b/test/mouse-test.js
index aa84fa4..22342b6 100644
--- a/test/mouse-test.js
+++ b/test/mouse-test.js
@@ -12,7 +12,7 @@ it('Mouse', function() {
     document : document
   };
 
-  var Mouse = sandboxed.require('../lib/mouse', {
+  var Mouse = sandboxed.require('../lib/addon/mouse', {
     locals : {
       window : window,
       document : document
