Widened help display

Widened help display

    module.exports = require 'yargs'
      .usage 'Usage: $0 [options] name1 name2 ...'
      .example '$0',
        'Creates a 50 x 15 level with 16 x 14 cells and an auto-generated name'
      .example '$0 -vvvvvvvv',
        "Create a 50 x 15 level with 16 x 14 cells, an auto-generated name, and
        logging set to verbosity level 8 (max)"
      .example '$0 -w 20 -h 20',
        'Creates a 50 x 15 level with 40 X 40 cells & an auto-generated name'
      .example '$0 -w 10 -h 10 -x 4',
        'Creates a 50 x 15 level with 40 x 40 cells and an auto-generated name'
      .example '$0 lvl1 lvl2',
        'Creates two levels, lvl1 & lvl2, each 50 X 15 with 16 x 14 cells'
      .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'
      .conflicts 'levels', 'l'
      .help 'help'
      .default
        verbosity:  3
        rows:       15
        columns:    50
        width:      8
        height:     7
        multiplier: 4
        pipeline:   [ 'png_blocks', 'png_walls', 'png_step_count' ]
      .epilogue '© Bryan Maynard 2016'
      .wrap 120
      .argv

    module.exports = require 'yargs'
      .usage 'Usage: $0 [options] name1 name2 ...'
      .example '$0',
        'Creates a 50 x 15 level with 16 x 14 cells and an auto-generated name'
      .example '$0 -vvvvvvvv',
        "Create a 50 x 15 level with 16 x 14 cells, an auto-generated name, and
        logging set to verbosity level 8 (max)"
      .example '$0 -w 20 -h 20',
        'Creates a 50 x 15 level with 40 X 40 cells & an auto-generated name'
      .example '$0 -w 10 -h 10 -x 4',
        'Creates a 50 x 15 level with 40 x 40 cells and an auto-generated name'
      .example '$0 lvl1 lvl2',
        'Creates two levels, lvl1 & lvl2, each 50 X 15 with 16 x 14 cells'
      .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'
      .conflicts 'levels', 'l'
      .help 'help'
      .default
        verbosity:  3
        rows:       15
        columns:    50
        width:      8
        height:     7
        multiplier: 4
        pipeline:   [ 'png_blocks', 'png_walls', 'png_step_count' ]
      .epilogue '© Bryan Maynard 2016'
      .argv


Fixed getTranslation/getX/getY/getZ reading from the wrong parts of the matrix.  Added setTranslation/setX/setY/setZ functions.  Added an experimental matrix interpolation function.

Matrices are arrays of 16 numbers forming a 4x4 matrix.

    temp1 = []
    temp2 = []
    rotationTemp = []
    tempVector = []
    tempVectorFrom = []
    tempVectorTo = []
    fromTemp = []
    toTemp = []
    tempVectorX = []
    tempVectorY = []
    tempVectorZ = []

    makeRotate = (axis1, axis2, axis3, axis4) ->
        temp3 = []
        rotationTemp.push temp3
        (radians, output) ->
            sin = Math.sin radians
            cos = Math.cos radians
            temp3[axis1] = cos
            temp3[axis2] = -sin
            temp3[axis3] = sin
            temp3[axis4] = cos
            module.exports.multiply output, temp3, output
            return

    vector = require "./vector.litcoffee"

    module.exports =

Given a matrix, calling the "identity" property writes the identity matrix to
it.

        identity: (output) ->
            for row in [0...4]
                for column in [0...4]
                    output[row * 4 + column] = if row is column then 1 else 0
            return

Given two matrices, calling the "copy" property copies every component from the
first to the second.

        copy: (input, output) ->
            output[index] = value for value, index in input
            return

Given three matrices, calling the "multiply" property multiplies the first two
together and writes the result to the third.

        multiply: (a, b, output) ->
            module.exports.copy a, temp1
            module.exports.copy b, temp2

            for row in [0...4]
                for column in [0...4]
                    temp = 0
                    for component in [0...4]
                        temp += temp1[component * 4 + column] * temp2[row * 4 + component]
                    output[row * 4 + column] = temp
            return

Given a number of radians and a matrix, calling the "rotateX" property modifies
the matrix to have been rotated by that number of radians about the X axis.

        rotateX: makeRotate 5, 6, 9, 10

Given a number of radians and a matrix, calling the "rotateY" property modifies
the matrix to have been rotated by that number of radians about the Y axis.

        rotateY: makeRotate 0, 2, 8, 10

Given a number of radians and a matrix, calling the "rotateZ" property modifies
the matrix to have been rotated by that number of radians about the Z axis.

        rotateZ: makeRotate 0, 1, 4, 5

Given a vector specifying the scaling factor on each axis and a matrix, calling
the "scale" property scales the matrix by those scaling factors.

        scale: (vector, output) ->
            output[index] *= vector[0] for index in [0...4]
            output[index] *= vector[1] for index in [4...8]
            output[index] *= vector[2] for index in [8...12]
            return

Given a vector specifying a translation and a matrix to translate, calling the
"translate" property applies that translation to that matrix.

        translate: (vector, output) ->
            output[3] += vector[0]
            output[7] += vector[1]
            output[11] += vector[2]
            return

Given a matrix, X, Y, Z and W values (defaulting to 0, 0, 0 and 1 respectively
if not given), calling the "apply" property returns an array of four numbers
representing the transformed vector.

        apply: (matrix, x, y, z, w) ->
            if x is undefined then x = 0
            if y is undefined then y = 0
            if z is undefined then z = 0
            if w is undefined then w = 1

            [
                x * matrix[0] + y * matrix[1] + z * matrix[2] + w * matrix[3]
                x * matrix[4] + y * matrix[5] + z * matrix[6] + w * matrix[7]
                x * matrix[8] + y * matrix[9] + z * matrix[10] + w * matrix[11]
                x * matrix[12] + y * matrix[13] + z * matrix[14] + w * matrix[15]
            ]

Given a matrix, input vector and output vector, calling the "applyToVector"
property writes the input vector transformed by the matrix to the output vector.

        applyToVector: (matrix, input, output) ->
            vector.copy input, vectorTemp
            output[0] = vectorTemp[0] * matrix[0] + vectorTemp[1] * matrix[1] + vectorTemp[2] * matrix[2] + matrix[3]
            output[1] = vectorTemp[0] * matrix[4] + vectorTemp[1] * matrix[5] + vectorTemp[2] * matrix[6] + matrix[7]
            output[2] = vectorTemp[0] * matrix[8] + vectorTemp[1] * matrix[9] + vectorTemp[2] * matrix[10] + matrix[11]
            return

Given a matrix and output vector, calling the "getTranslation" property writes
the translation applied by the matrix to the output vector.

        getTranslation: (matrix, output) ->
            output[0] = matrix[3]
            output[1] = matrix[7]
            output[2] = matrix[11]

Given a matrix and output vector, calling the "getX" property writes the vector
of the matrix's X axis (a scaled normal) to the output vector.

        getX: (matrix, output) ->
            output[0] = matrix[0]
            output[1] = matrix[1]
            output[2] = matrix[2]

Given a matrix and output vector, calling the "getY" property writes the vector
of the matrix's Y axis (a scaled normal) to the output vector.

        getY: (matrix, output) ->
            output[0] = matrix[4]
            output[1] = matrix[5]
            output[2] = matrix[6]

Given a matrix and output vector, calling the "getZ" property writes the vector
of the matrix's Z axis (a scaled normal) to the output vector.

        getZ: (matrix, output) ->
            output[0] = matrix[8]
            output[1] = matrix[9]
            output[2] = matrix[10]

# setTranslation

- A vector specifying the translation to set.
- A matrix to set the translation of.

Overwrites the translation of the matrix with the content of the given vector.

        setTranslation: (output, matrix) ->
            matrix[3] = output[0]
            matrix[7] = output[1]
            matrix[11] = output[2]

# setX

- A vector specifying the X axis vector to set.
- A matrix to set the X axis vector of.

Overwrites the X axis of the matrix with the content of the given vector.

        setX: (output, matrix) ->
            matrix[0] = output[0]
            matrix[1] = output[1]
            matrix[2] = output[2]

# setY

- A vector specifying the Y axis vector to set.
- A matrix to set the Y axis vector of.

Overwrites the Y axis of the matrix with the content of the given vector.

        setY: (output, matrix) ->
            matrix[4] = output[0]
            matrix[5] = output[1]
            matrix[6] = output[2]

# setZ

- A vector specifying the Z axis vector to set.
- A matrix to set the Z axis vector of.

Overwrites the Z axis of the matrix with the content of the given vector.

        setZ: (output, matrix) ->
            matrix[8] = output[0]
            matrix[9] = output[1]
            matrix[10] = output[2]

# interpolate

- An input matrix to interpolate from.
- An input matrix to interpolate to.
- A number specifying how far along to interpolate; "0" is "from" and "1" is
  "to".
- An output matrix.

Attempts to perform a somewhat crude interpolation between the two matrices
which is not very linear.  Good enough for smoothing over small changes.
Prioritizes the Z and Y axes over the X axis when ensuring orthogonal.

        interpolate: (from, to, alpha, output) ->
            module.exports.copy from, fromTemp
            module.exports.copy to, toTemp
            module.exports.identity output
            module.exports.getTranslation fromTemp, tempVectorFrom
            module.exports.getTranslation toTemp, tempVectorTo
            vector.interpolate tempVectorFrom, tempVectorTo, alpha, tempVector
            module.exports.setTranslation tempVector, output

            module.exports.getX fromTemp, tempVectorFrom
            module.exports.getX toTemp, tempVectorTo
            vector.interpolate tempVectorFrom, tempVectorTo, alpha, tempVector
            vector.normalize tempVector, tempVectorX, true

            module.exports.getY fromTemp, tempVectorFrom
            module.exports.getY toTemp, tempVectorTo
            vector.interpolate tempVectorFrom, tempVectorTo, alpha, tempVectorY

            vector.cross tempVectorX, tempVectorY, tempVectorZ
            vector.normalize tempVectorZ, tempVectorZ
            vector.cross tempVectorZ, tempVectorX, tempVectorY
            vector.normalize tempVectorY, tempVectorY

            module.exports.setX tempVectorX, output
            module.exports.setY tempVectorY, output
            module.exports.setZ tempVectorZ, output
            return

    module.exports.identity temp1
    module.exports.identity temp2
    for mat in rotationTemp
        module.exports.identity mat

Matrices are arrays of 16 numbers forming a 4x4 matrix.

    temp1 = []
    temp2 = []
    rotationTemp = []
    vectorTemp = []

    makeRotate = (axis1, axis2, axis3, axis4) ->
        temp3 = []
        rotationTemp.push temp3
        (radians, output) ->
            sin = Math.sin radians
            cos = Math.cos radians
            temp3[axis1] = cos
            temp3[axis2] = -sin
            temp3[axis3] = sin
            temp3[axis4] = cos
            module.exports.multiply output, temp3, output
            return

    vector = require "./vector.litcoffee"

    module.exports =

Given a matrix, calling the "identity" property writes the identity matrix to
it.

        identity: (output) ->
            for row in [0...4]
                for column in [0...4]
                    output[row * 4 + column] = if row is column then 1 else 0
            return

Given two matrices, calling the "copy" property copies every component from the
first to the second.

        copy: (input, output) ->
            output[index] = value for value, index in input
            return

Given three matrices, calling the "multiply" property multiplies the first two
together and writes the result to the third.

        multiply: (a, b, output) ->
            module.exports.copy a, temp1
            module.exports.copy b, temp2

            for row in [0...4]
                for column in [0...4]
                    temp = 0
                    for component in [0...4]
                        temp += temp1[component * 4 + column] * temp2[row * 4 + component]
                    output[row * 4 + column] = temp
            return

Given a number of radians and a matrix, calling the "rotateX" property modifies
the matrix to have been rotated by that number of radians about the X axis.

        rotateX: makeRotate 5, 6, 9, 10

Given a number of radians and a matrix, calling the "rotateY" property modifies
the matrix to have been rotated by that number of radians about the Y axis.

        rotateY: makeRotate 0, 2, 8, 10

Given a number of radians and a matrix, calling the "rotateZ" property modifies
the matrix to have been rotated by that number of radians about the Z axis.

        rotateZ: makeRotate 0, 1, 4, 5

Given a vector specifying the scaling factor on each axis and a matrix, calling
the "scale" property scales the matrix by those scaling factors.

        scale: (vector, output) ->
            output[index] *= vector[0] for index in [0...4]
            output[index] *= vector[1] for index in [4...8]
            output[index] *= vector[2] for index in [8...12]
            return

Given a vector specifying a translation and a matrix to translate, calling the
"translate" property applies that translation to that matrix.

        translate: (vector, output) ->
            output[3] += vector[0]
            output[7] += vector[1]
            output[11] += vector[2]
            return

Given a matrix, X, Y, Z and W values (defaulting to 0, 0, 0 and 1 respectively
if not given), calling the "apply" property returns an array of four numbers
representing the transformed vector.

        apply: (matrix, x, y, z, w) ->
            if x is undefined then x = 0
            if y is undefined then y = 0
            if z is undefined then z = 0
            if w is undefined then w = 1

            [
                x * matrix[0] + y * matrix[1] + z * matrix[2] + w * matrix[3]
                x * matrix[4] + y * matrix[5] + z * matrix[6] + w * matrix[7]
                x * matrix[8] + y * matrix[9] + z * matrix[10] + w * matrix[11]
                x * matrix[12] + y * matrix[13] + z * matrix[14] + w * matrix[15]
            ]

Given a matrix, input vector and output vector, calling the "applyToVector"
property writes the input vector transformed by the matrix to the output vector.

        applyToVector: (matrix, input, output) ->
            vector.copy input, vectorTemp
            output[0] = vectorTemp[0] * matrix[0] + vectorTemp[1] * matrix[1] + vectorTemp[2] * matrix[2] + matrix[3]
            output[1] = vectorTemp[0] * matrix[4] + vectorTemp[1] * matrix[5] + vectorTemp[2] * matrix[6] + matrix[7]
            output[2] = vectorTemp[0] * matrix[8] + vectorTemp[1] * matrix[9] + vectorTemp[2] * matrix[10] + matrix[11]
            return

Given a matrix and output vector, calling the "getTranslation" property writes
the translation applied by the matrix to the output vector.

        getTranslation: (matrix, output) ->
            output[0] = matrix[12]
            output[1] = matrix[13]
            output[2] = matrix[14]

Given a matrix and output vector, calling the "getX" property writes the vector
of the matrix's X axis (a scaled normal) to the output vector.

        getX: (matrix, output) ->
            output[0] = matrix[0]
            output[1] = matrix[4]
            output[2] = matrix[8]

Given a matrix and output vector, calling the "getY" property writes the vector
of the matrix's Y axis (a scaled normal) to the output vector.

        getY: (matrix, output) ->
            output[0] = matrix[1]
            output[1] = matrix[5]
            output[2] = matrix[9]

Given a matrix and output vector, calling the "getZ" property writes the vector
of the matrix's Z axis (a scaled normal) to the output vector.

        getZ: (matrix, output) ->
            output[0] = matrix[2]
            output[1] = matrix[6]
            output[2] = matrix[10]

    module.exports.identity temp1
    module.exports.identity temp2
    for mat in rotationTemp
        module.exports.identity mat


Clean up iteration logic

Clean up iteration logic

    q     = require 'q'
    fs    = require 'fs'
    async = require 'async'
    uuid  = require 'uuid-1345'

    microtime = require 'microtime'

    EventEmitter2 = require('eventemitter2').EventEmitter2
    emitter       = new EventEmitter2 wildcard: true

    available   = { }
    initialized = { }
    listeners   = { }

    underscore = (value) -> value.replace /\W+/g, '_'
    strip      = (name)  -> name.toLowerCase().replace /\W+/g, ''

    SEARCH_ROOTS  = { }
    WRAPPED       = { }
    _INITIALIZERS = { }
    HYDRATED      = { }
    LOCALS        = { }

    SKIP_WRAP = [
      'constructor'
      'initialize'
      'details'
      'fire'
      'warn'
      'listen'
      'set'
      'runtime_exception'
    ]

    HYRDATION_LISTENERS = { }

    INITIALIZERS = (cls, method) ->
      _INITIALIZERS[cls] = [ ] unless _INITIALIZERS[cls]?

      _INITIALIZERS[cls].push fn: method, called: false

    WRAP = (cls, method) ->
      WRAPPED[cls] = [ ] unless WRAPPED[cls]?

      WRAPPED[cls].indexOf(method) < 0

    determine_local = (token) ->
      project_local = false
      node_local    = false
      name          = token.substring 1, token.length

      if token[0] == '.'
        project_local = true
      else if token[0] == '~'
        node_local = true
      else
        name = token

      [project_local, node_local, name]

    parse_name_and_local = (tokens) ->
      [project_local, node_local, name] = determine_local tokens[0].trim()

      if tokens.length == 2
        alias = underscore tokens[1].trim()
      else if tokens.length == 1
        alias = underscore name
      else
        return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

      [project_local, node_local, name, alias]

    parse_alias_and_parent = (token) ->
      t = token.split '->'

      if t[0].indexOf('#') > -1
        r      = t[0].split '#'
        parent = r[0].trim()
        t[0]   = r[1]

      [parent, t]

    extract_properties = (token) ->
      [parent, t] = parse_alias_and_parent token
      [project_local, node_local, name, alias] = parse_name_and_local t

      [project_local, node_local, name, alias, parent]

    class Madul

      details: =>
        name  = @.__proto__.constructor.name
        props = for own key, val of @.__proto__
          if key != 'constructor' &&
             key != 'details'     &&
             key != 'initialize'  && ((
               key[0]            == '_' &&
               @.__proto__[key]? == false
             ) || key[0] != '_')

            if typeof val == 'function'
              value = val.constructor.name
            else if Array.isArray val
              value = for v in val
                if typeof v == 'function'
                  v.constructor.name
                else if typeof v == 'object'
                  v.constructor.name
                else
                  v
              value = value.join ','
            else if typeof val == 'object'
              value = val.constructor.name
            else
              value = val

            "#{key} => #{value}"

        "\n  #{name}\n    #{props.filter((e) -> e?).join '\n    '}"

      @DUMMY: (deps, cb) ->
        class __DUMMY__ extends Madul
          deps: deps

        new __DUMMY__()
          .initialize()
          .then cb

      @LISTEN: (event, callback) => emitter.on event, callback

      @FIRE: (event, args) => emitter.emit event, args

      @SEARCH_ROOT: (mod, path) =>
        Madul.FIRE '$.Madul.search_root.register', "#{mod}": path

        SEARCH_ROOTS[mod] = path.substring 0, path.lastIndexOf '/'

      @PARSE_SPEC: (value) =>
        tokens = value.split '='

        [project_local, node_local, name, alias, parent] = extract_properties tokens[0]

        if tokens.length == 2
          initializer = tokens[1].trim()
          toks        = initializer.split ':'
          initializer = toks[0].trim()

          if toks.length == 2
            prerequisites = toks[1].split(',').map (p) => p.trim()
          else if toks.length > 2
            return Madul.FIRE '!.Madul.dependency_spec.initializer.invalid', tokens[1]

        else if tokens.length > 2
          return Madul.FIRE '!.Madul.dependency_spec.invalid', d

        { ref: alias || underscore(name), alias, name, parent, initializer, prerequisites, project_local, node_local }

      @BUILD_SPEC: ({ search_root, name, alias, initializer, prerequisites }) =>
        unless name?
          return Madul.FIRE '!.Madul.dependency_spec.name-required', arguments[0]

        if prerequisites? && initializer? == false
          return Madul.FIRE '!.Madul.dependency_spec.prerequisites-require-initializer', arguments[0]

        "#{if search_root?   then "#{search_root}#"            else ''}\
         #{name}\
         #{if alias?         then " -> #{alias}"               else ''}\
         #{if initializer?   then " = #{initializer}"          else ''}\
         #{if prerequisites? then ":#{prerequisites.join ','}" else ''}\
        "

      listen: (event, callback) ->
        Madul.LISTEN "*.#{@constructor.name}.#{event}", callback

      fire: (event, args) ->
        Madul.FIRE "@.#{@constructor.name}.#{event}", args

      warn: (event, details, finisher) =>
        Madul.FIRE "!.#{@constructor.name}.#{event}", details

        finisher() if typeof finisher == 'function'

      runtime_exception: (exit = false) =>
        (err) =>
          Madul.FIRE "!.#{@constructor.name}.runtime-exception",
            stack:     err.stack
            message:   err.message
            timestamp: microtime.now()

          process.exit(1) if exit == 'DIE_ON_EXCEPTION'

      set: (prop, val) =>
        proto = @.__proto__
        mod   = available[strip proto.constructor.name.toLowerCase()]

        if mod?
          mod.__proto__[prop] = val

      _report: (method, state, id, args, breaker) =>
        invoke = undefined
        params =
          uuid:      id
          args:      args
          timestamp: microtime.now()

        if state == 'reject'
          if typeof breaker == 'function'
            stop = new Error()
            stop.break = true

            breaker stop

          @warn "#{method}.#{state}", params
        else
          @fire "#{method}.#{state}", params

      _respond: (proto, method, id, deferred) =>
        (state, data, breaker) =>
          process.nextTick =>
            deferred[state] data

            proto._report method, state, id, data, breaker

      _prep_invocation: (proto, method, input, def) =>
        out = [ ]
        id  = uuid.v4fast()
        res = proto._respond proto, method, id, def
        e   = (brk) =>
          error = (err) => res 'reject', err, brk

          if typeof brk == 'function'
            error
          else
            error brk

        if Array.isArray input
          out = out.concat input
        else if typeof input == 'object'
          out.push input
        else
          msg = "input to #{proto.constructor.name}.#{method} must be an Array of Object"

          proto.warn.call proto, 'input.invalid', msg

          throw new Error msg

        out.push (out) => res 'resolve', out
        out.push e
        out.push (out) => res 'notify',  out

        proto._report method, 'invoke', id, out

        out

      _process_decorators: (proto, type) =>
        if Array.isArray proto[type]
          proto[type].map (b) => Madul.PARSE_SPEC(b).ref
        else if typeof proto[type] == 'string'
          [ Madul.PARSE_SPEC(proto[type]).ref ]
        else
          [ ]

      _do_wrap: (proto, method, wrapped) =>
        if SKIP_WRAP.includes method
          wrapped()
        else
          Madul.FIRE "$.#{proto.constructor.name}.#{method}.wrap"

          if typeof proto[method] == 'function'
            proto["_#{method}"] = proto[method]

            proto[method] = =>
              def   = q.defer()
              args  = Array.prototype.slice.call arguments
              input = proto._prep_invocation proto, method, args, def

              try
                proto["_#{method}"].apply proto, input
              catch e
                failed = if input[0].fail? then input[0].fail else input[input.length - 2]

                proto.warn.call proto, 'runtime-exception', stack: e.stack, message: e.message

                failed e.message

              def.promise

            INITIALIZERS proto.constructor.name, method if method[0] == '$'

            WRAPPED[proto.constructor.name].push method

            wrapped()
          else if typeof proto[method] == 'object'

            if Array.isArray proto[method].validate
              args_format = 'ARRAY'
              decs        = proto[method].validate

              proto[method].validators = for val, i in decs
                "#{i}": Madul.PARSE_SPEC(val).ref
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = [ ]

              for own key, val of proto[method].validate
                if Array.isArray val
                  for v in val
                    decs.push v
                else if typeof val == 'object'
                  for own k, v of val
                    if Array.isArray v
                      for V in v
                        decs.push V
                    else
                      decs.push v
                else
                  decs.push val

              proto[method].validators = [ ]

              for own key, val of proto[method].validate
                if Array.isArray val
                  proto[method].validators.push "#{key}": for v in val
                    Madul.PARSE_SPEC(v).ref
                else if typeof val == 'object'
                  for own k, v of val
                    if Array.isArray v
                      proto[method].validators.push "#{key}.#{k}": for V in v
                        Madul.PARSE_SPEC(V).ref
                    else
                      proto[method].validators.push "#{key}.#{k}": Madul.PARSE_SPEC(v).ref
                else
                  proto[method].validators.push "#{key}": Madul.PARSE_SPEC(val).ref
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ proto[method].validate ]

              proto[method].validators = [ { 0: Madul.PARSE_SPEC(proto[method].validate).ref }]
            else if typeof proto[method].validate != 'undefined'
              proto.warn.call proto, 'meta.invalid', validate: 'must be a String, Object, or Array'
              return
            else
              args_format = 'ARRAY'
              decs        = [ ]

            if Array.isArray proto[method].before
              decs = decs.concat proto[method].before
            else if typeof proto[method].before == 'string'
              decs = decs.concat [ proto[method].before ]

            if Array.isArray proto[method].after
              decs = decs.concat proto[method].after
            else if typeof proto[method].after == 'string'
              decs = decs.concat [ Madul.PARSE_SPEC proto[method].after ]

            deduped = decs.filter (e, i, a) => a.indexOf(e) == i

            proto.fire.call proto, 'decorators.hydrate', deduped

            handle_err = (fn, args, next, reject) =>
              (err) =>
                proto.warn.call proto, "#{fn}.validator.failed", args
                reject err

                stop = new Error()
                stop.break = true

                next stop

            @_do_hydrate proto, deduped, (errors) =>
              if errors?
                wrapped errors
              else
                proto["_#{method}"] = proto[method]

                proto[method] = =>
                  def = q.defer()
                  me  = proto["_#{method}"]

                  if args_format == 'ARRAY'
                    args = Array.prototype.slice.call arguments
                  else if args_format == 'OBJECT'
                    args = arguments[0]
                  else
                    proto.warn.call proto, 'cannot-continue', 'No arg format specified'

                    return def.reject 'No arg format specified'

                  before = @_process_decorators me, 'before'
                  after  = @_process_decorators me, 'after'

                  q.Promise (resolve, reject) =>
                    async.eachSeries me.validators, (v, next) =>
                      arg       = Object.keys(v)[0]
                      validator = v[arg]
                      input     = arg
                      prop      = args

                      for a in arg.split '.'
                        prop  = prop[a]
                        input = a

                      if Array.isArray validator
                        async.eachSeries validator, (v, nxt) =>
                          proto.fire.call proto, 'validator.execute', "#{v}": prop

                          proto[v].EXECUTE.call proto[v], input, prop
                            .then nxt
                            .catch handle_err v, { "#{input}": prop }, nxt, (err) =>
                              reject err
                              def.reject err
                        , next
                      else
                        proto.fire.call proto, 'validator.execute', "#{validator}": prop

                        proto[validator].EXECUTE.call proto[validator], input, prop
                          .then next
                          .catch handle_err v, { "#{input}": prop }, next, (err) =>
                            reject err
                            def.reject err
                    , resolve
                  .catch (err) => def.reject err
                  .then =>
                    q.Promise (resolve, reject) =>
                      async.eachSeries before, (b, next) =>
                        proto.fire.call proto, 'before_filter.execute', "#{b}": args

                        proto[b].before.call proto[b], args
                          .then next
                          .catch handle_err b, args, next, (err) =>
                            reject err
                            def.reject err
                      , resolve
                  .catch (err) => def.reject err
                  .then =>
                    q.Promise (resolve, reject) =>
                      d     = q.defer()
                      input = proto._prep_invocation proto, method, args, d

                      try
                        me.behavior.apply proto, input
                          .then  (out) => resolve out
                          .catch (err) => reject  err
                      catch e
                        me.warn.call me, 'runtime-exception', stack: e.stack, message: e.message

                        reject e
                  .catch (err) => def.reject err
                  .then (result) =>
                    q.Promise (resolve, reject) =>
                      if after.length > 0
                        async.eachSeries after, (a, next) =>
                          proto.fire.call proto, 'after_filter.execute', "#{a}": args

                          proto[a].after.call proto[a], result
                            .then next
                            .catch handle_err b, args, next, (err) =>
                              reject err
                              def.reject err
                        , => resolve result
                      else
                        process.nextTick => resolve result
                  .then  (out) => def.resolve out
                  .catch (err) => def.reject  err

                  def.promise

                INITIALIZERS proto.constructor.name, method if method[0] == '$'

                WRAPPED[proto.constructor.name].push method

                wrapped()
          else
            proto.warn.call proto, 'cannot-wrap', method

      _wrap_methods: (proto, callback) =>
        name    = proto.constructor.name
        to_wrap = [ ]

        while proto? && Object.keys(proto).length > 0 && WRAPPED[name]? == false
          to_wrap.push { proto, name, methods: [ ] }

          for own prop, body of proto
            if prop[0]                  != '_'         &&
               typeof proto["_#{prop}"] == 'undefined' &&
               WRAP(name, prop)         == true

              if proto.deps?
                filtered = proto.deps.filter (d) => Madul.PARSE_SPEC(d).name == prop.replace /_/g, '-'

                continue if filtered.length > 0

              if typeof body == 'function' || typeof body?.behavior == 'function'
                to_wrap[to_wrap.length - 1].methods.push prop

          proto = proto.__proto__
          name  = proto.constructor.name

        async.each to_wrap.reverse(), (wrap, completed) =>
          async.each wrap.methods, (method, next) =>
            wrap.proto._do_wrap wrap.proto, method, (errors) =>
              if errors?
                stop = new Error()
                stop.break = true

                next stop
              else
                next()
          , (errors) =>
            if errors?
              stop = new Error()
              stop.break = true

              completed stop
            else
              @_call_initializers_for wrap.proto, wrap.name, completed
        , callback

      _make_available: (name, mod) =>
        Madul.FIRE "$.#{strip name}.available"

        available[strip name] = mod

      _hydrate_deps: (proto, done) =>
        protos = [ proto ]

        if proto.__proto__?
          while proto.__proto__? && Object.keys(proto.__proto__).length > 0
            protos.push proto = proto.__proto__

        async.each protos.reverse(), (p, next) =>
          name = p.constructor.name

          if p.hasOwnProperty 'deps'
            if HYDRATED[name] == undefined
              HYDRATED[name]            = false
              HYRDATION_LISTENERS[name] = [ next ]

              p._do_hydrate p, p.deps, (errors) =>
                if errors?
                  stop = new Error()
                  stop.break = true

                  next stop
                else
                  HYDRATED[name] = true

                  for listener in HYRDATION_LISTENERS[name]
                    listener()
            else if HYDRATED[name] == false
              HYRDATION_LISTENERS[name].push next
            else if HYDRATED[name] == true
              next()
          else
            next()
        , done

      _init_if_madul: (path, done, fail) =>
        mod      = require path
        proto    = mod
        is_madul = false

        while proto
          is_madul = true if proto.name == 'Madul'
          if is_madul                            == false      &&
             proto.constructor.name              != 'Object'   &&
             typeof proto                        == 'function' &&
             typeof proto.__super__?.constructor == 'function'
            proto = proto.__super__.constructor
          else
            proto = undefined

        if is_madul
          new mod()
            .initialize()
            .then  (m)   => done m
            .catch (err) => fail err
        else
          done mod

      _load: (me, name, path, loaded, fail) =>
        me._init_if_madul path, (mod) =>
          me._make_available name, mod
          loaded()
        , fail

      _check: (me, path, dep, ref, finished) =>
        fs.readdir path, (err, files) =>
          if err?
            me.warn 'file-not-found', err

            finished 'NOT_FOUND'
          else
            async.eachSeries files, (f, next) =>
              depth = "#{path}/#{f}"

              fs.stat depth, (e, s) =>
                if s.isDirectory() && f[0] != '.' && f != 'node_modules'
                  me._check me, depth, dep, ref, => next()
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  stop  = new Error()
                  stop.break = true

                  me._load me, ref, depth, =>
                    me._do_add me, ref, => next stop
                  , (err) => next stop
                else
                  next()
            , => finished()

      _do_add: (me, ref, next) =>
        Madul.FIRE "$.#{me.constructor.name}.dependency.register", ref

        me[underscore ref] = available[strip ref]

        next() if typeof next == 'function'

      _add: (me, ref, path, next) =>
        me._init_if_madul path, (mod) =>
          me._make_available ref, mod
          me._do_add me, ref, next
        , (err) =>
          stop = new Error()
          stop.break = true

          next stop

      _do_hydrate: (proto, deps, hydration_complete) =>
        initers = [ ]
        errors  = [ ]

        async.eachSeries deps, (d, next) =>
          spec = Madul.PARSE_SPEC d

          if spec.prerequisites?
            insert_at = for p in spec.prerequisites
              index_for = (sibling) => sibling.alias == p.alias

              initers.find index_for

            insert_at.sort()

            insert_at = if insert_at.length == 0 then 0 else insert_at[insert_at.length - 1]

            initers.splice insert_at, 0, alias: spec.alias, execute: spec.initializer
          else if spec.initializer?
            initers.push alias: spec.alias, execute: spec.initializer

          if typeof proto[underscore spec.ref] == 'undefined'
            if available[strip spec.ref]? == true
              proto._do_add proto, spec.ref, next
            else
              if spec.parent?
                if proto[spec.parent]?
                  proto._check proto, SEARCH_ROOTS[spec.parent], spec.name, spec.ref, (err) =>
                    if err?
                      deep = "#{SEARCH_ROOTS[spec.parent]}/node_modules/#{spec.parent}/dist"

                      proto._check proto, deep, spec.name, spec.ref, (e) =>
                        next()
                    else
                      next()
                else
                  proto.fire.call proto, 'search_root.load', { name: spec.name, alias: spec.alias, parent: spec.parent }

                  @_do_hydrate proto, [ spec.parent ], (errors) =>
                    if errors?
                      stop = new Error()
                      stop.break = true

                      next stop
                    else
                      if SEARCH_ROOTS[spec.parent] == undefined
                        SEARCH_ROOTS[spec.parent] = @_find_code_root spec.parent

                      proto._check proto, SEARCH_ROOTS[spec.parent], spec.name, spec.ref, (err) =>
                        if err?
                          deep = "#{SEARCH_ROOTS[spec.parent]}/node_modules/#{spec.parent}/dist"

                          proto._check proto, deep, spec.name, spec.ref, (e) =>
                            next()
                        else
                          next()
              else if spec.node_local
                key = @_find_require_key proto.constructor.name

                async.eachSeries require.cache[key].paths, (path, nxt) =>
                  @_load_from_package_json proto, path, spec.name, spec.ref, =>
                    nxt()
                  , =>
                    nxt()
                , =>
                  next()
              else if spec.project_local
                proto._check proto, LOCALS[proto.constructor.name], spec.name, spec.ref, (err) =>
                  if err?
                    details = not_found: spec.name
                    stop    = new Error()

                    stop.break = true

                    proto.warn.call proto, 'hydrating', details

                    errors.push(details)

                    next stop
                  else
                    next()
              else
                try
                  proto._add proto, spec.ref, spec.name, next
                catch e
                  path = "#{process.cwd()}/node_modules"

                  @_load_from_package_json proto, path, spec.name, spec.ref, next, =>
                    pth = LOCALS[proto.constructor.name]

                    try
                      proto._check proto, pth, spec.name, spec.ref, (err) =>
                        if err?
                          proto._check proto, "#{process.cwd()}/dist", spec.name, spec.ref, next
                        else
                          next()

          else
            next()
        , (err) =>
          if err?.length > 0
            proto.warn.call proto, 'hydration.halt', errors

            hydration_complete errors
          else
            async.eachSeries initers, (initer, next) =>
              proto[initer.execute].apply(@).then next
            , hydration_complete

      _load_from_package_json: (proto, path, name, ref, success, next) =>
        pkg = "#{path}/#{name}/package.json"
        fs.stat pkg, (err, stat) =>
          if err?
            next()
          else if stat.isFile()
            fs.readFile pkg, 'utf8', (err, data) =>
              json = JSON.parse data
              main = json.main || json._main || 'index.js'
              path = "#{path}/#{name}/#{main}"

              proto._add proto, ref, path, success
          else
            next()

      _finish_up: (proto, args) =>
        name = proto.constructor.name

        if listeners[name]?
          async.each listeners[name], (listener, next) =>
            listener @
            next()
          , => @_register_initialized name
        else
          @_register_initialized name

      _register_initialized: (name) =>
        @_make_available name, @

        initialized[name] = true

        Madul.FIRE "$.#{name}.initialized"

      _call_initializers_for: (proto, name, callback) =>
        if _INITIALIZERS[name]?
          async.each _INITIALIZERS[name], (initializer, next) =>
            if initializer.called == false
              proto[initializer.fn].apply proto
                .then =>
                  initializer.called = true
                  next()
            else
              next()
          , callback
        else
          callback()

      _do_find: (thing, cb) =>
        file  = thing.toLowerCase()
        found = for own key, val of require.cache
          if key.replace(/_/g, '').toLowerCase().includes file
            cb key

        filtered = found.filter (f) => f?

        if filtered.length > 0
          filtered.sort((a, b) => a.length - b.length)[0]
        else
          [ ]

      _find_require_key: (resource) =>
        @_do_find resource, (key) => key

      _find_code_root: (resource) =>
        @_do_find resource, (key) => key.substring(0, key.lastIndexOf '/').split '/'
          .join '/'

      initialize: =>
        deferred = q.defer()
        proto    = @.__proto__
        name     = proto.constructor.name

        Madul.FIRE "$.#{name}.request_instance"

        if initialized[name] == undefined
          Madul.FIRE "$.#{name}.initialize"

          initialized[name] = false
          listeners[name]   = [ deferred.resolve ]

          if LOCALS[name] == undefined
            LOCALS[name] = @_find_code_root name

          @_hydrate_deps proto, (errors) =>
            if errors?
              deferred.reject errors
            else
              @_wrap_methods proto, (err) =>
                if err?
                  deferred.reject err
                else
                  @_finish_up proto
        else if initialized[name] == false
          listeners[name].push deferred.resolve
        else if initialized[name] == true
          process.nextTick => deferred.resolve available[strip name]

        deferred.promise

    module.exports = Madul

    q     = require 'q'
    fs    = require 'fs'
    async = require 'async'
    uuid  = require 'uuid-1345'

    microtime = require 'microtime'

    EventEmitter2 = require('eventemitter2').EventEmitter2
    emitter       = new EventEmitter2 wildcard: true

    available   = { }
    initialized = { }
    listeners   = { }

    underscore = (value) -> value.replace /\W+/g, '_'
    strip      = (name)  -> name.toLowerCase().replace /\W+/g, ''

    SEARCH_ROOTS  = { }
    WRAPPED       = { }
    _INITIALIZERS = { }
    HYDRATED      = { }
    LOCALS        = { }

    SKIP_WRAP = [
      'constructor'
      'initialize'
      'details'
      'fire'
      'warn'
      'listen'
      'set'
      'runtime_exception'
    ]

    HYRDATION_LISTENERS = { }

    INITIALIZERS = (cls, method) ->
      _INITIALIZERS[cls] = [ ] unless _INITIALIZERS[cls]?

      _INITIALIZERS[cls].push fn: method, called: false

    WRAP = (cls, method) ->
      WRAPPED[cls] = [ ] unless WRAPPED[cls]?

      WRAPPED[cls].indexOf(method) < 0

    determine_local = (token) ->
      project_local = false
      node_local    = false
      name          = token.substring 1, token.length

      if token[0] == '.'
        project_local = true
      else if token[0] == '~'
        node_local = true
      else
        name = token

      [project_local, node_local, name]

    parse_name_and_local = (tokens) ->
      [project_local, node_local, name] = determine_local tokens[0].trim()

      if tokens.length == 2
        alias = underscore tokens[1].trim()
      else if tokens.length == 1
        alias = underscore name
      else
        return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

      [project_local, node_local, name, alias]

    parse_alias_and_parent = (token) ->
      t = token.split '->'

      if t[0].indexOf('#') > -1
        r      = t[0].split '#'
        parent = r[0].trim()
        t[0]   = r[1]

      [parent, t]

    extract_properties = (token) ->
      [parent, t] = parse_alias_and_parent token
      [project_local, node_local, name, alias] = parse_name_and_local t

      [project_local, node_local, name, alias, parent]

    class Madul

      details: =>
        name  = @.__proto__.constructor.name
        props = for own key, val of @.__proto__
          if key != 'constructor' &&
             key != 'details'     &&
             key != 'initialize'  && ((
               key[0]            == '_' &&
               @.__proto__[key]? == false
             ) || key[0] != '_')

            if typeof val == 'function'
              value = val.constructor.name
            else if Array.isArray val
              value = for v in val
                if typeof v == 'function'
                  v.constructor.name
                else if typeof v == 'object'
                  v.constructor.name
                else
                  v
              value = value.join ','
            else if typeof val == 'object'
              value = val.constructor.name
            else
              value = val

            "#{key} => #{value}"

        "\n  #{name}\n    #{props.filter((e) -> e?).join '\n    '}"

      @DUMMY: (deps, cb) ->
        class __DUMMY__ extends Madul
          deps: deps

        new __DUMMY__()
          .initialize()
          .then cb

      @LISTEN: (event, callback) => emitter.on event, callback

      @FIRE: (event, args) => emitter.emit event, args

      @SEARCH_ROOT: (mod, path) =>
        Madul.FIRE '$.Madul.search_root.register', "#{mod}": path

        SEARCH_ROOTS[mod] = path.substring 0, path.lastIndexOf '/'

      @PARSE_SPEC: (value) =>
        tokens = value.split '='

        [project_local, node_local, name, alias, parent] = extract_properties tokens[0]

        if tokens.length == 2
          initializer = tokens[1].trim()
          toks        = initializer.split ':'
          initializer = toks[0].trim()

          if toks.length == 2
            prerequisites = toks[1].split(',').map (p) => p.trim()
          else if toks.length > 2
            return Madul.FIRE '!.Madul.dependency_spec.initializer.invalid', tokens[1]

        else if tokens.length > 2
          return Madul.FIRE '!.Madul.dependency_spec.invalid', d

        { ref: alias || underscore(name), alias, name, parent, initializer, prerequisites, project_local, node_local }

      @BUILD_SPEC: ({ search_root, name, alias, initializer, prerequisites }) =>
        unless name?
          return Madul.FIRE '!.Madul.dependency_spec.name-required', arguments[0]

        if prerequisites? && initializer? == false
          return Madul.FIRE '!.Madul.dependency_spec.prerequisites-require-initializer', arguments[0]

        "#{if search_root?   then "#{search_root}#"            else ''}\
         #{name}\
         #{if alias?         then " -> #{alias}"               else ''}\
         #{if initializer?   then " = #{initializer}"          else ''}\
         #{if prerequisites? then ":#{prerequisites.join ','}" else ''}\
        "

      listen: (event, callback) ->
        Madul.LISTEN "*.#{@constructor.name}.#{event}", callback

      fire: (event, args) ->
        Madul.FIRE "@.#{@constructor.name}.#{event}", args

      warn: (event, details, finisher) =>
        Madul.FIRE "!.#{@constructor.name}.#{event}", details

        finisher() if typeof finisher == 'function'

      runtime_exception: (exit = false) =>
        (err) =>
          Madul.FIRE "!.#{@constructor.name}.runtime-exception",
            stack:     err.stack
            message:   err.message
            timestamp: microtime.now()

          process.exit(1) if exit == 'DIE_ON_EXCEPTION'

      set: (prop, val) =>
        proto = @.__proto__
        mod   = available[strip proto.constructor.name.toLowerCase()]

        if mod?
          mod.__proto__[prop] = val

      _report: (method, state, id, args, breaker) =>
        invoke = undefined
        params =
          uuid:      id
          args:      args
          timestamp: microtime.now()

        if state == 'reject'
          if typeof breaker == 'function'
            stop = new Error()
            stop.break = true

            breaker stop

          @warn "#{method}.#{state}", params
        else
          @fire "#{method}.#{state}", params

      _respond: (proto, method, id, deferred) =>
        (state, data, breaker) =>
          process.nextTick =>
            deferred[state] data

            proto._report method, state, id, data, breaker

      _prep_invocation: (proto, method, input, def) =>
        out = [ ]
        id  = uuid.v4fast()
        res = proto._respond proto, method, id, def
        e   = (brk) =>
          error = (err) => res 'reject', err, brk

          if typeof brk == 'function'
            error
          else
            error brk

        if Array.isArray input
          out = out.concat input
        else if typeof input == 'object'
          out.push input
        else
          msg = "input to #{proto.constructor.name}.#{method} must be an Array of Object"

          proto.warn.call proto, 'input.invalid', msg

          throw new Error msg

        out.push (out) => res 'resolve', out
        out.push e
        out.push (out) => res 'notify',  out

        proto._report method, 'invoke', id, out

        out

      _process_decorators: (proto, type) =>
        if Array.isArray proto[type]
          proto[type].map (b) => Madul.PARSE_SPEC(b).ref
        else if typeof proto[type] == 'string'
          [ Madul.PARSE_SPEC(proto[type]).ref ]
        else
          [ ]

      _do_wrap: (proto, method, wrapped) =>
        if SKIP_WRAP.includes method
          wrapped()
        else
          Madul.FIRE "$.#{proto.constructor.name}.#{method}.wrap"

          if typeof proto[method] == 'function'
            proto["_#{method}"] = proto[method]

            proto[method] = =>
              def   = q.defer()
              args  = Array.prototype.slice.call arguments
              input = proto._prep_invocation proto, method, args, def

              try
                proto["_#{method}"].apply proto, input
              catch e
                failed = if input[0].fail? then input[0].fail else input[input.length - 2]

                proto.warn.call proto, 'runtime-exception', stack: e.stack, message: e.message

                failed e.message

              def.promise

            INITIALIZERS proto.constructor.name, method if method[0] == '$'

            WRAPPED[proto.constructor.name].push method

            wrapped()
          else if typeof proto[method] == 'object'

            if Array.isArray proto[method].validate
              args_format = 'ARRAY'
              decs        = proto[method].validate

              proto[method].validators = for val, i in decs
                "#{i}": Madul.PARSE_SPEC(val).ref
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = [ ]

              for own key, val of proto[method].validate
                if Array.isArray val
                  for v in val
                    decs.push v
                else if typeof val == 'object'
                  for own k, v of val
                    if Array.isArray v
                      for V in v
                        decs.push V
                    else
                      decs.push v
                else
                  decs.push val

              proto[method].validators = [ ]

              for own key, val of proto[method].validate
                if Array.isArray val
                  proto[method].validators.push "#{key}": for v in val
                    Madul.PARSE_SPEC(v).ref
                else if typeof val == 'object'
                  for own k, v of val
                    if Array.isArray v
                      proto[method].validators.push "#{key}.#{k}": for V in v
                        Madul.PARSE_SPEC(V).ref
                    else
                      proto[method].validators.push "#{key}.#{k}": Madul.PARSE_SPEC(v).ref
                else
                  proto[method].validators.push "#{key}": Madul.PARSE_SPEC(val).ref
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ proto[method].validate ]

              proto[method].validators = [ { 0: Madul.PARSE_SPEC(proto[method].validate).ref }]
            else if typeof proto[method].validate != 'undefined'
              proto.warn.call proto, 'meta.invalid', validate: 'must be a String, Object, or Array'
              return
            else
              args_format = 'ARRAY'
              decs        = [ ]

            if Array.isArray proto[method].before
              decs = decs.concat proto[method].before
            else if typeof proto[method].before == 'string'
              decs = decs.concat [ proto[method].before ]

            if Array.isArray proto[method].after
              decs = decs.concat proto[method].after
            else if typeof proto[method].after == 'string'
              decs = decs.concat [ Madul.PARSE_SPEC proto[method].after ]

            deduped = decs.filter (e, i, a) => a.indexOf(e) == i

            proto.fire.call proto, 'decorators.hydrate', deduped

            handle_err = (fn, args, next, reject) =>
              (err) =>
                proto.warn.call proto, "#{fn}.validator.failed", args
                reject err

                stop = new Error()
                stop.break = true

                next stop

            @_do_hydrate proto, deduped, (errors) =>
              if errors?
                wrapped errors
              else
                proto["_#{method}"] = proto[method]

                proto[method] = =>
                  def = q.defer()
                  me  = proto["_#{method}"]

                  if args_format == 'ARRAY'
                    args = Array.prototype.slice.call arguments
                  else if args_format == 'OBJECT'
                    args = arguments[0]
                  else
                    proto.warn.call proto, 'cannot-continue', 'No arg format specified'

                    return def.reject 'No arg format specified'

                  before = @_process_decorators me, 'before'
                  after  = @_process_decorators me, 'after'

                  q.Promise (resolve, reject) =>
                    async.eachSeries me.validators, (v, next) =>
                      arg       = Object.keys(v)[0]
                      validator = v[arg]
                      input     = arg
                      prop      = args

                      for a in arg.split '.'
                        prop  = prop[a]
                        input = a

                      if Array.isArray validator
                        async.eachSeries validator, (v, nxt) =>
                          proto.fire.call proto, 'validator.execute', "#{v}": prop

                          proto[v].EXECUTE.call proto[v], input, prop
                            .then nxt
                            .catch handle_err v, { "#{input}": prop }, nxt, (err) =>
                              reject err
                              def.reject err
                        , next
                      else
                        proto.fire.call proto, 'validator.execute', "#{validator}": prop

                        proto[validator].EXECUTE.call proto[validator], input, prop
                          .then next
                          .catch handle_err v, { "#{input}": prop }, next, (err) =>
                            reject err
                            def.reject err
                    , resolve
                  .catch (err) => def.reject err
                  .then =>
                    q.Promise (resolve, reject) =>
                      async.eachSeries before, (b, next) =>
                        proto.fire.call proto, 'before_filter.execute', "#{b}": args

                        proto[b].before.call proto[b], args
                          .then next
                          .catch handle_err b, args, next, (err) =>
                            reject err
                            def.reject err
                      , resolve
                  .catch (err) => def.reject err
                  .then =>
                    q.Promise (resolve, reject) =>
                      d     = q.defer()
                      input = proto._prep_invocation proto, method, args, d

                      try
                        me.behavior.apply proto, input
                          .then  (out) => resolve out
                          .catch (err) => reject  err
                      catch e
                        me.warn.call me, 'runtime-exception', stack: e.stack, message: e.message

                        reject e
                  .catch (err) => def.reject err
                  .then (result) =>
                    q.Promise (resolve, reject) =>
                      if after.length > 0
                        async.eachSeries after, (a, next) =>
                          proto.fire.call proto, 'after_filter.execute', "#{a}": args

                          proto[a].after.call proto[a], result
                            .then next
                            .catch handle_err b, args, next, (err) =>
                              reject err
                              def.reject err
                        , => resolve result
                      else
                        process.nextTick => resolve result
                  .then  (out) => def.resolve out
                  .catch (err) => def.reject  err

                  def.promise

                INITIALIZERS proto.constructor.name, method if method[0] == '$'

                WRAPPED[proto.constructor.name].push method

                wrapped()
          else
            proto.warn.call proto, 'cannot-wrap', method

      _wrap_methods: (proto, callback) =>
        name    = proto.constructor.name
        to_wrap = [ ]

        while proto? && Object.keys(proto).length > 0 && WRAPPED[name]? == false
          to_wrap.push { proto, name, methods: [ ] }

          for own prop, body of proto
            if prop[0]                  != '_'         &&
               typeof proto["_#{prop}"] == 'undefined' &&
               WRAP(name, prop)         == true

              if proto.deps?
                filtered = proto.deps.filter (d) => Madul.PARSE_SPEC(d).name == prop.replace /_/g, '-'

                continue if filtered.length > 0

              if typeof body == 'function' || typeof body?.behavior == 'function'
                to_wrap[to_wrap.length - 1].methods.push prop

          proto = proto.__proto__
          name  = proto.constructor.name

        async.each to_wrap.reverse(), (wrap, completed) =>
          async.each wrap.methods, (method, next) =>
            wrap.proto._do_wrap wrap.proto, method, (errors) =>
              if errors?
                stop = new Error()
                stop.break = true

                next stop
              else
                next()
          , (errors) =>
            if errors?
              stop = new Error()
              stop.break = true

              completed stop
            else
              @_call_initializers_for wrap.proto, wrap.name, completed
        , callback

      _make_available: (name, mod) =>
        Madul.FIRE "$.#{strip name}.available"

        available[strip name] = mod

      _hydrate_deps: (proto, done) =>
        protos = [ proto ]

        if proto.__proto__?
          while proto.__proto__? && Object.keys(proto.__proto__).length > 0
            protos.push proto = proto.__proto__

        async.each protos.reverse(), (p, next) =>
          name = p.constructor.name

          if p.hasOwnProperty 'deps'
            if HYDRATED[name] == undefined
              HYDRATED[name]            = false
              HYRDATION_LISTENERS[name] = [ next ]

              p._do_hydrate p, p.deps, (errors) =>
                if errors?
                  stop = new Error()
                  stop.break = true

                  next stop
                else
                  HYDRATED[name] = true

                  for listener in HYRDATION_LISTENERS[name]
                    listener()
            else if HYDRATED[name] == false
              HYRDATION_LISTENERS[name].push next
            else if HYDRATED[name] == true
              next()
          else
            next()
        , done

      _init_if_madul: (path, done, fail) =>
        mod      = require path
        proto    = mod
        is_madul = false

        while proto
          is_madul = true if proto.name == 'Madul'
          if is_madul                            == false      &&
             proto.constructor.name              != 'Object'   &&
             typeof proto                        == 'function' &&
             typeof proto.__super__?.constructor == 'function'
            proto = proto.__super__.constructor
          else
            proto = undefined

        if is_madul
          new mod()
            .initialize()
            .then  (m)   => done m
            .catch (err) => fail err
        else
          done mod

      _load: (me, name, path, loaded, fail) =>
        me._init_if_madul path, (mod) =>
          me._make_available name, mod
          loaded()
        , fail

      _check: (me, path, dep, ref, finished) =>
        fs.readdir path, (err, files) =>
          if err?
            me.warn 'file-not-found', err

            finished 'NOT_FOUND'
          else
            error   = true
            checked = 0

            async.eachOfSeries files, (f, i, next) =>
              depth = "#{path}/#{f}"

              fs.stat depth, (e, s) =>
                if s.isDirectory() && f[0] != '.' && f != 'node_modules'
                  me._check me, depth, dep, ref, => next()
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  stop  = new Error()
                  stop.break = true

                  me._load me, ref, depth, =>
                    error  = undefined
                    loaded = true

                    me._do_add me, ref, => next stop
                  , (err) => next stop
                else
                  next()
            , => finished error

      _do_add: (me, ref, next) =>
        Madul.FIRE "$.#{me.constructor.name}.dependency.register", ref

        me[underscore ref] = available[strip ref]

        next() if typeof next == 'function'

      _add: (me, ref, path, next) =>
        me._init_if_madul path, (mod) =>
          me._make_available ref, mod
          me._do_add me, ref, next
        , (err) =>
          stop = new Error()
          stop.break = true

          next stop

      _do_hydrate: (proto, deps, hydration_complete) =>
        initers = [ ]
        errors  = [ ]

        async.eachSeries deps, (d, next) =>
          spec = Madul.PARSE_SPEC d

          if spec.prerequisites?
            insert_at = for p in spec.prerequisites
              index_for = (sibling) => sibling.alias == p.alias

              initers.find index_for

            insert_at.sort()

            insert_at = if insert_at.length == 0 then 0 else insert_at[insert_at.length - 1]

            initers.splice insert_at, 0, alias: spec.alias, execute: spec.initializer
          else if spec.initializer?
            initers.push alias: spec.alias, execute: spec.initializer

          if typeof proto[underscore spec.ref] == 'undefined'
            if available[strip spec.ref]? == true
              proto._do_add proto, spec.ref, next
            else
              if spec.parent?
                if proto[spec.parent]?
                  proto._check proto, SEARCH_ROOTS[spec.parent], spec.name, spec.ref, (err) =>
                    if err?
                      deep = "#{SEARCH_ROOTS[spec.parent]}/node_modules/#{spec.parent}/dist"

                      proto._check proto, deep, spec.name, spec.ref, (e) =>
                        next()
                    else
                      next()
                else
                  proto.fire.call proto, 'search_root.load', { name: spec.name, alias: spec.alias, parent: spec.parent }

                  @_do_hydrate proto, [ spec.parent ], (errors) =>
                    if errors?
                      stop = new Error()
                      stop.break = true

                      next stop
                    else
                      if SEARCH_ROOTS[spec.parent] == undefined
                        SEARCH_ROOTS[spec.parent] = @_find_code_root spec.parent

                      proto._check proto, SEARCH_ROOTS[spec.parent], spec.name, spec.ref, (err) =>
                        if err?
                          deep = "#{SEARCH_ROOTS[spec.parent]}/node_modules/#{spec.parent}/dist"

                          proto._check proto, deep, spec.name, spec.ref, (e) =>
                            next()
                        else
                          next()
              else if spec.node_local
                key = @_find_require_key proto.constructor.name

                async.eachSeries require.cache[key].paths, (path, nxt) =>
                  @_load_from_package_json proto, path, spec.name, spec.ref, =>
                    nxt()
                  , =>
                    nxt()
                , =>
                  next()
              else if spec.project_local
                proto._check proto, LOCALS[proto.constructor.name], spec.name, spec.ref, (err) =>
                  if err?
                    details = not_found: spec.name
                    stop    = new Error()

                    stop.break = true

                    proto.warn.call proto, 'hydrating', details

                    errors.push(details)

                    next stop
                  else
                    next()
              else
                try
                  proto._add proto, spec.ref, spec.name, next
                catch e
                  path = "#{process.cwd()}/node_modules"

                  @_load_from_package_json proto, path, spec.name, spec.ref, next, =>
                    pth = LOCALS[proto.constructor.name]

                    try
                      proto._check proto, pth, spec.name, spec.ref, (err) =>
                        if err?
                          proto._check proto, "#{process.cwd()}/dist", spec.name, spec.ref, next
                        else
                          next()

          else
            next()
        , (err) =>
          if err?.length > 0
            proto.warn.call proto, 'hydration.halt', errors

            hydration_complete errors
          else
            async.eachSeries initers, (initer, next) =>
              proto[initer.execute].apply(@).then next
            , hydration_complete

      _load_from_package_json: (proto, path, name, ref, success, next) =>
        pkg = "#{path}/#{name}/package.json"
        fs.stat pkg, (err, stat) =>
          if err?
            next()
          else if stat.isFile()
            fs.readFile pkg, 'utf8', (err, data) =>
              json = JSON.parse data
              main = json.main || json._main || 'index.js'
              path = "#{path}/#{name}/#{main}"

              proto._add proto, ref, path, success
          else
            next()

      _finish_up: (proto, args) =>
        name = proto.constructor.name

        if listeners[name]?
          async.each listeners[name], (listener, next) =>
            listener @
            next()
          , => @_register_initialized name
        else
          @_register_initialized name

      _register_initialized: (name) =>
        @_make_available name, @

        initialized[name] = true

        Madul.FIRE "$.#{name}.initialized"

      _call_initializers_for: (proto, name, callback) =>
        if _INITIALIZERS[name]?
          async.each _INITIALIZERS[name], (initializer, next) =>
            if initializer.called == false
              proto[initializer.fn].apply proto
                .then =>
                  initializer.called = true
                  next()
            else
              next()
          , callback
        else
          callback()

      _do_find: (thing, cb) =>
        file  = thing.toLowerCase()
        found = for own key, val of require.cache
          if key.replace(/_/g, '').toLowerCase().includes file
            cb key

        filtered = found.filter (f) => f?

        if filtered.length > 0
          filtered.sort((a, b) => a.length - b.length)[0]
        else
          [ ]

      _find_require_key: (resource) =>
        @_do_find resource, (key) => key

      _find_code_root: (resource) =>
        @_do_find resource, (key) => key.substring(0, key.lastIndexOf '/').split '/'
          .join '/'

      initialize: =>
        deferred = q.defer()
        proto    = @.__proto__
        name     = proto.constructor.name

        Madul.FIRE "$.#{name}.request_instance"

        if initialized[name] == undefined
          Madul.FIRE "$.#{name}.initialize"

          initialized[name] = false
          listeners[name]   = [ deferred.resolve ]

          if LOCALS[name] == undefined
            LOCALS[name] = @_find_code_root name

          @_hydrate_deps proto, (errors) =>
            if errors?
              deferred.reject errors
            else
              @_wrap_methods proto, (err) =>
                if err?
                  deferred.reject err
                else
                  @_finish_up proto
        else if initialized[name] == false
          listeners[name].push deferred.resolve
        else if initialized[name] == true
          process.nextTick => deferred.resolve available[strip name]

        deferred.promise

    module.exports = Madul


Remove debug output

Remove debug output

    raven       = require 'raven'
    sentry      = require './db/sentry'
    express     = require 'express'

    auth        = require './helper/auth'

    system      = require './system'
    collection  = require './collection'
    document    = require './document'

## Init

    app = express()

### Authentication

This routine is called for all request to the API. It is reponsible for
authenticating the user by validating the `api\_key`. It then sets some request
session variables so they become accessible throughout the entire system during
the rquest.

    app.use '/', (req, res, next) ->
      return next() if req.originalUrl.substr(0, 17) is '/CloudHealthCheck'

      auth.check req.query.api_key, (err, user) ->
        if user
          res.set 'X-RateLimit-Limit', user.limit
          res.set 'X-RateLimit-Remaining', user.remaining
          res.set 'X-RateLimit-Reset', user.reset

        req.user = user

        return next err if err

        next()

### Configuration

    app.use(express.favicon())
    app.use(express.logger(':date :remote-addr - :method :url :status :res[content-length] - :response-time ms')) if not process.env.SILENT
    app.set('json spaces', 0) if app.get('env') isnt 'testing'
    app.use(express.compress())
    app.use(express.json())
    app.disable('x-powered-by')
    app.set 'port', process.env.PORT_WWW or 8080
    app.use(app.router)

### Error handling

Before handling the error ours self make sure that it is propperly logged in
Sentry by using the express/connect middleware.

    app.use raven.middleware.express sentry

All errors passed to `next` or exceptions ends up here. We set the status code
to `500` if it is not already defined in the `Error` object. We then print the
error mesage and stack trace to the console for debug purposes.

Log 401 Unauthorized (warning) and 403 Forbidden (notice) errors to Sentry to
enhance debugging and oversight as Nasjonal Turbase gets more used.

Before returning a response to the user the request method is check. HEAD
requests shall not contain any body – this applies for errors as well.

    app.use (err, req, res, next) ->
      res.status err.status or 500

      if res.statusCode is 401
        sentry.captureMessage "Invalid API-key #{req.query.api_key}",
          level: 'warning'
          extra: sentry.parseRequest req, user: req.user

      if res.statusCode is 403
        sentry.captureMessage "Rate limit exceeded for #{req.tilbyder}",
          level: 'notice'
          extra: sentry.parseRequest req, user: req.user

      if res.statusCode >= 500
        console.error err.message
        console.error err.stack

      return res.end() if req.method is 'HEAD'
      return res.json message: err.message or 'Ukjent feil'

This the fmous 404 Not Found handler. If no route configuration for the request
is found, it ends up here. We don't do much fancy about it – just a standard
error message and HTTP status code.

    app.use (req, res) -> res.json 404, message: "Resurs ikke funnet"

## GET /

    app.get '/', (req, res) ->
      res.json message: 'Here be dragons'

## GET /CloudHealthCheck

> So...You’re seeing the dotCloud active health check looking to make sure that
> your service is up. There is no way for you to disable it, but you can prevent
> it and you can handle it [1]!

[1] [dotCloud](http://docs.dotcloud.com/tutorials/more/cloud-health-check/)

    app.all '/CloudHealthCheck', system.check

## GET /objekttyper

    app.get '/objekttyper', (req, res, next) ->
      res.json 200, ['turer', 'steder', 'områder', 'grupper', 'arrangementer', 'bilder']

## ALL /{collection}

    app.param 'collection', collection.param
    app.all '/:collection', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then collection.options req, res, next
        when 'HEAD', 'GET' then collection.get req, res, next
        when 'POST' then collection.post req, res, next
        else res.json 405, message: "HTTP Method #{req.method.toUpperCase()} Not Allowed"

## ALL /{collection}/{objectid}

    app.param 'objectid', document.param
    app.options '/:collection/:ojectid', document.options
    app.all '/:collection/:objectid', document.all, (req, res, next) ->
      switch req.method
        when 'HEAD', 'GET' then document.get req, res, next
        when 'PUT' then document.put req, res, next
        when 'PATCH' then document.patch req, res, next
        when 'DELETE' then document.delete req, res, next
        else res.json 405, message: "HTTP Method #{req.method.toUpperCase()} Not Allowed"

## Start

Ok, so if the server is running in stand-alone mode i.e. there is not
`module.parent` then continue with starting the databse and listening to a port.

    if not module.parent
      require('./db/redis')
      require('./db/mongo').once 'ready', ->
        console.log 'Database is open...'

        app.listen app.get('port'), ->
          console.log "Server is listening on port #{app.get('port')}"

However, if there is a `module.parent` don't do all the stuff above. This means
that there is some program that is including the server from it, e.g a test, and
hence it should not listen to a port for incomming connections and rather just
return the application instance so that we can do some testing on it.

    else
      module.exports = app

    raven       = require 'raven'
    sentry      = require './db/sentry'
    express     = require 'express'

    auth        = require './helper/auth'

    system      = require './system'
    collection  = require './collection'
    document    = require './document'

## Init

    app = express()

### Authentication

This routine is called for all request to the API. It is reponsible for
authenticating the user by validating the `api\_key`. It then sets some request
session variables so they become accessible throughout the entire system during
the rquest.

    app.use '/', (req, res, next) ->
      return next() if req.originalUrl.substr(0, 17) is '/CloudHealthCheck'

      auth.check req.query.api_key, (err, user) ->
        if user
          res.set 'X-RateLimit-Limit', user.limit
          res.set 'X-RateLimit-Remaining', user.remaining
          res.set 'X-RateLimit-Reset', user.reset

        req.user = user

        return next err if err

        next()

### Configuration

    app.use(express.favicon())
    app.use(express.logger(':date :remote-addr - :method :url :status :res[content-length] - :response-time ms')) if not process.env.SILENT
    app.set('json spaces', 0) if app.get('env') isnt 'testing'
    app.use(express.compress())
    app.use(express.json())
    app.disable('x-powered-by')
    app.set 'port', process.env.PORT_WWW or 8080
    app.use(app.router)

### Error handling

Before handling the error ours self make sure that it is propperly logged in
Sentry by using the express/connect middleware.

    app.use raven.middleware.express sentry

All errors passed to `next` or exceptions ends up here. We set the status code
to `500` if it is not already defined in the `Error` object. We then print the
error mesage and stack trace to the console for debug purposes.

Log 401 Unauthorized (warning) and 403 Forbidden (notice) errors to Sentry to
enhance debugging and oversight as Nasjonal Turbase gets more used.

Before returning a response to the user the request method is check. HEAD
requests shall not contain any body – this applies for errors as well.

    app.use (err, req, res, next) ->
      res.status err.status or 500

      console.log sentry

      if res.statusCode is 401
        sentry.captureMessage "Invalid API-key #{req.query.api_key}",
          level: 'warning'
          extra: sentry.parseRequest req, user: req.user

      if res.statusCode is 403
        sentry.captureMessage "Rate limit exceeded for #{req.tilbyder}",
          level: 'notice'
          extra: sentry.parseRequest req, user: req.user

      if res.statusCode >= 500
        console.error err.message
        console.error err.stack

      return res.end() if req.method is 'HEAD'
      return res.json message: err.message or 'Ukjent feil'

This the fmous 404 Not Found handler. If no route configuration for the request
is found, it ends up here. We don't do much fancy about it – just a standard
error message and HTTP status code.

    app.use (req, res) -> res.json 404, message: "Resurs ikke funnet"

## GET /

    app.get '/', (req, res) ->
      res.json message: 'Here be dragons'

## GET /CloudHealthCheck

> So...You’re seeing the dotCloud active health check looking to make sure that
> your service is up. There is no way for you to disable it, but you can prevent
> it and you can handle it [1]!

[1] [dotCloud](http://docs.dotcloud.com/tutorials/more/cloud-health-check/)

    app.all '/CloudHealthCheck', system.check

## GET /objekttyper

    app.get '/objekttyper', (req, res, next) ->
      res.json 200, ['turer', 'steder', 'områder', 'grupper', 'arrangementer', 'bilder']

## ALL /{collection}

    app.param 'collection', collection.param
    app.all '/:collection', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then collection.options req, res, next
        when 'HEAD', 'GET' then collection.get req, res, next
        when 'POST' then collection.post req, res, next
        else res.json 405, message: "HTTP Method #{req.method.toUpperCase()} Not Allowed"

## ALL /{collection}/{objectid}

    app.param 'objectid', document.param
    app.options '/:collection/:ojectid', document.options
    app.all '/:collection/:objectid', document.all, (req, res, next) ->
      switch req.method
        when 'HEAD', 'GET' then document.get req, res, next
        when 'PUT' then document.put req, res, next
        when 'PATCH' then document.patch req, res, next
        when 'DELETE' then document.delete req, res, next
        else res.json 405, message: "HTTP Method #{req.method.toUpperCase()} Not Allowed"

## Start

Ok, so if the server is running in stand-alone mode i.e. there is not
`module.parent` then continue with starting the databse and listening to a port.

    if not module.parent
      require('./db/redis')
      require('./db/mongo').once 'ready', ->
        console.log 'Database is open...'

        app.listen app.get('port'), ->
          console.log "Server is listening on port #{app.get('port')}"

However, if there is a `module.parent` don't do all the stuff above. This means
that there is some program that is including the server from it, e.g a test, and
hence it should not listen to a port for incomming connections and rather just
return the application instance so that we can do some testing on it.

    else
      module.exports = app