Commits

Anonymous committed cf50f4a

coffee code divided in different files

Comments (0)

Files changed (10)

coffee/CubeController.coffee

+class CubeController
+
+    current: -1
+
+    mode: 'stop'
+
+    view: undefined
+
+    model: undefined
+
+    turnlist: undefined
+
+    constructor:(cubeview) ->
+        @view = cubeview
+        @model = cubeview.model
+
+        # read the attributes
+        @turnlist = @view.$container.getAttribute('data-move').split(" ")
+
+        # add the text movements
+        @view.$container.insertAdjacentHTML "beforeend", '<div class="movtext">' + @turnlist.join(' ') + '</div><div class="movbuttons"><a class="first" href="#">|◀</a><a class="previous" href="#">◀|</a><a class="previous-play" href="#">◀</a><a class="stop" href="#">◼</a><a class="next-play" href="#">▶</a><a class="next" href="#">|▶</a><a class="last" href="#">▶|</a></div>'
+
+        # buttons clicks
+        @view.$container.querySelector('.next-play').addEventListener 'click', =>
+            @next_play()
+        @view.$container.querySelector('.next').addEventListener 'click', =>
+            @next()
+        @view.$container.querySelector('.stop').addEventListener 'click', =>
+            @stop()
+        @view.$container.querySelector('.last').addEventListener 'click', =>
+            @last()
+        @view.$container.querySelector('.first').addEventListener 'click', =>
+            @first()
+        @view.$container.querySelector('.previous').addEventListener 'click', =>
+            @previous()
+        @view.$container.querySelector('.previous-play').addEventListener 'click', =>
+            @previous_play()
+
+    end_callback: =>
+        if @mode is 'play'
+            @mode = 'stop'
+            if @current < @turnlist.length - 1
+                @next_play()
+        else if @mode is 'play_back'
+            @mode = 'stop'
+            if @current >= 0
+                @previous_play()
+        else if @mode is 'play_stop'
+            @mode = 'stop'
+
+    next: =>
+        window.setTimeout =>
+            if @mode is 'stop' and @current < @turnlist.length
+                @mode = 'play_stop'
+                @current++
+                @view.turn @turnlist[@current], @end_callback
+
+    next_play: =>
+        window.setTimeout =>
+            if @mode is 'stop'
+                @mode = 'play'
+                @current++
+                @view.turn @turnlist[@current], @end_callback
+
+    stop: =>
+        window.setTimeout =>
+            if @mode isnt 'stop'
+                @mode = 'stop'
+                @end_callback()
+
+    last : =>
+        window.setTimeout =>
+            if @mode is 'stop'
+                remaining_turnlist = @turnlist[@current+1..@turnlist.length-1]
+                @view.straightturn(remaining_turnlist.join(''))
+                @current = @turnlist.length - 1
+    first : =>
+        window.setTimeout =>
+            if @mode is 'stop'
+                @current = -1
+                @view.initState()
+
+    previous: =>
+        window.setTimeout =>
+            if @mode is 'stop' and @current > -1
+                @mode = 'play_stop'
+                @current--
+                inverted = @model.invert([@turnlist[@current+1]])
+                @view.turn inverted[0], @end_callback
+
+    previous_play: =>
+        window.setTimeout =>
+            if @mode is 'stop'
+                @mode = 'play_back'
+                @current--
+                inverted = @model.invert([@turnlist[@current+1]])
+                @view.turn inverted[0], @end_callback
+
+window.cube = window.cube or {}
+window.cube.controller = window.cube.controller or CubeController

coffee/CubeView.coffee

+class CubeView
+    # cube number to html cube faces correspondance
+    # the order is important for the display
+    faces:
+        3 : 'B' 
+        5 : 'D'
+        0 : 'U'
+        1 : 'F'
+        2 : 'R'
+        4 : 'L'
+
+    # cube colors to css colors correspondance
+    colors:
+        1: 'yellow'
+        2: 'blue'
+        3: 'red'
+        4: 'green'
+        5: 'orange'
+        6: 'white'
+
+    # list of movements where the specified face is hidden on the showcube
+    invisibles:
+        'F': ['RBD','RBLD','BLD','URBD','URBLD','UBLD','URB','URBL','UBL']
+        'R': ['BLD','FBLD','FLD','UBLD','UFBLD','UFLD','UBL','UFBL','UFL']
+        'U': ['FRD','FRLD','FLD','FRBD','FRBLD','FBLD','RBD','RBLD','BLD']
+        'L': ['FRD','FRBD','RBD','UFRD','UFRBD','URBD','UFR','UFRB','URB']
+        'D': ['URB','URBL','UBL','UFRB','UFRBL','UFBL','UFRB','UFRL','UFL']
+        'B': ['FLD','FRLD','FRD','UFLD','UFRLD','UFRD','UFL','UFRL','UFR']
+
+    ismoving: false
+
+    movcallback: undefined
+
+    coef: 2/3
+
+    minlength: undefined
+
+    constructor:($container) ->
+        @$container = $container
+        @model = new window.cube.model
+
+        # set the maximum width of the future cube
+        minlength = $container.clientWidth
+        height = $container.clientHeight
+        if height < minlength
+            minlength = height
+        @minlength = minlength
+
+        # center the viewer in the container
+        minlength = minlength * @coef
+        perspective = minlength * 10 / @coef
+        offsetX = perspective / 200 * @coef * 4
+        offsetY = perspective / 200 * @coef * 2
+        remaining_spaceX = (1-@coef)*(@minlength) - offsetX
+        remaining_spaceY = (1-@coef)*(@minlength) - offsetY
+        offsetX+=remaining_spaceX/4
+        offsetY+=remaining_spaceY/4
+
+        transforms =
+            'F': ''
+            'B': 'rotateY(180deg)'
+            'R': 'rotateY(90deg)'
+            'L': 'rotateY(-90deg)'
+            'U': 'rotateX(90deg)'
+            'D': 'rotateX(-90deg)'
+
+        # create the showcube
+        htmlstring = '<div class="viewer" style="left:' + offsetX + 'px;top:' + offsetY + 'px;-moz-perspective: ' + perspective + 'px"><div class="cube showcube" style="height:' + minlength + 'px;width:' + minlength + 'px;">'
+        for i, face of @faces
+            htmlstring+= '<div style="-moz-transform: ' + transforms[face] + ' translateZ('  + (minlength/2-1) + 'px);" class="face-' + face + '">'
+            for facet, j in @model.state[i]
+                hideclass = ("turn-#{mov}-hidden" for mov in @invisibles[face][j]).join(' ')
+                htmlstring+= '<div class="facet-' + face + j + ' ' + hideclass + '"><div></div></div>'
+            htmlstring+= '</div>'
+        htmlstring+= '</div></div>'
+        @$container.insertAdjacentHTML "beforeend", htmlstring
+        @renderColors()
+
+        # create a second cube and hide it
+        @$showcube = @$container.querySelector '.showcube'
+        @$shadowcube = @$showcube.cloneNode true
+        @$shadowcube.className = 'cube shadowcube'
+        $viewer = @$container.querySelector '.viewer'
+        $viewer.insertBefore @$shadowcube, $viewer.firstChild
+
+        for eventtype in ['transitionend', 'oTransitionEnd', 'webkitTransitionEnd']
+            @$showcube.addEventListener eventtype, @transitionend
+
+        # force a repaint of the cube to avoid display bugs
+        $cubeofcoffee = document.querySelectorAll '.cubeofcoffee'
+        for $container in $cubeofcoffee
+            $container.style.visibility = 'hidden'
+
+        window.setTimeout ->
+            for $container in $cubeofcoffee
+                $container.style.borderWidth = "" + 2 + 'px'
+                $container.style.visibility = 'visible'
+        , 0
+
+
+    renderColors: =>
+        for face, i in @model.state
+            for facet, j in face
+                $facets = @$container.getElementsByClassName "facet-#{@faces[i]}#{j}"
+                for $facet in $facets
+                    $facet.querySelector('div').style.backgroundColor = @colors[facet]
+
+    straightturn: (mov) =>
+        @model.combination(mov)
+        @renderColors()
+
+    initState: () =>
+        @model.init()
+        @renderColors()
+
+    turn: (mov, callback) ->
+        @movcallback = callback
+        @ismoving = true
+        @$container.querySelector('.showcube').classList.add('transitioned')
+        @model.combination(mov)
+        movclass = "show-#{mov[0]}"
+        if mov.length > 1
+            if mov[1] is "'"
+                movclass+= " #{movclass}-inv"
+            else if mov[1] is "2"
+                movclass+= " #{movclass}-double"
+        for $cube in @$container.getElementsByClassName 'cube'
+            $cube.className+= ' ' + movclass
+
+    transitionend: =>
+        @renderColors()
+
+        @$showcube.className = "cube showcube"
+        @$shadowcube.className = "cube shadowcube"
+
+        @ismoving = false
+
+        if @movcallback
+            window.setTimeout =>
+                @movcallback.apply(this)
+                @movcallback = undefined
+            , 0
+
+        return true
+
+window.cube = window.cube or {}
+window.cube.view = window.cube.view or CubeView

coffee/app.coffee

-class CubeView
-    # cube number to html cube faces correspondance
-    # the order is important for the display
-    faces:
-        3 : 'B' 
-        5 : 'D'
-        0 : 'U'
-        1 : 'F'
-        2 : 'R'
-        4 : 'L'
-
-    # cube colors to css colors correspondance
-    colors:
-        1: 'yellow'
-        2: 'blue'
-        3: 'red'
-        4: 'green'
-        5: 'orange'
-        6: 'white'
-
-    # list of movements where the specified face is hidden on the showcube
-    invisibles:
-        'F': ['RBD','RBLD','BLD','URBD','URBLD','UBLD','URB','URBL','UBL']
-        'R': ['BLD','FBLD','FLD','UBLD','UFBLD','UFLD','UBL','UFBL','UFL']
-        'U': ['FRD','FRLD','FLD','FRBD','FRBLD','FBLD','RBD','RBLD','BLD']
-        'L': ['FRD','FRBD','RBD','UFRD','UFRBD','URBD','UFR','UFRB','URB']
-        'D': ['URB','URBL','UBL','UFRB','UFRBL','UFBL','UFRB','UFRL','UFL']
-        'B': ['FLD','FRLD','FRD','UFLD','UFRLD','UFRD','UFL','UFRL','UFR']
-
-    ismoving: false
-
-    movcallback: undefined
-
-    coef: 2/3
-
-    minlength: undefined
-
-    constructor:($container) ->
-        @$container = $container
-        @model = new Cube
-
-        # set the maximum width of the future cube
-        minlength = $container.clientWidth
-        height = $container.clientHeight
-        if height < minlength
-            minlength = height
-        @minlength = minlength
-
-        # center the viewer in the container
-        minlength = minlength * @coef
-        perspective = minlength * 10 / @coef
-        offsetX = perspective / 200 * @coef * 4
-        offsetY = perspective / 200 * @coef * 2
-        remaining_spaceX = (1-@coef)*(@minlength) - offsetX
-        remaining_spaceY = (1-@coef)*(@minlength) - offsetY
-        offsetX+=remaining_spaceX/4
-        offsetY+=remaining_spaceY/4
-
-        transforms =
-            'F': ''
-            'B': 'rotateY(180deg)'
-            'R': 'rotateY(90deg)'
-            'L': 'rotateY(-90deg)'
-            'U': 'rotateX(90deg)'
-            'D': 'rotateX(-90deg)'
-
-        # create the showcube
-        htmlstring = '<div class="viewer" style="left:' + offsetX + 'px;top:' + offsetY + 'px;-moz-perspective: ' + perspective + 'px"><div class="cube showcube" style="height:' + minlength + 'px;width:' + minlength + 'px;">'
-        for i, face of @faces
-            htmlstring+= '<div style="-moz-transform: ' + transforms[face] + ' translateZ('  + (minlength/2-1) + 'px);" class="face-' + face + '">'
-            for facet, j in @model.state[i]
-                hideclass = ("turn-#{mov}-hidden" for mov in @invisibles[face][j]).join(' ')
-                htmlstring+= '<div class="facet-' + face + j + ' ' + hideclass + '"><div></div></div>'
-            htmlstring+= '</div>'
-        htmlstring+= '</div></div>'
-        @$container.insertAdjacentHTML "beforeend", htmlstring
-        @renderColors()
-
-        # create a second cube and hide it
-        @$showcube = @$container.querySelector '.showcube'
-        @$shadowcube = @$showcube.cloneNode true
-        @$shadowcube.className = 'cube shadowcube'
-        $viewer = @$container.querySelector '.viewer'
-        $viewer.insertBefore @$shadowcube, $viewer.firstChild
-
-        for eventtype in ['transitionend', 'oTransitionEnd', 'webkitTransitionEnd']
-            @$showcube.addEventListener eventtype, @transitionend
-
-        # force a repaint of the cube to avoid display bugs
-        $cubeofcoffee = document.querySelectorAll '.cubeofcoffee'
-        for $container in $cubeofcoffee
-            $container.style.visibility = 'hidden'
-
-        window.setTimeout ->
-            for $container in $cubeofcoffee
-                $container.style.borderWidth = "" + 2 + 'px'
-                $container.style.visibility = 'visible'
-        , 0
-
-
-    renderColors: =>
-        for face, i in @model.state
-            for facet, j in face
-                $facets = @$container.getElementsByClassName "facet-#{@faces[i]}#{j}"
-                for $facet in $facets
-                    $facet.querySelector('div').style.backgroundColor = @colors[facet]
-
-    straightturn: (mov) =>
-        @model.combination(mov)
-        @renderColors()
-
-    initState: () =>
-        @model.init()
-        @renderColors()
-
-    turn: (mov, callback) ->
-        @movcallback = callback
-        @ismoving = true
-        @$container.querySelector('.showcube').classList.add('transitioned')
-        @model.combination(mov)
-        movclass = "show-#{mov[0]}"
-        if mov.length > 1
-            if mov[1] is "'"
-                movclass+= " #{movclass}-inv"
-            else if mov[1] is "2"
-                movclass+= " #{movclass}-double"
-        for $cube in @$container.getElementsByClassName 'cube'
-            $cube.className+= ' ' + movclass
-
-    transitionend: =>
-        @renderColors()
-
-        @$showcube.className = "cube showcube"
-        @$shadowcube.className = "cube shadowcube"
-
-        @ismoving = false
-
-        if @movcallback
-            window.setTimeout =>
-                @movcallback.apply(this)
-                @movcallback = undefined
-            , 0
-
-        return true
-
-class CubeController
-
-    current: -1
-
-    mode: 'stop'
-
-    view: undefined
-
-    model: undefined
-
-    turnlist: undefined
-
-    constructor:(cubeview) ->
-        @view = cubeview
-        @model = cubeview.model
-
-        # read the attributes
-        @turnlist = @view.$container.getAttribute('data-move').split(" ")
-
-        # add the text movements
-        @view.$container.insertAdjacentHTML "beforeend", '<div class="movtext">' + @turnlist.join(' ') + '</div><div class="movbuttons"><a class="first" href="#">|◀</a><a class="previous" href="#">◀|</a><a class="previous-play" href="#">◀</a><a class="stop" href="#">◼</a><a class="next-play" href="#">▶</a><a class="next" href="#">|▶</a><a class="last" href="#">▶|</a></div>'
-
-        # buttons clicks
-        @view.$container.querySelector('.next-play').addEventListener 'click', =>
-            @next_play()
-        @view.$container.querySelector('.next').addEventListener 'click', =>
-            @next()
-        @view.$container.querySelector('.stop').addEventListener 'click', =>
-            @stop()
-        @view.$container.querySelector('.last').addEventListener 'click', =>
-            @last()
-        @view.$container.querySelector('.first').addEventListener 'click', =>
-            @first()
-        @view.$container.querySelector('.previous').addEventListener 'click', =>
-            @previous()
-        @view.$container.querySelector('.previous-play').addEventListener 'click', =>
-            @previous_play()
-
-    end_callback: =>
-        if @mode is 'play'
-            @mode = 'stop'
-            if @current < @turnlist.length - 1
-                @next_play()
-        else if @mode is 'play_back'
-            @mode = 'stop'
-            if @current >= 0
-                @previous_play()
-        else if @mode is 'play_stop'
-            @mode = 'stop'
-
-    next: =>
-        window.setTimeout =>
-            if @mode is 'stop' and @current < @turnlist.length
-                @mode = 'play_stop'
-                @current++
-                @view.turn @turnlist[@current], @end_callback
-
-    next_play: =>
-        window.setTimeout =>
-            if @mode is 'stop'
-                @mode = 'play'
-                @current++
-                @view.turn @turnlist[@current], @end_callback
-
-    stop: =>
-        window.setTimeout =>
-            if @mode isnt 'stop'
-                @mode = 'stop'
-                @end_callback()
-
-    last : =>
-        window.setTimeout =>
-            if @mode is 'stop'
-                remaining_turnlist = @turnlist[@current+1..@turnlist.length-1]
-                @view.straightturn(remaining_turnlist.join(''))
-                @current = @turnlist.length - 1
-    first : =>
-        window.setTimeout =>
-            if @mode is 'stop'
-                @current = -1
-                @view.initState()
-
-    previous: =>
-        window.setTimeout =>
-            if @mode is 'stop' and @current > -1
-                @mode = 'play_stop'
-                @current--
-                inverted = @model.invert([@turnlist[@current+1]])
-                @view.turn inverted[0], @end_callback
-
-    previous_play: =>
-        window.setTimeout =>
-            if @mode is 'stop'
-                @mode = 'play_back'
-                @current--
-                inverted = @model.invert([@turnlist[@current+1]])
-                @view.turn inverted[0], @end_callback
-
 document.addEventListener 'DOMContentLoaded', ->
 
     for $container in document.querySelectorAll '.cubeofcoffee'
-        window.$test = new CubeController(new CubeView($container))
+        window.$test = new window.cube.controller(new window.cube.view($container))
 
 
         #       window.setInterval ->

coffee/cube.coffee

-window.Cube = class Cube
+Cube = class Cube
     init: =>
         @state = (face[0..] for face in @initstate) # deep copy
     constructor: ->
     #{@state[5][6..8].join('')}\n
 ";
 
+window.cube = window.cube or {}
+window.cube.model = window.cube.model or Cube
     }
 
     .cube.transitioned {
-        -moz-transition: -moz-transform 1s;
+        -moz-transition: -moz-transform 0.5s;
         -moz-transition-timing-function: ease-in;
         -webkit-transition: -webkit-transform 1s;
         -o-transition: -o-transform 1s;
         <link href="css/style.css" type="text/css" rel="stylesheet">
         <script src="js/libs/jquery-1.5.2.js"></script>
         <script src="js/cube.js"></script>
+        <script src="js/CubeView.js"></script>
+        <script src="js/CubeController.js"></script>
         <script src="js/app.js"></script>
 <style>
     .container {

js/CubeController.js

+// Generated by CoffeeScript 1.3.3
+(function() {
+  var CubeController,
+    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
+
+  CubeController = (function() {
+
+    CubeController.prototype.current = -1;
+
+    CubeController.prototype.mode = 'stop';
+
+    CubeController.prototype.view = void 0;
+
+    CubeController.prototype.model = void 0;
+
+    CubeController.prototype.turnlist = void 0;
+
+    function CubeController(cubeview) {
+      this.previous_play = __bind(this.previous_play, this);
+
+      this.previous = __bind(this.previous, this);
+
+      this.first = __bind(this.first, this);
+
+      this.last = __bind(this.last, this);
+
+      this.stop = __bind(this.stop, this);
+
+      this.next_play = __bind(this.next_play, this);
+
+      this.next = __bind(this.next, this);
+
+      this.end_callback = __bind(this.end_callback, this);
+
+      var _this = this;
+      this.view = cubeview;
+      this.model = cubeview.model;
+      this.turnlist = this.view.$container.getAttribute('data-move').split(" ");
+      this.view.$container.insertAdjacentHTML("beforeend", '<div class="movtext">' + this.turnlist.join(' ') + '</div><div class="movbuttons"><a class="first" href="#">|◀</a><a class="previous" href="#">◀|</a><a class="previous-play" href="#">◀</a><a class="stop" href="#">◼</a><a class="next-play" href="#">▶</a><a class="next" href="#">|▶</a><a class="last" href="#">▶|</a></div>');
+      this.view.$container.querySelector('.next-play').addEventListener('click', function() {
+        return _this.next_play();
+      });
+      this.view.$container.querySelector('.next').addEventListener('click', function() {
+        return _this.next();
+      });
+      this.view.$container.querySelector('.stop').addEventListener('click', function() {
+        return _this.stop();
+      });
+      this.view.$container.querySelector('.last').addEventListener('click', function() {
+        return _this.last();
+      });
+      this.view.$container.querySelector('.first').addEventListener('click', function() {
+        return _this.first();
+      });
+      this.view.$container.querySelector('.previous').addEventListener('click', function() {
+        return _this.previous();
+      });
+      this.view.$container.querySelector('.previous-play').addEventListener('click', function() {
+        return _this.previous_play();
+      });
+    }
+
+    CubeController.prototype.end_callback = function() {
+      if (this.mode === 'play') {
+        this.mode = 'stop';
+        if (this.current < this.turnlist.length - 1) {
+          return this.next_play();
+        }
+      } else if (this.mode === 'play_back') {
+        this.mode = 'stop';
+        if (this.current >= 0) {
+          return this.previous_play();
+        }
+      } else if (this.mode === 'play_stop') {
+        return this.mode = 'stop';
+      }
+    };
+
+    CubeController.prototype.next = function() {
+      var _this = this;
+      return window.setTimeout(function() {
+        if (_this.mode === 'stop' && _this.current < _this.turnlist.length) {
+          _this.mode = 'play_stop';
+          _this.current++;
+          return _this.view.turn(_this.turnlist[_this.current], _this.end_callback);
+        }
+      });
+    };
+
+    CubeController.prototype.next_play = function() {
+      var _this = this;
+      return window.setTimeout(function() {
+        if (_this.mode === 'stop') {
+          _this.mode = 'play';
+          _this.current++;
+          return _this.view.turn(_this.turnlist[_this.current], _this.end_callback);
+        }
+      });
+    };
+
+    CubeController.prototype.stop = function() {
+      var _this = this;
+      return window.setTimeout(function() {
+        if (_this.mode !== 'stop') {
+          _this.mode = 'stop';
+          return _this.end_callback();
+        }
+      });
+    };
+
+    CubeController.prototype.last = function() {
+      var _this = this;
+      return window.setTimeout(function() {
+        var remaining_turnlist;
+        if (_this.mode === 'stop') {
+          remaining_turnlist = _this.turnlist.slice(_this.current + 1, (_this.turnlist.length - 1) + 1 || 9e9);
+          _this.view.straightturn(remaining_turnlist.join(''));
+          return _this.current = _this.turnlist.length - 1;
+        }
+      });
+    };
+
+    CubeController.prototype.first = function() {
+      var _this = this;
+      return window.setTimeout(function() {
+        if (_this.mode === 'stop') {
+          _this.current = -1;
+          return _this.view.initState();
+        }
+      });
+    };
+
+    CubeController.prototype.previous = function() {
+      var _this = this;
+      return window.setTimeout(function() {
+        var inverted;
+        if (_this.mode === 'stop' && _this.current > -1) {
+          _this.mode = 'play_stop';
+          _this.current--;
+          inverted = _this.model.invert([_this.turnlist[_this.current + 1]]);
+          return _this.view.turn(inverted[0], _this.end_callback);
+        }
+      });
+    };
+
+    CubeController.prototype.previous_play = function() {
+      var _this = this;
+      return window.setTimeout(function() {
+        var inverted;
+        if (_this.mode === 'stop') {
+          _this.mode = 'play_back';
+          _this.current--;
+          inverted = _this.model.invert([_this.turnlist[_this.current + 1]]);
+          return _this.view.turn(inverted[0], _this.end_callback);
+        }
+      });
+    };
+
+    return CubeController;
+
+  })();
+
+  window.cube = window.cube || {};
+
+  window.cube.controller = window.cube.controller || CubeController;
+
+}).call(this);
+// Generated by CoffeeScript 1.3.3
+(function() {
+  var CubeView,
+    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
+
+  CubeView = (function() {
+
+    CubeView.prototype.faces = {
+      3: 'B',
+      5: 'D',
+      0: 'U',
+      1: 'F',
+      2: 'R',
+      4: 'L'
+    };
+
+    CubeView.prototype.colors = {
+      1: 'yellow',
+      2: 'blue',
+      3: 'red',
+      4: 'green',
+      5: 'orange',
+      6: 'white'
+    };
+
+    CubeView.prototype.invisibles = {
+      'F': ['RBD', 'RBLD', 'BLD', 'URBD', 'URBLD', 'UBLD', 'URB', 'URBL', 'UBL'],
+      'R': ['BLD', 'FBLD', 'FLD', 'UBLD', 'UFBLD', 'UFLD', 'UBL', 'UFBL', 'UFL'],
+      'U': ['FRD', 'FRLD', 'FLD', 'FRBD', 'FRBLD', 'FBLD', 'RBD', 'RBLD', 'BLD'],
+      'L': ['FRD', 'FRBD', 'RBD', 'UFRD', 'UFRBD', 'URBD', 'UFR', 'UFRB', 'URB'],
+      'D': ['URB', 'URBL', 'UBL', 'UFRB', 'UFRBL', 'UFBL', 'UFRB', 'UFRL', 'UFL'],
+      'B': ['FLD', 'FRLD', 'FRD', 'UFLD', 'UFRLD', 'UFRD', 'UFL', 'UFRL', 'UFR']
+    };
+
+    CubeView.prototype.ismoving = false;
+
+    CubeView.prototype.movcallback = void 0;
+
+    CubeView.prototype.coef = 2 / 3;
+
+    CubeView.prototype.minlength = void 0;
+
+    function CubeView($container) {
+      this.transitionend = __bind(this.transitionend, this);
+
+      this.initState = __bind(this.initState, this);
+
+      this.straightturn = __bind(this.straightturn, this);
+
+      this.renderColors = __bind(this.renderColors, this);
+
+      var $cubeofcoffee, $viewer, eventtype, face, facet, height, hideclass, htmlstring, i, j, minlength, mov, offsetX, offsetY, perspective, remaining_spaceX, remaining_spaceY, transforms, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2;
+      this.$container = $container;
+      this.model = new window.cube.model;
+      minlength = $container.clientWidth;
+      height = $container.clientHeight;
+      if (height < minlength) {
+        minlength = height;
+      }
+      this.minlength = minlength;
+      minlength = minlength * this.coef;
+      perspective = minlength * 10 / this.coef;
+      offsetX = perspective / 200 * this.coef * 4;
+      offsetY = perspective / 200 * this.coef * 2;
+      remaining_spaceX = (1 - this.coef) * this.minlength - offsetX;
+      remaining_spaceY = (1 - this.coef) * this.minlength - offsetY;
+      offsetX += remaining_spaceX / 4;
+      offsetY += remaining_spaceY / 4;
+      transforms = {
+        'F': '',
+        'B': 'rotateY(180deg)',
+        'R': 'rotateY(90deg)',
+        'L': 'rotateY(-90deg)',
+        'U': 'rotateX(90deg)',
+        'D': 'rotateX(-90deg)'
+      };
+      htmlstring = '<div class="viewer" style="left:' + offsetX + 'px;top:' + offsetY + 'px;-moz-perspective: ' + perspective + 'px"><div class="cube showcube" style="height:' + minlength + 'px;width:' + minlength + 'px;">';
+      _ref = this.faces;
+      for (i in _ref) {
+        face = _ref[i];
+        htmlstring += '<div style="-moz-transform: ' + transforms[face] + ' translateZ(' + (minlength / 2 - 1) + 'px);" class="face-' + face + '">';
+        _ref1 = this.model.state[i];
+        for (j = _i = 0, _len = _ref1.length; _i < _len; j = ++_i) {
+          facet = _ref1[j];
+          hideclass = ((function() {
+            var _j, _len1, _ref2, _results;
+            _ref2 = this.invisibles[face][j];
+            _results = [];
+            for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
+              mov = _ref2[_j];
+              _results.push("turn-" + mov + "-hidden");
+            }
+            return _results;
+          }).call(this)).join(' ');
+          htmlstring += '<div class="facet-' + face + j + ' ' + hideclass + '"><div></div></div>';
+        }
+        htmlstring += '</div>';
+      }
+      htmlstring += '</div></div>';
+      this.$container.insertAdjacentHTML("beforeend", htmlstring);
+      this.renderColors();
+      this.$showcube = this.$container.querySelector('.showcube');
+      this.$shadowcube = this.$showcube.cloneNode(true);
+      this.$shadowcube.className = 'cube shadowcube';
+      $viewer = this.$container.querySelector('.viewer');
+      $viewer.insertBefore(this.$shadowcube, $viewer.firstChild);
+      _ref2 = ['transitionend', 'oTransitionEnd', 'webkitTransitionEnd'];
+      for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
+        eventtype = _ref2[_j];
+        this.$showcube.addEventListener(eventtype, this.transitionend);
+      }
+      $cubeofcoffee = document.querySelectorAll('.cubeofcoffee');
+      for (_k = 0, _len2 = $cubeofcoffee.length; _k < _len2; _k++) {
+        $container = $cubeofcoffee[_k];
+        $container.style.visibility = 'hidden';
+      }
+      window.setTimeout(function() {
+        var _l, _len3, _results;
+        _results = [];
+        for (_l = 0, _len3 = $cubeofcoffee.length; _l < _len3; _l++) {
+          $container = $cubeofcoffee[_l];
+          $container.style.borderWidth = "" + 2 + 'px';
+          _results.push($container.style.visibility = 'visible');
+        }
+        return _results;
+      }, 0);
+    }
+
+    CubeView.prototype.renderColors = function() {
+      var $facet, $facets, face, facet, i, j, _i, _len, _ref, _results;
+      _ref = this.model.state;
+      _results = [];
+      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+        face = _ref[i];
+        _results.push((function() {
+          var _j, _len1, _results1;
+          _results1 = [];
+          for (j = _j = 0, _len1 = face.length; _j < _len1; j = ++_j) {
+            facet = face[j];
+            $facets = this.$container.getElementsByClassName("facet-" + this.faces[i] + j);
+            _results1.push((function() {
+              var _k, _len2, _results2;
+              _results2 = [];
+              for (_k = 0, _len2 = $facets.length; _k < _len2; _k++) {
+                $facet = $facets[_k];
+                _results2.push($facet.querySelector('div').style.backgroundColor = this.colors[facet]);
+              }
+              return _results2;
+            }).call(this));
+          }
+          return _results1;
+        }).call(this));
+      }
+      return _results;
+    };
+
+    CubeView.prototype.straightturn = function(mov) {
+      this.model.combination(mov);
+      return this.renderColors();
+    };
+
+    CubeView.prototype.initState = function() {
+      this.model.init();
+      return this.renderColors();
+    };
+
+    CubeView.prototype.turn = function(mov, callback) {
+      var $cube, movclass, _i, _len, _ref, _results;
+      this.movcallback = callback;
+      this.ismoving = true;
+      this.$container.querySelector('.showcube').classList.add('transitioned');
+      this.model.combination(mov);
+      movclass = "show-" + mov[0];
+      if (mov.length > 1) {
+        if (mov[1] === "'") {
+          movclass += " " + movclass + "-inv";
+        } else if (mov[1] === "2") {
+          movclass += " " + movclass + "-double";
+        }
+      }
+      _ref = this.$container.getElementsByClassName('cube');
+      _results = [];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        $cube = _ref[_i];
+        _results.push($cube.className += ' ' + movclass);
+      }
+      return _results;
+    };
+
+    CubeView.prototype.transitionend = function() {
+      var _this = this;
+      this.renderColors();
+      this.$showcube.className = "cube showcube";
+      this.$shadowcube.className = "cube shadowcube";
+      this.ismoving = false;
+      if (this.movcallback) {
+        window.setTimeout(function() {
+          _this.movcallback.apply(_this);
+          return _this.movcallback = void 0;
+        }, 0);
+      }
+      return true;
+    };
+
+    return CubeView;
+
+  })();
+
+  window.cube = window.cube || {};
+
+  window.cube.view = window.cube.view || CubeView;
+
+}).call(this);
 // Generated by CoffeeScript 1.3.3
 (function() {
-  var CubeController, CubeView,
-    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
-
-  CubeView = (function() {
-
-    CubeView.prototype.faces = {
-      3: 'B',
-      5: 'D',
-      0: 'U',
-      1: 'F',
-      2: 'R',
-      4: 'L'
-    };
-
-    CubeView.prototype.colors = {
-      1: 'yellow',
-      2: 'blue',
-      3: 'red',
-      4: 'green',
-      5: 'orange',
-      6: 'white'
-    };
-
-    CubeView.prototype.invisibles = {
-      'F': ['RBD', 'RBLD', 'BLD', 'URBD', 'URBLD', 'UBLD', 'URB', 'URBL', 'UBL'],
-      'R': ['BLD', 'FBLD', 'FLD', 'UBLD', 'UFBLD', 'UFLD', 'UBL', 'UFBL', 'UFL'],
-      'U': ['FRD', 'FRLD', 'FLD', 'FRBD', 'FRBLD', 'FBLD', 'RBD', 'RBLD', 'BLD'],
-      'L': ['FRD', 'FRBD', 'RBD', 'UFRD', 'UFRBD', 'URBD', 'UFR', 'UFRB', 'URB'],
-      'D': ['URB', 'URBL', 'UBL', 'UFRB', 'UFRBL', 'UFBL', 'UFRB', 'UFRL', 'UFL'],
-      'B': ['FLD', 'FRLD', 'FRD', 'UFLD', 'UFRLD', 'UFRD', 'UFL', 'UFRL', 'UFR']
-    };
-
-    CubeView.prototype.ismoving = false;
-
-    CubeView.prototype.movcallback = void 0;
-
-    CubeView.prototype.coef = 2 / 3;
-
-    CubeView.prototype.minlength = void 0;
-
-    function CubeView($container) {
-      this.transitionend = __bind(this.transitionend, this);
-
-      this.initState = __bind(this.initState, this);
-
-      this.straightturn = __bind(this.straightturn, this);
-
-      this.renderColors = __bind(this.renderColors, this);
-
-      var $cubeofcoffee, $viewer, eventtype, face, facet, height, hideclass, htmlstring, i, j, minlength, mov, offsetX, offsetY, perspective, remaining_spaceX, remaining_spaceY, transforms, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2;
-      this.$container = $container;
-      this.model = new Cube;
-      minlength = $container.clientWidth;
-      height = $container.clientHeight;
-      if (height < minlength) {
-        minlength = height;
-      }
-      this.minlength = minlength;
-      minlength = minlength * this.coef;
-      perspective = minlength * 10 / this.coef;
-      offsetX = perspective / 200 * this.coef * 4;
-      offsetY = perspective / 200 * this.coef * 2;
-      remaining_spaceX = (1 - this.coef) * this.minlength - offsetX;
-      remaining_spaceY = (1 - this.coef) * this.minlength - offsetY;
-      offsetX += remaining_spaceX / 4;
-      offsetY += remaining_spaceY / 4;
-      transforms = {
-        'F': '',
-        'B': 'rotateY(180deg)',
-        'R': 'rotateY(90deg)',
-        'L': 'rotateY(-90deg)',
-        'U': 'rotateX(90deg)',
-        'D': 'rotateX(-90deg)'
-      };
-      htmlstring = '<div class="viewer" style="left:' + offsetX + 'px;top:' + offsetY + 'px;-moz-perspective: ' + perspective + 'px"><div class="cube showcube" style="height:' + minlength + 'px;width:' + minlength + 'px;">';
-      _ref = this.faces;
-      for (i in _ref) {
-        face = _ref[i];
-        htmlstring += '<div style="-moz-transform: ' + transforms[face] + ' translateZ(' + (minlength / 2 - 1) + 'px);" class="face-' + face + '">';
-        _ref1 = this.model.state[i];
-        for (j = _i = 0, _len = _ref1.length; _i < _len; j = ++_i) {
-          facet = _ref1[j];
-          hideclass = ((function() {
-            var _j, _len1, _ref2, _results;
-            _ref2 = this.invisibles[face][j];
-            _results = [];
-            for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
-              mov = _ref2[_j];
-              _results.push("turn-" + mov + "-hidden");
-            }
-            return _results;
-          }).call(this)).join(' ');
-          htmlstring += '<div class="facet-' + face + j + ' ' + hideclass + '"><div></div></div>';
-        }
-        htmlstring += '</div>';
-      }
-      htmlstring += '</div></div>';
-      this.$container.insertAdjacentHTML("beforeend", htmlstring);
-      this.renderColors();
-      this.$showcube = this.$container.querySelector('.showcube');
-      this.$shadowcube = this.$showcube.cloneNode(true);
-      this.$shadowcube.className = 'cube shadowcube';
-      $viewer = this.$container.querySelector('.viewer');
-      $viewer.insertBefore(this.$shadowcube, $viewer.firstChild);
-      _ref2 = ['transitionend', 'oTransitionEnd', 'webkitTransitionEnd'];
-      for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
-        eventtype = _ref2[_j];
-        this.$showcube.addEventListener(eventtype, this.transitionend);
-      }
-      $cubeofcoffee = document.querySelectorAll('.cubeofcoffee');
-      for (_k = 0, _len2 = $cubeofcoffee.length; _k < _len2; _k++) {
-        $container = $cubeofcoffee[_k];
-        $container.style.visibility = 'hidden';
-      }
-      window.setTimeout(function() {
-        var _l, _len3, _results;
-        _results = [];
-        for (_l = 0, _len3 = $cubeofcoffee.length; _l < _len3; _l++) {
-          $container = $cubeofcoffee[_l];
-          $container.style.borderWidth = "" + 2 + 'px';
-          _results.push($container.style.visibility = 'visible');
-        }
-        return _results;
-      }, 0);
-    }
-
-    CubeView.prototype.renderColors = function() {
-      var $facet, $facets, face, facet, i, j, _i, _len, _ref, _results;
-      _ref = this.model.state;
-      _results = [];
-      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
-        face = _ref[i];
-        _results.push((function() {
-          var _j, _len1, _results1;
-          _results1 = [];
-          for (j = _j = 0, _len1 = face.length; _j < _len1; j = ++_j) {
-            facet = face[j];
-            $facets = this.$container.getElementsByClassName("facet-" + this.faces[i] + j);
-            _results1.push((function() {
-              var _k, _len2, _results2;
-              _results2 = [];
-              for (_k = 0, _len2 = $facets.length; _k < _len2; _k++) {
-                $facet = $facets[_k];
-                _results2.push($facet.querySelector('div').style.backgroundColor = this.colors[facet]);
-              }
-              return _results2;
-            }).call(this));
-          }
-          return _results1;
-        }).call(this));
-      }
-      return _results;
-    };
-
-    CubeView.prototype.straightturn = function(mov) {
-      this.model.combination(mov);
-      return this.renderColors();
-    };
-
-    CubeView.prototype.initState = function() {
-      this.model.init();
-      return this.renderColors();
-    };
-
-    CubeView.prototype.turn = function(mov, callback) {
-      var $cube, movclass, _i, _len, _ref, _results;
-      this.movcallback = callback;
-      this.ismoving = true;
-      this.$container.querySelector('.showcube').classList.add('transitioned');
-      this.model.combination(mov);
-      movclass = "show-" + mov[0];
-      if (mov.length > 1) {
-        if (mov[1] === "'") {
-          movclass += " " + movclass + "-inv";
-        } else if (mov[1] === "2") {
-          movclass += " " + movclass + "-double";
-        }
-      }
-      _ref = this.$container.getElementsByClassName('cube');
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        $cube = _ref[_i];
-        _results.push($cube.className += ' ' + movclass);
-      }
-      return _results;
-    };
-
-    CubeView.prototype.transitionend = function() {
-      var _this = this;
-      this.renderColors();
-      this.$showcube.className = "cube showcube";
-      this.$shadowcube.className = "cube shadowcube";
-      this.ismoving = false;
-      if (this.movcallback) {
-        window.setTimeout(function() {
-          _this.movcallback.apply(_this);
-          return _this.movcallback = void 0;
-        }, 0);
-      }
-      return true;
-    };
-
-    return CubeView;
-
-  })();
-
-  CubeController = (function() {
-
-    CubeController.prototype.current = -1;
-
-    CubeController.prototype.mode = 'stop';
-
-    CubeController.prototype.view = void 0;
-
-    CubeController.prototype.model = void 0;
-
-    CubeController.prototype.turnlist = void 0;
-
-    function CubeController(cubeview) {
-      this.previous_play = __bind(this.previous_play, this);
-
-      this.previous = __bind(this.previous, this);
-
-      this.first = __bind(this.first, this);
-
-      this.last = __bind(this.last, this);
-
-      this.stop = __bind(this.stop, this);
-
-      this.next_play = __bind(this.next_play, this);
-
-      this.next = __bind(this.next, this);
-
-      this.end_callback = __bind(this.end_callback, this);
-
-      var _this = this;
-      this.view = cubeview;
-      this.model = cubeview.model;
-      this.turnlist = this.view.$container.getAttribute('data-move').split(" ");
-      this.view.$container.insertAdjacentHTML("beforeend", '<div class="movtext">' + this.turnlist.join(' ') + '</div><div class="movbuttons"><a class="first" href="#">|◀</a><a class="previous" href="#">◀|</a><a class="previous-play" href="#">◀</a><a class="stop" href="#">◼</a><a class="next-play" href="#">▶</a><a class="next" href="#">|▶</a><a class="last" href="#">▶|</a></div>');
-      this.view.$container.querySelector('.next-play').addEventListener('click', function() {
-        return _this.next_play();
-      });
-      this.view.$container.querySelector('.next').addEventListener('click', function() {
-        return _this.next();
-      });
-      this.view.$container.querySelector('.stop').addEventListener('click', function() {
-        return _this.stop();
-      });
-      this.view.$container.querySelector('.last').addEventListener('click', function() {
-        return _this.last();
-      });
-      this.view.$container.querySelector('.first').addEventListener('click', function() {
-        return _this.first();
-      });
-      this.view.$container.querySelector('.previous').addEventListener('click', function() {
-        return _this.previous();
-      });
-      this.view.$container.querySelector('.previous-play').addEventListener('click', function() {
-        return _this.previous_play();
-      });
-    }
-
-    CubeController.prototype.end_callback = function() {
-      if (this.mode === 'play') {
-        this.mode = 'stop';
-        if (this.current < this.turnlist.length - 1) {
-          return this.next_play();
-        }
-      } else if (this.mode === 'play_back') {
-        this.mode = 'stop';
-        if (this.current >= 0) {
-          return this.previous_play();
-        }
-      } else if (this.mode === 'play_stop') {
-        return this.mode = 'stop';
-      }
-    };
-
-    CubeController.prototype.next = function() {
-      var _this = this;
-      return window.setTimeout(function() {
-        if (_this.mode === 'stop' && _this.current < _this.turnlist.length) {
-          _this.mode = 'play_stop';
-          _this.current++;
-          return _this.view.turn(_this.turnlist[_this.current], _this.end_callback);
-        }
-      });
-    };
-
-    CubeController.prototype.next_play = function() {
-      var _this = this;
-      return window.setTimeout(function() {
-        if (_this.mode === 'stop') {
-          _this.mode = 'play';
-          _this.current++;
-          return _this.view.turn(_this.turnlist[_this.current], _this.end_callback);
-        }
-      });
-    };
-
-    CubeController.prototype.stop = function() {
-      var _this = this;
-      return window.setTimeout(function() {
-        if (_this.mode !== 'stop') {
-          _this.mode = 'stop';
-          return _this.end_callback();
-        }
-      });
-    };
-
-    CubeController.prototype.last = function() {
-      var _this = this;
-      return window.setTimeout(function() {
-        var remaining_turnlist;
-        if (_this.mode === 'stop') {
-          remaining_turnlist = _this.turnlist.slice(_this.current + 1, (_this.turnlist.length - 1) + 1 || 9e9);
-          _this.view.straightturn(remaining_turnlist.join(''));
-          return _this.current = _this.turnlist.length - 1;
-        }
-      });
-    };
-
-    CubeController.prototype.first = function() {
-      var _this = this;
-      return window.setTimeout(function() {
-        if (_this.mode === 'stop') {
-          _this.current = -1;
-          return _this.view.initState();
-        }
-      });
-    };
-
-    CubeController.prototype.previous = function() {
-      var _this = this;
-      return window.setTimeout(function() {
-        var inverted;
-        if (_this.mode === 'stop' && _this.current > -1) {
-          _this.mode = 'play_stop';
-          _this.current--;
-          inverted = _this.model.invert([_this.turnlist[_this.current + 1]]);
-          return _this.view.turn(inverted[0], _this.end_callback);
-        }
-      });
-    };
-
-    CubeController.prototype.previous_play = function() {
-      var _this = this;
-      return window.setTimeout(function() {
-        var inverted;
-        if (_this.mode === 'stop') {
-          _this.mode = 'play_back';
-          _this.current--;
-          inverted = _this.model.invert([_this.turnlist[_this.current + 1]]);
-          return _this.view.turn(inverted[0], _this.end_callback);
-        }
-      });
-    };
-
-    return CubeController;
-
-  })();
 
   document.addEventListener('DOMContentLoaded', function() {
     var $container, _i, _len, _ref, _results;
     _results = [];
     for (_i = 0, _len = _ref.length; _i < _len; _i++) {
       $container = _ref[_i];
-      _results.push(window.$test = new CubeController(new CubeView($container)));
+      _results.push(window.$test = new window.cube.controller(new window.cube.view($container)));
     }
     return _results;
   });
   var Cube,
     __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
 
-  window.Cube = Cube = (function() {
+  Cube = Cube = (function() {
 
     Cube.prototype.init = function() {
       var face;
 
   })();
 
+  window.cube = window.cube || {};
+
+  window.cube.model = window.cube.model || Cube;
+
 }).call(this);