Link to existing doc content instead of repeating it

# Batman.App

`Batman.App` is the central object in any Batman application. It manages the routing table and the current URL parameters, as well as the initial start of the application. It should also be used as a namespace for models and views so that other objects can find them. Batman assumes that there will only ever be one `Batman.App` in use at once.

## Batman.currentApp

A Batman-wide reference to the currently running `Batman.App`.

## @run() : App

`App.run` is the central entry point for a Batman application. `@run` takes these steps to initialize a Batman application:

 1. Instantiate a `Dispatcher`, an internal object for mananging action dispatch to controllers.
 2. Instantiate a `Navigator`, an internal object for managing the URL via pushState or hashbangs.
 3. Instantiate the `layout` view according to the `layout` property on the `App`.
 4. Wait for the layout view to fire it's `ready` event.
 5. Start the first action dispatch by telling the `Navigator` to begin monitoring the URL.

_Note_: `@run` emits the `run` class event on the `App`, but not necessarily as soon as `@run` is called. Because the `layout` View renders asynchronously and may need to fetch other components, the `run` event can and often does fire long after `@run` is called. If you need to execute code as soon as the `App` has started running, add a listener to the `run` event on the `App` class. If you need to execute code as soon as the layout has rendered, you can use the `ready` event on the `App` class.

`@run` can be called before or on the `load` DOMEvent of the window. `@run` will return the App if the commencement was successful and complete, or `false` if the App must wait for the `layout` to render or if the `App` has already run.

#### starting an application with DOMEvents
```coffeescript
window.addEventListener 'load', ->
  MyApp.run()
```

#### starting an application with jQuery
```coffeescript
$ ->
  MyApp.run()
```

## @stop() : App

`@stop` stops the `App` it's called upon. The URL will stop being monitored and no more actions will be dispatched. In usual Batman development you shouldn't have to call this.

## @routes

`@routes` is a class level property referencing the root level `NamedRouteQuery` which allows for binding to routes on objects. See the [`data-route` binding](batman.view_bindings.html#data-route) for more information.

## @controllers

`@controllers` is a class level property containing the singleton `Batman.Controller` instances for each subclass in the application. This `controllers` directory puts these instances at the lowercase name of the controller. For example, the `TodosController` would be found at `controllers.todos`. `@controllers` ideally should never be bound to, but it is very useful for debugging in the console and other such workarounds.

    test "App.controllers references a directory of controller instances", ->
      class Alfred extends Batman.App
      class Alfred.TodosController extends Batman.Controller
      controller = Alfred.get('controllers.todos')
      equal Batman._functionName(controller.constructor), "TodosController"

    test "Multi-word controller names have a lowercase first letter", ->
      class Alfred extends Batman.App
      class Alfred.ReminderEmailsController extends Batman.Controller
      controller = Alfred.get('controllers.reminderEmails')
      equal Batman._functionName(controller.constructor), "ReminderEmailsController"

## @layout

`@layout` is the base view of the entire view hierarchy. By default, it will parse any data-* attributes in the entire document, excluding any `data-yield`'s, when `App.run()` is called. Use `MyApp.layout = null` to disable the creation of this default view.

## @currentParams

`@currentParams` contains the URL parameters for the current request, including the path relative to the app's base path (`Batman.config.pathToApp`). Some interesting parts to look at: `@currentParams.controller`, `@currentParams.action`.

## @paramsManager
## @paramsPusher

## 'run' class event

The `run` class event is fired once the app has run. This indeterminately but often happens before the app's layout has finished rendering.

## 'ready' class event

The `ready` class event is fired once the app's layout is rendered.

# Batman.App Routing

The `Batman` routing DSL is similar to Rails 3's routing DSL. It is oriented around the notion of a resource:

## @route

`@route` defines a custom route and can be pointed to a controller action directly. For example:

```coffeescript
class window.Example extends Batman.App
  @route 'comments', 'pages#comments'

class Example.PagesController extends Batman.Controller
  comments: ->
```

Would result in `/comments` being added to the routing map, pointed to `PagesController#comments`.

## @resources(resourceName : String[, otherResourceNames... : String][, options : Object][, scopedCallback : Function])

`@resources` is modeled after the Rails routing `resources` method. It automatically defines some routes and matches them to controller actions. For example,

```coffeescript
class App extends Batman.App
  @resources 'pages'

class App.PagesController extends Batman.Controller
  index: ->
    # ...
  new: ->
    # ...
  show: (params) ->
    App.Page.find params.id, (err, page) ->
      @set('currentPage', page)
  edit: (params) ->
    App.Page.find params.id, (err, page) ->
      @set('currentPage', page)
```

Will set up these routes:

Path | Controller Action
-- | -- |
/pages | App.PagesController#index
/pages/new | App.PagesController#new
/pages/:id | App.PagesController#show
/pages/:id/edit | App.PagesController#edit

Note that unlike Rails, `destroy`, `update`, and `create` are not performed by controller actions in batman.js. Instead, call `save` or `destroy` on your records directly.
To access a generated route from within a view, use the [`data-route` binding](batman.view_bindings.html#data-route).

### Nested Resources

You may also nest resources, as in Rails:

```coffeescript
class App extends Batman.App
  @resources 'pages', ->
    @resources 'comments'
```

Will set up these routes for `App.Comment`:

Path | Controller Action
-- | -- |
/pages/:page_id/comments | App.CommentsController#index
/pages/:page_id/comments/new | App.CommentsController#new
/pages/:page_id/comments/:id | App.CommentsController#show
/pages/:page_id/comments/:id/edit | App.CommentsController#edit

## @member

`@member` defines a routable action you can call on a specific instance of a member of a collection resource. For example, if you have a collection of `Page` resources, and a user can post a comment on a specific page:

```coffeescript
class window.Example extends Batman.App
  @resources 'pages', ->
    @member 'comment'

class Example.PagesController extends Batman.Controller
  comment: (params) ->
```

Would result in `/pages/:id/comment` being added to the routing map, pointed to `PagesController#comment`.

## @collection

`@collection` is similar to `@member` in that it adds routable actions to a `@resources` set of routes. In this case the action would apply to the entire collection. For example, if you have a list of spam comments made across _all_ your `Page` resources:

```coffeescript
class window.Example extends Batman.App
  @resources 'pages', ->
    @collection 'spam_comments'

class Example.PagesController extends Batman.Controller
  comments: ->
```

Would result in `/pages/spam_comments` being added to the routing map, pointed to `PagesController#spam_comments`.

## @root

`@root` defines the root controller and action to be used when visiting the base application URL. For example:

```coffeescript
class window.Example extends Batman.App
  @root 'pages#index'

class Example.PagesController extends Batman.Controller
  index: ->
```

Would result in `/` being pointed to `PagesController#index`.

# Batman.App

`Batman.App` is the central object in any Batman application. It manages the routing table and the current URL parameters, as well as the initial start of the application. It should also be used as a namespace for models and views so that other objects can find them. Batman assumes that there will only ever be one `Batman.App` in use at once.

## Batman.currentApp

A Batman-wide reference to the currently running `Batman.App`.

## @run() : App

`App.run` is the central entry point for a Batman application. `@run` takes these steps to initialize a Batman application:

 1. Instantiate a `Dispatcher`, an internal object for mananging action dispatch to controllers.
 2. Instantiate a `Navigator`, an internal object for managing the URL via pushState or hashbangs.
 3. Instantiate the `layout` view according to the `layout` property on the `App`.
 4. Wait for the layout view to fire it's `ready` event.
 5. Start the first action dispatch by telling the `Navigator` to begin monitoring the URL.

_Note_: `@run` emits the `run` class event on the `App`, but not necessarily as soon as `@run` is called. Because the `layout` View renders asynchronously and may need to fetch other components, the `run` event can and often does fire long after `@run` is called. If you need to execute code as soon as the `App` has started running, add a listener to the `run` event on the `App` class. If you need to execute code as soon as the layout has rendered, you can use the `ready` event on the `App` class.

`@run` can be called before or on the `load` DOMEvent of the window. `@run` will return the App if the commencement was successful and complete, or `false` if the App must wait for the `layout` to render or if the `App` has already run.

#### starting an application with DOMEvents
```coffeescript
window.addEventListener 'load', ->
  MyApp.run()
```

#### starting an application with jQuery
```coffeescript
$ ->
  MyApp.run()
```

## @stop() : App

`@stop` stops the `App` it's called upon. The URL will stop being monitored and no more actions will be dispatched. In usual Batman development you shouldn't have to call this.

## @routes

`@routes` is a class level property referencing the root level `NamedRouteQuery` which allows for binding to routes on objects. See `data-route` bindings for more information.

## @controllers

`@controllers` is a class level property containing the singleton `Batman.Controller` instances for each subclass in the application. This `controllers` directory puts these instances at the lowercase name of the controller. For example, the `TodosController` would be found at `controllers.todos`. `@controllers` ideally should never be bound to, but it is very useful for debugging in the console and other such workarounds.

    test "App.controllers references a directory of controller instances", ->
      class Alfred extends Batman.App
      class Alfred.TodosController extends Batman.Controller
      controller = Alfred.get('controllers.todos')
      equal Batman._functionName(controller.constructor), "TodosController"

    test "Multi-word controller names have a lowercase first letter", ->
      class Alfred extends Batman.App
      class Alfred.ReminderEmailsController extends Batman.Controller
      controller = Alfred.get('controllers.reminderEmails')
      equal Batman._functionName(controller.constructor), "ReminderEmailsController"

## @layout

`@layout` is the base view of the entire view hierarchy. By default, it will parse any data-* attributes in the entire document, excluding any `data-yield`'s, when `App.run()` is called. Use `MyApp.layout = null` to disable the creation of this default view.

## @currentParams

`@currentParams` contains the URL parameters for the current request, including the path relative to the app's base path (`Batman.config.pathToApp`). Some interesting parts to look at: `@currentParams.controller`, `@currentParams.action`.

## @paramsManager
## @paramsPusher

## 'run' class event

The `run` class event is fired once the app has run. This indeterminately but often happens before the app's layout has finished rendering.

## 'ready' class event

The `ready` class event is fired once the app's layout is rendered.

# Batman.App Routing

The `Batman` routing DSL is similar to Rails 3's routing DSL. It is oriented around the notion of a resource:

## @route

`@route` defines a custom route and can be pointed to a controller action directly. For example:

```coffeescript
class window.Example extends Batman.App
  @route 'comments', 'pages#comments'

class Example.PagesController extends Batman.Controller
  comments: ->
```

Would result in `/comments` being added to the routing map, pointed to `PagesController#comments`.

## @resources(resourceName : String[, otherResourceNames... : String][, options : Object][, scopedCallback : Function])

`@resources` is modeled after the Rails routing `resources` method. It automatically defines some routes and matches them to controller actions. For example,

```coffeescript
class App extends Batman.App
  @resources 'pages'

class App.PagesController extends Batman.Controller
  index: ->
    # ...
  new: ->
    # ...
  show: (params) ->
    App.Page.find params.id, (err, page) ->
      @set('currentPage', page)
  edit: (params) ->
    App.Page.find params.id, (err, page) ->
      @set('currentPage', page)
```

Will set up these routes:

Path | Controller Action | View binding
-- | -- | -- |
/pages | App.PagesController#index | `data-route="routes.pages"`
/pages/new | App.PagesController#new | `data-route="routes.pages.new"`
/pages/:id | App.PagesController#show | `data-route="routes.pages[currentPage]"`
/pages/:id/edit | App.PagesController#edit | `data-route="routes.pages[currentPage].edit"`

Of course, `destroy`, `update`, and `create` are not performed by controller actions in Batman. Instead, call `save` or `destroy` on your records.

### Nested Resources

You may also nest resources, as in Rails:

```coffeescript
class App extends Batman.App
  @resources 'pages', ->
    @resources 'comments'
```

Will set up these routes for `App.Comment`:

Path | Controller Action | View binding
-- | -- | -- |
/pages/:page_id/comments | App.CommentsController#index | `data-route="routes.pages[currentPage].comments"`
/pages/:page_id/comments/new | App.CommentsController#new | `data-route="routes.pages[currentPage].comments.new"`
/pages/:page_id/comments/:id | App.CommentsController#show | `data-route="routes.pages[currentPage].comments[currentComment]"`
/pages/:page_id/comments/:id/edit | App.CommentsController#edit | `data-route="routes.pages[currentPage].comments[currentComment].edit"`

## @member

`@member` defines a routable action you can call on a specific instance of a member of a collection resource. For example, if you have a collection of `Page` resources, and a user can post a comment on a specific page:

```coffeescript
class window.Example extends Batman.App
  @resources 'pages', ->
    @member 'comment'

class Example.PagesController extends Batman.Controller
  comment: (params) ->
```

Would result in `/pages/:id/comment` being added to the routing map, pointed to `PagesController#comment`.

## @collection

`@collection` is similar to `@member` in that it adds routable actions to a `@resources` set of routes. In this case the action would apply to the entire collection. For example, if you have a list of spam comments made across _all_ your `Page` resources:

```coffeescript
class window.Example extends Batman.App
  @resources 'pages', ->
    @collection 'spam_comments'

class Example.PagesController extends Batman.Controller
  comments: ->
```

Would result in `/pages/spam_comments` being added to the routing map, pointed to `PagesController#spam_comments`.

## @root

`@root` defines the root controller and action to be used when visiting the base application URL. For example:

```coffeescript
class window.Example extends Batman.App
  @root 'pages#index'

class Example.PagesController extends Batman.Controller
  index: ->
```

Would result in `/` being pointed to `PagesController#index`.


fix minor issue with method debug output assuming input as an object

# Method - controller of functions

## Class Method

    debug = require('debug')('yang:method')
    co = require('co') # TODO: should deprecate soon...
    Property = require('./property')

    class Method extends Property
      constructor: ->
        super
        @state.enumerable = false

      debug: -> debug @uri, arguments...

      get: (pattern) -> switch
        when pattern? then super
        when @binding? then @do.bind this
        else @content

      set: (value, opts={ suppress: false }) ->
        { suppress, actor } = opts
        @state.prev = @state.value
        @state.value = switch
          when @schema.apply? then @schema.apply value, @context.with(opts)
          else value
        @emit 'update', this, actor unless suppress
        return this

### do ()

A convenience wrap to a Property instance that holds a function to
perform a Promise-based execution.

Always returns a Promise.

      do: (input={}) ->
        unless (@binding instanceof Function) or (@content instanceof Function)
          return Promise.reject @error "cannot perform action on a property without function"
        transaction = true if @root.kind is 'module' and @root.transactable isnt true
        @debug "[do] executing method: #{@name}"
        @debug input
        @root.transactable = true if transaction
        try
          ctx = @context
          if @schema.input?
            @debug "[do] evaluating input schema"
            res = @schema.input.eval { input }, @context.with suppress: true
            input = res.input || {}
          # first apply schema bound function (if availble), otherwise
          # execute assigned function (if available and not 'missing')
          if @binding?
            @debug "[do] calling bound function with: #{Object.keys(input)}"
            @debug @binding.toString()
            output = @binding.call ctx, input
          else
            @debug "[do] calling assigned function: #{@content.name}"
            output = @content.call @container, input, ctx

          return co =>
            output = yield Promise.resolve output
            if @schema.output?
              @debug "[do] evaluating output schema"
              res = @schema.output.eval { output }, @context.with suppress: true
              output = res.output
            if transaction
              @root.save()
              @root.transactable = false
            return output
        catch e
          @debug e
          if transaction
            @root.rollback()
            @root.transactable = false
          return Promise.reject e

### toJSON

This call always returns undefined for the Method node.

      toJSON: (tag=false) ->
        value = undefined
        value = "#{@name}": value if tag
        return value

    module.exports = Method

# Method - controller of functions

## Class Method

    debug = require('debug')('yang:method')
    co = require('co') # TODO: should deprecate soon...
    Property = require('./property')

    class Method extends Property
      constructor: ->
        super
        @state.enumerable = false

      debug: -> debug @uri, arguments...

      get: (pattern) -> switch
        when pattern? then super
        when @binding? then @do.bind this
        else @content

      set: (value, opts={ suppress: false }) ->
        { suppress, actor } = opts
        @state.prev = @state.value
        @state.value = switch
          when @schema.apply? then @schema.apply value, @context.with(opts)
          else value
        @emit 'update', this, actor unless suppress
        return this

### do ()

A convenience wrap to a Property instance that holds a function to
perform a Promise-based execution.

Always returns a Promise.

      do: (input={}) ->
        unless (@binding instanceof Function) or (@content instanceof Function)
          return Promise.reject @error "cannot perform action on a property without function"
        transaction = true if @root.kind is 'module' and @root.transactable isnt true
        @debug "[do] executing method: #{@name}"
        @debug input
        @root.transactable = true if transaction
        try
          ctx = @context
          if @schema.input?
            @debug "[do] evaluating input schema"
            res = @schema.input.eval { input }, @context.with suppress: true
            input = res.input
          # first apply schema bound function (if availble), otherwise
          # execute assigned function (if available and not 'missing')
          if @binding?
            @debug "[do] calling bound function with: #{Object.keys(input)}"
            @debug @binding.toString()
            output = @binding.call ctx, input
          else
            @debug "[do] calling assigned function: #{@content.name}"
            output = @content.call @container, input, ctx

          return co =>
            output = yield Promise.resolve output
            if @schema.output?
              @debug "[do] evaluating output schema"
              res = @schema.output.eval { output }, @context.with suppress: true
              output = res.output
            if transaction
              @root.save()
              @root.transactable = false
            return output
        catch e
          @debug e
          if transaction
            @root.rollback()
            @root.transactable = false
          return Promise.reject e

### toJSON

This call always returns undefined for the Method node.

      toJSON: (tag=false) ->
        value = undefined
        value = "#{@name}": value if tag
        return value

    module.exports = Method


Changed the constrain method of the navmesh module to impose less structure on its callers.

# navmesh

Navmeshes are stored as "MSN" (MasSplat Navmesh) and are used to define where
entities (including the player) can travel.  By default, they are unable to
leave the surface, "crawling" over it.  Each tile is a 3D triangle.  A light
Any two triangles sharing two vertices are joined and the edge formed may be
crossed from one to the other, otherwise, the edge is treated as a form of wall.

MSN is a binary format.  It is comprised of:

| Type    | Num.              | Description                                                |
| ------- | ----------------- | ---------------------------------------------------------- |
| uint16  | 1                 | The number of vertices defined.                            |
| uint16  | 1                 | The number of triangles defined.                           |
| float32 | 3x num. vertices  | The X, Y and Z of each vertex.                             |
| uint16  | 3x num. triangles | The first, second and third vertex index of each triangle. |

    file = require "./file.litcoffee"
    vector = require "./vector.litcoffee"
    plane = require "./plane.litcoffee"

## load

- filename: The "real" location of the MSN file to load.  (i.e. already
            "require"-d)
- callback: A callback to execute with the array of objects representing the
            loaded objects on success, containing:

+ plane: A plane object for the surface of the triangle itself.
+ vertices: An array of vectors specifying the locations of the vertices which
            make up the triangle.
+ edges: An array of three objects representing the edges of the triangle,
       containing:

* neighbor: When null, there is no other triangle over this edge.  Otherwise
            a reference to the triangle object which can be found over it.
* plane: A plane facing inwards from the edge.  If this edge borders another
         triangle, this will be aligned to both this triangle and the
         neighbor.

    load = (path, callback) ->
        file.arrayBuffer path, (response) ->
            header = new Uint16Array response, 0, 2
            vertexData = new Float32Array response, 4, header[0] * 3
            indices = new Uint16Array response, 4 + header[0] * 4 * 3, header[1] * 3

            vertices = for i in [0...vertexData.length] by 3
                [
                    vertexData[i]
                    vertexData[i + 1]
                    vertexData[i + 2]
                ]

            triangles = for i in [0...indices.length] by 3
                plane: plane.fromTriangle vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]]
                indices: [
                    indices[i]
                    indices[i + 1]
                    indices[i + 2]
                ]
                vertices: [
                    vertices[indices[i]]
                    vertices[indices[i + 1]]
                    vertices[indices[i + 2]]
                ]

            for triangle in triangles
                triangle.edges = for edge in [0...3]
                    vertexA = triangle.indices[edge]
                    vertexB = triangle.indices[(edge + 1) % 3]
                    vertexC = []
                    vector.add.vector vertices[vertexA], triangle.plane.normal, vertexC
                    neighbor = null
                    for other in triangles
                        if triangle is other then continue
                        if vertexA not in other.indices then continue
                        if vertexB not in other.indices then continue
                        neighbor = other
                        vector.add.vector vertexC, other.plane.normal, vertexC
                        break
                    neighbor: neighbor
                    plane: plane.fromTriangle vertices[vertexA], vertexC, vertices[vertexB]

            callback triangles
            return
        return

## constrain

- A vector specifying the location moved to.
- A reference to the navmesh triangle which contained the location moved from.

Updates the location vector to take into account collision with navmesh triangle
walls and returns the new containing navmesh triangle.

    constrain = (location, triangle) ->

        for iterations in [0...25]
            distanceA = plane.distance triangle.edges[0].plane, location
            distanceB = plane.distance triangle.edges[1].plane, location
            distanceC = plane.distance triangle.edges[2].plane, location
            if distanceA >= 0 and distanceB >= 0 and distanceC >= 0
                break

            if distanceA < 0 and triangle.edges[0].neighbor
                triangle = triangle.edges[0].neighbor
                continue

            if distanceB < 0 and triangle.edges[1].neighbor
                triangle = triangle.edges[1].neighbor
                continue

            if distanceC < 0 and triangle.edges[2].neighbor
                triangle = triangle.edges[2].neighbor
                continue

            if distanceA < 0 and distanceB < 0
                vector.copy triangle.vertices[1], location
                continue

            if distanceB < 0 and distanceC < 0
                vector.copy triangle.vertices[2], location
                continue

            if distanceC < 0 and distanceA < 0
                vector.copy triangle.vertices[0], location
                continue

            if distanceA < 0
                plane.project triangle.edges[0].plane, location, location
                continue

            if distanceB < 0
                plane.project triangle.edges[1].plane, location, location
                continue

            if distanceC < 0
                plane.project triangle.edges[2].plane, location, location
                continue

        plane.project triangle.plane, location, location
        triangle

    module.exports = { load, constrain }

# navmesh

Navmeshes are stored as "MSN" (MasSplat Navmesh) and are used to define where
entities (including the player) can travel.  By default, they are unable to
leave the surface, "crawling" over it.  Each tile is a 3D triangle.  A light
Any two triangles sharing two vertices are joined and the edge formed may be
crossed from one to the other, otherwise, the edge is treated as a form of wall.

MSN is a binary format.  It is comprised of:

| Type    | Num.              | Description                                                |
| ------- | ----------------- | ---------------------------------------------------------- |
| uint16  | 1                 | The number of vertices defined.                            |
| uint16  | 1                 | The number of triangles defined.                           |
| float32 | 3x num. vertices  | The X, Y and Z of each vertex.                             |
| uint16  | 3x num. triangles | The first, second and third vertex index of each triangle. |

    file = require "./file.litcoffee"
    vector = require "./vector.litcoffee"
    plane = require "./plane.litcoffee"

## load

- filename: The "real" location of the MSN file to load.  (i.e. already
            "require"-d)
- callback: A callback to execute with the array of objects representing the
            loaded objects on success, containing:

+ plane: A plane object for the surface of the triangle itself.
+ vertices: An array of vectors specifying the locations of the vertices which
            make up the triangle.
+ edges: An array of three objects representing the edges of the triangle,
       containing:

* neighbor: When null, there is no other triangle over this edge.  Otherwise
            a reference to the triangle object which can be found over it.
* plane: A plane facing inwards from the edge.  If this edge borders another
         triangle, this will be aligned to both this triangle and the
         neighbor.

    load = (path, callback) ->
        file.arrayBuffer path, (response) ->
            header = new Uint16Array response, 0, 2
            vertexData = new Float32Array response, 4, header[0] * 3
            indices = new Uint16Array response, 4 + header[0] * 4 * 3, header[1] * 3

            vertices = for i in [0...vertexData.length] by 3
                [
                    vertexData[i]
                    vertexData[i + 1]
                    vertexData[i + 2]
                ]

            triangles = for i in [0...indices.length] by 3
                plane: plane.fromTriangle vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]]
                indices: [
                    indices[i]
                    indices[i + 1]
                    indices[i + 2]
                ]
                vertices: [
                    vertices[indices[i]]
                    vertices[indices[i + 1]]
                    vertices[indices[i + 2]]
                ]

            for triangle in triangles
                triangle.edges = for edge in [0...3]
                    vertexA = triangle.indices[edge]
                    vertexB = triangle.indices[(edge + 1) % 3]
                    vertexC = []
                    vector.add.vector vertices[vertexA], triangle.plane.normal, vertexC
                    neighbor = null
                    for other in triangles
                        if triangle is other then continue
                        if vertexA not in other.indices then continue
                        if vertexB not in other.indices then continue
                        neighbor = other
                        vector.add.vector vertexC, other.plane.normal, vertexC
                        break
                    neighbor: neighbor
                    plane: plane.fromTriangle vertices[vertexA], vertexC, vertices[vertexB]

            callback triangles
            return
        return

## constrain

Call with an object containing:

- location: An array of three numbers specifying the X, Y and Z moved to.
- triangle: A reference to the triangle the entity is currently in.

This will modify these properties to constrain the entity to the surface of the
navmesh.

    constrain = (obj) ->

        for iterations in [0...25]
            distanceA = plane.distance obj.triangle.edges[0].plane, obj.location
            distanceB = plane.distance obj.triangle.edges[1].plane, obj.location
            distanceC = plane.distance obj.triangle.edges[2].plane, obj.location
            if distanceA >= 0 and distanceB >= 0 and distanceC >= 0
                break

            if distanceA < 0 and obj.triangle.edges[0].neighbor
                obj.triangle = obj.triangle.edges[0].neighbor
                continue

            if distanceB < 0 and obj.triangle.edges[1].neighbor
                obj.triangle = obj.triangle.edges[1].neighbor
                continue

            if distanceC < 0 and obj.triangle.edges[2].neighbor
                obj.triangle = obj.triangle.edges[2].neighbor
                continue

            if distanceA < 0 and distanceB < 0
                vector.copy obj.triangle.vertices[1], obj.location
                continue

            if distanceB < 0 and distanceC < 0
                vector.copy obj.triangle.vertices[2], obj.location
                continue

            if distanceC < 0 and distanceA < 0
                vector.copy obj.triangle.vertices[0], obj.location
                continue

            if distanceA < 0
                plane.project obj.triangle.edges[0].plane, obj.location, obj.location
                continue

            if distanceB < 0
                plane.project obj.triangle.edges[1].plane, obj.location, obj.location
                continue

            if distanceC < 0
                plane.project obj.triangle.edges[2].plane, obj.location, obj.location
                continue

        plane.project obj.triangle.plane, obj.location, obj.location
        return

    module.exports = { load, constrain }