Use the new conversion functions in the debug loader

Debug Routines
==============

Occasionally, software has bugs. It's also often quite convenient
to be able to fix those bugs.

    window.DEBUG = {}

Debug Data Collections
----------------------

This is a collection of debug data, for great debugging, and debug.

    window.DEBUG.loadDebugData = ->
        dateBase = do DayBase
        WS.message.push
            type: 'mode'
            mode: 'judge'
        WS.message.push
            type: 'override'
            override: null
        WS.message.push
            type: 'teams'
            teams:
                aaa:
                    college: 'College A'
                    name: 'Team A'
                    notes: 'Bees'
                    present: yes
                bbb:
                    college: 'College B'
                    name: 'Team B'
                    notes: ''
                    present: yes
                ccc:
                    college: 'College C'
                    name: 'Team C Alpha'
                    notes: ''
                    present: no
                ccc2:
                    college: 'College C'
                    name: 'Team C Beta'
                    notes: ''
                    present: yes
                ddd:
                    college: 'College D'
                    name: 'Team D'
                    notes: 'eyes'
                    present: yes
        WS.message.push
            type: 'day'
            schedule: [
                {key: 'w', start: dateBase + 3600*9, displayName: 'Doors Open', association: 0}
                {key: 'x', start: dateBase + 3600*9 + 1800, displayName: 'Tinker Time', association: 0}
                {key: 'y', start: dateBase + 3600*11, displayName: 'Briefing', association: 3}
                {key: 'z', start: dateBase + 3600*12, displayName: 'League', association: 1}
            ]

Debug Routines
==============

Occasionally, software has bugs. It's also often quite convenient
to be able to fix those bugs.

    window.DEBUG = {}

Debug Data Collections
----------------------

This is a collection of debug data, for great debugging, and debug.

    window.DEBUG.loadDebugData = ->
        currentDate = new Date
        currentDate.setHours 0
        currentDate.setMinutes 0
        currentDate.setSeconds 0
        dateBase = currentDate.valueOf() / 1000
        WS.message.push
            type: 'mode'
            mode: 'judge'
        WS.message.push
            type: 'override'
            override: null
        WS.message.push
            type: 'teams'
            teams:
                aaa:
                    college: 'College A'
                    name: 'Team A'
                    notes: 'Bees'
                    present: yes
                bbb:
                    college: 'College B'
                    name: 'Team B'
                    notes: ''
                    present: yes
                ccc:
                    college: 'College C'
                    name: 'Team C Alpha'
                    notes: ''
                    present: no
                ccc2:
                    college: 'College C'
                    name: 'Team C Beta'
                    notes: ''
                    present: yes
                ddd:
                    college: 'College D'
                    name: 'Team D'
                    notes: 'eyes'
                    present: yes
        WS.message.push
            type: 'day'
            schedule: [
                {key: 'w', start: dateBase + 3600*9, displayName: 'Doors Open', association: 0}
                {key: 'x', start: dateBase + 3600*9 + 1800, displayName: 'Tinker Time', association: 0}
                {key: 'y', start: dateBase + 3600*11, displayName: 'Briefing', association: 3}
                {key: 'z', start: dateBase + 3600*12, displayName: 'League', association: 1}
            ]


Added dynamic update to Box class

Added dynamic update to Box class

Signed-off-by: Diwank Singh <a78369447041e6bcf2913d083e4ed301785fc609@gmail.com>

Re: [Letter to a Source-Code-Reader](http://stewd.io/pong/lib/pong.js)

Dear Stewart

Thanks for inspiring me and many like me with the wonders of js.
With all it's warts and issues, JS is still one of my favorite languages.
I think simply by it's virtue of being the language of the web, it surpasses most others
in it's ability to champion the spirit of openness and the creative.

I have tried to keep this as simple as possible for the many awesome source code lovers
to read, copy-paste and critique.

Thanks again for caring to write that letter in 2009. It made a kid smile.

Diwank Singh
July 2013

*****

Browser Bricks
==============

Alright, let's get on with it.

Helper Functions
----------------

First, let's define some helper functions for the application.

    @_ = _ =   # _ namespace
      # Extend objects
      extend: (dest, src) ->
        dest[k] = v for own k, v of src
        dest

      # Pick properties
      pick: (obj, props) ->
        result = {}
        result[k] = obj[k] for k in props when obj[k]?

        result

      # UUID function (Copied shamelessly from https://gist.github.com/bmc/1893440)
      uuid: ->
        'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) ->
          r = Math.random() * 16 | 0
          v = if c is 'x' then r else (r & 0x3|0x8)
          v.toString(16)
        )

      # Simple serializer for flat objects
      serialize: (obj, {sep, eq}, cb) ->
        # Exec callback on all values of obj
        obj[k] = cb v for own k, v of obj if cb?

        # Return serialized obj
        ("#{ k }#{ eq }#{ v }" for own k, v of obj).join sep

      # Defer execution of function
      defer: (fn, args...) -> window.setTimeout fn, 1, args...

      # Clone object
      clone: (obj) -> _.extend {}, obj

Init Function
-------------

Let's write a global init function that can be used to register callbacks which are
executed 'onload'.

    # Callback register
    @init = init = do ->
      # Store registered callbacks
      callbacks = []

      # Run callbacks in order registered
      exec = -> fn?() for fn in callbacks

      # Onload callback
      onLoad = (fn) ->
        window.removeEventListener 'load', init, false
        fn?()

      (cb) ->
        if cb?
          # Register callback
          callbacks.push cb
        else
          # Defer execution until stack cleared
          onLoad -> _.defer exec

        false

    # Attach DOM load listener
    window.addEventListener 'load', init, false

Class: Box
----------

Now, let's define a box that will be the basic building block for the game.
All the objects will inherit from this class.

    class Box
      _EDITABLE: ['height', 'width', 'top', 'left']   # Editable settings
      _settings:
        # Default settings
        height: 100
        width:  200
        top:    0
        left:   0

        # Fixed props
        toolbar:     false
        directories: false
        fullscreen:  false
        location:    false
        menubar:     false
        resizable:   false
        scrollbars:  false
        status:      false

      _window: null  # Empty window object

      constructor: (@url, settings) ->
        # Override settings.
        @_update settings

        # Set random name
        @id = _.uuid()
        this

      # -- Private --

      _update: (settings) ->
        # Update settings
        _.extend @_settings, (_.pick settings, @_EDITABLE)

        # Adjust window props
        @_window?.moveTo (@_get 'left'), (@_get 'top')
        @_window?.resizeTo (@_get 'width'), (@_get 'height')

        # Return a copy of settings
        @_getAll()

      _get: (prop) -> @_settings[prop] if prop in @_EDITABLE
      _getAll: -> _.clone @_settings

      # -- Public --

      # Show window with settings.
      show: ->
        # Serialize options
        opts = _.serialize @_getAll(), {sep: ',', eq: '='}, (v) ->
          switch v
            when false then 'no'
            when true then 'yes'
            else v+''

        @_window = window.open @url, @id, opts
        this

      # Hide the window.
      hide: ->
        @_window.close()
        @_window = null
        this

      # Reset window settings.
      reset: ->
        @_update Box::settings
        this

      # Return or update window position coords.
      position: (coords...) ->
        # Set new coords
        if coords.length then @_update
          left: coords[0] ? Box::settings.left  # x
          top:  coords[1] ? Box::settings.top   # y

        # Return coords
        [(@_get 'left'), (@_get 'top')]

      # Return or update window dimensions.
      size: (dimensions...) ->
        # Set new dimensions
        if dimensions.length then @_update
          width: dimensions[0] ? Box::settings.width
          height:  dimensions[1] ? Box::settings.height

        # Return dimensions
        [(@_get 'width'), (@_get 'height')]

Re: [Letter to a Source-Code-Reader](http://stewd.io/pong/lib/pong.js)

Dear Stewart

Thanks for inspiring me and many like me with the wonders of js.
With all it's warts and issues, JS is still one of my favorite languages.
I think simply by it's virtue of being the language of the web, it surpasses most others
in it's ability to champion the spirit of openness and the creative.

I have tried to keep this as simple as possible for the many awesome source code lovers
to read, copy-paste and critique.

Thanks again for caring to write that letter in 2009. It made a kid smile.

Diwank Singh
July 2013

*****

Browser Bricks
==============

Alright, let's get on with it.

Helper Functions
----------------

First, let's define some helper functions for the application.

    @_ = _ =   # _ namespace
      # Extend objects
      extend: (dest, src) ->
        dest[k] = v for own k, v of src
        dest

      # Pick properties
      pick: (obj, props) ->
        result = {}
        result[k] = obj[k] for k in props when obj[k]?

        result

      # UUID function (Copied shamelessly from https://gist.github.com/bmc/1893440)
      uuid: ->
        'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) ->
          r = Math.random() * 16 | 0
          v = if c is 'x' then r else (r & 0x3|0x8)
          v.toString(16)
        )

      # Simple serializer for flat objects
      serialize: (obj, {sep, eq}, cb) ->
        # Exec callback on all values of obj
        obj[k] = cb v for own k, v of obj if cb?

        # Return serialized obj
        ("#{ k }#{ eq }#{ v }" for own k, v of obj).join sep

      # Defer execution of function
      defer: (fn, args...) -> window.setTimeout fn, 1, args...

      # Clone object
      clone: (obj) -> _.extend {}, obj

Init Function
-------------

Let's write a global init function that can be used to register callbacks which are
executed 'onload'.

    # Callback register
    @init = init = do ->
      # Store registered callbacks
      callbacks = []

      # Run callbacks in order registered
      exec = -> fn?() for fn in callbacks

      # Onload callback
      onLoad = (fn) ->
        window.removeEventListener 'load', init, false
        fn?()

      (cb) ->
        if cb?
          # Register callback
          callbacks.push cb
        else
          # Defer execution until stack cleared
          onLoad -> _.defer exec

        false

    # Attach DOM load listener
    window.addEventListener 'load', init, false

Class: Box
----------

Now, let's define a box that will be the basic building block for the game.
All the objects will inherit from this class.

    class Box
      _EDITABLE: ['height', 'width', 'top', 'left']   # Editable settings
      _settings:
        # Default settings
        height: 100
        width:  200
        top:    0
        left:   0

        # Fixed props
        toolbar:     false
        directories: false
        fullscreen:  false
        location:    false
        menubar:     false
        resizable:   false
        scrollbars:  false
        status:      false

      _window: null  # Empty window object

      constructor: (@url, settings) ->
        # Override settings.
        @_update settings

        # Set random name
        @id = _.uuid()
        this

      # -- Private --

      _update: (settings) -> _.extend @_settings, (_.pick settings, @_EDITABLE)
      _get: (prop) -> @_settings[prop] if prop in @_EDITABLE
      _getAll: -> _.clone @_settings

      # -- Public --

      # Show window with settings.
      show: ->
        # Serialize options
        opts = _.serialize @_getAll(), {sep: ',', eq: '='}, (v) ->
          switch v
            when false then 'no'
            when true then 'yes'
            else v+''

        @_window = window.open @url, @id, opts
        this

      # Hide the window.
      hide: ->
        @_window.close()
        @_window = null
        this

      # Reset window settings.
      reset: ->
        @_update Box::settings
        this

      # Return or update window position coords.
      position: (coords) ->
        # Set new coords
        if coords? then @_update
          left: coords[0] ? Box::settings.left  # x
          top:  coords[1] ? Box::settings.top   # y

        # Return coords
        [(@_get 'left'), (@_get 'top')]


Update thumbnail version table documentation

    Upload = require 's3-uploader'

Configure [s3-uploader](https://github.com/Turistforeningen/node-s3-uploader) to
store the following versions:

| Suffix    | Max Height | Max Width | Aspect Ratio |
|-----------|------------|-----------|--------------|
| `-full`   | `1200`     | `1200`    |              |
| `-800`    | `800`      | `800`     | `3:2`        |
| `-500`    | `500`      | `500`     | `3:2`        |
| `-260`    | `260`      | `260`     | `3:2`        |
| `-150`    | `150`      | `150`     | `3:2`        |

    module.exports = new Upload process.env.AWS_BUCKET_NAME,
      aws:
        region: process.env.AWS_BUCKET_REGION
        path: process.env.AWS_BUCKET_PATH
        acl: 'public-read'
        httpOptions: timeout: 60000

      returnExif: true

      cleanup:
        original: true
        versions: true

      original:
        awsImageAcl: 'private'

      versions: [
        suffix: '-full'
        quality: 80
        maxHeight: 1200
        maxWidth: 1200
      ,
        suffix: '-800'
        maxHeight: 800
        maxWidth: 800
        aspect: '3:2!h'
      ,
        suffix: '-500'
        maxHeight: 500
        maxWidth: 500
        aspect: '3:2!h'
      ,
        suffix: '-260'
        maxHeight: 260
        maxWidth: 260
        aspect: '3:2!h'
      ,
        suffix: '-150'
        maxHeight: 150
        maxWidth: 150
        aspect: '3:2!h'
      ]

    Upload = require 's3-uploader'

Configure [s3-uploader](https://github.com/Turistforeningen/node-s3-uploader) to
store the following versions:

| Suffix    | Max Height | Max Width | Aspect Ratio |
|-----------|------------|-----------|--------------|
| `-full`   | `1200`     | `1200`    |              |
| `-thumb`  | `250`      | `250`     | `1:1`        |
| `-800`    | `800`      | `800`     | `3:2`        |
| `-500`    | `500`      | `500`     | `3:2`        |
| `-260`    | `260`      | `260`     | `3:2`        |
| `-150`    | `150`      | `150`     | `3:2`        |

    module.exports = new Upload process.env.AWS_BUCKET_NAME,
      aws:
        region: process.env.AWS_BUCKET_REGION
        path: process.env.AWS_BUCKET_PATH
        acl: 'public-read'
        httpOptions: timeout: 60000

      returnExif: true

      cleanup:
        original: true
        versions: true

      original:
        awsImageAcl: 'private'

      versions: [
        suffix: '-full'
        quality: 80
        maxHeight: 1200
        maxWidth: 1200
      ,
        suffix: '-800'
        maxHeight: 800
        maxWidth: 800
        aspect: '3:2!h'
      ,
        suffix: '-500'
        maxHeight: 500
        maxWidth: 500
        aspect: '3:2!h'
      ,
        suffix: '-260'
        maxHeight: 260
        maxWidth: 260
        aspect: '3:2!h'
      ,
        suffix: '-150'
        maxHeight: 150
        maxWidth: 150
        aspect: '3:2!h'
      ]


Finish writing documentation.

Finish writing documentation.

Routing
=======
This file serves as the "glue" between the express router and sanity. Basically, we want a rails-esque routing system with all the routes declared in one location.  One advantage over rails, though, is that we're going to allow some degree of function composition in that we can declare multiple, reusable actions per-route, then let them pass the return value from one to the next.

This is done via unapologetic use of Promises.

##Libraries

    Promise = require 'bluebird'
    fs = Promise.promisifyAll require 'fs'
    _ = require 'lodash'

As a note, the `Promise.promisifyAll` function simply adds `Async` to the end of the methods in `fs` and subsequently allows Promises to be used instead of callbacks.

##Local Modules

    getControllers = require './getControllers'
    policies = require './policies'

Let's kickstart this router.

    module.exports = (app) ->

-----------

This grabs the controllers and returns back a promise'd object of them. It made more sense to put this in a separate file, since it'sarguably useful in its own right.

        getControllers()

Once we've gotten all the controllers, we'll move on

        .then (controllerObject) ->

Let's load in the routes file

            configuredRoutes = require '../config/routes'

Let's loop through the routes file and do the appropriate mapping.[1]
            _.each configuredRoutes, (totalString, route) ->

Routes are stored like METHOD /route, so we'll split on spaces. To make this a bit more dev-friendly, let's get rid of redundant spaces and newlines.

                [method, endpoint] = route
                             .replace /(?:\r\n|\r|\n)/g, ' '
                             .replace /\s\s+/g, ' '
                             .trim()
                             .split ' '

-----------

This bigass thing here is for dev-friendliness.  I don't want to punish people for separating controller calls to multiple lines if they want, and I don't want punish them for adding multiple spaces.  Subsequently, I replace newlines with a  space, then replace extra spaces down to one space, trim it, and split on the @ sign so I can make the dichotomy between application logic and error-handling logic. Utilizing Coffee's "multi-return" thing, I can set the values pretty cleanly, but not before I make sure the values are trimmed.

                [actionString, catchString] = totalString
                                  .replace /(?:\r\n|\r|\n)/g, ' '
                                  .replace /\s\s+/g, ' '
                                  .trim()
                                  .split '@'
                                  .map (i) -> do i.trim
-----------

Again, just make it cleaner, we'll utilize the "multi-return" thing coffeescript does. Since I don't want a hard requirement for a catch to exist, I will put a conditional to see if the catch is defined.

                [catchController,catchFunction] = catchString.split '.' if catchString?

If we have a catch defined, awesome, else we'll just feed in an empty function.

                catcher = controllerObject[catchController]?[catchFunction] || ->

Split the routes on a space so as to separate individual action handlers.

                allRoutes = actionString.split ' '

-------

Loop through all the actions that are provided for that route, look them up, return back the handles on the function. So as to save a "push" command we'll use a map

                actionHandles = _.map allRoutes, (a) ->

First we need to separate out the error handling stuff from the actual program, so let's split that out, and utilize the multi-return value feature of coffeescript.

                    [actionStuff, errorStuff] = a.split '!'

Since I don't want to make a hard requirement to provide an error-handler, let's put a put quick "if" at the end of this to make sure we have errorstuff to assign.

                    [errorController, errorAction] = errorStuff.split '.' if errorStuff?

Let's parse out the controller and action.

                    [myController, myAction] = actionStuff.split '.'

Now let's grab the appropriate stuff out of the controllers.

                    finalAction =  controllerObject[myController][myAction]
                    finalError = controllerObject[errorController]?[errorAction]

Since everything is parsed out, let's just wrap this in an object so as to easily pipe into the promises.

                    finalObject =
                        action: finalAction
                        error: finalError
                        controllerName: myController
                        actionName: myAction

Once everything is done, let's just return out of the map and move on.

                    return finalObject

The `wrapper` function.
-----------------------

This here is the glue that does the joining of the actual functions.  In a nutshell, when the request it made, it should run `wrapper`, which will loop through the functions that were returned by the previous map, and run them sequentially as part of the promise chain.  I would like to eventually add a mechanism in which to do this in parallel (instead of just sequentially) eventually.

                wrapper = (req, res) ->

We need to make sure the user is allowed to use everything that this route has to offer.  Due to the beauty of Bluebird, if this this trips up, it'll just kill the promise chain and make it so that we don't go any farther than we're allowed to.

                        authPromise = policies actionHandles, req, res

Once we've gotten all the handles on the functions we need to call, we can concat it to all previous promises. Afterwards we want these to run sequentially, so we use the reduce function to run them, then converge into a single, final promise.

                        finalPromise =
                            _.chain [authPromise]
                            .flatten()
                            .concat actionHandles
                            .reduce (cur, next) ->
                                cur.then next.action, next.error
                            .value()

Everything should be done.  We can finally render a template or return back JSON depending on what they did on that last function

                        finalPromise.then (endData) ->

What happens now is pretty simple.  A requirement for frameworkey is that you return an object with your data and the `renderType` property. From there it's pretty straightforward.

                            if endData.renderType.toLowerCase() == 'html'
                                # We used "toLowerCase" to make it more dev-friendly.
                                res.render endData.page
                            else if endData.renderType.toLowerCase() == 'json'
                                res.send endData.data

We'll use the global catch defined at the end of the actions to handle residual errors.  If there's an issue, we go here. We can default to an empty function if there's an issue.

                        finalPromise.catch catcher

As stated above, wrapper will return a new function based on what we send in for "allRoutes".  We're adding the "toLowerCase()" to make this a bit more dev-friendly.

                app[do method.toLowerCase] endpoint, wrapper

[1]: I *really* hate how the value comes before the key in Lodash

Routing
=======
This file serves as the "glue" between the express router and sanity. Basically, we want a rails-esque routing system with all the routes declared in one location.  One advantage over rails, though, is that we're going to allow some degree of function composition in that we can declare multiple, reusable actions per-route, then let them pass the return value from one to the next.

This is done via unapologetic use of Promises.

##Libraries
    Promise = require 'bluebird'
    fs = Promise.promisifyAll require 'fs'
    _ = require 'lodash'

##Local
    getControllers = require './getControllers'
    policies = require './policies'

    module.exports = (app) ->
        # This grabs the controllers and returns back a promise'd object of
        # them. It made more sense to put this in a separate file, since it's
        # arguably useful in its own right.
        getControllers()

        # Note, do this asynchronously. we'll load the controllers and policies
        # simultaneously.
        .then (controllerObject) ->
            console.log "sdafsd"

            #Let's load in the routes file
            configuredRoutes = require '../config/routes'

            # Let's loop through the routes file and do the appropriate mapping.
            # NOTE: I really hate that the value comes before the key.
            _.each configuredRoutes, (totalString, route) ->
                # routes are stored like METHOD /route, so we'll split on spaces.
                # To make this a bit more dev-friendly, let's get rid of redundant
                # spaces and newlines.
                [method, endpoint] = route
                             .replace /(?:\r\n|\r|\n)/g, ' '
                             .replace /\s\s+/g, ' '
                             .trim()
                             .split ' '

                # This bigass thing here is for dev-friendliness.  I don't want to punish people
                # for separating controller calls to multiple lines if they want, and I don't want
                # punish them for adding multiple spaces.  Subsequently, I replace newlines with a
                # space, then replace extra spaces down to one space, trim it, and split on the @
                # sign so I can make the dichotomy between application logic and error-handling logic.
                # Utilizing Coffee's "multi-return" thing, I can set the values pretty cleanly,
                # but not before I make sure the values are trimmed.
                [actionString, catchString] = totalString
                                  .replace /(?:\r\n|\r|\n)/g, ' '
                                  .replace /\s\s+/g, ' '
                                  .trim()
                                  .split '@'
                                  .map (i) -> do i.trim

                # Again, just make it cleaner, we'll utilize the "multi-return" thing coffeescript does.
                # Since I don't want a hard requirement for a catch to exist, I will put a conditional to
                # see if the catch is defined.
                [catchController,catchFunction] = catchString.split '.' if catchString?

                # If we have a catch defined, awesome, else we'll just feed in an empty function.
                catcher = controllerObject[catchController]?[catchFunction] || ->

                # Split the routes on a space so as to separate individual action handlers.
                allRoutes = actionString.split ' '

                # Loop through all the actions that are provided for that route,
                # look them up, return back the handles on the function.
                #
                # So as to save a "push" command we'll use a map
                actionHandles = _.map allRoutes, (a) ->
                    # First we need to separate out the error handling stuff from the
                    # actual program, so let's split that out, and utilize the multi-return
                    # value feature of coffeescript.
                    [actionStuff, errorStuff] = a.split '!'

                    # Since I don't want to make a hard requirement to provide an error-handler,
                    # Let's put a put quick "if" at the end of this to make sure we have errorstuff
                    # to assign.
                    [errorController, errorAction] = errorStuff.split '.' if errorStuff?

                    #Let's parse out the controller and action.
                    [myController, myAction] = actionStuff.split '.'

                    # Now let's grab the appropriate stuff out of the controllers.
                    finalAction =  controllerObject[myController][myAction]
                    finalError = controllerObject[errorController]?[errorAction]

                    # Since everything is parsed out, let's just wrap this in an object
                    # So as to easily pipe into the promises.
                    finalObject =
                        action: finalAction
                        error: finalError
                        controllerName: myController
                        actionName: myAction
                    return finalObject

                wrapper = (req, res) ->

                        # We need to make sure the user is allowed to use everything that
                        # this route has to offer.  Due to the beauty of Bluebird, if
                        # this this trips up, it'll just kill the promise chain and
                        # make it so that we don't go any farther than we're allowed to.
                        console.log "blah"
                        authPromise = policies actionHandles, req, res

                        # Once we've gotten all the handles on the functions we need
                        # to call, we can concat it to all previous promises. Afterwards
                        # we want these to run sequentially, so we use the reduce function
                        # to run them, then converge into a single, final promise.
                        finalPromise =
                            _.chain [authPromise]
                            .flatten()
                            .concat actionHandles
                            .reduce (cur, next) ->
                                cur.then next.action, next.error
                            .value()

                        # Everything should be done.  We can finally render a template
                        # or return back JSON depending on what they did on that last function
                        finalPromise.then (endData) ->

                            # If they want HTML, we'll give them HTML, gosh-darnit!
                            #
                            # We're using toLowerCase to make it a bit more dev-friendly
                            # in case they want to write html as HTML for some reason
                            if endData.renderType.toLowerCase() == 'html'
                                # End the request by rendering the jade template
                                res.render endData.page

                            # If they're making an API, let them make an api.
                            else if endData.renderType.toLowerCase() == 'json'
                                # end the request by sending back a status JSON
                                res.send endData.data

                        # We'll use the global catch defined at the end of the actions
                        # to handle residual errors.  If there's an issue, we go here.
                        # We can default to an empty function if there's an issue.
                        finalPromise.catch catcher

                # As stated above, wrapper will return a new function based on what
                # we send in for "allRoutes".  We're adding the "toLowerCase()" to make
                # this a bit more dev-friendly.
                console.log method
                app[do method.toLowerCase] endpoint, wrapper


added draw stub test

added draw stub test

# TEST CLASS: Shape
* Parent: [Index][Parent]

---

    should = require 'should'
    module.exports = (Shape, name='Shape') ->

      describe name, ->
        it 'should be a class', -> Shape.should.be.a.class

---

## CONSTRUCTOR

        describe '#constructor(args)', ->
          it 'should return an instance of Shape', ->
            (new Shape).should.be.an.instanceof Shape

Constructor should copy regions passed as named arguments into the instance

          it 'should copy the regions to the instance', ->
            shape = new Shape regions: (regions = test: (region = []))
            shape.regions.test.should.be.equal region
            shape.regions.should.not.be.equal regions

---

## METHODS

        describe '#getEventRegions', ->
          it 'should return the regions matching the event', ->
            shape = new Shape regions: test: [0,0,10,10]
            regions = shape.getEventRegions localX:5, localY:5
            regions.should.have.property 'test'
            regions.test[0].should.be.equal 0
            regions.test[1].should.be.equal 0
            regions.test[2].should.be.equal 10
            regions.test[3].should.be.equal 10

          it 'should return undefined if no regions match', ->
            shape = new Shape regions: test: [0,0,10,10]
            should(shape.getEventRegions localX:20, localY:20).not.be.ok

        describe '#draw', ->
          it 'should return the shape', ->
            (shape = new Shape).draw().should.be.equal shape

---

## LISTENERS

Mousemove capturing listener should store the event in the runtime
and localize the event coordinates.

        describe '#mousemoveCaptureListener', ->
          it 'should return the shape', ->
            (shape = new Shape)
              .mousemoveCaptureListener()
              .should.be.equal shape

---

Mousedown capturing listener should store the event in the runtime
and localize the event coordinates.

        describe '#mousedownCaptureListener', ->
          it 'should return the shape', ->
            (shape = new Shape)
              .mousedownCaptureListener()
              .should.be.equal shape

---

Mouseup capturing listener should store the event in the runtime
and localize the event coordinates.

        describe '#mouseupCaptureListener', ->
          it 'should return the shape', ->
            (shape = new Shape)
              .mouseupCaptureListener()
              .should.be.equal shape

[Shape#constructor]: ../shape.litcoffee#constructor
[Parent]: ./index.litcoffee

# TEST CLASS: Shape
* Parent: [Index][Parent]

---

    should = require 'should'
    module.exports = (Shape, name='Shape') ->

      describe name, ->
        it 'should be a class', -> Shape.should.be.a.class

---

## CONSTRUCTOR

        describe '#constructor(args)', ->
          it 'should return an instance of Shape', ->
            (new Shape).should.be.an.instanceof Shape

Constructor should copy regions passed as named arguments into the instance

          it 'should copy the regions to the instance', ->
            shape = new Shape regions: (regions = test: (region = []))
            shape.regions.test.should.be.equal region
            shape.regions.should.not.be.equal regions

---

## METHODS

        describe '#getEventRegions', ->
          it 'should return the regions matching the event', ->
            shape = new Shape regions: test: [0,0,10,10]
            regions = shape.getEventRegions localX:5, localY:5
            regions.should.have.property 'test'
            regions.test[0].should.be.equal 0
            regions.test[1].should.be.equal 0
            regions.test[2].should.be.equal 10
            regions.test[3].should.be.equal 10

          it 'should return undefined if no regions match', ->
            shape = new Shape regions: test: [0,0,10,10]
            should(shape.getEventRegions localX:20, localY:20).not.be.ok

---

## LISTENERS

Mousemove capturing listener should store the event in the runtime
and localize the event coordinates.

        describe '#mousemoveCaptureListener', ->
          it 'should return the shape', ->
            (shape = new Shape)
              .mousemoveCaptureListener()
              .should.be.equal shape

---

Mousedown capturing listener should store the event in the runtime
and localize the event coordinates.

        describe '#mousedownCaptureListener', ->
          it 'should return the shape', ->
            (shape = new Shape)
              .mousedownCaptureListener()
              .should.be.equal shape

---

Mouseup capturing listener should store the event in the runtime
and localize the event coordinates.

        describe '#mouseupCaptureListener', ->
          it 'should return the shape', ->
            (shape = new Shape)
              .mouseupCaptureListener()
              .should.be.equal shape

[Shape#constructor]: ../shape.litcoffee#constructor
[Parent]: ./index.litcoffee


Documention for encoders "as" option

Documention for encoders "as" option

# Batman.Model

For a general explanation of `Batman.Model` and how it works, see [the guide](/docs/models.html).

_Note_: This documentation uses the term _model_ to refer to the class `Model`
or a `Model` subclass, and the term _record_ to refer to one instance of a
model.

## @primaryKey : string

`primaryKey` is a class level configuration option to change which key batman.js uses as the primary key. Change the option using `set`, like so:

    test 'primary key can be set using @set', ->
      class Shop extends Batman.Model
        @set 'primaryKey', 'shop_id'

      equal Shop.get('primaryKey'), 'shop_id'

The `primaryKey` is what batman.js uses to compare instances to see if they represent the same domain-level object: if two records have the same value at the key specified by `primaryKey`, only one will be in the identity map. The key specified by `primaryKey` is also used by the associations system when determining if a record is related to another record, and by the remote storage adapters to generate URLs for records.

_Note_: The default primaryKey is 'id'.

## @storageKey : string

`storageKey` is a class level option which gives the storage adapters something to interpolate into their specific key generation schemes. In the case of `LocalStorage` or `SessionStorage` adapters, the `storageKey` defines what namespace to store this record under in the `localStorage` or `sessionStorage` host objects, and with the case of the `RestStorage` family of adapters, the `storageKey` assists in URL generation. See the documentation for the storage adapter of your choice for more information.

The default `storageKey` is `null`.

## @persist(mechanism : StorageAdapter) : StorageAdapter

`@persist` is how a `Model` subclass is told to persist itself by means of a `StorageAdapter`. `@persist` accepts either a `StorageAdapter` class or instance and will return either the instantiated class or the instance passed to it for further modification.

    test 'models can be told to persist via a storage adapter', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @persist TestStorageAdapter

      record = new Shop
      ok record.hasStorage()

    test '@persist returns the instantiated storage adapter', ->
      adapter = false
      class Shop extends Batman.Model
        @resourceName: 'shop'
        adapter = @persist TestStorageAdapter

      ok adapter instanceof Batman.StorageAdapter

    test '@persist accepts already instantiated storage adapters', ->
      adapter = new Batman.StorageAdapter
      adapter.someHandyConfigurationOption = true
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @persist adapter

      record = new Shop
      ok record.hasStorage()

## @encode(keys...[, encoderObject : [Object|Function]])

`@encode` specifies a list of `keys` a model should expect from and send back to a storage adapter, and any transforms to apply to those attributes as they enter and exit the world of batman.js in the optional `encoderObject`.

The `encoderObject` should have an `encode` and/or a `decode` key which point to functions. The functions accept the "raw" data (the batman.js land value in the case of `encode`, and the backend land value in the case of `decode`), and should return the data suitable for the other side of the link. The functions should have the following signatures:

    encoderObject = {
      encode: (value, key, builtJSON, record) ->
      decode: (value, key, incomingJSON, outgoingObject, record) ->
    }

By default these functions are the identity functions. They apply no transformation. The arguments for `encode` functions are as follows:

 + `value` is the client side value of the `key` on the `record`
 + `key` is the key which the `value` is stored under on the `record`. This is useful when passing the same `encoderObject` which needs to pivot on what key is being encoded to different calls to `encode`.
 + `builtJSON` is the object which is modified by each encoder which will eventually be returned by `toJSON`.
 + `record` is the record on which `toJSON` has been called.

For `decode` functions:

 + `value` is the raw value of the `key` which will end up on the `record`.
 + `key` is the key which the `value` is stored under in the incoming JSON.
 + `incomingJSON` is the JSON which is being decoded into the `record`. This can be used to create compound key decoders.
 + `outgoingObject` is the object which is built up by the decoders and then `mixin`'d to the record.
 + `record` is the record on which `fromJSON` has been called.

The `encode` and `decode` keys can also be false to avoid using the default identity function encoder or decoder.

To encode a `key` under a name which differs from that in the raw data, you can specify the `as` option with its raw key name. The `as` option can be either a string or function.

If you specify the `as` option as a function it will have the following arguments:

 + `key` is the name which the `value` is stored under in the raw data.
 + `value` is the `value` of the `key` which will end up on the `record`.
 + `data` is the object which is modified by each encoder or decoder.
 + `record` is the record on which `toJSON` or `fromJSON` has been called.

_Note_: `Batman.Model` subclasses have no encoders by default, except for one which automatically decodes the `primaryKey` of the model, which is usually `id`. To get any data into or out of your model, you must white-list the keys you expect from the server or storage attribute.

    test '@encode accepts a list of keys which are used during decoding', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', 'url', 'email', 'country'

      json = {name: "Snowdevil", url: "snowdevil.ca"}
      record = new Shop()
      record.fromJSON(json)
      equal record.get('name'), "Snowdevil"

    test '@encode accepts a list of keys which are used during encoding', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', 'url', 'email', 'country'

      record = new Shop(name: "Snowdevil", url: "snowdevil.ca")
      deepEqual record.toJSON(), {name: "Snowdevil", url: "snowdevil.ca"}

    test '@encode accepts custom encoders', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name',
          encode: (name) -> name.toUpperCase()

      record = new Shop(name: "Snowdevil")
      deepEqual record.toJSON(), {name: "SNOWDEVIL"}

    test '@encode accepts custom decoders', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name',
          decode: (name) -> name.replace('_', ' ')

      record = new Shop()
      record.fromJSON {name: "Snow_devil"}
      equal record.get('name'), "Snow devil"

    test '@encode can be passed an encoderObject with false to prevent the default encoder or decoder', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', {encode: false, decode: (x) -> x}
        @encode 'url'

      record = new Shop()
      record.fromJSON {name: "Snowdevil", url: "snowdevil.ca"}
      equal record.get('name'), 'Snowdevil'
      equal record.get('url'), "snowdevil.ca"
      deepEqual record.toJSON(), {url: "snowdevil.ca"}, 'The name key is absent because of encode: false'

    test '@encode accepts an as option to encode a key under a name which differs from that in the raw data', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'countryCode',
          as: 'country_code'
          encode: @defaultEncoder.encode
          decode: @defaultEncoder.decode

      record = new Shop(countryCode: 'SE')
      deepEqual record.toJSON(), {country_code: 'SE'}

Some more handy examples:

    test '@encode can be used to turn comma separated values into arrays', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'tags',
          decode: (string) -> string.split(', ')
          encode: (array) -> array.join(', ')

      record = new Post()
      record.fromJSON({tags: 'new, hot, cool'})
      deepEqual record.get('tags'), ['new', 'hot', 'cool']
      deepEqual record.toJSON(), {tags: 'new, hot, cool'}

    test '@encode can be used to turn arrays into sets', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'tags',
          decode: (array) -> new Batman.Set(array...)
          encode: (set) -> set.toArray()

      record = new Post()
      record.fromJSON({tags: ['new', 'hot', 'cool']})
      ok record.get('tags') instanceof Batman.Set
      deepEqual record.toJSON(), {tags: ['new', 'hot', 'cool']}

    test '@encode accepts the as option as a function', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'countryCode',
          as: (key) -> Batman.helpers.underscore(key)
          encode: @defaultEncoder.encode
          decode: @defaultEncoder.decode

      record = new Shop(countryCode: 'SE')
      deepEqual record.toJSON(), {country_code: 'SE'}

## @validate(keys...[, options : [Object|Function]])

Validations allow a model to be marked as `valid` or `invalid` based on a set of programmatic rules. By validating a model's data before it gets to the server we can provide immediate feedback to the user about what they have entered and forgo waiting on a round trip to the server. `validate` allows the attachment of validations to the model on particular keys, where the validation is either a built in one (invoked by use of options to pass to them) or a custom one (invoked by use of a custom function as the second argument).

_Note_: Validation in batman.js is always asynchronous, despite the fact that none of the validations may use an asynchronous operation to check for validity. This is so that the API is consistent regardless of the validations used.

Built in validators are attached by calling `@validate` with options designating how to calculate the validity of the key:

    test '@validate accepts options to check for validity', ->
      QUnit.expect(0)
      class Post extends Batman.Model
        @resourceName: 'post'
        @validate 'title', 'body', {presence: true}

The built in validation options are listed below:

 + `presence : boolean`: Assert that the string value is existent (not undefined or null) and has length greater than 0.
 + `numeric : true`: Assert that the value is or can be coerced into a number using `parseFloat`.
 + `greaterThan : number`: Assert that the value is greater than the given number.
 + `greaterThanOrEqualTo : number`: Assert that the value is greater than or equal to the given number.
 + `equalTo : number`: Assert that the value is equal to the given number.
 + `lessThan : number`: Assert that the value is less than the given number.
 + `lessThanOrEqualTo : number`: Assert that the value is less than or equal to the given number.
 + `minLength : number`: Assert that the value's `length` property is greater than the given number.
 + `maxLength : number`: Assert that the value's `length` property is less than the given number.
 + `length : number`: Assert that the value's `length` property is exactly the given number.
 + `lengthWithin : [number, number]` or `lengthIn : [number, number]`: Assert that the value's `length` property is within the ranger specified by the given array of two numbers, where the first number is the lower bound and the second number is the upper bound.
 + `inclusion : in : [list, of, acceptable, values]`: Assert that the value is equal to one of the values in an array.
 + `exclusion : in : [list, of, unacceptable, values]`: Assert that the value is not equal to any of the values in an array.

Custom validators should have the signature `(errors, record, key, callback)`. The arguments are as follows:

 + `errors`: an `ErrorsSet` instance which expects to have `add` called on it to add errors to the model
 + `record`: the record being validated
 + `key`: the key to which the validation has been attached
 + `callback`: a function to call once validation has been completed. Calling this function is __mandatory__.

See [`Model::validate`](/docs/api/batman.model.html#prototype_function_validate) for information on how to get a particular record's validity.

## @loaded : Set

The `loaded` set is available on every model class and holds every model instance seen by the system in order to function as an identity map. Successfully loading or saving individual records or batches of records will result in those records being added to the `loaded` set. Destroying instances will remove records from the identity set.

    test 'the loaded set stores all records seen', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @persist TestStorageAdapter
        @encode 'name'

      ok Post.get('loaded') instanceof Batman.Set
      equal Post.get('loaded.length'), 0
      post = new Post()
      post.save()
      equal Post.get('loaded.length'), 1

    test 'the loaded adds new records caused by loads and removes records caused by destroys', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new TestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}

      Post.persist(adapter)
      Post.load()
      equal Post.get('loaded.length'), 2
      post = false
      Post.find(1, (err, result) -> post = result)
      post.destroy()
      equal Post.get('loaded.length'), 1

## @all : Set

The `all` set is an alias to the `loaded` set but with an added implicit `load` on the model. `Model.get('all')` will synchronously return the `loaded` set and asynchronously call `Model.load()` without options to load a batch of records and populate the set originally returned (the `loaded` set) with the records returned by the server.

_Note_: The notion of "all the records" is relative only to the client. It completely depends on the storage adapter in use and any backends which they may contact to determine what comes back during a `Model.load`. This means that if for example your API paginates records, the set found in `all` may hold on the first 50 records instead of the entire backend set.

`all` is useful for listing every instance of a model in a view, and since the `loaded` set will change when the `load` returns, it can be safely bound to.

    asyncTest 'the all set asynchronously fetches records when gotten', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new AsyncTestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}

      Post.persist(adapter)
      equal Post.get('all.length'), 0, "The synchronously returned set is empty"
      delay ->
        equal Post.get('all.length'), 2, "After the async load the set is populated"

## @clear() : Set

`Model.clear()` empties that `Model`'s identity map. This is useful for tests and other unnatural situations where records new to the system are guaranteed to be as such.

    test 'clearing a model removes all records from the identity map', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new TestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}
      Post.persist(adapter)
      Post.load()
      equal Post.get('loaded.length'), 2
      Post.clear()
      equal Post.get('loaded.length'), 0, "After clear() the loaded set is empty"

## @find(id, callback : Function) : Model

`Model.find()` retrieves a record with the specified `id` from the storage adapter and calls back with an error if one occurred and the record if the operation was successful. `find` delegates to the storage adapter the `Model` has been `@persist`ed with, so it is up to the storage adapter's semantics to determine what type of errors may return and the timeline on which the callback may be called. The `callback` is a required function which should adopt the node style callback signature which accepts two arguments: an error, and the record asked for. `find` returns an "unloaded" record which, following the load completion, will be populated with the data from the storage adapter.

_Note_: `find` gives two results to calling code: one immediately, and one later. `find` returns a record synchronously as it is called and calls back with a record, and importantly these two records are __not__ guaranteed to be the same instance. This is because batman.js maps the identities of incoming and outgoing records such that there is only ever one canonical instance representing a record, which is useful so bindings are always bound to the same thing. In practice, this means that calling code should use the record `find` calls back with if anything is going to bind to that object, which is most of the time. The returned record however remains useful for state inspection and bookkeeping.

    asyncTest '@find calls back the requested model if no error occurs', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist AsyncTestStorageAdapter,
          storage:
            'posts2': {name: "Two", id:2}

      post = Post.find 2, (err, result) ->
        throw err if err
        post = result
      equal post.get('name'), undefined
      delay ->
        equal post.get('name'), "Two"

_Note_: `find` must be passed a callback function. This is for two reasons: calling code must be aware that `find`'s return value is not necessarily the canonical instance, and calling code must be able to handle errors.

    asyncTest '@find calls back with the error if an error occurs', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist AsyncTestStorageAdapter

      error = false
      post = Post.find 3, (err, result) ->
        error = err
      delay ->
        ok error instanceof Error

## @load(options = {}, callback : Function)

`Model.load()` retrieves an array of records according to the given `options` from the storage adapter and calls back with an error if one occurred and the set of records if the operation was successful. `load` delegates to the storage adapter the `Model` has been `@persist`ed with, so it is up to the storage adapter's semantics to determine what the options do, what kind of errors may arise, and the timeline on which the callback may be called. The `callback` is a required function which should adopt the node style callback signature which accepts two arguments, an error, and the array of records. `load` returns undefined.

For the two main `StorageAdapter`s batman.js provides, the `options` do different things:

- For `Batman.LocalStorage`, `options` act as a filter. The adapter will scan all the records in `localStorage` and return only those records which match all the key/value pairs given in the options.
- For `Batman.RestStorage`, `options` are serialized into query parameters on the `GET` request.

It accepts a callback with two arguments: any error that occurred, and an array of loaded records.

    asyncTest '@load calls back an array of records retrieved from the storage adapter', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist TestStorageAdapter,
          storage:
            'posts1': {name: "One", id:1}
            'posts2': {name: "Two", id:2}

      posts = false
      Post.load (err, result) ->
        throw err if err
        posts = result

      delay ->
        equal posts.length, 2
        equal posts[0].get('name'), "One"

    asyncTest '@load calls back with an empty array if no records are found', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist TestStorageAdapter, storage: []

      posts = false
      Post.load (err, result) ->
        throw err if err
        posts = result

      delay ->
        equal posts.length, 0

## @create(attributes = {}, callback) : Model

## @findOrCreate(attributes = {}, callback) : Model

## id : value

## dirtyKeys : Set

## ::%errors : Batman.ErrorsSet

`errors` is a `Batman.ErrorsSet`, which is simply a `Batman.Set` of [`Batman.ValidationError`](/docs/api/batman.validationerror.html)s present on the model instance.

- `user.get('errors')` returns the errors on the `user` record
- `user.get('errors.length')` returns the number of errors, total

You can also access the errors for a specific attribute of the record:

- `user.get('errors.email_address')` returns the errors on the `email_address` attribute
- `user.get('errors.email_address.length')` returns the number of errors on the `email_address` attribute

## constructor(idOrAttributes = {}) : Model

## ::isNew() : boolean
Returns whether or not the instance represents a record that hasn't yet been persisted to the server. The default implementation simply checks if `@get('id')` is undefined, but you could override this on your own models.

It is used to determine whether `record.save()` will perform a `create` action or a `save` action.

## updateAttributes(attributes) : Model

## toString() : string

## ::toJSON() : Object

Returns a JavaScript object containing the attributes of the record, using any specified encoders.

    test "toJSON returns a JavaScript object with the record's attributes", ->
      class Criminal extends Batman.Model
        @encode "name", "notorious"

      criminal = new Criminal(name: "Talia al Ghul", notorious: true)
      criminal_json = criminal.toJSON()
      equal criminal_json.name, "Talia al Ghul"
      equal criminal_json.notorious, true

## ::fromJSON() : Model

Reloads attributes of a record from a JavaScript object.

    test 'fromJSON overwrites existing attributes', ->
      class Criminal extends Batman.Model
        @encode "name", "notorious"

      criminal = new Criminal(name: "Dr. Jonathan Crane", notorious: false)
      new_params =
        name: "Scarecrow"
        notorious: true
      criminal.fromJSON(new_params)

      equal criminal.get("notorious"), true
      equal criminal.get("name"), "Scarecrow"

## toParam() : value

## state() : string

## hasStorage() : boolean

## ::load(options = {}, callback)
`Load` tries to read the record from its storage adapter. The options object will be passed to the storage adapter when it performs the `read` operation. The callback takes three parameters: error, the loaded record, and the environment. `Load`ing a record clears all errors on that record.

If the read operation fails or if the record is in a state which doesn't permit `load`, (for example, calling `load` on a deleted record) the callback will be invoked with an error.

## ::save(options = {}, callback)
`Save` [validates](http://localhost:4000/docs/api/batman.model.html#prototype_function_validate) the record, and if it passes, fires the corresponding storage operation (defined by the `Batman.StorageAdapter` passed to  [`@persist`](/docs/api/batman.model.html#class_function_persist)). When the storage operation is complete, the callback is invoked with two parameters: any JavaScript error and the record.

If the record [`isNew`](/docs/api/batman.model.html#prototype_function_isnew), `save` performs a `create` operation. Otherwise, it performs a `save` operation.

If the record is not valid, the [validation errors](/docs/api/batman.validationerror.html) will be passed to the first parameter of the callback function and the storage operation will not be performed.

## ::destroy(options = {}, callback)

`Destroy` fires the corresponding storage operation. The callback takes three arguments: JavaScript Error, the record, and the environment. If the operation is successful, the record is removed from its Model's [`loaded`](/docs/api/batman.model.html#class_function_loaded) set.

```coffeescript
criminal = new Criminal name: "The penguin"
criminal.destroy (err, record, env) ->
  if err
    console.log "Oh no! #{record.get('name')} is still on the loose!"
```

If the record's current lifecycle state doesn't allow the `destroy` action, the callback will be invoked with a `Batman.StateMachine.InvalidTransitionError`. For example, this could occur if `destroy` is called on an already-destroyed record.

## ::validate(callback)

`Model::validate` checks the model against the validations declared in the model definition (with [`Model@validate`](/docs/api/batman.model.html#class_function_validate)). This method accepts a callback with two arguments: any JS error that occurred within the validator function, and the set of [`Batman.ValidationError`](/docs/api/batman.validationerror.html)s that the input generated.

For example:

    test "validate(callback) will call the callback only after all keys have been validated", ->
      class Product extends Batman.Model
        @validate 'name', 'price', presence: yes

      newProduct = new Product
      newProduct.validate (javascriptError, validationErrors) ->
        throw javascriptError if javascriptError
        equal validationErrors.length, 2
        equal newProduct.get('errors.length'), 2
        equal newProduct.get('errors.name.length'), 1
        equal newProduct.get('errors.price.length'), 1

# Batman.ValidationError

`Batman.ValidationError`s represent a failure for a model's field to to pass validation.
They are usually accessed by getting a model's [errors](/docs/api/batman.model.html#prototype_accessor_errors).

## ::%fullMessage

Returns the human-readable attribute name and the validation message:

    test "ValidationError should humanize attribute in the full message", ->
      error = new Batman.ValidationError("fooBarBaz", "isn't valid")
      equal error.get('fullMessage'), "Foo bar baz isn't valid"

# Batman.Model

For a general explanation of `Batman.Model` and how it works, see [the guide](/docs/models.html).

_Note_: This documentation uses the term _model_ to refer to the class `Model`
or a `Model` subclass, and the term _record_ to refer to one instance of a
model.

## @primaryKey : string

`primaryKey` is a class level configuration option to change which key batman.js uses as the primary key. Change the option using `set`, like so:

    test 'primary key can be set using @set', ->
      class Shop extends Batman.Model
        @set 'primaryKey', 'shop_id'

      equal Shop.get('primaryKey'), 'shop_id'

The `primaryKey` is what batman.js uses to compare instances to see if they represent the same domain-level object: if two records have the same value at the key specified by `primaryKey`, only one will be in the identity map. The key specified by `primaryKey` is also used by the associations system when determining if a record is related to another record, and by the remote storage adapters to generate URLs for records.

_Note_: The default primaryKey is 'id'.

## @storageKey : string

`storageKey` is a class level option which gives the storage adapters something to interpolate into their specific key generation schemes. In the case of `LocalStorage` or `SessionStorage` adapters, the `storageKey` defines what namespace to store this record under in the `localStorage` or `sessionStorage` host objects, and with the case of the `RestStorage` family of adapters, the `storageKey` assists in URL generation. See the documentation for the storage adapter of your choice for more information.

The default `storageKey` is `null`.

## @persist(mechanism : StorageAdapter) : StorageAdapter

`@persist` is how a `Model` subclass is told to persist itself by means of a `StorageAdapter`. `@persist` accepts either a `StorageAdapter` class or instance and will return either the instantiated class or the instance passed to it for further modification.

    test 'models can be told to persist via a storage adapter', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @persist TestStorageAdapter

      record = new Shop
      ok record.hasStorage()

    test '@persist returns the instantiated storage adapter', ->
      adapter = false
      class Shop extends Batman.Model
        @resourceName: 'shop'
        adapter = @persist TestStorageAdapter

      ok adapter instanceof Batman.StorageAdapter

    test '@persist accepts already instantiated storage adapters', ->
      adapter = new Batman.StorageAdapter
      adapter.someHandyConfigurationOption = true
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @persist adapter

      record = new Shop
      ok record.hasStorage()

## @encode(keys...[, encoderObject : [Object|Function]])

`@encode` specifies a list of `keys` a model should expect from and send back to a storage adapter, and any transforms to apply to those attributes as they enter and exit the world of batman.js in the optional `encoderObject`.

The `encoderObject` should have an `encode` and/or a `decode` key which point to functions. The functions accept the "raw" data (the batman.js land value in the case of `encode`, and the backend land value in the case of `decode`), and should return the data suitable for the other side of the link. The functions should have the following signatures:

    encoderObject = {
      encode: (value, key, builtJSON, record) ->
      decode: (value, key, incomingJSON, outgoingObject, record) ->
    }

By default these functions are the identity functions. They apply no transformation. The arguments for `encode` functions are as follows:

 + `value` is the client side value of the `key` on the `record`
 + `key` is the key which the `value` is stored under on the `record`. This is useful when passing the same `encoderObject` which needs to pivot on what key is being encoded to different calls to `encode`.
 + `builtJSON` is the object which is modified by each encoder which will eventually be returned by `toJSON`. To send the server the encoded value under a different key than the `key`, modify this object by putting the value under the desired key, and return `undefined`.
 + `record` is the record on which `toJSON` has been called.

For `decode` functions:

 + `value` is the server side value of the `key` which will end up on the `record`.
 + `key` is the key which the `value` is stored under in the incoming JSON.
 + `incomingJSON` is the JSON which is being decoded into the `record`. This can be used to create compound key decoders.
 + `outgoingObject` is the object which is built up by the decoders and then `mixin`'d to the record.
 + `record` is the record on which `fromJSON` has been called.

The `encode` and `decode` keys can also be false to avoid using the default identity function encoder or decoder.

_Note_: `Batman.Model` subclasses have no encoders by default, except for one which automatically decodes the `primaryKey` of the model, which is usually `id`. To get any data into or out of your model, you must white-list the keys you expect from the server or storage attribute.

    test '@encode accepts a list of keys which are used during decoding', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', 'url', 'email', 'country'

      json = {name: "Snowdevil", url: "snowdevil.ca"}
      record = new Shop()
      record.fromJSON(json)
      equal record.get('name'), "Snowdevil"

    test '@encode accepts a list of keys which are used during encoding', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', 'url', 'email', 'country'

      record = new Shop(name: "Snowdevil", url: "snowdevil.ca")
      deepEqual record.toJSON(), {name: "Snowdevil", url: "snowdevil.ca"}

    test '@encode accepts custom encoders', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name',
          encode: (name) -> name.toUpperCase()

      record = new Shop(name: "Snowdevil")
      deepEqual record.toJSON(), {name: "SNOWDEVIL"}

    test '@encode accepts custom decoders', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name',
          decode: (name) -> name.replace('_', ' ')

      record = new Shop()
      record.fromJSON {name: "Snow_devil"}
      equal record.get('name'), "Snow devil"

    test '@encode can be passed an encoderObject with false to prevent the default encoder or decoder', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', {encode: false, decode: (x) -> x}
        @encode 'url'

      record = new Shop()
      record.fromJSON {name: "Snowdevil", url: "snowdevil.ca"}
      equal record.get('name'), 'Snowdevil'
      equal record.get('url'), "snowdevil.ca"
      deepEqual record.toJSON(), {url: "snowdevil.ca"}, 'The name key is absent because of encode: false'

Some more handy examples:

    test '@encode can be used to turn comma separated values into arrays', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'tags',
          decode: (string) -> string.split(', ')
          encode: (array) -> array.join(', ')

      record = new Post()
      record.fromJSON({tags: 'new, hot, cool'})
      deepEqual record.get('tags'), ['new', 'hot', 'cool']
      deepEqual record.toJSON(), {tags: 'new, hot, cool'}

    test '@encode can be used to turn arrays into sets', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'tags',
          decode: (array) -> new Batman.Set(array...)
          encode: (set) -> set.toArray()

      record = new Post()
      record.fromJSON({tags: ['new', 'hot', 'cool']})
      ok record.get('tags') instanceof Batman.Set
      deepEqual record.toJSON(), {tags: ['new', 'hot', 'cool']}

## @validate(keys...[, options : [Object|Function]])

Validations allow a model to be marked as `valid` or `invalid` based on a set of programmatic rules. By validating a model's data before it gets to the server we can provide immediate feedback to the user about what they have entered and forgo waiting on a round trip to the server. `validate` allows the attachment of validations to the model on particular keys, where the validation is either a built in one (invoked by use of options to pass to them) or a custom one (invoked by use of a custom function as the second argument).

_Note_: Validation in batman.js is always asynchronous, despite the fact that none of the validations may use an asynchronous operation to check for validity. This is so that the API is consistent regardless of the validations used.

Built in validators are attached by calling `@validate` with options designating how to calculate the validity of the key:

    test '@validate accepts options to check for validity', ->
      QUnit.expect(0)
      class Post extends Batman.Model
        @resourceName: 'post'
        @validate 'title', 'body', {presence: true}

The built in validation options are listed below:

 + `presence : boolean`: Assert that the string value is existent (not undefined or null) and has length greater than 0.
 + `numeric : true`: Assert that the value is or can be coerced into a number using `parseFloat`.
 + `greaterThan : number`: Assert that the value is greater than the given number.
 + `greaterThanOrEqualTo : number`: Assert that the value is greater than or equal to the given number.
 + `equalTo : number`: Assert that the value is equal to the given number.
 + `lessThan : number`: Assert that the value is less than the given number.
 + `lessThanOrEqualTo : number`: Assert that the value is less than or equal to the given number.
 + `minLength : number`: Assert that the value's `length` property is greater than the given number.
 + `maxLength : number`: Assert that the value's `length` property is less than the given number.
 + `length : number`: Assert that the value's `length` property is exactly the given number.
 + `lengthWithin : [number, number]` or `lengthIn : [number, number]`: Assert that the value's `length` property is within the ranger specified by the given array of two numbers, where the first number is the lower bound and the second number is the upper bound.
 + `inclusion : in : [list, of, acceptable, values]`: Assert that the value is equal to one of the values in an array.
 + `exclusion : in : [list, of, unacceptable, values]`: Assert that the value is not equal to any of the values in an array.

Custom validators should have the signature `(errors, record, key, callback)`. The arguments are as follows:

 + `errors`: an `ErrorsSet` instance which expects to have `add` called on it to add errors to the model
 + `record`: the record being validated
 + `key`: the key to which the validation has been attached
 + `callback`: a function to call once validation has been completed. Calling this function is __mandatory__.

See [`Model::validate`](/docs/api/batman.model.html#prototype_function_validate) for information on how to get a particular record's validity.

## @loaded : Set

The `loaded` set is available on every model class and holds every model instance seen by the system in order to function as an identity map. Successfully loading or saving individual records or batches of records will result in those records being added to the `loaded` set. Destroying instances will remove records from the identity set.

    test 'the loaded set stores all records seen', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @persist TestStorageAdapter
        @encode 'name'

      ok Post.get('loaded') instanceof Batman.Set
      equal Post.get('loaded.length'), 0
      post = new Post()
      post.save()
      equal Post.get('loaded.length'), 1

    test 'the loaded adds new records caused by loads and removes records caused by destroys', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new TestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}

      Post.persist(adapter)
      Post.load()
      equal Post.get('loaded.length'), 2
      post = false
      Post.find(1, (err, result) -> post = result)
      post.destroy()
      equal Post.get('loaded.length'), 1

## @all : Set

The `all` set is an alias to the `loaded` set but with an added implicit `load` on the model. `Model.get('all')` will synchronously return the `loaded` set and asynchronously call `Model.load()` without options to load a batch of records and populate the set originally returned (the `loaded` set) with the records returned by the server.

_Note_: The notion of "all the records" is relative only to the client. It completely depends on the storage adapter in use and any backends which they may contact to determine what comes back during a `Model.load`. This means that if for example your API paginates records, the set found in `all` may hold on the first 50 records instead of the entire backend set.

`all` is useful for listing every instance of a model in a view, and since the `loaded` set will change when the `load` returns, it can be safely bound to.

    asyncTest 'the all set asynchronously fetches records when gotten', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new AsyncTestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}

      Post.persist(adapter)
      equal Post.get('all.length'), 0, "The synchronously returned set is empty"
      delay ->
        equal Post.get('all.length'), 2, "After the async load the set is populated"

## @clear() : Set

`Model.clear()` empties that `Model`'s identity map. This is useful for tests and other unnatural situations where records new to the system are guaranteed to be as such.

    test 'clearing a model removes all records from the identity map', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new TestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}
      Post.persist(adapter)
      Post.load()
      equal Post.get('loaded.length'), 2
      Post.clear()
      equal Post.get('loaded.length'), 0, "After clear() the loaded set is empty"

## @find(id, callback : Function) : Model

`Model.find()` retrieves a record with the specified `id` from the storage adapter and calls back with an error if one occurred and the record if the operation was successful. `find` delegates to the storage adapter the `Model` has been `@persist`ed with, so it is up to the storage adapter's semantics to determine what type of errors may return and the timeline on which the callback may be called. The `callback` is a required function which should adopt the node style callback signature which accepts two arguments: an error, and the record asked for. `find` returns an "unloaded" record which, following the load completion, will be populated with the data from the storage adapter.

_Note_: `find` gives two results to calling code: one immediately, and one later. `find` returns a record synchronously as it is called and calls back with a record, and importantly these two records are __not__ guaranteed to be the same instance. This is because batman.js maps the identities of incoming and outgoing records such that there is only ever one canonical instance representing a record, which is useful so bindings are always bound to the same thing. In practice, this means that calling code should use the record `find` calls back with if anything is going to bind to that object, which is most of the time. The returned record however remains useful for state inspection and bookkeeping.

    asyncTest '@find calls back the requested model if no error occurs', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist AsyncTestStorageAdapter,
          storage:
            'posts2': {name: "Two", id:2}

      post = Post.find 2, (err, result) ->
        throw err if err
        post = result
      equal post.get('name'), undefined
      delay ->
        equal post.get('name'), "Two"

_Note_: `find` must be passed a callback function. This is for two reasons: calling code must be aware that `find`'s return value is not necessarily the canonical instance, and calling code must be able to handle errors.

    asyncTest '@find calls back with the error if an error occurs', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist AsyncTestStorageAdapter

      error = false
      post = Post.find 3, (err, result) ->
        error = err
      delay ->
        ok error instanceof Error

## @load(options = {}, callback : Function)

`Model.load()` retrieves an array of records according to the given `options` from the storage adapter and calls back with an error if one occurred and the set of records if the operation was successful. `load` delegates to the storage adapter the `Model` has been `@persist`ed with, so it is up to the storage adapter's semantics to determine what the options do, what kind of errors may arise, and the timeline on which the callback may be called. The `callback` is a required function which should adopt the node style callback signature which accepts two arguments, an error, and the array of records. `load` returns undefined.

For the two main `StorageAdapter`s batman.js provides, the `options` do different things:

- For `Batman.LocalStorage`, `options` act as a filter. The adapter will scan all the records in `localStorage` and return only those records which match all the key/value pairs given in the options.
- For `Batman.RestStorage`, `options` are serialized into query parameters on the `GET` request.

It accepts a callback with two arguments: any error that occurred, and an array of loaded records.

    asyncTest '@load calls back an array of records retrieved from the storage adapter', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist TestStorageAdapter,
          storage:
            'posts1': {name: "One", id:1}
            'posts2': {name: "Two", id:2}

      posts = false
      Post.load (err, result) ->
        throw err if err
        posts = result

      delay ->
        equal posts.length, 2
        equal posts[0].get('name'), "One"

    asyncTest '@load calls back with an empty array if no records are found', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist TestStorageAdapter, storage: []

      posts = false
      Post.load (err, result) ->
        throw err if err
        posts = result

      delay ->
        equal posts.length, 0

## @create(attributes = {}, callback) : Model

## @findOrCreate(attributes = {}, callback) : Model

## id : value

## dirtyKeys : Set

## ::%errors : Batman.ErrorsSet

`errors` is a `Batman.ErrorsSet`, which is simply a `Batman.Set` of [`Batman.ValidationError`](/docs/api/batman.validationerror.html)s present on the model instance.

- `user.get('errors')` returns the errors on the `user` record
- `user.get('errors.length')` returns the number of errors, total

You can also access the errors for a specific attribute of the record:

- `user.get('errors.email_address')` returns the errors on the `email_address` attribute
- `user.get('errors.email_address.length')` returns the number of errors on the `email_address` attribute

## constructor(idOrAttributes = {}) : Model

## ::isNew() : boolean
Returns whether or not the instance represents a record that hasn't yet been persisted to the server. The default implementation simply checks if `@get('id')` is undefined, but you could override this on your own models.

It is used to determine whether `record.save()` will perform a `create` action or a `save` action.

## updateAttributes(attributes) : Model

## toString() : string

## ::toJSON() : Object

Returns a JavaScript object containing the attributes of the record, using any specified encoders.

    test "toJSON returns a JavaScript object with the record's attributes", ->
      class Criminal extends Batman.Model
        @encode "name", "notorious"

      criminal = new Criminal(name: "Talia al Ghul", notorious: true)
      criminal_json = criminal.toJSON()
      equal criminal_json.name, "Talia al Ghul"
      equal criminal_json.notorious, true

## ::fromJSON() : Model

Reloads attributes of a record from a JavaScript object.

    test 'fromJSON overwrites existing attributes', ->
      class Criminal extends Batman.Model
        @encode "name", "notorious"

      criminal = new Criminal(name: "Dr. Jonathan Crane", notorious: false)
      new_params =
        name: "Scarecrow"
        notorious: true
      criminal.fromJSON(new_params)

      equal criminal.get("notorious"), true
      equal criminal.get("name"), "Scarecrow"

## toParam() : value

## state() : string

## hasStorage() : boolean

## ::load(options = {}, callback)
`Load` tries to read the record from its storage adapter. The options object will be passed to the storage adapter when it performs the `read` operation. The callback takes three parameters: error, the loaded record, and the environment. `Load`ing a record clears all errors on that record.

If the read operation fails or if the record is in a state which doesn't permit `load`, (for example, calling `load` on a deleted record) the callback will be invoked with an error.

## ::save(options = {}, callback)
`Save` [validates](http://localhost:4000/docs/api/batman.model.html#prototype_function_validate) the record, and if it passes, fires the corresponding storage operation (defined by the `Batman.StorageAdapter` passed to  [`@persist`](/docs/api/batman.model.html#class_function_persist)). When the storage operation is complete, the callback is invoked with two parameters: any JavaScript error and the record.

If the record [`isNew`](/docs/api/batman.model.html#prototype_function_isnew), `save` performs a `create` operation. Otherwise, it performs a `save` operation.

If the record is not valid, the [validation errors](/docs/api/batman.validationerror.html) will be passed to the first parameter of the callback function and the storage operation will not be performed.

## ::destroy(options = {}, callback)

`Destroy` fires the corresponding storage operation. The callback takes three arguments: JavaScript Error, the record, and the environment. If the operation is successful, the record is removed from its Model's [`loaded`](/docs/api/batman.model.html#class_function_loaded) set.

```coffeescript
criminal = new Criminal name: "The penguin"
criminal.destroy (err, record, env) ->
  if err
    console.log "Oh no! #{record.get('name')} is still on the loose!"
```

If the record's current lifecycle state doesn't allow the `destroy` action, the callback will be invoked with a `Batman.StateMachine.InvalidTransitionError`. For example, this could occur if `destroy` is called on an already-destroyed record.

## ::validate(callback)

`Model::validate` checks the model against the validations declared in the model definition (with [`Model@validate`](/docs/api/batman.model.html#class_function_validate)). This method accepts a callback with two arguments: any JS error that occurred within the validator function, and the set of [`Batman.ValidationError`](/docs/api/batman.validationerror.html)s that the input generated.

For example:

    test "validate(callback) will call the callback only after all keys have been validated", ->
      class Product extends Batman.Model
        @validate 'name', 'price', presence: yes

      newProduct = new Product
      newProduct.validate (javascriptError, validationErrors) ->
        throw javascriptError if javascriptError
        equal validationErrors.length, 2
        equal newProduct.get('errors.length'), 2
        equal newProduct.get('errors.name.length'), 1
        equal newProduct.get('errors.price.length'), 1

# Batman.ValidationError

`Batman.ValidationError`s represent a failure for a model's field to to pass validation.
They are usually accessed by getting a model's [errors](/docs/api/batman.model.html#prototype_accessor_errors).

## ::%fullMessage

Returns the human-readable attribute name and the validation message:

    test "ValidationError should humanize attribute in the full message", ->
      error = new Batman.ValidationError("fooBarBaz", "isn't valid")
      equal error.get('fullMessage'), "Foo bar baz isn't valid"