only conditionally traverse up parent during commit if opts.suppress is false

# Container - controller of object properties

## Class Container

    delegate = require 'delegates'
    Emitter  = require('events').EventEmitter
    Property = require('./property')
    kProp = Symbol.for('property')

    class Container extends Property
      logger: require('debug')('yang:container')

      constructor: ->
        super arguments...
        @state.children = new Map # committed props
        @state.pending = new Map # uncommitted changed props
        @state.delta = undefined
        @state.proxy =
          has: (obj, key) => @children.has(key) or key of obj
          get: (obj, key) => switch
            when key is kProp then this
            when key is 'toJSON' then @toJSON.bind(this)
            when @has(key) then @get(key)
            when key of obj then obj[key]
            when key is 'inspect' then @toJSON.bind(this)
            when key of this and typeof @[key] is 'function' then @[key].bind(this)
          set: (obj, key, value) => switch
            when @has(key) then @_get(key).set(value)
            else obj[key] = value
          deleteProperty: (obj, key) => switch
            when @has(key) then @_get(key).delete()
            when key of obj then delete obj[key]
        Object.setPrototypeOf @state, Emitter.prototype

      delegate @prototype, 'state'
        .getter 'children'
        .getter 'pending'
        .getter 'delta'
        .method 'once'
        .method 'on'
        .method 'off'
        .method 'emit'

      @property 'props',
        get: -> Array.from(@children.values())

      @property 'changed',
        get: -> @pending.size > 0 or @state.changed

      @property 'changes',
        get: -> @pending.values()

      @property 'change',
        get: -> switch
          when @changed and not @active then null
          when @changed and @pending.size
            obj = {}
            obj[prop.key] = prop.change for prop from @changes
            obj
          when @changed then @data

      @property 'data',
        set: (value) -> @set value, { force: true }
        get: ->
          value = switch
            when @binding?.get? then @binding.get @context
            else @value
          return value unless value instanceof Object
          new Proxy value, @state.proxy

      clone: ->
        copy = super children: new Map, pending: new Map
        copy.add prop.clone(parent: copy) for prop in @props
        return copy

### add (child)

This call is used to add a child property to map of children.

      add: (child) ->
        @children.set child.key, child
        if @value?
          Object.defineProperty @value, child.key,
            configurable: true
            enumerable: child.active

### remove (child)

This call is used to remove a child property from map of children.

      remove: (child) ->
        @children.delete child.key
        if @value?
          delete @value[child.key]

### has (key)

      has: (key) -> @children.has(key)

### get (key)

      _get: (key) -> @children.get(key)

      get: (key) -> switch
        when key? and @has(key) then @_get(key).data
        else super arguments...

### set (obj, opts)

      set: (obj, opts={}) ->
        # TODO: should we preserve prior changes and restore if super fails?
        @pending.clear()
        # TODO: should we also clear Object.defineProperties?
        try obj = Object.assign {}, obj if kProp of obj
        super obj, opts
        # remove all props not part of pending changes
        subopts = Object.assign {}, opts
        #prop.delete(subopts) for prop in @props when not @pending.has(prop.key)
        @props.forEach (prop) => prop.delete(subopts) unless @pending.has(prop.key)
        return this

### merge (obj, opts)

Enumerate key/value of the passed in `obj` and merge into known child
properties.

      merge: (obj, opts={}) ->
        opts.origin ?= this
        return @delete opts if obj is null
        return @set obj, opts if opts.replace or not @value?

        # TODO: protect this as a transaction?
        { deep = true } = opts

        subopts = Object.assign {}, opts, inner: true, replace: not deep
        for own k, v of obj
          @debug => "[merge] looking for #{k} inside #{@children.size} children"
          prop = @children.get(k) ? @in(k)
          continue unless prop? and not Array.isArray(prop)
          @debug => "[merge] applying value to child prop #{prop.key}"
          prop.merge(v, subopts)
        # TODO: we should consider evaluating schema.attrs here before update
        @update @value, opts

### update

Updates the value to the data model. Called *once* for each node that
is part of the change branch.

      _update: (value, opts) ->
        @debug => "[update] handle #{@pending.size} changed props"

        for prop from @changes
          @debug => "[update] child #{prop.uri} changed? #{prop.changed}"
          @add prop, opts
          @pending.delete prop.key unless prop.changed

      update: (value, opts={}) ->
        opts.origin ?= this

        if value instanceof Property
          @debug => "[update] pending.set #{value.key}"
          @pending.set value.key, value if value.parent is this
          if opts.inner or opts.origin is this
            return this
          # higher up from change origin
          value = @value

        @_update value, opts # internal update handler

        # we must clear children here if being deleted before calling super (which calls parent.update)
        @children.clear() if value is null
        super value, opts

        @emit 'update', this, opts
        return this

### commit (opts)

Commits the changes to the data model. Async transaction.
Events: commit, change

      commit: (opts={}) ->
        return true unless @changed

        if @locked
          return new Promise (resolve, reject) => @once 'commit', (res) => resolve res

        @debug => "[commit] #{@pending.size} changes"
        try
          @state.locked = true
          @state.delta = @change
          @state.setMaxListeners(30 + (@pending.size * 2))

          subopts = Object.assign {}, opts, inner: true

          # 1. traverse down the children
          await prop.commit subopts for prop from @changes when not prop.locked

          @debug => "[commit] execute commit binding (if any)..." unless opts.sync
          await @binding?.commit? @context.with(opts) unless opts.sync

          # TODO: enable this later after kos stops using a '.' dummy container between module and nodes
          # opts.origin = this if @pending.size > 1 or not @active
          opts.origin ?= this

          # 2. traverse up the parent (if inner or not suppressed and has parent)
          if (opts.inner or not opts.suppress) and @parent?
            promise = @parent.commit? opts
              .then (ok) =>
                @debug => "[commit] parent returned: #{ok}"
                await @revert opts unless ok
                if ok
                  @emit 'change', opts.origin, opts.actor unless opts.suppress
                  @finalize()
                @emit 'commit', ok, opts
                return ok
          unless promise?
            @emit 'change', opts.origin, opts.actor unless opts.suppress
            @finalize()
            @emit 'commit', true, opts
            promise = true
        catch err
          @debug => "[commit] revert due to #{err.message}"
          await @revert opts
          @emit 'commit', false, opts
          throw @error err, 'commit'
        finally
          @state.locked = false

        return switch
          when opts.inner then true
          else Promise.resolve promise

      revert: (opts={}) ->
        return unless @changed

        @debug => "[revert] #{@pending.size} changes"
        # below is hackish but works to make a copy of current value
        # to be used as ctx.prior during revert commit binding call
        @state.value = @toJSON()
        await prop.revert opts for prop from @changes
        @add prop for prop from @changes
        await super opts

      finalize: ->
        @pending.clear()
        super()

### toJSON

This call creates a new copy of the current `Property.data`
completely detached/unbound to the underlying data schema. It's main
utility is to represent the current data state for subsequent
serialization/transmission. It accepts optional argument `tag` which
when called with `true` will tag the produced object with the current
property's `@name`.

      toJSON: (key, state = true) ->
        props = @props
        value = switch
          when props.length
            obj = {}
            for prop in props when prop.enumerable and (state or prop.mutable)
              value = prop.toJSON false, state
              obj[prop.key] = value if value?
            obj
          else @value
        value = "#{@name}": value if key is true
        return value

### inspect

      inspect: ->
        output = super arguments...
        return Object.assign output, children: @children.size

    module.exports = Container

# Container - controller of object properties

## Class Container

    delegate = require 'delegates'
    Emitter  = require('events').EventEmitter
    Property = require('./property')
    kProp = Symbol.for('property')

    class Container extends Property
      logger: require('debug')('yang:container')

      constructor: ->
        super arguments...
        @state.children = new Map # committed props
        @state.pending = new Map # uncommitted changed props
        @state.delta = undefined
        @state.proxy =
          has: (obj, key) => @children.has(key) or key of obj
          get: (obj, key) => switch
            when key is kProp then this
            when key is 'toJSON' then @toJSON.bind(this)
            when @has(key) then @get(key)
            when key of obj then obj[key]
            when key is 'inspect' then @toJSON.bind(this)
            when key of this and typeof @[key] is 'function' then @[key].bind(this)
          set: (obj, key, value) => switch
            when @has(key) then @_get(key).set(value)
            else obj[key] = value
          deleteProperty: (obj, key) => switch
            when @has(key) then @_get(key).delete()
            when key of obj then delete obj[key]
        Object.setPrototypeOf @state, Emitter.prototype

      delegate @prototype, 'state'
        .getter 'children'
        .getter 'pending'
        .getter 'delta'
        .method 'once'
        .method 'on'
        .method 'off'
        .method 'emit'

      @property 'props',
        get: -> Array.from(@children.values())

      @property 'changed',
        get: -> @pending.size > 0 or @state.changed

      @property 'changes',
        get: -> @pending.values()

      @property 'change',
        get: -> switch
          when @changed and not @active then null
          when @changed and @pending.size
            obj = {}
            obj[prop.key] = prop.change for prop from @changes
            obj
          when @changed then @data

      @property 'data',
        set: (value) -> @set value, { force: true }
        get: ->
          value = switch
            when @binding?.get? then @binding.get @context
            else @value
          return value unless value instanceof Object
          new Proxy value, @state.proxy

      clone: ->
        copy = super children: new Map, pending: new Map
        copy.add prop.clone(parent: copy) for prop in @props
        return copy

### add (child)

This call is used to add a child property to map of children.

      add: (child) ->
        @children.set child.key, child
        if @value?
          Object.defineProperty @value, child.key,
            configurable: true
            enumerable: child.active

### remove (child)

This call is used to remove a child property from map of children.

      remove: (child) ->
        @children.delete child.key
        if @value?
          delete @value[child.key]

### has (key)

      has: (key) -> @children.has(key)

### get (key)

      _get: (key) -> @children.get(key)

      get: (key) -> switch
        when key? and @has(key) then @_get(key).data
        else super arguments...

### set (obj, opts)

      set: (obj, opts={}) ->
        # TODO: should we preserve prior changes and restore if super fails?
        @pending.clear()
        # TODO: should we also clear Object.defineProperties?
        try obj = Object.assign {}, obj if kProp of obj
        super obj, opts
        # remove all props not part of pending changes
        subopts = Object.assign {}, opts
        #prop.delete(subopts) for prop in @props when not @pending.has(prop.key)
        @props.forEach (prop) => prop.delete(subopts) unless @pending.has(prop.key)
        return this

### merge (obj, opts)

Enumerate key/value of the passed in `obj` and merge into known child
properties.

      merge: (obj, opts={}) ->
        opts.origin ?= this
        return @delete opts if obj is null
        return @set obj, opts if opts.replace or not @value?

        # TODO: protect this as a transaction?
        { deep = true } = opts

        subopts = Object.assign {}, opts, inner: true, replace: not deep
        for own k, v of obj
          @debug => "[merge] looking for #{k} inside #{@children.size} children"
          prop = @children.get(k) ? @in(k)
          continue unless prop? and not Array.isArray(prop)
          @debug => "[merge] applying value to child prop #{prop.key}"
          prop.merge(v, subopts)
        # TODO: we should consider evaluating schema.attrs here before update
        @update @value, opts

### update

Updates the value to the data model. Called *once* for each node that
is part of the change branch.

      _update: (value, opts) ->
        @debug => "[update] handle #{@pending.size} changed props"

        for prop from @changes
          @debug => "[update] child #{prop.uri} changed? #{prop.changed}"
          @add prop, opts
          @pending.delete prop.key unless prop.changed

      update: (value, opts={}) ->
        opts.origin ?= this

        if value instanceof Property
          @debug => "[update] pending.set #{value.key}"
          @pending.set value.key, value if value.parent is this
          if opts.inner or opts.origin is this
            return this
          # higher up from change origin
          value = @value

        @_update value, opts # internal update handler

        # we must clear children here if being deleted before calling super (which calls parent.update)
        @children.clear() if value is null
        super value, opts

        @emit 'update', this, opts
        return this

### commit (opts)

Commits the changes to the data model. Async transaction.
Events: commit, change

      commit: (opts={}) ->
        return true unless @changed

        if @locked
          return new Promise (resolve, reject) => @once 'commit', (res) => resolve res

        @debug => "[commit] #{@pending.size} changes"
        try
          @state.locked = true
          @state.delta = @change
          @state.setMaxListeners(30 + (@pending.size * 2))

          subopts = Object.assign {}, opts, inner: true

          # 1. traverse down the children
          await prop.commit subopts for prop from @changes when not prop.locked

          @debug => "[commit] execute commit binding (if any)..." unless opts.sync
          await @binding?.commit? @context.with(opts) unless opts.sync

          # TODO: enable this later after kos stops using a '.' dummy container between module and nodes
          # opts.origin = this if @pending.size > 1 or not @active
          opts.origin ?= this

          # 2. traverse up the parent (if has parent)
          promise = @parent?.commit? opts
            .then (ok) =>
              @debug => "[commit] parent returned: #{ok}"
              await @revert opts unless ok
              if ok
                @emit 'change', opts.origin, opts.actor unless opts.suppress
                @finalize()
              @emit 'commit', ok, opts
              return ok
          unless promise?
            @emit 'change', opts.origin, opts.actor unless opts.suppress
            @finalize()
            promise = true
        catch err
          @debug => "[commit] revert due to #{err.message}"
          await @revert opts
          @emit 'commit', false, opts
          throw @error err, 'commit'
        finally
          @state.locked = false

        return switch
          when opts.inner then true
          else Promise.resolve promise

      revert: (opts={}) ->
        return unless @changed

        @debug => "[revert] #{@pending.size} changes"
        # below is hackish but works to make a copy of current value
        # to be used as ctx.prior during revert commit binding call
        @state.value = @toJSON()
        await prop.revert opts for prop from @changes
        @add prop for prop from @changes
        await super opts

      finalize: ->
        @pending.clear()
        super()

### toJSON

This call creates a new copy of the current `Property.data`
completely detached/unbound to the underlying data schema. It's main
utility is to represent the current data state for subsequent
serialization/transmission. It accepts optional argument `tag` which
when called with `true` will tag the produced object with the current
property's `@name`.

      toJSON: (key, state = true) ->
        props = @props
        value = switch
          when props.length
            obj = {}
            for prop in props when prop.enumerable and (state or prop.mutable)
              value = prop.toJSON false, state
              obj[prop.key] = value if value?
            obj
          else @value
        value = "#{@name}": value if key is true
        return value

### inspect

      inspect: ->
        output = super arguments...
        return Object.assign output, children: @children.size

    module.exports = Container


Updated the game module to include basic physics.  Needs iteration.

# game

This module contains your game logic.  Its methods are called by the "index"
module to update the game state.

    gamepad = require "./input/gamepad.litcoffee"
    keyboard = require "./input/keyboard.litcoffee"

    context = require "./rendering/context.litcoffee"
    cloud = require "./rendering/cloud.litcoffee"
    matrix = require "./matrix.litcoffee"
    plane = require "./plane.litcoffee"
    misc = require "./misc.litcoffee"
    navmesh = require "./navmesh.litcoffee"
    vector = require "./vector.litcoffee"

    triangle = undefined

    testEntity = testMap = testNavmesh = undefined

# load
Called before the first "tick"/"draw" to load any resources needed by the game.
Execute the argument when you have finished successfully.

    load = (callback) ->
        keyboard()
        context.load()
        cloud.load (require "./testEntity.msc"), (testEntity_) ->
            testEntity = testEntity_
            cloud.load (require "./tracks/test/geometry.msc"), (testMap_) ->
                testMap = testMap_
                navmesh.load (require "./tracks/test/navmesh.msn"), (testNavmesh_) ->
                    testNavmesh = testNavmesh_
                    triangle = testNavmesh[0]
                    callback()
                    return
                return
            return
        return

# tick
Called at 20Hz to update game state.  Guaranteed to be called once between
"load" and "draw".  May be called more or than once per call to "draw" or not at
all.

    firstTick = true
    firstDraw = true

    entityTransform = []
    entityTransformToDraw = []
    entityTransformPreviousTick = []
    entityTransformPreviousDraw = []
    matrix.identity entityTransform

    surfaceCorrectedEntityTransform = []
    matrix.identity surfaceCorrectedEntityTransform

    cameraTransform = []
    cameraTransformPreviousDraw = []
    matrix.identity cameraTransform

    velocity = [0, 0, 0]
    xAxis = []
    yAxis = []
    zAxis = []
    translation = []
    acceleration = []
    forwardVelocity = []
    sidewardVelocity = []

    tick = ->
        if not firstTick
            matrix.copy entityTransform, entityTransformPreviousTick

        matrix.translate velocity, entityTransform

        # Left/right rotation.
        matrix.rotateY ((gamepad.left - gamepad.right) * 0.1), entityTransform, true

        # Apply navmesh triangle collision.
        matrix.getTranslation entityTransform, translation
        triangle = navmesh.constrain translation, triangle

        # Gravity.
        velocity[1] -= 0.2

        # Forwards/backwards movement.
        matrix.getZ entityTransform, zAxis

        # Determine if we're underground.
        altitude = plane.distance triangle.plane, translation

        if altitude < 0
            velocity = velocity
            plane.project triangle.plane, translation, translation

            # Reflecting the velocity against the hit surface but then
            # flattening it has the effect that hitting a ramp bounces you up it
            # but you don't bounce when falling onto the floor.
            vector.reflect velocity, triangle.plane.normal, velocity
            vector.flatten velocity, triangle.plane.normal, velocity

            vector.multiply.byScalar zAxis, ((gamepad.forward - gamepad.backward) * 0.2), acceleration
            vector.add.vector velocity, acceleration, velocity

            # Apply friction.  There is more sidewards than backwards/forwards.
            vector.flatten velocity, zAxis, sidewardVelocity
            vector.straighten velocity, zAxis, forwardVelocity
            vector.multiply.byScalar sidewardVelocity, 0.9, sidewardVelocity
            vector.multiply.byScalar forwardVelocity, 0.99, forwardVelocity
            vector.add.vector sidewardVelocity, forwardVelocity, velocity

        # Apply air resistance.
        vector.multiply.byScalar velocity, 0.98, velocity

        # This section attempts to align the entity with the triangle surface.

        # We take the triangle's normal as the Y/up axis.

        # First, flatten the Z/forward axis onto the surface.
        vector.flatten zAxis, triangle.plane.normal, zAxis
        vector.normalize zAxis, zAxis

        # Then, find the X/right axis which is perpendicular to the Z/forward
        # and Y/up axes.
        vector.cross triangle.plane.normal, zAxis, xAxis
        matrix.setX xAxis, surfaceCorrectedEntityTransform
        matrix.setY triangle.plane.normal, surfaceCorrectedEntityTransform
        matrix.setZ zAxis, surfaceCorrectedEntityTransform

        # Blend between our current transform and the aligned one.
        matrix.interpolate entityTransform, surfaceCorrectedEntityTransform, 0.1, entityTransform

        matrix.setTranslation translation, entityTransform

        if firstTick
            matrix.copy entityTransform, entityTransformPreviousTick
            firstTick = false
        return

# draw
Called with the progress through the current frame (a number between 0 and 1) to
redraw the scene.

    draw = (progress) ->
        if not firstDraw
            matrix.copy entityTransformToDraw, entityTransformPreviousDraw
            matrix.copy cameraTransform, cameraTransformPreviousDraw

        matrix.interpolate entityTransformPreviousTick, entityTransform, progress, entityTransformToDraw

        matrix.invert entityTransformToDraw, cameraTransform
        matrix.translate [0,-10, 10], cameraTransform

        if firstDraw
            matrix.copy entityTransformToDraw, entityTransformPreviousDraw
            matrix.copy cameraTransform, cameraTransformPreviousDraw
            firstDraw = false

        context.begin 0, 0, context.width, context.height, 1, cameraTransformPreviousDraw, cameraTransform, 0.1, 0.5, 0.9
        cloud.draw testMap
        cloud.draw testEntity, entityTransformPreviousDraw, entityTransformToDraw

        return

    module.exports = { load, tick, draw }

    context = require "./rendering/context.litcoffee"
    cloud = require "./rendering/cloud.litcoffee"
    matrix = require "./matrix.litcoffee"
    misc = require "./misc.litcoffee"
    loadVertices = require "./rendering/loadVertices.litcoffee"

    identity = []
    matrix.identity identity
    matrix.translate -150, -20, -150, identity

    oldTransform = []
    newTransform = []

    turned = oldTurned = 0

    testMap = undefined

    module.exports =

Call the "load" property to initialize the game.

    load: (callback) ->
        context.load()
        cloud.load ->
            loadVertices (require "./testMap.msc"), (testMap_) ->
                testMap = testMap_
                callback()
                return
            return
        return

Call the "tick" property at 20Hz to update game state.

    tick: ->
        oldTurned = turned
        turned += 0.05
        return

Call the "draw" property with the progress through the current frame in 0...1
space to render the game.

    draw: (progress) ->
        matrix.copy newTransform, oldTransform
        matrix.identity newTransform
        matrix.rotateY (misc.interpolate oldTurned, turned, progress), newTransform
        matrix.translate 50, 0, 0, newTransform
        context.begin 0, 0, context.width, context.height, 1, oldTransform, newTransform, 0.1, 0.5, 0.9
        cloud.draw testMap, identity, identity
        return


Made cells taller and wider to allow for more rendering detail

    module.exports = require 'yargs'
      .usage 'Usage: $0 [options] levelname anotherlevelname yetanotherlevelname ...'
      .example '$0',
        "Creates a level with default row and column counts,
         the default size and multiplier for each cell,
         an auto-generated name,
         and logging set to default verbosity\n"
      .example '$0 -vvvvvvvv',
        "Creates a level with default row and column counts,
         the default size and multiplier for each cell,
         an auto-generated name,
         and logging set to verbosity level 8 (max)\n"
      .example '$0 -w 20 -h 20',
        "Creates a level with default row and column counts,
         the cells 20 units wide, 20 units high,
         expanded by the default multiplier,
         an auto-generated name,
         and logging set to default verbosity\n"
      .example '$0 -w 10 -h 10 -x 4',
        "Creates a level with default row and column counts,
         40 x 40 unit cells,
         an auto-generated name,
         and logging set to default verbosity\n"
      .example '$0 lvl1 lvl2',
        "Creates two levels; named lvl1 and lvl2 -
         each with default row and column counts,
         the default size and multiplier for each cell,
         and logging set to default verbosity\n"
      .example '$0 --levels one two three',
        "Creates three levels; named one, two, and three -
         each with default row and column counts,
         the default size and multiplier for each cell,
         and logging set to default verbosity\n"
      .example '$0 -l10',
        "Creates ten auto-named levels -
         each with default row and column counts,
         the default size and multiplier for each cell,
         and logging set to default verbosity\n"
      .count 'verbosity'
      .alias 'v', 'verbosity'
      .describe 'v', 'Level of logging verbosity: 1 - 8'
      .alias 'r', 'rows'
      .describe 'r', 'Number of rows for map'
      .alias 'c', 'columns'
      .describe 'c', 'Number of columns for map'
      .alias 'w', 'width'
      .describe 'w', 'Width of a grid cell'
      .alias 'h', 'height'
      .describe 'h', 'Height of a grid cell'
      .alias 'x', 'multiplier'
      .describe 'x', 'Increase cell size by x times'
      .number 'l'
      .describe 'l', 'Number of auto-named levels to create'
      .array 'levels'
      .describe 'levels', 'Array of named levels to create'
      .array 'pipeline'
      .alias 'p', 'pipeline'
      .describe 'p', 'The steps of the render pipleline'
      .string 'conf'
      .describe 'conf', 'Absolute path to config file'
      .string 'block.fill_color'
      .describe 'block.fill_color', 'Path block color. Can be an html color name or hex value'
      .string 'ground.fill_color'
      .describe 'ground.fill_color', 'Ground block color. Can be an html color name or hex value'
      .string 'step_count.text.align'
      .choices 'step_count.text.align', [ 'left', 'center', 'right' ]
      .string 'step_count.text.color'
      .describe 'step_count.text.color', 'Can be either html color names or hex values'
      .number 'ground.segments'
      .number 'ground.max_height_diff'
      .number 'wall.width'
      .string 'wall.color'
      .describe 'wall.color', 'Can be either html color names or hex values'
      .conflicts 'levels', 'l'
      .help 'help'
      .default
        verbosity:  3
        rows:       15
        columns:    50
        width:      24
        height:     24
        multiplier: 4
        pipeline:   [ 'png_blocks', 'png_walls', 'png_grounder', 'png_step_count' ]
        block:
          fill_color: 'white'
        ground:
          fill_color:     '#888'
          segments:        24
          max_height_diff: 4
        step_count:
          text:
            align: 'center'
            color: 'black'
        wall:
          width: 1
          color: '#666'
          segments: 24
      .epilogue '© Bryan Maynard 2016'
      .wrap 120
      .argv

    module.exports = require 'yargs'
      .usage 'Usage: $0 [options] levelname anotherlevelname yetanotherlevelname ...'
      .example '$0',
        "Creates a level with default row and column counts,
         the default size and multiplier for each cell,
         an auto-generated name,
         and logging set to default verbosity\n"
      .example '$0 -vvvvvvvv',
        "Creates a level with default row and column counts,
         the default size and multiplier for each cell,
         an auto-generated name,
         and logging set to verbosity level 8 (max)\n"
      .example '$0 -w 20 -h 20',
        "Creates a level with default row and column counts,
         the cells 20 units wide, 20 units high,
         expanded by the default multiplier,
         an auto-generated name,
         and logging set to default verbosity\n"
      .example '$0 -w 10 -h 10 -x 4',
        "Creates a level with default row and column counts,
         40 x 40 unit cells,
         an auto-generated name,
         and logging set to default verbosity\n"
      .example '$0 lvl1 lvl2',
        "Creates two levels; named lvl1 and lvl2 -
         each with default row and column counts,
         the default size and multiplier for each cell,
         and logging set to default verbosity\n"
      .example '$0 --levels one two three',
        "Creates three levels; named one, two, and three -
         each with default row and column counts,
         the default size and multiplier for each cell,
         and logging set to default verbosity\n"
      .example '$0 -l10',
        "Creates ten auto-named levels -
         each with default row and column counts,
         the default size and multiplier for each cell,
         and logging set to default verbosity\n"
      .count 'verbosity'
      .alias 'v', 'verbosity'
      .describe 'v', 'Level of logging verbosity: 1 - 8'
      .alias 'r', 'rows'
      .describe 'r', 'Number of rows for map'
      .alias 'c', 'columns'
      .describe 'c', 'Number of columns for map'
      .alias 'w', 'width'
      .describe 'w', 'Width of a grid cell'
      .alias 'h', 'height'
      .describe 'h', 'Height of a grid cell'
      .alias 'x', 'multiplier'
      .describe 'x', 'Increase cell size by x times'
      .number 'l'
      .describe 'l', 'Number of auto-named levels to create'
      .array 'levels'
      .describe 'levels', 'Array of named levels to create'
      .array 'pipeline'
      .alias 'p', 'pipeline'
      .describe 'p', 'The steps of the render pipleline'
      .string 'conf'
      .describe 'conf', 'Absolute path to config file'
      .string 'block.fill_color'
      .describe 'block.fill_color', 'Path block color. Can be an html color name or hex value'
      .string 'ground.fill_color'
      .describe 'ground.fill_color', 'Ground block color. Can be an html color name or hex value'
      .string 'step_count.text.align'
      .choices 'step_count.text.align', [ 'left', 'center', 'right' ]
      .string 'step_count.text.color'
      .describe 'step_count.text.color', 'Can be either html color names or hex values'
      .number 'ground.segments'
      .number 'ground.max_height_diff'
      .number 'wall.width'
      .string 'wall.color'
      .describe 'wall.color', 'Can be either html color names or hex values'
      .conflicts 'levels', 'l'
      .help 'help'
      .default
        verbosity:  3
        rows:       15
        columns:    50
        width:      8
        height:     7
        multiplier: 4
        pipeline:   [ 'png_blocks', 'png_walls', 'png_grounder', 'png_step_count' ]
        block:
          fill_color: 'white'
        ground:
          fill_color:     '#888'
          segments:        8
          max_height_diff: 4
        step_count:
          text:
            align: 'center'
            color: 'black'
        wall:
          width: 1
          color: '#666'
      .epilogue '© Bryan Maynard 2016'
      .wrap 120
      .argv


better docs for source maps

better docs for source maps

Source maps allow JavaScript runtimes to match running JavaScript back to
the original source code that corresponds to it. This can be minified
JavaScript, but in our case, we're concerned with mapping pretty-printed
JavaScript back to CoffeeScript.

In order to produce maps, we must keep track of positions (line number, column number)
that originated every node in the syntax tree, and be able to generate a
[map file](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit)
— which is a compact, VLQ-encoded representation of the JSON serialization
of this information — to write out alongside the generated JavaScript.

LineMap
-------

A **LineMap** object keeps track of information about original line and column
positions for a single line of output JavaScript code.
**SourceMaps** are implemented in terms of **LineMaps**.

    class LineMap
      constructor: (@line) ->
        @columns = []

      add: (column, [sourceLine, sourceColumn], options={}) ->
        return if @columns[column] and options.noReplace
        @columns[column] = {line: @line, column, sourceLine, sourceColumn}

      sourceLocation: (column) ->
        column-- until (mapping = @columns[column]) or (column <= 0)
        mapping and [mapping.sourceLine, mapping.sourceColumn]

SourceMap
---------

Maps locations in a single generated JavaScript file back to locations in
the original CoffeeScript source file.

This is intentionally agnostic towards how a source map might be represented on
disk. Once the compiler is ready to produce a "v3"-style source map, we can walk
through the arrays of line and column buffer to produce it.

    class SourceMap
      constructor: ->
        @lines = []

Adds a mapping to this SourceMap. `sourceLocation` and `generatedLocation`
are both `[line, column]` arrays. If `options.noReplace` is true, then if there
is already a mapping for the specified `line` and `column`, this will have no
effect.

      add: (sourceLocation, generatedLocation, options = {}) ->
        [line, column] = generatedLocation
        lineMap = (@lines[line] or= new LineMap(line))
        lineMap.add column, sourceLocation, options

Look up the original position of a given `line` and `column` in the generated
code.

      sourceLocation: ([line, column]) ->
        line-- until (lineMap = @lines[line]) or (line <= 0)
        lineMap and lineMap.sourceLocation column

V3 SourceMap Generation
-----------------------

Builds up a V3 source map, returning the generated JSON as a string.
`options.sourceRoot` may be used to specify the sourceRoot written to the source
map.  Also, `options.sourceFiles` and `options.generatedFile` may be passed to
set "sources" and "file", respectively.

      generate: (options = {}, code = null) ->
        writingline       = 0
        lastColumn        = 0
        lastSourceLine    = 0
        lastSourceColumn  = 0
        needComma         = no
        buffer            = ""

        for lineMap, lineNumber in @lines when lineMap
          for mapping in lineMap.columns when mapping
            while writingline < mapping.line
              lastColumn = 0
              needComma = no
              buffer += ";"
              writingline++

Write a comma if we've already written a segment on this line.

            if needComma
              buffer += ","
              needComma = no

Write the next segment. Segments can be 1, 4, or 5 values.  If just one, then it
is a generated column which doesn't match anything in the source code.

The starting column in the generated source, relative to any previous recorded
column for the current line:

            buffer += @encodeVlq mapping.column - lastColumn
            lastColumn = mapping.column

The index into the list of sources:

            buffer += @encodeVlq 0

The starting line in the original source, relative to the previous source line.

            buffer += @encodeVlq mapping.sourceLine - lastSourceLine
            if lastSourceLine isnt mapping.sourceLine
              lastSourceLine = mapping.sourceLine
              lastSourceColumn = 0

The starting column in the original source, relative to the previous column.

            buffer += @encodeVlq mapping.sourceColumn - lastSourceColumn
            lastSourceColumn = mapping.sourceColumn
            needComma = yes

Produce the canonical JSON object format for a "v3" source map.

        v3 =
          version:    3
          file:       options.generatedFile or ''
          sourceRoot: options.sourceRoot or ''
          sources:    options.sourceFiles or ['']
          names:      []
          mappings:   buffer

        v3.sourcesContent = [code] if options.inline

        JSON.stringify v3, null, 2

Base64 VLQ Encoding
-------------------

Note that SourceMap VLQ encoding is "backwards".  MIDI-style VLQ encoding puts
the most-significant-bit (MSB) from the original value into the MSB of the VLQ
encoded value (see [Wikipedia](http://en.wikipedia.org/wiki/File:Uintvar_coding.svg)).
SourceMap VLQ does things the other way around, with the least significat four
bits of the original value encoded into the first byte of the VLQ encoded value.

      VLQ_SHIFT            = 5
      VLQ_CONTINUATION_BIT = 1 << VLQ_SHIFT             # 0010 0000
      VLQ_VALUE_MASK       = VLQ_CONTINUATION_BIT - 1   # 0001 1111

      encodeVlq: (value) ->
        answer = ''

        # Least significant bit represents the sign.
        signBit = if value < 0 then 1 else 0

        # The next bits are the actual value.
        valueToEncode = (Math.abs(value) << 1) + signBit

        # Make sure we encode at least one character, even if valueToEncode is 0.
        while valueToEncode or not answer
          nextChunk = valueToEncode & VLQ_VALUE_MASK
          valueToEncode = valueToEncode >> VLQ_SHIFT
          nextChunk |= VLQ_CONTINUATION_BIT if valueToEncode
          answer += @encodeBase64 nextChunk

        answer

Regular Base64 Encoding
-----------------------

      BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

      encodeBase64: (value) ->
        BASE64_CHARS[value] or throw new Error "Cannot Base64 encode value: #{value}"

Our API for source maps is just the `SourceMap` class.

    module.exports = SourceMap

Source maps allow JavaScript runtimes to match running JavaScript back to
the original source code that corresponds to it. This can be minified
JavaScript, but in our case, we're concerned with mapping pretty-printed
JavaScript back to CoffeeScript.

In order to produce maps, we must keep track of positions (line number, column number)
that originated every node in the syntax tree, and be able to generate a
[map file](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit)
— which is a compact, VLQ-encoded representation of the JSON serialization
of this information — to write out alongside the generated JavaScript.

LineMap
-------

A **LineMap** object keeps track of information about original line and column
positions for a single line of output JavaScript code.
**SourceMaps** are implemented in terms of **LineMaps**.

    class LineMap
      constructor: (@line) ->
        @columns = []

      add: (column, [sourceLine, sourceColumn], options={}) ->
        return if @columns[column] and options.noReplace
        @columns[column] = {line: @line, column, sourceLine, sourceColumn}

      sourceLocation: (column) ->
        column-- until (mapping = @columns[column]) or (column <= 0)
        mapping and [mapping.sourceLine, mapping.sourceColumn]

SourceMap
---------

Maps locations in for a single generated JavaScript file back to locations in
the original CoffeeScript source file.

This is intentionally agnostic towards how a source map might be represented on
disk. Once the compiler is ready to produce a "v3"-style source map, we can walk
through the arrays of line and column buffer to produce it.

    class SourceMap
      constructor: ->
        @lines = []

Adds a mapping to this SourceMap. `sourceLocation` and `generatedLocation`
are both `[line, column]` arrays. If `options.noReplace` is true, then if there
is already a mapping for the specified `line` and `column`, this will have no
effect.

      add: (sourceLocation, generatedLocation, options = {}) ->
        [line, column] = generatedLocation
        lineMap = (@lines[line] or= new LineMap(line))
        lineMap.add column, sourceLocation, options

Look up the original position of a given `line` and `column` in the generated
code.

      sourceLocation: ([line, column]) ->
        line-- until (lineMap = @lines[line]) or (line <= 0)
        lineMap and lineMap.sourceLocation column

V3 SourceMap Generation
-----------------------

Builds up a V3 source map, returning the generated JSON as a string.
`options.sourceRoot` may be used to specify the sourceRoot written to the source
map.  Also, `options.sourceFiles` and `options.generatedFile` may be passed to
set "sources" and "file", respectively.

      generate: (options = {}, code = null) ->
        writingline       = 0
        lastColumn        = 0
        lastSourceLine    = 0
        lastSourceColumn  = 0
        needComma         = no
        buffer            = ""

        for lineMap, lineNumber in @lines when lineMap
          for mapping in lineMap.columns when mapping
            while writingline < mapping.line
              lastColumn = 0
              needComma = no
              buffer += ";"
              writingline++

Write a comma if we've already written a segment on this line.

            if needComma
              buffer += ","
              needComma = no

Write the next segment. Segments can be 1, 4, or 5 values.  If just one, then it
is a generated column which doesn't match anything in the source code.

The starting column in the generated source, relative to any previous recorded
column for the current line:

            buffer += @encodeVlq mapping.column - lastColumn
            lastColumn = mapping.column

The index into the list of sources:

            buffer += @encodeVlq 0

The starting line in the original source, relative to the previous source line.

            buffer += @encodeVlq mapping.sourceLine - lastSourceLine
            if lastSourceLine isnt mapping.sourceLine
              lastSourceLine = mapping.sourceLine
              lastSourceColumn = 0

The starting column in the original source, relative to the previous column.

            buffer += @encodeVlq mapping.sourceColumn - lastSourceColumn
            lastSourceColumn = mapping.sourceColumn
            needComma = yes

Produce the canonical JSON object format for a "v3" source map.

        v3 =
          version:    3
          file:       options.generatedFile or ''
          sourceRoot: options.sourceRoot or ''
          sources:    options.sourceFiles or ['']
          names:      []
          mappings:   buffer

        v3.sourcesContent = [code] if options.inline

        JSON.stringify v3, null, 2

Base64 VLQ Encoding
-------------------

Note that SourceMap VLQ encoding is "backwards".  MIDI-style VLQ encoding puts
the most-significant-bit (MSB) from the original value into the MSB of the VLQ
encoded value (see [Wikipedia](http://en.wikipedia.org/wiki/File:Uintvar_coding.svg)).
SourceMap VLQ does things the other way around, with the least significat four
bits of the original value encoded into the first byte of the VLQ encoded value.

      VLQ_SHIFT            = 5
      VLQ_CONTINUATION_BIT = 1 << VLQ_SHIFT             # 0010 0000
      VLQ_VALUE_MASK       = VLQ_CONTINUATION_BIT - 1   # 0001 1111

      encodeVlq: (value) ->
        answer = ''

        # Least significant bit represents the sign.
        signBit = if value < 0 then 1 else 0

        # The next bits are the actual value.
        valueToEncode = (Math.abs(value) << 1) + signBit

        # Make sure we encode at least one character, even if valueToEncode is 0.
        while valueToEncode or not answer
          nextChunk = valueToEncode & VLQ_VALUE_MASK
          valueToEncode = valueToEncode >> VLQ_SHIFT
          nextChunk |= VLQ_CONTINUATION_BIT if valueToEncode
          answer += @encodeBase64 nextChunk

        answer

Regular Base64 Encoding
-----------------------

      BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

      encodeBase64: (value) ->
        BASE64_CHARS[value] or throw new Error "Cannot Base64 encode value: #{value}"

Our API for source maps is just the `SourceMap` class.

    module.exports = SourceMap


Add missing return statement

Add missing return statement

    module.exports = MongoQS = (opts) ->
      @ops = opts?.ops or ['!', '^', '$', '~', '>', '<']
      @alias = opts?.alias or {}
      @ignore = opts?.ignore or {}
      @custom = opts?.custom or {}

      for param, field of @custom
        switch param
          when 'bbox' then @custom.bbox = @customBBOX field
          when 'near' then @custom.near = @customNear field
          when 'after' then @custom.after = @customAfter field

      return @

    MongoQS.prototype.customBBOX = (field) ->
      (res, bbox) ->
        bbox = bbox.split ','

        if bbox.length is 4
          bbox[key] = parseFloat(val) for val, key in bbox

          res[field] = $geoWithin: $geometry:
            type: 'Polygon'
            coordinates: [[
              [bbox[0], bbox[1]]
              [bbox[2], bbox[1]]
              [bbox[2], bbox[3]]
              [bbox[0], bbox[3]]
              [bbox[0], bbox[1]]
            ]]

        return

    MongoQS.prototype.customNear = (field) ->
      (query, input) ->
        input = input.split ','

        if input.length is 2
          input[key] = parseFloat(val) for val, key in input

          query[field] = $near: $geometry:
            type: 'Point'
            coordinates: input

        return

    MongoQS.prototype.customAfter = (field) ->
      (query, input) ->

        if not isNaN input
          input = input + '000' if (input + '').length is 10
          input = parseInt input

        input = new Date input

        if input.toString() isnt 'Invalid Date'
          query[field] = $gte: input.toISOString()

        return

    MongoQS.prototype.parse = (query) ->
      res = {}

      for key, val of query
        continue if @ignore[key]
        continue if typeof val isnt 'string'
        continue if not /^[a-zæøå0-9-_.]+$/i.test key

        key = @alias[key] if @alias[key]

If the value is empty we treat the query parameter as an
[$exists](http://docs.mongodb.org/manual/reference/operator/query/exists/)
operator.

        if not val
          res[key] = $exists: true

Check for supported operators in `@ops`. This is configured when
instanciating `MongoQS` and the defaults are `!`, `^`, `$`, `~`, `>`, and `<`.

        else if val.charAt(0) in @ops
          op = val.charAt(0)
          val = val.substr(1)

          res[key] = switch op
            when '!'
              if val
                $ne: if isNaN(val) then val else parseFloat(val, 10)
              else
                $exists: false
            when '>' then $gt: parseFloat(val, 10)
            when '<' then $lt: parseFloat(val, 10)
            else
              val = val.replace /[^a-zæøå0-9-_.* ]/i, ''
              switch op
                when '^' then $regex: '^' + val, $options: 'i'
                when '$' then $regex: val + '$', $options: 'i'
                else $regex: val, $options: 'i'

        else
          res[key] = if isNaN(val) then val else parseFloat(val, 10)

      res

    module.exports = MongoQS = (opts) ->
      @ops = opts?.ops or ['!', '^', '$', '~', '>', '<']
      @alias = opts?.alias or {}
      @ignore = opts?.ignore or {}
      @custom = opts?.custom or {}

      for param, field of @custom
        switch param
          when 'bbox' then @custom.bbox = @customBBOX field
          when 'near' then @custom.near = @customNear field
          when 'after' then @custom.after = @customAfter field

      return @

    MongoQS.prototype.customBBOX = (field) ->
      (res, bbox) ->
        bbox = bbox.split ','

        if bbox.length is 4
          bbox[key] = parseFloat(val) for val, key in bbox

          res[field] = $geoWithin: $geometry:
            type: 'Polygon'
            coordinates: [[
              [bbox[0], bbox[1]]
              [bbox[2], bbox[1]]
              [bbox[2], bbox[3]]
              [bbox[0], bbox[3]]
              [bbox[0], bbox[1]]
            ]]

        return

    MongoQS.prototype.customNear = (field) ->
      (query, input) ->
        input = input.split ','

        if input.length is 2
          input[key] = parseFloat(val) for val, key in input

          query[field] = $near: $geometry:
            type: 'Point'
            coordinates: input

        return

    MongoQS.prototype.customAfter = (field) ->
      (query, input) ->

        if not isNaN input
          input = input + '000' if (input + '').length is 10
          input = parseInt input

        input = new Date input

        if input.toString() isnt 'Invalid Date'
          query[field] = $gte: input.toISOString()

    MongoQS.prototype.parse = (query) ->
      res = {}

      for key, val of query
        continue if @ignore[key]
        continue if typeof val isnt 'string'
        continue if not /^[a-zæøå0-9-_.]+$/i.test key

        key = @alias[key] if @alias[key]

If the value is empty we treat the query parameter as an
[$exists](http://docs.mongodb.org/manual/reference/operator/query/exists/)
operator.

        if not val
          res[key] = $exists: true

Check for supported operators in `@ops`. This is configured when
instanciating `MongoQS` and the defaults are `!`, `^`, `$`, `~`, `>`, and `<`.

        else if val.charAt(0) in @ops
          op = val.charAt(0)
          val = val.substr(1)

          res[key] = switch op
            when '!'
              if val
                $ne: if isNaN(val) then val else parseFloat(val, 10)
              else
                $exists: false
            when '>' then $gt: parseFloat(val, 10)
            when '<' then $lt: parseFloat(val, 10)
            else
              val = val.replace /[^a-zæøå0-9-_.* ]/i, ''
              switch op
                when '^' then $regex: '^' + val, $options: 'i'
                when '$' then $regex: val + '$', $options: 'i'
                else $regex: val, $options: 'i'

        else
          res[key] = if isNaN(val) then val else parseFloat(val, 10)

      res


Fix nested object parsing to properly assign values at the correct level

    Madul = require 'madul'

    class Config extends Madul

      deps: [ 'arguments', 'fs', 'path', 'node-uuid' ]

      post_initialize: =>
        levels = [ ]

        process.env.MADUL_LOG_LEVEL = if @arguments?.verbosity? then @arguments.verbosity else 3

        if @arguments.conf?
          config = @arguments.conf
        else
          config = @path.join __dirname, '..', '.skyll.conf.js'

        if @arguments?._?.length > 0
          levels = levels.concat argv._
        else if @arguments?.l?
          for level in [0...argv.l]
            levels.push @node_uuid.v4()
        else if @arguments?.levels? == false
          levels.push new Date().toString()

        for key, val of @arguments
          if key.length > 2 && typeof val != 'undefined'
            if key == 'levels'
              levels = levels.concat val
            else
              if typeof val == 'object' && val != null && val.length? == false
                @dive_deeper key, val, @
              else
                @[key] = val

        @fs.stat config, (err) =>
          if err?
            @fail 'DOES NOT EXIST', file: config
          else
            for key, val of require config
              if key == 'levels'
                for level in [0...val]
                  levels.push new Date(Date.now() - (((val - 1) - level) * 1000)).toString()
              else
                if typeof val == 'object' && val != null && val.length? == false
                  @dive_deeper key, val, @
                else
                  @[key] = val

            levels.push new Date().toString() if levels.length == 0

            @levels = levels
            @grid   = ((false for j in [0..@columns]) for i in [0..@rows])
            @width  = @width  * @multiplier
            @height = @height * @multiplier

            @done()

      dive_deeper: (prop, obj, context) =>
        for key, val of obj
          context[prop] = { } unless context[prop]?

          if typeof val == 'object' && val != null && val.length? == false
            @dive_deeper key, val, context[prop]
          else
            context[prop][key] = val

    module.exports = Config

    Madul = require 'madul'

    class Config extends Madul

      deps: [ 'arguments', 'fs', 'path', 'node-uuid' ]

      post_initialize: =>
        levels = [ ]

        process.env.MADUL_LOG_LEVEL = if @arguments?.verbosity? then @arguments.verbosity else 3

        if @arguments.conf?
          config = @arguments.conf
        else
          config = @path.join __dirname, '..', '.skyll.conf.js'

        if @arguments?._?.length > 0
          levels = levels.concat argv._
        else if @arguments?.l?
          for level in [0...argv.l]
            levels.push @node_uuid.v4()
        else if @arguments?.levels? == false
          levels.push new Date().toString()

        for key, val of @arguments
          if key.length > 2 && typeof val != 'undefined'
            if key == 'levels'
              levels = levels.concat val
            else
              if typeof val == 'object' && val != null && val.length? == false
                @dive_deeper key, val, @
              else
                @[key] = val

        @fs.stat config, (err) =>
          if err?
            @fail 'DOES NOT EXIST', file: config
          else
            for key, val of require config
              if key == 'levels'
                for level in [0...val]
                  levels.push new Date(Date.now() - (((val - 1) - level) * 1000)).toString()
              else
                if typeof val == 'object' && val != null && val.length? == false
                  @dive_deeper val, @
                else
                  @[key] = val

          levels.push new Date().toString() if levels.length == 0

          @levels = levels
          @grid   = ((false for j in [0..@columns]) for i in [0..@rows])
          @width  = @width  * @multiplier
          @height = @height * @multiplier

            @done()

        deferred.promise

      dive_deeper: (obj, context) =>
        for key, val of obj
          context[key] = { } unless context[key]?

          if typeof val == 'object' && val != null && val.length? == false
            @dive_deeper val, context[key]
          else
            context[key] = val

    module.exports = Config


Add docs for wrapAccessor

Add docs for wrapAccessor

# /api/Data Structures/Batman.Object

`Batman.Object` is the superclass for virtually all objects in a batman.js application. `Batman.Object` mixes in:

- `Batman.Observable` for `get`, `set`, `observe` and others
- `Batman.EventEmitter` for `on`, `off`, `fire` and others

See [`Batman.Object Accessors`](/docs/api/batman.object_accessors.html) for a full description of `@accessor`, which defines properties on `Batman.Object`s.

## @accessor([keys...], objectOrFunction)

If `keys` is empty, defines a new default accessor for instances of the object, otherwise defines a new accessor on instances of the `Object` for `keys`.

`objectOrFunction` may be:

- An object with `get`, `set`, and/or `unset` keys whose values are functions which implement those operations.
- A function which will be treated as the `get` key of the accessor object.

## @classAccessor([keys...], objectOrFunction)

Follows the pattern of `Bamtan.Object.accessor`, but defines the accessor on the class (constructor) instead of on instances of the object.

    test '@classAccessor defines an accessor on the class', ->
      class WayneManor extends Batman.Object
        @classAccessor 'address', -> "123 Wayne Dr."

      equal WayneManor.get('address'), "123 Wayne Dr."
      # Wayne Manor burned down...
      equal (new WayneManor(isRebuilt: true)).constructor.get('address'), "123 Wayne Dr."

## @mixin(objects...) : prototype

Mixes in `objects` to the `Object`'s prototype. Keys from `objects` are applied with `set`. If any of `objects` has an `initialize` function, it will be called with the prototype being mixed into.

_Note_: `@mixin`, similar to `@accessor`, applies to all instances of a class. If you need to mix in to the class itself, look at `classMixin`. `@mixin` is intended for use during the class definition of a `Batman.Object` subclass.

    test '@mixin extends the prototype of a Batman.Object subclass', ->
      FishBehaviour =
        canBreatheUnderwater: true
      MammalBehaviour =
        initialize: ->
          @set('isMammal', true)
        canBreatheAboveWater: true

      class Platypus extends Batman.Object
        @mixin FishBehaviour, MammalBehaviour

      platypus = new Platypus
      ok platypus.get('isMammal'), "the initialize function is called with the target prototype"
      ok platypus.get('canBreatheAboveWater')
      ok platypus.get('canBreatheUnderwater')

## @classMixin(objects...) : this

`@classMixin` mixes `objects` into the class (constructor) in the same way that `@mixin` mixes into the prototype.

    test '@classMixin extends the Batman.Object subclass', ->
      Singleton =
        initialze: (subject) ->
          subject.accessor 'instance', -> new subject

      class Highlander extends Batman.Object
        @classMixin Singleton

      instance = Highlander.get('instance')
      ok instance == Highlander.get('instance'), "There can only be one."

## @observeAll(key, callback : function) : prototype

`@observeAll` extends the `Batman.Object` implementation of `Batman.Observable` with the ability to observe all instances of the class (and subclasses). Observers attached with `@observeAll` function exactly as if they were attached to the object directly. Returns the prototype of the class.

_Note_: `@observeAll` is intended to be used during the class definition for a `Batman.Object` subclass, but it can be called after the class has been defined as a function on the class. It supports being called after instances of the class have been instantiated as well.

    test "@observeAll attaches handlers which get called upon change", ->
      results = []
      class Song extends Batman.Object
        @observeAll 'length', (newValue, oldValue) -> results.push newValue

      song = new Song({length: 340, bpm: 120})
      equal song.set('length', 200), 200
      deepEqual results[1], 200

    test "@observeAll can attach handlers after instance instantiation", ->
      results = []
      class Song extends Batman.Object

      song = new Song({length: 340, bpm: 120})
      equal song.set('length', 360), 360
      deepEqual results[0], undefined
      Song.observeAll 'length', (newValue, oldValue) -> results.push newValue
      equal song.set('length', 200), 200
      deepEqual results[0], 200

## @delegate(properties..., options)

Delegates `properties` to `options.to` by creating new accessors for `properties` which call `to.get(property)`. `options` must include a `to` Object.

## @singleton(singletonMethodName[="sharedInstance"])

Shorthand for [singleton classes](http://en.wikipedia.org/wiki/Singleton_pattern). Defines a class accessor `singletonMethodName` which returns the singleton instance.

## @wrapAccessor([keys...,] wrapperFunction: Function)

Defines a *wrap accessor* for the given keys. These accessors are intended to
extend an existing accessor or property by wrapping calls to `get`/`set`/`unset`.

`wrapperFunction` is called immediately, and should return an object with the
same format as an accessor definition. It is passed an object that represents
the original accessor being wrapped, called `core`.

Some trivial examples:

    test "@wrapAccessor can be used to extend get functionality", ->
      class Product extends Batman.Object
        @wrapAccessor 'title', (core) ->
          get: (key) -> 'Product ' + core.get.call(this, key) # Call the original get function.

      foo = new Product(title: 'Foo')
      equal foo.get('title'), 'Product Foo'

    test "@wrapAccessor can be used to extend set functionality", ->
      class Product extends Batman.Object
        @wrapAccessor 'title', (core) ->
          set: (key, value) ->
            core.set.call(this, key, value.toUpperCase()) # Call the original set function, with different arguments.

      foo = new Product(title: 'Product Foo')
      equal foo.get('title'), 'PRODUCT FOO'

Here's a real-world example of a fairly common use-case.
`Product` has a `handle`, which is the token used to identify the product in a
URL. If the user hasn't set a custom handle, then the handle should be generated
from the title. If they do set a custom handle, then changes to the title should
not affect the handle.

    test "@wrapAccessor makes custom shit woohoo", ->
      handleize = (value) -> value?.toLowerCase().replace(/\W+/g, '-')

      class Product extends Batman.Object
        @wrapAccessor 'handle', (core) ->
          get: -> core.get.apply(@, arguments) || handleize(@get('title'))

        @wrapAccessor 'title', (core) ->
          set: (key, value) ->
            if @get('handle') == handleize(@get('title'))
              @set('handle', handleize(value))

            core.set.call(this, key, value)

      foo = new Product(title: 'Product Foo!!')
      equal foo.get('handle'), 'product-foo-' # Handle is automatically set.

      foo.set('title', 'Product Bar')
      equal foo.get('handle'), 'product-bar' # Handle is automatically set again.

      foo.set('handle', 'custom-handle') # User defines a custom handle for this product...
      foo.set('title', 'Product Foo!!')
      equal foo.get('handle'), 'custom-handle' # so now it's not automatically set.

`@wrapAccessor` may be called with no keys to wrap *all* accessors.

## @wrapClassAccessor([keys...,] wrapperFunction: Function )

Like `@wrapAccessor`, but to wrap a class-level accessor.

## ::wrapAccessor([keys...,] wrapperFunction)

Like `@wrapAccessor`, but wraps an accessor on a single instance.

## ::constructor(objects...) : Object

Creates a new `Batman.Object` with properties from `objects`. If items in `objects` have the same keys, later values take precendence over earlier ones. Values are applied with `set`, so custom accessors are applied. The `Batman` namespace performs the same function.

    test 'Batman() function allows for handy creation of Batman.Objects', ->
      object = Batman(foo: 'bar')
      equal typeof object.get, 'function'

    test 'Batman.Object constructor function accepts multiple mixin arguments and later mixins take precedence.', ->
      song = Batman({length: 100, bpm: 120}, {bpm: 130})
      equal song.get('length'), 100
      equal song.get('bpm'), 130, "The property from the second object passed to the constructor overwrites that from the first."

## ::toJSON() : object

`toJSON` returns a vanilla JavaScript object representing this `Batman.Object`.

    test 'toJSON returns a vanilla JS object', ->
      object = Batman(foo: 'bar')
      deepEqual object.toJSON(), {foo: 'bar'}

## ::hashKey() : string

Returns a unique string identifying this `Batman.Object`.

## ::batchAccessorChanges(key, wrappedFunction)

Prevents accessor `key` from being recalculated while the `wrappedFunction` is called on the `Object`. After `wrappedFunction` is complete, the accessor will be recomputed. Returns the result of `wrappedFunction`.

## ::accessor([keys...], objectOrFunction)

`accessor` defines an accessor on one instance of an object instead of on all instances like the class level `@accessor`. See `@accessor` for the details surrounding accessors.

    test 'accessor can be called on an instance of Batman.Object to define an accessor just on that instance', ->
      class Post extends Batman.Object
        @accessor 'summary', -> @get('body').slice(0, 10) + "..."

      post = new Post(body: "Why Batman is Useful: A lengthy post on an important subject")
      equal post.get('summary'), "Why Batman..."
      post.accessor('longSummary', -> @get('body').slice(0, 20) + "...")  # "Instance level accessor defines accessors just for that instance"
      equal post.get('longSummary'), "Why Batman is Useful..."

    test 'defining an accessor on an instance does not affect the other instances', ->
      class Post extends Batman.Object

      post = new Post(body: "Why Batman is Useful: A lengthy post on an important subject")
      otherPost = new Post(body: "Why State Machines Are Useful: Another lengthy post")
      post.accessor 'longSummary', -> @get('body').slice(0, 20) + "..."
      equal post.get('longSummary'), "Why Batman is Useful..."
      equal otherPost.get('longSummary'), undefined

## ::mixin(objects...) : this

Mixes `objects` into the `Object` instance. Keys from `objects` are applied with `set`. If any of `objects` has an `initialize` function, it will be called with the prototype being mixed into.

    test 'mixin on an instance applies the keys from the mixed in object to the instance', ->
      class Snake extends Batman.Object

      snake = new Snake()
      snake.mixin {canSlither: true}, {canHiss: true}
      ok snake.get('canSlither')
      ok snake.get('canHiss')

# /api/Data Structures/Batman.Object

`Batman.Object` is the superclass for virtually all objects in a batman.js application. `Batman.Object` mixes in:

- `Batman.Observable` for `get`, `set`, `observe` and others
- `Batman.EventEmitter` for `on`, `off`, `fire` and others

See [`Batman.Object Accessors`](/docs/api/batman.object_accessors.html) for a full description of `@accessor`, which defines properties on `Batman.Object`s.

## @accessor([keys...], objectOrFunction)

If `keys` is empty, defines a new default accessor for instances of the object, otherwise defines a new accessor on instances of the `Object` for `keys`.

`objectOrFunction` may be:

- An object with `get`, `set`, and/or `unset` keys whose values are functions which implement those operations.
- A function which will be treated as the `get` key of the accessor object.

## @classAccessor([keys...], objectOrFunction)

Follows the pattern of `Bamtan.Object.accessor`, but defines the accessor on the class (constructor) instead of on instances of the object.

    test '@classAccessor defines an accessor on the class', ->
      class WayneManor extends Batman.Object
        @classAccessor 'address', -> "123 Wayne Dr."

      equal WayneManor.get('address'), "123 Wayne Dr."
      # Wayne Manor burned down...
      equal (new WayneManor(isRebuilt: true)).constructor.get('address'), "123 Wayne Dr."

## @mixin(objects...) : prototype

Mixes in `objects` to the `Object`'s prototype. Keys from `objects` are applied with `set`. If any of `objects` has an `initialize` function, it will be called with the prototype being mixed into.

_Note_: `@mixin`, similar to `@accessor`, applies to all instances of a class. If you need to mix in to the class itself, look at `classMixin`. `@mixin` is intended for use during the class definition of a `Batman.Object` subclass.

    test '@mixin extends the prototype of a Batman.Object subclass', ->
      FishBehaviour =
        canBreatheUnderwater: true
      MammalBehaviour =
        initialize: ->
          @set('isMammal', true)
        canBreatheAboveWater: true

      class Platypus extends Batman.Object
        @mixin FishBehaviour, MammalBehaviour

      platypus = new Platypus
      ok platypus.get('isMammal'), "the initialize function is called with the target prototype"
      ok platypus.get('canBreatheAboveWater')
      ok platypus.get('canBreatheUnderwater')

## @classMixin(objects...) : this

`@classMixin` mixes `objects` into the class (constructor) in the same way that `@mixin` mixes into the prototype.

    test '@classMixin extends the Batman.Object subclass', ->
      Singleton =
        initialze: (subject) ->
          subject.accessor 'instance', -> new subject

      class Highlander extends Batman.Object
        @classMixin Singleton

      instance = Highlander.get('instance')
      ok instance == Highlander.get('instance'), "There can only be one."

## @observeAll(key, callback : function) : prototype

`@observeAll` extends the `Batman.Object` implementation of `Batman.Observable` with the ability to observe all instances of the class (and subclasses). Observers attached with `@observeAll` function exactly as if they were attached to the object directly. Returns the prototype of the class.

_Note_: `@observeAll` is intended to be used during the class definition for a `Batman.Object` subclass, but it can be called after the class has been defined as a function on the class. It supports being called after instances of the class have been instantiated as well.

    test "@observeAll attaches handlers which get called upon change", ->
      results = []
      class Song extends Batman.Object
        @observeAll 'length', (newValue, oldValue) -> results.push newValue

      song = new Song({length: 340, bpm: 120})
      equal song.set('length', 200), 200
      deepEqual results[1], 200

    test "@observeAll can attach handlers after instance instantiation", ->
      results = []
      class Song extends Batman.Object

      song = new Song({length: 340, bpm: 120})
      equal song.set('length', 360), 360
      deepEqual results[0], undefined
      Song.observeAll 'length', (newValue, oldValue) -> results.push newValue
      equal song.set('length', 200), 200
      deepEqual results[0], 200

## @delegate(properties..., options)

Delegates `properties` to `options.to` by creating new accessors for `properties` which call `to.get(property)`. `options` must include a `to` Object.

## @singleton(singletonMethodName[="sharedInstance"])

Shorthand for [singleton classes](http://en.wikipedia.org/wiki/Singleton_pattern). Defines a class accessor `singletonMethodName` which returns the singleton instance.

## @wrapAccessor([keys...,] wrapperFunction: Function)
## @wrapClassAccessor([keys...,] wrapperFunction: Function )
## ::wrapAccessor([keys...,] wrapperFunction)

## ::constructor(objects...) : Object

Creates a new `Batman.Object` with properties from `objects`. If items in `objects` have the same keys, later values take precendence over earlier ones. Values are applied with `set`, so custom accessors are applied. The `Batman` namespace performs the same function.

    test 'Batman() function allows for handy creation of Batman.Objects', ->
      object = Batman(foo: 'bar')
      equal typeof object.get, 'function'

    test 'Batman.Object constructor function accepts multiple mixin arguments and later mixins take precedence.', ->
      song = Batman({length: 100, bpm: 120}, {bpm: 130})
      equal song.get('length'), 100
      equal song.get('bpm'), 130, "The property from the second object passed to the constructor overwrites that from the first."

## ::toJSON() : object

`toJSON` returns a vanilla JavaScript object representing this `Batman.Object`.

    test 'toJSON returns a vanilla JS object', ->
      object = Batman(foo: 'bar')
      deepEqual object.toJSON(), {foo: 'bar'}

## ::hashKey() : string

Returns a unique string identifying this `Batman.Object`.

## ::batchAccessorChanges(key, wrappedFunction)

Prevents accessor `key` from being recalculated while the `wrappedFunction` is called on the `Object`. After `wrappedFunction` is complete, the accessor will be recomputed. Returns the result of `wrappedFunction`.

## ::accessor([keys...], objectOrFunction)

`accessor` defines an accessor on one instance of an object instead of on all instances like the class level `@accessor`. See `@accessor` for the details surrounding accessors.

    test 'accessor can be called on an instance of Batman.Object to define an accessor just on that instance', ->
      class Post extends Batman.Object
        @accessor 'summary', -> @get('body').slice(0, 10) + "..."

      post = new Post(body: "Why Batman is Useful: A lengthy post on an important subject")
      equal post.get('summary'), "Why Batman..."
      post.accessor('longSummary', -> @get('body').slice(0, 20) + "...")  # "Instance level accessor defines accessors just for that instance"
      equal post.get('longSummary'), "Why Batman is Useful..."

    test 'defining an accessor on an instance does not affect the other instances', ->
      class Post extends Batman.Object

      post = new Post(body: "Why Batman is Useful: A lengthy post on an important subject")
      otherPost = new Post(body: "Why State Machines Are Useful: Another lengthy post")
      post.accessor 'longSummary', -> @get('body').slice(0, 20) + "..."
      equal post.get('longSummary'), "Why Batman is Useful..."
      equal otherPost.get('longSummary'), undefined

## ::mixin(objects...) : this

Mixes `objects` into the `Object` instance. Keys from `objects` are applied with `set`. If any of `objects` has an `initialize` function, it will be called with the prototype being mixed into.

    test 'mixin on an instance applies the keys from the mixed in object to the instance', ->
      class Snake extends Batman.Object

      snake = new Snake()
      snake.mixin {canSlither: true}, {canHiss: true}
      ok snake.get('canSlither')
      ok snake.get('canHiss')


Add link from main spec to pluralize tests

react-maybe-matchers was built to write tests for another project.
The tests for the other project worked as a framework for testing
the matchers.  As such, the specs in this project have lagged behind.
I will try to update some realistic integration tests as soon
as possible.

One of the problems with integration tests is that you can't write
tests for failing matchers.  This project is unfortunately missing
any unit tests (high up on my priority list).

## Integration tests

In the [integration tests](./spec/integration_spec.litcoffee) you
will find examples of how to use the matchers.

    require("./integration_spec.litcoffee")

## String#pluralize unit tests

Some [examples of pluralizing strings]("./pluralize_spec.litcoffee")

    require("./pluralize_spec.litcoffee")

react-maybe-matchers was built to write tests for another project.
The tests for the other project worked as a framework for testing
the matchers.  As such, the specs in this project have lagged behind.
I will try to update some realistic integration tests as soon
as possible.

One of the problems with integration tests is that you can't write
tests for failing matchers.  This project is unfortunately missing
any unit tests (high up on my priority list).

## Integration tests

In the [integration tests](./spec/integration_spec.litcoffee) you
will find examples of how to use the matchers.

    require("./integration_spec.litcoffee")

## String#pluralize unit tests

    require("./pluralize_spec.litcoffee")


Fix links in spec (again)

Fix links in spec (again)

# Tests for react-maybe-matchers

react-maybe-matchers was built to write tests for another project.
The tests for the other project worked as a framework for testing
the matchers.  As such, the specs in this project have lagged behind.
I will try to update some realistic integration tests as soon
as possible.

One of the problems with integration tests is that you can't write
tests for failing matchers.  This project is unfortunately missing
any unit tests (high up on my priority list).

## Integration tests

In the [integration tests](./integration_spec.litcoffee#integration-tests) you
will find examples of how to use the matchers.

    require("./integration_spec.litcoffee")

## String#pluralize unit tests

Some [examples of pluralizing strings](./pluralize_spec.litcoffee#unit-tests-for-stringpluralize)

    require("./pluralize_spec.litcoffee")

# Tests for react-maybe-matchers

react-maybe-matchers was built to write tests for another project.
The tests for the other project worked as a framework for testing
the matchers.  As such, the specs in this project have lagged behind.
I will try to update some realistic integration tests as soon
as possible.

One of the problems with integration tests is that you can't write
tests for failing matchers.  This project is unfortunately missing
any unit tests (high up on my priority list).

## Integration tests

In the [integration tests](./spec/integration_spec.litcoffee#integration-tests) you
will find examples of how to use the matchers.

    require("./integration_spec.litcoffee")

## String#pluralize unit tests

Some [examples of pluralizing strings]("./pluralize_spec.litcoffee#unit-tests-for-stringpluralize")

    require("./pluralize_spec.litcoffee")


Beauty

Beauty

# Application entry point.

*Definition of the main top-level Angular module, with dependency gathering
and config/run hook invocation.*

Top-level module.

    angular.module 'shrub', ['shrub.core']

Include core Angular dependencies.

    coreDependencies = []
    coreDependencies.push 'ngRoute'
    coreDependencies.push 'ngSanitize'

`packageDependencies` will be automatically generated and populated by Grunt.
Packages implement the hook `angularPackageDependencies` to specify their
3rd-party module dependencies.

###### TODO: Link this to where this happens in Grunt for illustration.

    coreDependencies.push packageDependencies...

Include core shrub dependencies.

    coreDependencies.push 'shrub.config'
    coreDependencies.push 'shrub.packages'
    coreDependencies.push 'shrub.require'

Define the core Shrub module.

    angular.module('shrub.core', coreDependencies)

      .config([
        '$injector', 'shrub-pkgmanProvider'
        ({invoke}, {invokeFlat}) ->

#### Invoke hook `appConfig`.

Invoked when the Angular application is in the configuration phase.
Implementations should return an
[annotated function](http://docs.angularjs.org/guide/di#dependency-annotation).

          invoke injectable for injectable in invokeFlat 'appConfig'

      ])

      .run([

        '$injector', 'shrub-pkgman'
        ({invoke}, {invokeFlat}) ->

#### Invoke hook `appRun`.

Invoked when the Angular application is the run phase. Implementations should
return an
[annotated function](http://docs.angularjs.org/guide/di#dependency-annotation).

          invoke injectable for injectable in invokeFlat 'appRun'

      ])

# Application entry point.

Top-level module.

    angular.module 'shrub', ['shrub.core']

Include core Angular dependencies.

    coreDependencies = []
    coreDependencies.push 'ngRoute'
    coreDependencies.push 'ngSanitize'

`packageDependencies` will be automatically generated and populated by Grunt.
Packages implement the hook `angularPackageDependencies` to specify their
3rd-party module dependencies.

###### TODO: Link this to where this happens in Grunt for illustration.

    coreDependencies.push packageDependencies...

Include core shrub dependencies.

    coreDependencies.push 'shrub.config'
    coreDependencies.push 'shrub.packages'
    coreDependencies.push 'shrub.require'

Define the core Shrub module.

    angular.module('shrub.core', coreDependencies)

      .config([
        '$injector', 'shrub-pkgmanProvider'
        ({invoke}, {invokeFlat}) ->

#### Invoke hook `appConfig`.

Invoked when the Angular application is in the configuration phase.
Implementations should return an
[annotated function](http://docs.angularjs.org/guide/di#dependency-annotation).

          invoke injectable for injectable in invokeFlat 'appConfig'

      ])

      .run([

        '$injector', 'shrub-pkgman'
        ({invoke}, {invokeFlat}) ->

#### Invoke hook `appRun`.

Invoked when the Angular application is the run phase. Implementations should
return an
[annotated function](http://docs.angularjs.org/guide/di#dependency-annotation).

          invoke injectable for injectable in invokeFlat 'appRun'

      ])


Using the methods fixed for https://github.com/o2platform/fluentnode/issues/68 on http json calls

dependencies

    http  = require('http')
    https = require('https');
    url   = require('url')
    Server = http.Server

settings

    global.__fluentnode ?= {}
    global.__fluentnode.http ?= {}
    using global.__fluentnode.http, ->
      @.HTTP_GET_TIMEOUT = 500
      @.HTTP_GET_DELAY   = 10

**Server::add_Sockets_Close_Suport**

    Server::add_Sockets_Close_Suport = ()->
      #add support for capturing and closing open sockets
      @._sockets = {}
      @._socket_Count = 0;
      @.on 'connection',  (socket)=>
        socket_id = @._socket_Count++
        @._sockets[socket_id] = socket

        socket.on 'close',  ()=>
          delete @._sockets[socket_id];
      @

    Server::close_And_Destroy_Sockets = (callback)->
      if (@._sockets != undefined)                    # if this was set, destroy open sockets
        for socket_Id of @._sockets
            @._sockets[socket_Id].destroy()
            delete @._sockets[socket_Id];
      @.close ->
        callback()

    Server::listen_OnPort_Saying = (port, text, callback)->
      ip = '127.0.0.1'
      @.respond_With_String_As_Text(text)
       .add_Sockets_Close_Suport()
       .listen port, ip, ->
          callback()

    Server::respond_With_Request_Headers = (value)->
      delete @._events.request
      simple_Response = (req, res) ->
        res.writeHead(200, {'Content-Type': 'application/json'})
        res.end(req.headers.json_Str())
      @.addListener('request', simple_Response)
      @

    Server::respond_With_String_As_Text = (value)->
      delete @._events.request                                # removes previous listeners
      simple_Response = (req, res) ->
          res.writeHead(200, {'Content-Type': 'text/plain'})
          res.end(value)
      @.addListener('request', simple_Response)
      @

    Server::respond_With_Object_As_Json = (value)->
      delete @._events.request
      json_Response = (req, res) ->
        res.writeHead(200, {'Content-Type': 'application/json'})
        res.end(value.json_Str())
      @.addListener('request', json_Response)
      @

    Server::respond_With_Request_Object = ()->
      delete @._events.request
      json_Response = (req, res) ->
        res.writeHead(200, {'Content-Type': 'application/json'})
        res.end(req.json_Inspect())                           # unfortunatly there doesn't seem to be a way to create a JSON parseable object from req
      @.addListener('request', json_Response)
      @

    String::http_Status = (callback) ->
      http.get @.str(), (res) ->
        callback res.statusCode

    String::http_GET = (callback) ->
      url = url.parse(@.str())
      engine = if url.protocol is 'https:' then https else http
      req = engine.get @.str(), (res) ->
        data = '';
        res.on 'data', (chunk) -> data += chunk
        res.on 'end' , (     ) -> callback null, data, res

      req.on   'error',(err  ) ->
        callback err, null, null
      req

    String::GET = (callback) ->
      @.http_GET (error, data, res)-> callback(data)

@.**GET_Json**
@.**json_GET**

Makes a GET request to @ and JSON parses the html data received

Will throw an error if the returned data is not a valid JSON objec

Twin methods: json_GET

    String::GET_Json = (callback) ->
      @.http_GET (error, data, res)-> callback(data.json_Parse())

    String::json_GET = String::GET_Json

@.**json_GET_With_Timeout**

Makes a GET request (with a 500ms wait for valid data),
and JSON parses the html data received

    String::json_GET_With_Timeout = (callback)->
      @.http_GET_With_Timeout (data)->
        callback data.json_Parse()

@.**http_GET_Wait_For_Null**

Waits until a GET request to @ results null (or empty)

This is a good util method to check when servers go offline

    String::http_GET_Wait_For_Null = (callback)->
      timeout  = global.__fluentnode.http.HTTP_GET_TIMEOUT
      delay    = global.__fluentnode.http.HTTP_GET_DELAY
      attempts = ~~(timeout/delay)
      try_Http_Get = (next) =>
        @.GET (data)  =>
          if data
            next.invoke_In(delay)
          else
            callback(null)
      run_Tests = (count)=>
        if count
          try_Http_Get ()->
            run_Tests(count-1)
        else
          callback new Error("[http_GET_Wait_For_Null] never got a null from server #{@} after #{attempts} attempts")

      run_Tests(attempts)

@.**http_GET_With_Timeout**

Makes a GET request (with a 500ms wait for valid data)

    String::http_GET_With_Timeout = (callback)->
      timeout = global.__fluentnode.http.HTTP_GET_TIMEOUT
      delay   = global.__fluentnode.http.HTTP_GET_DELAY
      attempts = ~~(timeout/delay)
      try_Http_Get = (next) =>
        @.GET (data) =>
          if data
            callback(data)
          else
            (delay).invoke_After(next)
      run_Tests = (count)=>
        if count
          try_Http_Get ()->
            run_Tests(count-1)
        else
          callback null

      run_Tests attempts

    String::http_With_Options = (options, callback) ->
      url = url.parse(@.str())
      engine = if url.protocol is 'https:' then https else http
      options.hostname = options.hostname || url.hostname
      options.port     = options.port     || url.port
      options.path     = options.path     || url.path
      options.method   = options.method   || 'GET'

      req = engine.get options, (res) ->
        data = '';
        res.on 'data', (chunk) -> data += chunk
        res.on 'end' , (     ) -> callback null, data, res

      req.on   'error',(err  ) ->
        callback err, null, null
      req

    ###options =
        hostname: @,
        port: port,
        path: '/',
        method: 'GET'
        console.log @.str()###

---
back to [index](index.html)

dependencies

    http  = require('http')
    https = require('https');
    url   = require('url')
    Server = http.Server

settings

    global.__fluentnode ?= {}
    global.__fluentnode.http ?= {}
    using global.__fluentnode.http, ->
      @.HTTP_GET_TIMEOUT = 500
      @.HTTP_GET_DELAY   = 10

**Server::add_Sockets_Close_Suport**

    Server::add_Sockets_Close_Suport = ()->
      #add support for capturing and closing open sockets
      @._sockets = {}
      @._socket_Count = 0;
      @.on 'connection',  (socket)=>
        socket_id = @._socket_Count++
        @._sockets[socket_id] = socket

        socket.on 'close',  ()=>
          delete @._sockets[socket_id];
      @

    Server::close_And_Destroy_Sockets = (callback)->
      if (@._sockets != undefined)                    # if this was set, destroy open sockets
        for socket_Id of @._sockets
            @._sockets[socket_Id].destroy()
            delete @._sockets[socket_Id];
      @.close ->
        callback()

    Server::listen_OnPort_Saying = (port, text, callback)->
      ip = '127.0.0.1'
      @.respond_With_String_As_Text(text)
       .add_Sockets_Close_Suport()
       .listen port, ip, ->
          callback()

    Server::respond_With_Request_Headers = (value)->
      delete @._events.request
      simple_Response = (req, res) ->
        res.writeHead(200, {'Content-Type': 'application/json'})
        res.end(JSON.stringify(req.headers))
      @.addListener('request', simple_Response)
      @

    Server::respond_With_String_As_Text = (value)->
      delete @._events.request                                # removes previous listeners
      simple_Response = (req, res) ->
          res.writeHead(200, {'Content-Type': 'text/plain'})
          res.end(value)
      @.addListener('request', simple_Response)
      @

    Server::respond_With_Object_As_Json = (value)->
      delete @._events.request
      json_Response = (req, res) ->
        res.writeHead(200, {'Content-Type': 'application/json'})
        res.end(JSON.stringify(value))
      @.addListener('request', json_Response)
      @

    Server::respond_With_Request_Object = ()->
      delete @._events.request
      json_Response = (req, res) ->
        res.writeHead(200, {'Content-Type': 'application/json'})
        res.end(req.json_inspect())                           # unfortunatly there doesn't seem to be a way to create a JSON parseable object from req
      @.addListener('request', json_Response)
      @

    String::http_Status = (callback) ->
      http.get @.str(), (res) ->
        callback res.statusCode

    String::http_GET = (callback) ->
      url = url.parse(@.str())
      engine = if url.protocol is 'https:' then https else http
      req = engine.get @.str(), (res) ->
        data = '';
        res.on 'data', (chunk) -> data += chunk
        res.on 'end' , (     ) -> callback null, data, res

      req.on   'error',(err  ) ->
        callback err, null, null
      req

    String::GET = (callback) ->
      @.http_GET (error, data, res)-> callback(data)

@.**GET_Json**
@.**json_GET**

Makes a GET request to @ and JSON parses the html data received

Will throw an error if the returned data is not a valid JSON objec

Twin methods: json_GET

    String::GET_Json = (callback) ->
      @.http_GET (error, data, res)-> callback(JSON.parse(data))

    String::json_GET = String::GET_Json

@.**json_GET_With_Timeout**

Makes a GET request (with a 500ms wait for valid data),
and JSON parses the html data received

    String::json_GET_With_Timeout = (callback)->
      @.http_GET_With_Timeout (data)->
        callback data.json_Parse()

@.**http_GET_Wait_For_Null**

Waits until a GET request to @ results null (or empty)

This is a good util method to check when servers go offline

    String::http_GET_Wait_For_Null = (callback)->
      timeout  = global.__fluentnode.http.HTTP_GET_TIMEOUT
      delay    = global.__fluentnode.http.HTTP_GET_DELAY
      attempts = ~~(timeout/delay)
      try_Http_Get = (next) =>
        @.GET (data)  =>
          if data
            next.invoke_In(delay)
          else
            callback(null)
      run_Tests = (count)=>
        if count
          try_Http_Get ()->
            run_Tests(count-1)
        else
          callback new Error("[http_GET_Wait_For_Null] never got a null from server #{@} after #{attempts} attempts")

      run_Tests(attempts)

@.**http_GET_With_Timeout**

Makes a GET request (with a 500ms wait for valid data)

    String::http_GET_With_Timeout = (callback)->
      timeout = global.__fluentnode.http.HTTP_GET_TIMEOUT
      delay   = global.__fluentnode.http.HTTP_GET_DELAY
      attempts = ~~(timeout/delay)
      try_Http_Get = (next) =>
        @.GET (data) =>
          if data
            callback(data)
          else
            (delay).invoke_After(next)
      run_Tests = (count)=>
        if count
          try_Http_Get ()->
            run_Tests(count-1)
        else
          callback null

      run_Tests attempts

    String::http_With_Options = (options, callback) ->
      url = url.parse(@.str())
      engine = if url.protocol is 'https:' then https else http
      options.hostname = options.hostname || url.hostname
      options.port     = options.port     || url.port
      options.path     = options.path     || url.path
      options.method   = options.method   || 'GET'

      req = engine.get options, (res) ->
        data = '';
        res.on 'data', (chunk) -> data += chunk
        res.on 'end' , (     ) -> callback null, data, res

      req.on   'error',(err  ) ->
        callback err, null, null
      req

    ###options =
        hostname: @,
        port: port,
        path: '/',
        method: 'GET'
        console.log @.str()###

---
back to [index](index.html)