Don't call initializer and initer methods directly

Instead, invoke them from their prototype, passing @. This ensures scope is
correct.

    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   = { }

    code_root = process.env.SEARCH_ROOT || 'dist'

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

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

    HYRDATION_LISTENERS = { }

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

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

    WRAP = (cls, method) ->
      unless WRAPPED[cls]?
        WRAPPED[cls] = [
          'constructor'
          'initialize'
          'details'
        ]

      WRAPPED[cls].indexOf(method) < 0

    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    '}"

      @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 '/'

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

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

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

      _report: (name, method, state, id, args) =>
        Madul.FIRE "@.#{name}.#{method}.#{state}",
          uuid:      id
          args:      args
          timestamp: microtime.now()

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

            proto._report proto.constructor.name, method, state, id, data

      _prep_invocation: (proto, method, input, def) =>
        id  = uuid.v4fast()
        res = proto._respond proto, method, id, def

        if Array.isArray input
          input.push (out) => res 'resolve', out
          input.push (err) => res 'reject',  err
          input.push (out) => res 'notify',  out
        else if typeof input == 'object'
          input.done   = (out) => res 'resolve', out
          input.fail   = (err) => res 'reject',  err
          input.update = (out) => res 'notify',  out

          input = [ input ]
        else
          msg = "input to #{proto.constructor.name}.#{method} must be an Array of Object"
          @warn 'input.invalid', msg
          throw new Error msg

        proto._report proto.constructor.name, method, 'invoke', id, input

        input

      _do_wrap: (proto, method) =>
        if method != 'fire' && method != 'warn' && method != 'listen'
          Madul.FIRE "$.#{proto.constructor.name}.#{method}.wrap"

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

            proto[method] = =>
              def  = q.defer()
              args = if arguments[0]? then Array.prototype.slice.call arguments else [ ]

              proto["_#{method}"].apply @, proto._prep_invocation proto, method, args, def

              def.promise
          else if typeof proto[method] == 'object'

            if Array.isArray proto[method].validate
              args_format = 'ARRAY'
              decs        = for val in proto[method].validate
                @_parse_handle(val).ref

              proto[method].validate = decs
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = for own key, val of proto[method].validate
                { ref } = @_parse_handle val
                proto[method].validate[key] = ref
                ref
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ @_parse_handle(proto[method].validate).ref ]
            else if typeof proto[method].validate != 'undefined'
              @warn 'meta.invalid', validate: 'must be a String, Object, or Array'
              return
            else
              args_format = 'ARRAY'
              decs        = [ ]

            decs = decs.concat(proto[method].before.map (b, i) =>
              { ref } = @_parse_handle b
              proto[method].before[i] = ref
              ref
            ) if proto[method].before?

            decs = decs.concat(proto[method].after.map (a, i) =>
              { ref } = @_parse_handle a
              proto[method].after[i] = ref
              ref
            ) if proto[method].after?

            Madul.FIRE '$.Madul.decorators.hydrate', decs

            @_do_hydrate proto, decs, =>
              proto["_#{method}"] = proto[method]

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

                if args_format == 'ARRAY'
                  args = Array.prototype.slice.call arguments

                  if me.validate?
                    validators = for val, i in me.validate
                      { ref } = @_parse_handle val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[i]
                      proto[ref].EXECUTE args[i]
                else if args_format == 'OBJECT'
                  args = arguments[0]

                  if me.validate?
                    validators = for own key, val of me.validate
                      { ref } = @_parse_handle val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[key]
                      proto[ref].EXECUTE args[key]
                else
                  @warn 'cannot-continue', 'No arg format specified'

                  return def.reject 'No arg format specified'

                me.before = [ ] unless me.before?
                me.after  = [ ] unless me.after?

                q.all validators
                .then =>
                  q.all me.before.map (b) =>
                    Madul.FIRE '$.Madul.before_filter.execute', "#{b}": args
                    proto[b].before args
                .then =>
                  me.behavior.apply @, @_prep_invocation proto, method, args, def
                .then (result) =>
                  if me.after.length > 0
                    q.all me.after.map (b) =>
                      Madul.FIRE '$.Madul.after_filter.execute', "#{b}": result
                      b.after result
                  else
                    d = q.defer()

                    process.nextTick => d.resolve result

                    d.promise
                .then  (out) => def.resolve out
                .catch (err) => def.reject  err

                def.promise
          else
            @warn 'cannot-wrap', method

          WRAPPED[proto.constructor.name].push 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

              continue if proto.deps? && proto.deps.indexOf(prop.replace(/_/g, '-')) > -1

              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

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

            next()
          , => @_call_initializers_for wrap.proto, wrap.name, completed
        , callback

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

        available[strip name] = mod

      _hydrate_deps: (done) =>
        proto  = @.__proto__
        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, =>
                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, callback) =>
        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 callback
        else
          callback mod

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

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

            done type: 'ERROR', info: err
          else
            async.each files, (f, next) =>
              depth = "#{path}/#{f}"

              fs.stat depth, (e, s) =>
                if s.isDirectory() && f[0] != '.'
                  me._check me, depth, dep, ref, next
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  me._load me, ref, depth, (mod) => me._do_add me, mod, ref, next
                else
                  next()
            , finished

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

        me[underscore ref] = mod

        next()

      _add: (me, ref, path, next) =>
        me._init_if_madul path, (mod) =>
          me._make_available ref, mod
          me._do_add me, mod, ref, next

      _parse_handle: (value) =>
        tokens = value.split '='

        if tokens.length == 2
          initer = tokens[1].trim()
          t      = tokens[0].split '->'

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

            root = SEARCH_ROOTS[r[0].trim()]
            t[0] = r[1]

          if t.length == 2
            name  = t[0].trim()
            alias = t[1].trim()
          else if t.length == 1
            name = alias = t[0].trim()
          else
            return next @warn 'alias.invalid', tokens[1]

          toks = initer.split ':'

          if toks.length == 2
            initer = toks[0].trim()
            pres   = toks[1].split(',').map (p) => p.trim()
          else if toks.length == 1
            initer = toks[0].trim()
          else
            return next @warn 'dependency-initializer.invalid', tokens[1]

        else if tokens.length == 1
          t = tokens[0].split '->'

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

            root = SEARCH_ROOTS[r[0].trim()]
            t[0] = r[1]

          if t.length == 2
            name  = t[0].trim()
            alias = t[1].trim()
          else if t.length == 1
            name = alias = t[0].trim()
          else
            return next @warn 'alias.invalid', tokens[1]

        else
          return next @warn 'dependency.invalid', d

        { ref: alias || name, alias, name, root, initer, pres }

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

        async.each deps, (d, next) =>
          { ref, alias, name, root, initer, pres } = @_parse_handle d

          if pres?
            insert_at = for p in pres
              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: alias, execute: initer

          if proto[underscore ref]? == false
            if available[strip ref]? == true
              proto._do_add proto, available[strip ref], ref, next
            else
              try
                proto._add proto, ref, name, next
              catch e
                if root?
                  Madul.FIRE '$.Madul.search_root.load', { name, alias, root }

                  proto._check proto, root, name, ref, next
                else
                  cwd = process.cwd()
                  pkg = "#{cwd}/node_modules/#{name}/package.json"

                  fs.stat pkg, (err, stat) =>
                    if stat?.isFile()
                      fs.readFile pkg, 'utf8', (err, data) =>
                        json = JSON.parse data
                        main = json.main || json._main || 'index.js'
                        path = "#{cwd}/node_modules/#{name}/#{main}"

                        proto._add proto, ref, path, next
                    else
                      proto._check proto, "#{cwd}/#{code_root}", name, ref, next
          else
            next()
        , =>
          async.eachSeries initers, (initer, next) =>
            proto[initer.execute].apply(@).then next
          , hydration_complete

      _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: (name, callback) =>
        if _INITIALIZERS[name]?
          async.each _INITIALIZERS[name], (initializer, next) =>
            if initializer.called == false
              proto[initializer.fn].apply @
                .then =>
                  initializer.called = true
                  next()
            else
              next()
          , callback
        else
          callback()

      _invoke_parent_initializers: (callback) =>
        proto = @.__proto__

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

          async.each parents, (parent, next) =>
            @_call_initializers_for parent.constructor.name, next
          , callback
        else
          callback()

      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 ]

          @_wrap_methods()
          @_hydrate_deps => @_invoke_parent_initializers => @_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   = { }

    code_root = process.env.SEARCH_ROOT || 'dist'

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

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

    HYRDATION_LISTENERS = { }

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

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

    WRAP = (cls, method) ->
      unless WRAPPED[cls]?
        WRAPPED[cls] = [
          'constructor'
          'initialize'
          'details'
        ]

      WRAPPED[cls].indexOf(method) < 0

    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    '}"

      @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 '/'

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

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

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

      _report: (name, method, state, id, args) =>
        Madul.FIRE "@.#{name}.#{method}.#{state}",
          uuid:      id
          args:      args
          timestamp: microtime.now()

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

            proto._report proto.constructor.name, method, state, id, data

      _prep_invocation: (proto, method, input, def) =>
        id  = uuid.v4fast()
        res = proto._respond proto, method, id, def

        if Array.isArray input
          input.push (out) => res 'resolve', out
          input.push (err) => res 'reject',  err
          input.push (out) => res 'notify',  out
        else if typeof input == 'object'
          input.done   = (out) => res 'resolve', out
          input.fail   = (err) => res 'reject',  err
          input.update = (out) => res 'notify',  out

          input = [ input ]
        else
          msg = "input to #{proto.constructor.name}.#{method} must be an Array of Object"
          @warn 'input.invalid', msg
          throw new Error msg

        proto._report proto.constructor.name, method, 'invoke', id, input

        input

      _do_wrap: (proto, method) =>
        if method != 'fire' && method != 'warn' && method != 'listen'
          Madul.FIRE "$.#{proto.constructor.name}.#{method}.wrap"

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

            proto[method] = =>
              def  = q.defer()
              args = if arguments[0]? then Array.prototype.slice.call arguments else [ ]

              proto["_#{method}"].apply @, proto._prep_invocation proto, method, args, def

              def.promise
          else if typeof proto[method] == 'object'

            if Array.isArray proto[method].validate
              args_format = 'ARRAY'
              decs        = for val in proto[method].validate
                @_parse_handle(val).ref

              proto[method].validate = decs
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = for own key, val of proto[method].validate
                { ref } = @_parse_handle val
                proto[method].validate[key] = ref
                ref
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ @_parse_handle(proto[method].validate).ref ]
            else if typeof proto[method].validate != 'undefined'
              @warn 'meta.invalid', validate: 'must be a String, Object, or Array'
              return
            else
              args_format = 'ARRAY'
              decs        = [ ]

            decs = decs.concat(proto[method].before.map (b, i) =>
              { ref } = @_parse_handle b
              proto[method].before[i] = ref
              ref
            ) if proto[method].before?

            decs = decs.concat(proto[method].after.map (a, i) =>
              { ref } = @_parse_handle a
              proto[method].after[i] = ref
              ref
            ) if proto[method].after?

            Madul.FIRE '$.Madul.decorators.hydrate', decs

            @_do_hydrate proto, decs, =>
              proto["_#{method}"] = proto[method]

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

                if args_format == 'ARRAY'
                  args = Array.prototype.slice.call arguments

                  if me.validate?
                    validators = for val, i in me.validate
                      { ref } = @_parse_handle val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[i]
                      proto[ref].EXECUTE args[i]
                else if args_format == 'OBJECT'
                  args = arguments[0]

                  if me.validate?
                    validators = for own key, val of me.validate
                      { ref } = @_parse_handle val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[key]
                      proto[ref].EXECUTE args[key]
                else
                  @warn 'cannot-continue', 'No arg format specified'

                  return def.reject 'No arg format specified'

                me.before = [ ] unless me.before?
                me.after  = [ ] unless me.after?

                q.all validators
                .then =>
                  q.all me.before.map (b) =>
                    Madul.FIRE '$.Madul.before_filter.execute', "#{b}": args
                    proto[b].before args
                .then =>
                  me.behavior.apply @, @_prep_invocation proto, method, args, def
                .then (result) =>
                  if me.after.length > 0
                    q.all me.after.map (b) =>
                      Madul.FIRE '$.Madul.after_filter.execute', "#{b}": result
                      b.after result
                  else
                    d = q.defer()

                    process.nextTick => d.resolve result

                    d.promise
                .then  (out) => def.resolve out
                .catch (err) => def.reject  err

                def.promise
          else
            @warn 'cannot-wrap', method

          WRAPPED[proto.constructor.name].push 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

              continue if proto.deps? && proto.deps.indexOf(prop.replace(/_/g, '-')) > -1

              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

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

            next()
          , => @_call_initializers_for wrap.proto, wrap.name, completed
        , callback

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

        available[strip name] = mod

      _hydrate_deps: (done) =>
        proto  = @.__proto__
        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, =>
                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, callback) =>
        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 callback
        else
          callback mod

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

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

            done type: 'ERROR', info: err
          else
            async.each files, (f, next) =>
              depth = "#{path}/#{f}"

              fs.stat depth, (e, s) =>
                if s.isDirectory() && f[0] != '.'
                  me._check me, depth, dep, ref, next
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  me._load me, ref, depth, (mod) => me._do_add me, mod, ref, next
                else
                  next()
            , finished

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

        me[underscore ref] = mod

        next()

      _add: (me, ref, path, next) =>
        me._init_if_madul path, (mod) =>
          me._make_available ref, mod
          me._do_add me, mod, ref, next

      _parse_handle: (value) =>
        tokens = value.split '='

        if tokens.length == 2
          initer = tokens[1].trim()
          t      = tokens[0].split '->'

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

            root = SEARCH_ROOTS[r[0].trim()]
            t[0] = r[1]

          if t.length == 2
            name  = t[0].trim()
            alias = t[1].trim()
          else if t.length == 1
            name = alias = t[0].trim()
          else
            return next @warn 'alias.invalid', tokens[1]

          toks = initer.split ':'

          if toks.length == 2
            initer = toks[0].trim()
            pres   = toks[1].split(',').map (p) => p.trim()
          else if toks.length == 1
            initer = toks[0].trim()
          else
            return next @warn 'dependency-initializer.invalid', tokens[1]

        else if tokens.length == 1
          t = tokens[0].split '->'

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

            root = SEARCH_ROOTS[r[0].trim()]
            t[0] = r[1]

          if t.length == 2
            name  = t[0].trim()
            alias = t[1].trim()
          else if t.length == 1
            name = alias = t[0].trim()
          else
            return next @warn 'alias.invalid', tokens[1]

        else
          return next @warn 'dependency.invalid', d

        { ref: alias || name, alias, name, root, initer, pres }

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

        async.each deps, (d, next) =>
          { ref, alias, name, root, initer, pres } = @_parse_handle d

          if pres?
            insert_at = for p in pres
              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: alias, execute: initer

          if proto[underscore ref]? == false
            if available[strip ref]? == true
              proto._do_add proto, available[strip ref], ref, next
            else
              try
                proto._add proto, ref, name, next
              catch e
                if root?
                  Madul.FIRE '$.Madul.search_root.load', { name, alias, root }

                  proto._check proto, root, name, ref, next
                else
                  cwd = process.cwd()
                  pkg = "#{cwd}/node_modules/#{name}/package.json"

                  fs.stat pkg, (err, stat) =>
                    if stat?.isFile()
                      fs.readFile pkg, 'utf8', (err, data) =>
                        json = JSON.parse data
                        main = json.main || json._main || 'index.js'
                        path = "#{cwd}/node_modules/#{name}/#{main}"

                        proto._add proto, ref, path, next
                    else
                      proto._check proto, "#{cwd}/#{code_root}", name, ref, next
          else
            next()
        , =>
          async.eachSeries initers, (initer, next) =>
            @[initer.execute]().then next
          , hydration_complete

      _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: (name, callback) =>
        if _INITIALIZERS[name]?
          async.each _INITIALIZERS[name], (initializer, next) =>
            if initializer.called == false
              @[initializer.fn]()
                .then =>
                  initializer.called = true
                  next()
            else
              next()
          , callback
        else
          callback()

      _invoke_parent_initializers: (callback) =>
        proto = @.__proto__

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

          async.each parents, (parent, next) =>
            @_call_initializers_for parent.constructor.name, next
          , callback
        else
          callback()

      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 ]

          @_wrap_methods()
          @_hydrate_deps => @_invoke_parent_initializers => @_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


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 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

Source maps allow JavaScript runtimes to match running JavaScript back to
the original CoffeeScript source code that corresponds to it. In order to
produce maps, we must keep track of positions (line number, column number)
for every construct in the syntax tree, and be able to generate a map file
-- which is a compact, VLQ-encoded representation of the JSON serialization
of this information -- to write out alongside the generated JavaScript.

    {merge} = require './helpers'

LineMap
-------

Keeps track of information about column positions within a single line of
output JavaScript code. **SourceMap**s are implemented in terms of **LineMap**s.

    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


Clean up documentation for collection source code

    "use strict"

    ObjectID    = require('mongodb').ObjectID
    stringify   = require('JSONStream').stringify
    createHash  = require('crypto').createHash

    mongo       = require './db/mongo'
    cache       = require './cache'

## PARAM collection

    exports.param = (req, res, next, col) ->
      if col not in ['turer', 'steder', 'grupper', 'områder', 'bilder', 'arrangementer']
        return res.json 404, message: 'Objekttype ikke funnet'

      req.type = col
      req.db   = col: mongo[col]

      next()

## OPTIONS /{collection}

    exports.options = (req, res, next) ->
      res.setHeader 'Access-Control-Allow-Methods', 'HEAD, GET, POST, PATCH, PUT'
      res.send()

## GET /{collection}

    exports.get = (req, res, next) ->
      query = {}

### ?tag=`String`

      if typeof req.query.tag is 'string' and req.query.tag isnt ''
        if req.query.tag.charAt(0) is '!' and req.query.tag.length > 1
          query['tags.0'] = $ne: req.query.tag.substr(1)
        else
          query['tags.0'] = req.query.tag

### ?grupper=`String`

      if typeof req.query.gruppe is 'string' and req.query.gruppe isnt ''
        query['grupper'] = req.query.gruppe

### ?after=`Mixed`

      if typeof req.query.after is 'string' and req.query.after isnt ''
        if not isNaN(req.query.after)
          req.query.after = new Date(parseInt(req.query.after, 10)).toISOString()
        query.endret = {$gte:req.query.after}

### ?bbox=`min_lng`,`min_lat`,`max_lng`,`max_lat`

      if typeof req.query.bbox is 'string' and req.query.bbox.split(',').length is 4
        bbox = req.query.bbox.split(',')
        bbox[i] = parseFloat(val) for val, i in bbox

        query.geojson =
          '$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]]
              ]]

### ?privat.`String`=`String`

This allows the user to filter documents based on private document properties.
This will autumaticly limit returned documents to those owned by the current
user.

#### ToDo

 * Limit number of private fields?
 * Limit depth of private fields?

`NB` This section is looping through all of the url query parameters and hence
should take the queries from above sections into concideration so we don't need
to do double amount of work.

      for key, val of req.query when key.substr(0,7) is 'privat.'
        if /^[a-zæøåA-ZÆØÅ0-9_.]+$/.test key
          val = parseFloat(val) if not isNaN val # @TODO(starefossen) is this acceptable?
          query.tilbyder = req.usr
          query[key] = val

Limit queries to own documents or public documents i.e. where `doc.status` is
`Offentlig` if not `query.tilbyder` is set.

      query['$or'] = [{status: 'Offentlig'}, {tilbyder: req.usr}] if not query.tilbyder

Only project a few fields to since lists are mostly used intermediate before
fetching the entire document.

      fields = tilbyder: true, endret: true, status: true, navn: true

Set up MongoDB options.

      options =
        limit: Math.min((parseInt(req.query.limit, 10) or 20), 50)
        skip: parseInt(req.query.skip, 10) or 0
        sort: 'endret'

Retrive matching documents from MongoDB.

      cursor = req.db.col.find(query, fields, options)
      cursor.count (err, total) ->
        return next err if err
        res.set 'Count-Return', Math.min(options.limit, total)
        res.set 'Count-Total', total
        return res.end() if req.method is 'HEAD'
        return res.json documents: [], count: 0, total: 0 if total is 0
        res.set 'Content-Type', 'application/json; charset=utf-8'

Stream documents user in order to prevent loading them into memory.

        op = '{"documents":['
        cl = '],"count":' + Math.min(options.limit, total) + ',"total":' + total + '}'

        cursor.stream().pipe(stringify(op, ',', cl)).pipe(res)

## POST /{collection}

    exports.post = (req, res, next) ->
      #
      # @TODO move update to :/collection/:document
      # @TODO add access control
      #

      return res.json 400, message: 'Body is missing' if Object.keys(req.body).length is 0
      return res.json 422, message: 'Body should be a JSON Hash' if req.body instanceof Array

      warnings = []
      errors   = []
      message  = ''

      req.body._id = new ObjectID(req.body._id) # @TODO restrict this
      req.body.tilbyder = req.usr
      req.body.endret = new Date().toISOString()

      if not req.body.lisens
        req.body.lisens = 'CC BY-ND-NC 3.0 NO'
        warnings.push
          resource: req.type
          field: 'lisens'
          value: req.body.lisens
          code: 'missing_field'

      if not req.body.status
        req.body.status = 'Kladd'
        warnings.push
          resource: req.type
          field: 'status'
          value: req.body.status
          code: 'missing_field'

      req.body.checksum = createHash('md5').update(JSON.stringify(req.body)).digest("hex")

      req.db.col.save req.body, {safe: true, w: 1}, (err) ->
        return next(err) if err
        cache.setForType req.type, req.body._id, req.body, (err, data) ->
          return next(err) if err
          return res.json 201,
            document:
              _id: req.body._id
            count: 1
            message: message if message
            warnings: warnings if warnings.length > 0
            errors: errors if errors.length > 0

## PATCH /{collection}

    exports.patch = (req, res, next) ->
      res.json 501, message: 'HTTP method not implmented'

## PUT /{collection}

    exports.put = (req, res, next) ->
      res.json 501, message: 'HTTP method not implmented'

    "use strict"

    ObjectID    = require('mongodb').ObjectID
    stringify   = require('JSONStream').stringify
    createHash  = require('crypto').createHash

    mongo       = require './db/mongo'
    cache       = require './cache'

## PARAM collection

    exports.param = (req, res, next, col) ->
      if col not in ['turer', 'steder', 'grupper', 'områder', 'bilder', 'arrangementer']
        return res.json 404, message: 'Objekttype ikke funnet'

      req.type = col
      req.db   = col: mongo[col]

      next()

## OPTIONS /{collection}

    exports.options = (req, res, next) ->
      res.setHeader 'Access-Control-Allow-Methods', 'HEAD, GET, POST, PATCH, PUT'
      res.send()

## GET /{collection}

    exports.get = (req, res, next) ->
      query = {}

### ?tag=`String`

      if typeof req.query.tag is 'string' and req.query.tag isnt ''
        if req.query.tag.charAt(0) is '!' and req.query.tag.length > 1
          query['tags.0'] = $ne: req.query.tag.substr(1)
        else
          query['tags.0'] = req.query.tag

### ?grupper=`String`

      if typeof req.query.gruppe is 'string' and req.query.gruppe isnt ''
        query['grupper'] = req.query.gruppe

### ?after=`Mixed`

      if typeof req.query.after is 'string' and req.query.after isnt ''
        if not isNaN(req.query.after)
          req.query.after = new Date(parseInt(req.query.after, 10)).toISOString()
        query.endret = {$gte:req.query.after}

### ?bbox=`min_lng`,`min_lat`,`max_lng`,`max_lat`

      if typeof req.query.bbox is 'string' and req.query.bbox.split(',').length is 4
        bbox = req.query.bbox.split(',')
        bbox[i] = parseFloat(val) for val, i in bbox

        query.geojson =
          '$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]]
              ]]

### ?privat.`String`=`String`

 * @TODO(starefossen) limit number of private fields
 * @TODO(starefossen) limit depth of private field

`NB` This secution is itterating over all the url queries and hence should
take the queries above into concideration so we don't need to do double work.

      for key, val of req.query when key.substr(0,7) is 'privat.'
        if /^[a-zæøåA-ZÆØÅ0-9_.]+$/.test key
          val = parseFloat(val) if not isNaN val # @TODO(starefossen) is this acceptable?
          query.tilbyder = req.usr
          query[key] = val

Limit queries to own documents or public documents i.e. status = 'Offentlig'
if not tilbyder query is not set.

      query['$or'] = [{status: 'Offentlig'}, {tilbyder: req.usr}] if not query.tilbyder

Only project a few fields to since lists are mostly used intermediate before
fetching the entire document.

      fields = tilbyder: true, endret: true, status: true, navn: true

Set up MongoDB options.

      options =
        limit: Math.min((parseInt(req.query.limit, 10) or 20), 50)
        skip: parseInt(req.query.skip, 10) or 0
        sort: 'endret'

Retrive matching documents from MongoDB.

      cursor = req.db.col.find(query, fields, options)
      cursor.count (err, total) ->
        return next err if err
        res.set 'Count-Return', Math.min(options.limit, total)
        res.set 'Count-Total', total
        return res.end() if req.method is 'HEAD'
        return res.json documents: [], count: 0, total: 0 if total is 0
        res.set 'Content-Type', 'application/json; charset=utf-8'

Stream documents user in order to prevent loading them into memory.

        op = '{"documents":['
        cl = '],"count":' + Math.min(options.limit, total) + ',"total":' + total + '}'

        cursor.stream().pipe(stringify(op, ',', cl)).pipe(res)

## POST /{collection}

    exports.post = (req, res, next) ->
      #
      # @TODO move update to :/collection/:document
      # @TODO add access control
      #

      return res.json 400, message: 'Body is missing' if Object.keys(req.body).length is 0
      return res.json 422, message: 'Body should be a JSON Hash' if req.body instanceof Array

      warnings = []
      errors   = []
      message  = ''

      req.body._id = new ObjectID(req.body._id) # @TODO restrict this
      req.body.tilbyder = req.usr
      req.body.endret = new Date().toISOString()

      if not req.body.lisens
        req.body.lisens = 'CC BY-ND-NC 3.0 NO'
        warnings.push
          resource: req.type
          field: 'lisens'
          value: req.body.lisens
          code: 'missing_field'

      if not req.body.status
        req.body.status = 'Kladd'
        warnings.push
          resource: req.type
          field: 'status'
          value: req.body.status
          code: 'missing_field'

      req.body.checksum = createHash('md5').update(JSON.stringify(req.body)).digest("hex")

      req.db.col.save req.body, {safe: true, w: 1}, (err) ->
        return next(err) if err
        cache.setForType req.type, req.body._id, req.body, (err, data) ->
          return next(err) if err
          return res.json 201,
            document:
              _id: req.body._id
            count: 1
            message: message if message
            warnings: warnings if warnings.length > 0
            errors: errors if errors.length > 0

## PATCH /{collection}

    exports.patch = (req, res, next) ->
      res.json 501, message: 'HTTP method not implmented'

## PUT /{collection}

    exports.put = (req, res, next) ->
      res.json 501, message: 'HTTP method not implmented'


Remove numberRegex - fixes #6.

Remove numberRegex - fixes #6.

Node-XLSX-Stream
================

Node-XLSX-Stream is written in literate coffeescript. The following is the actual source of the
module.

    fs = require('fs')
    blobs = require('./blobs')
    Archiver = require('archiver')

    module.exports = class XlsxWriter

### Simple writes

##### XlsxWriter.write(out: String, data: Array, cb: Function)

The simplest way to use Node-XLSX-Stream is to use the write method.

The callback comes directly from `fs.writeFile` and has the arity `(err)`

      # @param {String} out Output file path.
      # @param {Array} data Data to write.
      # @param {Function} cb Callback to call when done. Fed (err).
      @write = (out, data, cb) ->
        writer = new XlsxWriter({out: out})
        writer.addRows(data)
        writer.writeToFile(cb)

### Advanced usage

Node-XLSX-Stream has more advanced features available for better customization
of spreadsheets.

When constructing a writer, pass it an optional file path and customization options.

##### new XlsxWriter([options]: Object) : XlsxWriter

      # Build a writer object.
      # @param {Object} [options] Preparation options.
      # @param {String} [options.out] Output file path.
      # @param {Array}  [options.columns] Column definition. Must be added in constructor.
      # @example options.columns = [
      #     {  width: 30 }, // width is in 'characters'
      #     {  width: 10 }
      # ]
      constructor: (options = {}) ->

        # Support just passing a string path into the constructor.
        if (typeof options == 'string')
          options = {out: options}

        # Set options.
        defaults = {
          defaultWidth: 15
          zip: {
            forceUTC: true # this is required, zips will be unreadable without it
          },
          columns: []
        }
        @options = _extend(defaults, options)

        # Start sheet.
        @_resetSheet()

        # Write column definition.
        @defineColumns(@options.columns)

        # Create Zip.
        zipOptions = @options.zip || {}
        zipOptions.forceUTC = true # force this on in all cases for now, otherwise we're useless
        @zip = Archiver('zip', zipOptions)

        # Archiver attaches an exit listener on the process, we don't want this,
        # it will fire if this object is never finalized.
        @zip.catchEarlyExitAttached = true

        # Hook this passthrough into the zip stream.
        @zip.append(@sheetStream, {name: 'xl/worksheets/sheet1.xml'})

#### Adding rows

Rows are easy to add one by one or all at once. Data types within the sheet will
be inferred from the data types passed to addRow().

##### addRow(row: Object)

Add a single row.

      # @example (javascript)
      # writer.addRow({
      #     "A String Column" : "A String Value",
      #     "A Number Column" : 12345,
      #     "A Date Column" : new Date(1999,11,31)
      # })
      addRow: (row) ->

        # Values in header are defined by the keys of the object we've passed in.
        # They need to be written the first time they're passed in.
        if !@haveHeader
          @_write(blobs.sheetDataHeader)
          @_startRow()
          col = 1
          for key of row
            @_addCell(key, col)
            @cellMap.push(key)
            col += 1
          @_endRow()

          @haveHeader = true

        @_startRow()
        for key, col in @cellMap
          @_addCell(row[key] || "", col + 1)
        @_endRow()

##### addRows(rows: Array)

Rows can be added in batch.

      addRows: (rows) ->
        for row in rows
          @addRow(row)

##### defineColumns(columns: Array)

Column definitions can be easily added, but it *must* be done before rows are added
to prevent a nasty Excel bug.

      # @example (javascript)
      # writer.defineColumns([
      #     {  width: 30 }, // width is in 'characters'
      #     {  width: 10 }
      # ])
      defineColumns: (columns) ->
        if @haveHeader
          throw new Error """
            Columns cannot be added after rows! Unfortunately Excel will crash
            if column definitions come after sheet data. Please move your `defineColumns()`
            call before any `addRow()` calls, or define options.columns in the XlsxWriter
            constructor.
          """
        @options.columns = columns
        # Write column metadata.
        # Would really like to do this at the end so that we don't have to mandate
        # it comes first, but Excel pukes if <cols> comes before <sheetData>.
        @_write(@_generateColumnDefinition())

#### File generation

Once you are done adding rows & defining columns, you have a few options
for generating the file. The `writeToFile` helper is a one-stop-shop for writing
directly to a file using `fs.writeFile`; otherwise, you can pack() manually,
which will return a readable stream.

##### writeToFile([fileName]: String, cb: Function)

Writes data to a file. Convenience method.

If no filename is specified, will attempt to use the one specified in the
constructor as `options.out`.

The callback is fed directly to `fs.writeFile`.

      # @param {String} [fileName] File path to write.
      # @param {Function} cb Callback.
      writeToFile: (fileName, cb) ->
        if fileName instanceof Function
          cb = fileName
          fileName = @options.out
        if !fileName
          throw new Error("Filename required. Supply one in writeToFile() or in options.out.")

        # Create zip, pipe it into a file writeStream.
        zip = @createReadStream(fileName)
        fileStream = fs.createWriteStream(fileName)
        fileStream.once 'finish', cb
        zip.pipe(fileStream)
        @finalize()

##### createReadStream() : Stream **Deprecated**

      # @return {Stream} Readable stream with ZIP data.
      createReadStream: () ->
        @getReadStream()

##### getReadStream() : Stream

Returns a readable stream from this file. You can pipe this directly to a file
or response object. Be sure to use 'binary' mode.

You are responsible for indicating that you have finished
the file generation by calling `finalize()`, which will end the sheet stream.

      # @return {Stream} Readable stream with ZIP data.
      getReadStream: () ->
        @zip

##### finalize()

Finishes up the sheet & generate shared strings. You must call this manually if
you are using `createReadStream`.

      finalize: () ->

        if @finalized
          throw new Error "This XLSX was already finalized."

        # Mark this as finished
        @finalized = true

        # If there was data, end sheetData
        if @haveHeader
          @_write(blobs.sheetDataFooter)

        # Write relationships data.
        @_write(blobs.worksheetRels(@relationships))

        # Generate shared strings
        @_generateStrings()

        # Generate external rels
        @_generateRelationships()

        # End sheet
        @sheetStream.end(blobs.sheetFooter)

        # Add supporting files to zip and finalize it. The readStream (@zip) will soon emit
        # an 'end' event.
        @_finalizeZip()

##### dispose()

Cancel use of this writer and close all streams. This is not needed if you've written to a file.

      dispose: () ->
        return if @disposed

        @sheetStream.end()
        @sheetStream.unpipe()
        @zip.unpipe()
        while(@zip.read()) # drain stream
          1; # noop
        delete @zip
        delete @sheetStream
        @disposed = true

#### Internal methods

Adds a cell to the row in progress.

      # @param {String|Number|Date} value Value to write.
      # @param {Number}             col   Column index.
      _addCell: (value = '', col) ->
        row = @currentRow
        cell = @_getCellIdentifier(row, col)

        # Hyperlink support
        if Object.prototype.toString.call(value) == '[object Object]'
          if !value.value || !value.hyperlink
            throw new Error("A hyperlink cell must have both 'value' and 'hyperlink' keys.")
          @_addCell(value.value, col)
          @_createRelationship(cell, value.hyperlink)
          return

        if typeof value == 'number'
          @rowBuffer += blobs.numberCell(value, cell)
        else if value instanceof Date
          date = @_dateToOADate(value)
          @rowBuffer += blobs.dateCell(date, cell)
        else
          index = @_lookupString(value)
          @rowBuffer += blobs.cell(index, cell)

Begins a row. Call this before starting any row. Will start a buffer
for all proceeding cells, until @_endRow is called.

      _startRow: () ->
        @rowBuffer = blobs.startRow(@currentRow)
        @currentRow += 1

Ends a row. Will write the row to the sheet.

      _endRow: () ->
        @_write(@rowBuffer + blobs.endRow)

Given row and column indices, returns a cell identifier, e.g. "E20"

      # @param {Number} row  Row index.
      # @param {Number} cell Cell index.
      # @return {String}     Cell identifier.
      _getCellIdentifier: (row, col) ->
        colIndex = ''
        if @cellLabelMap[col]
          colIndex = @cellLabelMap[col]
        else
          if col == 0
            # Provide a fallback for empty spreadsheets
            row = 1
            col = 1

          input = (+col - 1).toString(26)
          while input.length
            a = input.charCodeAt(input.length - 1)
            colIndex = String.fromCharCode(a + if a >= 48 and a <= 57 then 17 else -22) + colIndex
            input = if input.length > 1 then (parseInt(input.substr(0, input.length - 1), 26) - 1).toString(26) else ""
          @cellLabelMap[col] = colIndex

        return colIndex + row

Creates column definitions, if any definitions exist.
This will write column styles, widths, etc.

      # @return {String} Column definition.
      _generateColumnDefinition: () ->
        # <cols/> tag (empty) crashes excel, weeeeee
        if !@options.columns || !@options.columns.length
          return ''

        columnDefinition = ''
        columnDefinition += blobs.startColumns

        idx = 1
        for index, column of @options.columns
          columnDefinition += blobs.column(column.width || @options.defaultWidth, idx)
          idx += 1

        columnDefinition += blobs.endColumns
        return columnDefinition

Generates StringMap XML. Used as a finalization step - don't call this while
building the xlsx is in progress.

Saves string data to this object so it can be written to the zip.

      _generateStrings: () ->
        stringTable = ''
        for string in @strings
          stringTable += blobs.string(@escapeXml(string))
        @stringsData = blobs.stringsHeader(@strings.length) + stringTable + blobs.stringsFooter

Looks up a string inside the internal string map. If it doesn't exist, it will be added to the map.

      # @param {String} value String to look up.
      # @return {Number}      Index within the string map where this string is located.
      _lookupString: (value) ->
        if !@stringMap[value]
          @stringMap[value] = @stringIndex
          @strings.push(value)
          @stringIndex += 1
        return @stringMap[value]

Create a relationship. For now, this is always a hyperlink.
This writes to a array that will later be used define the rels.

      _createRelationship: (cell, target) ->
        @relationships.push({cell: cell, target: target})

Generate external relationships data. This is saved into "xl/worksheets/_rels/sheet1.xml.rels".

      _generateRelationships: () ->
        @relsData = blobs.externalWorksheetRels(@relationships)

Converts a Date to an OADate.
See [this stackoverflow post](http://stackoverflow.com/a/15550284/2644351)

      # @param {Date} date Date to convert.
      # @return {Number}   OADate.
      _dateToOADate: (date) ->
        epoch = new Date(1899,11,30)
        msPerDay = 8.64e7

        v = -1 * (epoch - date) / msPerDay

        # Deal with dates prior to 1899-12-30 00:00:00
        dec = v - Math.floor(v)

        if v < 0 and dec
          v = Math.floor(v) - dec

        return v

Convert an OADate to a Date.

      # @param {Number} oaDate OADate.
      # @return {Date}         Converted date.
      _OADateToDate: (oaDate) ->
        epoch = new Date(1899,11,30)
        msPerDay = 8.64e7

        # Deal with -ve values
        dec = oaDate - Math.floor(oaDate)

        if oaDate < 0 and dec
          oaDate = Math.floor(oaDate) - dec

        return new Date(oaDate * msPerDay + +epoch)

Resets sheet data. Called on initialization.

      _resetSheet: () ->

        # Sheet data storage.
        @sheetData = ''
        @strings = []
        @stringMap = {}
        @stringIndex = 0
        @stringData = null
        @currentRow = 0

        # Cell data storage
        @cellMap = []
        @cellLabelMap = {}

        # Column data storage
        @columns = []

        # Rels data storage
        @relData = ''
        @relationships = []

        # Flags
        @haveHeader = false
        @finalized = false

        # Create sheet stream.
        PassThrough = require('stream').PassThrough
        @sheetStream = new PassThrough()

        # Start off the sheet.
        @_write(blobs.sheetHeader)

Finalizes this file and adds supporting docs. Should not be called directly.

      _finalizeZip: () ->
        @zip
          .append(blobs.contentTypes, {name: '[Content_Types].xml'})
          .append(blobs.rels, {name: '_rels/.rels'})
          .append(blobs.workbook, {name: 'xl/workbook.xml'})
          .append(blobs.styles, {name: 'xl/styles.xml'})
          .append(blobs.workbookRels, {name: 'xl/_rels/workbook.xml.rels'})
          .append(@relsData, {name: 'xl/worksheets/_rels/sheet1.xml.rels'})
          .append(@stringsData, {name: 'xl/sharedStrings.xml'})
          .finalize()

Wrapper around writing sheet data.

      # @param {String} data Data to write to the sheet.
      _write: (data) ->
        @sheetStream.write(data)

Utility method for escaping XML - used within blobs and can be used manually.

      # @param {String} str String to escape.
      escapeXml: (str = '') ->
        return str.replace(/&/g, '&')
          .replace(/</g, '<')
          .replace(/>/g, '>')

Simple extend helper.

    _extend = (dest, src) ->
      for key, val of src
        dest[key] = val
      dest

Node-XLSX-Stream
================

Node-XLSX-Stream is written in literate coffeescript. The following is the actual source of the
module.

    fs = require('fs')
    blobs = require('./blobs')
    Archiver = require('archiver')
    numberRegex = /^[1-9\.][\d\.]+$/

    module.exports = class XlsxWriter

### Simple writes

##### XlsxWriter.write(out: String, data: Array, cb: Function)

The simplest way to use Node-XLSX-Stream is to use the write method.

The callback comes directly from `fs.writeFile` and has the arity `(err)`

      # @param {String} out Output file path.
      # @param {Array} data Data to write.
      # @param {Function} cb Callback to call when done. Fed (err).
      @write = (out, data, cb) ->
        writer = new XlsxWriter({out: out})
        writer.addRows(data)
        writer.writeToFile(cb)

### Advanced usage

Node-XLSX-Stream has more advanced features available for better customization
of spreadsheets.

When constructing a writer, pass it an optional file path and customization options.

##### new XlsxWriter([options]: Object) : XlsxWriter

      # Build a writer object.
      # @param {Object} [options] Preparation options.
      # @param {String} [options.out] Output file path.
      # @param {Array}  [options.columns] Column definition. Must be added in constructor.
      # @example options.columns = [
      #     {  width: 30 }, // width is in 'characters'
      #     {  width: 10 }
      # ]
      constructor: (options = {}) ->

        # Support just passing a string path into the constructor.
        if (typeof options == 'string')
          options = {out: options}

        # Set options.
        defaults = {
          defaultWidth: 15
          zip: {
            forceUTC: true # this is required, zips will be unreadable without it
          },
          columns: []
        }
        @options = _extend(defaults, options)

        # Start sheet.
        @_resetSheet()

        # Write column definition.
        @defineColumns(@options.columns)

        # Create Zip.
        zipOptions = @options.zip || {}
        zipOptions.forceUTC = true # force this on in all cases for now, otherwise we're useless
        @zip = Archiver('zip', zipOptions)

        # Archiver attaches an exit listener on the process, we don't want this,
        # it will fire if this object is never finalized.
        @zip.catchEarlyExitAttached = true

        # Hook this passthrough into the zip stream.
        @zip.append(@sheetStream, {name: 'xl/worksheets/sheet1.xml'})

#### Adding rows

Rows are easy to add one by one or all at once. Data types within the sheet will
be inferred from the data types passed to addRow().

##### addRow(row: Object)

Add a single row.

      # @example (javascript)
      # writer.addRow({
      #     "A String Column" : "A String Value",
      #     "A Number Column" : 12345,
      #     "A Date Column" : new Date(1999,11,31)
      # })
      addRow: (row) ->

        # Values in header are defined by the keys of the object we've passed in.
        # They need to be written the first time they're passed in.
        if !@haveHeader
          @_write(blobs.sheetDataHeader)
          @_startRow()
          col = 1
          for key of row
            @_addCell(key, col)
            @cellMap.push(key)
            col += 1
          @_endRow()

          @haveHeader = true

        @_startRow()
        for key, col in @cellMap
          @_addCell(row[key] || "", col + 1)
        @_endRow()

##### addRows(rows: Array)

Rows can be added in batch.

      addRows: (rows) ->
        for row in rows
          @addRow(row)

##### defineColumns(columns: Array)

Column definitions can be easily added, but it *must* be done before rows are added
to prevent a nasty Excel bug.

      # @example (javascript)
      # writer.defineColumns([
      #     {  width: 30 }, // width is in 'characters'
      #     {  width: 10 }
      # ])
      defineColumns: (columns) ->
        if @haveHeader
          throw new Error """
            Columns cannot be added after rows! Unfortunately Excel will crash
            if column definitions come after sheet data. Please move your `defineColumns()`
            call before any `addRow()` calls, or define options.columns in the XlsxWriter
            constructor.
          """
        @options.columns = columns
        # Write column metadata.
        # Would really like to do this at the end so that we don't have to mandate
        # it comes first, but Excel pukes if <cols> comes before <sheetData>.
        @_write(@_generateColumnDefinition())

#### File generation

Once you are done adding rows & defining columns, you have a few options
for generating the file. The `writeToFile` helper is a one-stop-shop for writing
directly to a file using `fs.writeFile`; otherwise, you can pack() manually,
which will return a readable stream.

##### writeToFile([fileName]: String, cb: Function)

Writes data to a file. Convenience method.

If no filename is specified, will attempt to use the one specified in the
constructor as `options.out`.

The callback is fed directly to `fs.writeFile`.

      # @param {String} [fileName] File path to write.
      # @param {Function} cb Callback.
      writeToFile: (fileName, cb) ->
        if fileName instanceof Function
          cb = fileName
          fileName = @options.out
        if !fileName
          throw new Error("Filename required. Supply one in writeToFile() or in options.out.")

        # Create zip, pipe it into a file writeStream.
        zip = @createReadStream(fileName)
        fileStream = fs.createWriteStream(fileName)
        fileStream.once 'finish', cb
        zip.pipe(fileStream)
        @finalize()

##### createReadStream() : Stream **Deprecated**

      # @return {Stream} Readable stream with ZIP data.
      createReadStream: () ->
        @getReadStream()

##### getReadStream() : Stream

Returns a readable stream from this file. You can pipe this directly to a file
or response object. Be sure to use 'binary' mode.

You are responsible for indicating that you have finished
the file generation by calling `finalize()`, which will end the sheet stream.

      # @return {Stream} Readable stream with ZIP data.
      getReadStream: () ->
        @zip

##### finalize()

Finishes up the sheet & generate shared strings. You must call this manually if
you are using `createReadStream`.

      finalize: () ->

        if @finalized
          throw new Error "This XLSX was already finalized."

        # Mark this as finished
        @finalized = true

        # If there was data, end sheetData
        if @haveHeader
          @_write(blobs.sheetDataFooter)

        # Write relationships data.
        @_write(blobs.worksheetRels(@relationships))

        # Generate shared strings
        @_generateStrings()

        # Generate external rels
        @_generateRelationships()

        # End sheet
        @sheetStream.end(blobs.sheetFooter)

        # Add supporting files to zip and finalize it. The readStream (@zip) will soon emit
        # an 'end' event.
        @_finalizeZip()

##### dispose()

Cancel use of this writer and close all streams. This is not needed if you've written to a file.

      dispose: () ->
        return if @disposed

        @sheetStream.end()
        @sheetStream.unpipe()
        @zip.unpipe()
        while(@zip.read()) # drain stream
          1; # noop
        delete @zip
        delete @sheetStream
        @disposed = true

#### Internal methods

Adds a cell to the row in progress.

      # @param {String|Number|Date} value Value to write.
      # @param {Number}             col   Column index.
      _addCell: (value = '', col) ->
        row = @currentRow
        cell = @_getCellIdentifier(row, col)

        # Hyperlink support
        if Object.prototype.toString.call(value) == '[object Object]'
          if !value.value || !value.hyperlink
            throw new Error("A hyperlink cell must have both 'value' and 'hyperlink' keys.")
          @_addCell(value.value, col)
          @_createRelationship(cell, value.hyperlink)
          return

        if typeof value == 'number' or numberRegex.test(value)
          @rowBuffer += blobs.numberCell(value, cell)
        else if value instanceof Date
          date = @_dateToOADate(value)
          @rowBuffer += blobs.dateCell(date, cell)
        else
          index = @_lookupString(value)
          @rowBuffer += blobs.cell(index, cell)

Begins a row. Call this before starting any row. Will start a buffer
for all proceeding cells, until @_endRow is called.

      _startRow: () ->
        @rowBuffer = blobs.startRow(@currentRow)
        @currentRow += 1

Ends a row. Will write the row to the sheet.

      _endRow: () ->
        @_write(@rowBuffer + blobs.endRow)

Given row and column indices, returns a cell identifier, e.g. "E20"

      # @param {Number} row  Row index.
      # @param {Number} cell Cell index.
      # @return {String}     Cell identifier.
      _getCellIdentifier: (row, col) ->
        colIndex = ''
        if @cellLabelMap[col]
          colIndex = @cellLabelMap[col]
        else
          if col == 0
            # Provide a fallback for empty spreadsheets
            row = 1
            col = 1

          input = (+col - 1).toString(26)
          while input.length
            a = input.charCodeAt(input.length - 1)
            colIndex = String.fromCharCode(a + if a >= 48 and a <= 57 then 17 else -22) + colIndex
            input = if input.length > 1 then (parseInt(input.substr(0, input.length - 1), 26) - 1).toString(26) else ""
          @cellLabelMap[col] = colIndex

        return colIndex + row

Creates column definitions, if any definitions exist.
This will write column styles, widths, etc.

      # @return {String} Column definition.
      _generateColumnDefinition: () ->
        # <cols/> tag (empty) crashes excel, weeeeee
        if !@options.columns || !@options.columns.length
          return ''

        columnDefinition = ''
        columnDefinition += blobs.startColumns

        idx = 1
        for index, column of @options.columns
          columnDefinition += blobs.column(column.width || @options.defaultWidth, idx)
          idx += 1

        columnDefinition += blobs.endColumns
        return columnDefinition

Generates StringMap XML. Used as a finalization step - don't call this while
building the xlsx is in progress.

Saves string data to this object so it can be written to the zip.

      _generateStrings: () ->
        stringTable = ''
        for string in @strings
          stringTable += blobs.string(@escapeXml(string))
        @stringsData = blobs.stringsHeader(@strings.length) + stringTable + blobs.stringsFooter

Looks up a string inside the internal string map. If it doesn't exist, it will be added to the map.

      # @param {String} value String to look up.
      # @return {Number}      Index within the string map where this string is located.
      _lookupString: (value) ->
        if !@stringMap[value]
          @stringMap[value] = @stringIndex
          @strings.push(value)
          @stringIndex += 1
        return @stringMap[value]

Create a relationship. For now, this is always a hyperlink.
This writes to a array that will later be used define the rels.

      _createRelationship: (cell, target) ->
        @relationships.push({cell: cell, target: target})

Generate external relationships data. This is saved into "xl/worksheets/_rels/sheet1.xml.rels".

      _generateRelationships: () ->
        @relsData = blobs.externalWorksheetRels(@relationships)

Converts a Date to an OADate.
See [this stackoverflow post](http://stackoverflow.com/a/15550284/2644351)

      # @param {Date} date Date to convert.
      # @return {Number}   OADate.
      _dateToOADate: (date) ->
        epoch = new Date(1899,11,30)
        msPerDay = 8.64e7

        v = -1 * (epoch - date) / msPerDay

        # Deal with dates prior to 1899-12-30 00:00:00
        dec = v - Math.floor(v)

        if v < 0 and dec
          v = Math.floor(v) - dec

        return v

Convert an OADate to a Date.

      # @param {Number} oaDate OADate.
      # @return {Date}         Converted date.
      _OADateToDate: (oaDate) ->
        epoch = new Date(1899,11,30)
        msPerDay = 8.64e7

        # Deal with -ve values
        dec = oaDate - Math.floor(oaDate)

        if oaDate < 0 and dec
          oaDate = Math.floor(oaDate) - dec

        return new Date(oaDate * msPerDay + +epoch)

Resets sheet data. Called on initialization.

      _resetSheet: () ->

        # Sheet data storage.
        @sheetData = ''
        @strings = []
        @stringMap = {}
        @stringIndex = 0
        @stringData = null
        @currentRow = 0

        # Cell data storage
        @cellMap = []
        @cellLabelMap = {}

        # Column data storage
        @columns = []

        # Rels data storage
        @relData = ''
        @relationships = []

        # Flags
        @haveHeader = false
        @finalized = false

        # Create sheet stream.
        PassThrough = require('stream').PassThrough
        @sheetStream = new PassThrough()

        # Start off the sheet.
        @_write(blobs.sheetHeader)

Finalizes this file and adds supporting docs. Should not be called directly.

      _finalizeZip: () ->
        @zip
          .append(blobs.contentTypes, {name: '[Content_Types].xml'})
          .append(blobs.rels, {name: '_rels/.rels'})
          .append(blobs.workbook, {name: 'xl/workbook.xml'})
          .append(blobs.styles, {name: 'xl/styles.xml'})
          .append(blobs.workbookRels, {name: 'xl/_rels/workbook.xml.rels'})
          .append(@relsData, {name: 'xl/worksheets/_rels/sheet1.xml.rels'})
          .append(@stringsData, {name: 'xl/sharedStrings.xml'})
          .finalize()

Wrapper around writing sheet data.

      # @param {String} data Data to write to the sheet.
      _write: (data) ->
        @sheetStream.write(data)

Utility method for escaping XML - used within blobs and can be used manually.

      # @param {String} str String to escape.
      escapeXml: (str = '') ->
        return str.replace(/&/g, '&')
          .replace(/</g, '<')
          .replace(/>/g, '>')

Simple extend helper.

    _extend = (dest, src) ->
      for key, val of src
        dest[key] = val
      dest


Docs for conjunction / disjunction

Docs for conjunction / disjunction

We always start with the JavaScript-like magic scoping mojo!

    ((root) ->
      root = this
      _ = root._ || require 'underscore'
      F = {}

Non-determinism
---------------

Non-deterministic functions are functions that can have more (or less) than one result.  As known from logic, a binary relation xRy (where x ∈ X, y ∈ Y) can be represented by a *function*  `X -> PowerSet{Y}`. As usual in computer science, we interpret the set `PowerSet{Y}` as a multi-set (realized as a regular scheme list). Compare with SQL, which likewise uses multisets and sequences were sets are properly called for. Also compare with [Wadler's "representing failure as a list of successes."](http://citeseer.uark.edu:8080/citeseerx/showciting;jsessionid=FF5F5EAA9D94B1A8618C49C37451D762?cid=377301).

Thus, we represent a 'relation' (aka `non-deterministic function') as a regular CoffeeScript function that returns an array of possible results.

First, we define two primitive non-deterministic functions; one of them yields no result whatsoever for any argument; the other merely returns its argument as the sole result.

    F.succeed = (result) -> [result]
    F.fail = _.always []

We build more complex non-deterministic functions by combining the existing ones with the help of the following two combinators.

`(disjunction l r)` returns all the results of `l` and all the results of `r`, or returns no results only if neither `l` nor `r` returned any.  In that sense, it is analogous to the logical disjunctionunction.

    disjunction = (l, r) ->
      (x) -> _.cat(l(x), r(x))

`(conjunction l r)` looks like a functional composition of `r` and `l`.  Only `(l x)` may return several results, so we have to apply `r` to each of them.  Obviously `(conjunction fail f)` and `(conjunction f fail)` are both equivalent to `fail`: they return no results, ever. It that sense, `conjunction` is analogous to the logical conjunction.

    conjunction = (l, r) ->
      (x) -> _.mapcat(l(x), r)

    F.disj = () ->
      return F.fail if _.isEmpty(arguments)
      disjunction(_.first(arguments),
	              F.disj.apply(this, _.rest(arguments)))

  F.conj = () ->
    clauses = _.toArray(arguments)
    return F.succeed if _.isEmpty(clauses)
    return _.first(clauses) if _.size(clauses) is 1
    conjunction(_.first(clauses),
                (s) -> F.conj.apply(null, _.rest(clauses))(s))

  # Knowledge representation
  # ------------------------

  class LVar
    constructor: (@name) ->

  F.lvar = (name) -> new LVar(name)
  F.isLVar = (v) -> (v instanceof LVar)

  find = (v, bindings) ->
    lvar = bindings.lookup(v)
    return lvar if F.isLVar(v)
    if _.isArray(lvar)
      if _.isEmpty(lvar)
        return lvar
      else
        return _.cons(find(_.first(lvar), bindings), find(_.rest(lvar), bindings))
    lvar

  class Bindings
    constructor: (seed = {}) ->
      @binds = _.merge({}, seed)
    extend: (lvar, value) ->
      o = {}
      o[lvar.name] = value
      new Bindings(_.merge(@binds, o))
    has: (lvar) ->
      @binds.hasOwnProperty(lvar.name)
    lookup: (lvar) ->
      return lvar if !F.isLVar(lvar)
      return this.lookup(@binds[lvar.name]) if this.has(lvar)
      lvar

  F.ignorance = new Bindings()

  # Unification
  # -----------

  F.unify = (l, r, bindings) ->
    t1 = bindings.lookup(l)
    t2 = bindings.lookup(r)

    if _.isEqual(t1, t2)
      return s
    if F.isLVar(t1)
      return bindings.extend(t1, t2)
    if F.isLVar(t2)
      return bindings.extend(t2, t1)
    if _.isArray(t1) && _.isArray(t2)
      s = F.unify(_.first(t1), _.first(t2), bindings)
      s = if (s isnt null) then F.unify(_.rest(t1), _.rest(t2), bindings) else s
      return s
    return null

  # Operational logic
  # -----------------

  F.goal = (l, r) ->
    (bindings) ->
      result = F.unify(l, r, bindings)
      return F.succeed(result) if result isnt null
      return F.fail(bindings)

  F.run = (goal) ->
    goal(F.ignorance)

  # Logico
  # ------

  F.choice = ($v, list) ->
    return F.fail if _.isEmpty(list)

    F.disj(F.goal($v, _.first(list)),
                  F.choice($v, _.rest(list)))

  # Exports and sundries
  # --------------------

  if module?
    module.exports = F
  else
    root.F = F

)(this)

We always start with the JavaScript-like magic scoping mojo!

    ((root) ->
      root = this
      _ = root._ || require 'underscore'
      F = {}

Non-determinism
---------------

Non-deterministic functions are functions that can have more (or less) than one result.  As known from logic, a binary relation xRy (where x ∈ X, y ∈ Y) can be represented by a *function*  `X -> PowerSet{Y}`. As usual in computer science, we interpret the set `PowerSet{Y}` as a multi-set (realized as a regular scheme list). Compare with SQL, which likewise uses multisets and sequences were sets are properly called for. Also compare with [Wadler's "representing failure as a list of successes."](http://citeseer.uark.edu:8080/citeseerx/showciting;jsessionid=FF5F5EAA9D94B1A8618C49C37451D762?cid=377301).

Thus, we represent a 'relation' (aka `non-deterministic function') as a regular CoffeeScript function that returns an array of possible results.

First, we define two primitive non-deterministic functions; one of them yields no result whatsoever for any argument; the other merely returns its argument as the sole result.

    F.succeed = (result) -> [result]
    F.fail = _.always []

  disjunction = (l, r) ->
    (x) -> _.cat(l(x), r(x))
  conjunction = (l, r) ->
    (x) -> _.mapcat(l(x), r)

  F.disj = () ->
    return F.fail if _.isEmpty(arguments)
    disjunction(_.first(arguments), F.disj.apply(this, _.rest(arguments)))

  F.conj = () ->
    clauses = _.toArray(arguments)
    return F.succeed if _.isEmpty(clauses)
    return _.first(clauses) if _.size(clauses) is 1
    conjunction(_.first(clauses),
                (s) -> F.conj.apply(null, _.rest(clauses))(s))

  # Knowledge representation
  # ------------------------

  class LVar
    constructor: (@name) ->

  F.lvar = (name) -> new LVar(name)
  F.isLVar = (v) -> (v instanceof LVar)

  find = (v, bindings) ->
    lvar = bindings.lookup(v)
    return lvar if F.isLVar(v)
    if _.isArray(lvar)
      if _.isEmpty(lvar)
        return lvar
      else
        return _.cons(find(_.first(lvar), bindings), find(_.rest(lvar), bindings))
    lvar

  class Bindings
    constructor: (seed = {}) ->
      @binds = _.merge({}, seed)
    extend: (lvar, value) ->
      o = {}
      o[lvar.name] = value
      new Bindings(_.merge(@binds, o))
    has: (lvar) ->
      @binds.hasOwnProperty(lvar.name)
    lookup: (lvar) ->
      return lvar if !F.isLVar(lvar)
      return this.lookup(@binds[lvar.name]) if this.has(lvar)
      lvar

  F.ignorance = new Bindings()

  # Unification
  # -----------

  F.unify = (l, r, bindings) ->
    t1 = bindings.lookup(l)
    t2 = bindings.lookup(r)

    if _.isEqual(t1, t2)
      return s
    if F.isLVar(t1)
      return bindings.extend(t1, t2)
    if F.isLVar(t2)
      return bindings.extend(t2, t1)
    if _.isArray(t1) && _.isArray(t2)
      s = F.unify(_.first(t1), _.first(t2), bindings)
      s = if (s isnt null) then F.unify(_.rest(t1), _.rest(t2), bindings) else s
      return s
    return null

  # Operational logic
  # -----------------

  F.goal = (l, r) ->
    (bindings) ->
      result = F.unify(l, r, bindings)
      return F.succeed(result) if result isnt null
      return F.fail(bindings)

  F.run = (goal) ->
    goal(F.ignorance)

  # Logico
  # ------

  F.choice = ($v, list) ->
    return F.fail if _.isEmpty(list)

    F.disj(F.goal($v, _.first(list)),
                  F.choice($v, _.rest(list)))

  # Exports and sundries
  # --------------------

  if module?
    module.exports = F
  else
    root.F = F

)(this)