fix(query): run query post filter on parsed query object

    MongoQS     = require 'mongo-querystring'
    Document    = require './model/Document'
    stringify   = require('JSONStream').stringify

    sentry      = require './db/sentry'
    mongo       = require './db/mongo'

    collections = [
      'turer'
      'steder'
      'grupper'
      'områder'
      'bilder'
      'arrangementer'
    ]

    qs = new MongoQS
      alias:
        tag: 'tags.0'
        gruppe: 'grupper'
        endret: 'after'
      blacklist:
        api_key     : true # other use
        order       : true # reserved
        sort        : true # other use
        limit       : true # other use
        skip        : true # other use
        fields      : true # other use
        _id         : true # use API endpoint
      custom:
        bbox: 'geojson'
        near: 'geojson'
        after: 'endret'

## PARAM {collection}

    exports.param = (req, res, next, col) ->
      col = decodeURIComponent col

      if col not in collections
        return res.status(404).json message: "Type #{col} not found"

      req.type = col
      req.db   = col: mongo[col], query: {}

      next()

    exports.paramCol2 = (req, res, next, col2) ->
      if col not in collections
        return res.status(404).json message: "Type #{col2} not found"

      req.type      = col2
      req.db.col    = mongo[col2]
      req.db.query  = [{status: 'Offentlig'}, {tilbyder: req.user.tilbyder}]

      next()

## OPTIONS /{collection}

    exports.options = (req, res, next) ->
      res.setHeader 'Access-Control-Expose-Headers', [
        'ETag', 'Location', 'Last-Modified', 'Count-Return', 'Count-Total'
      ].join(', ')
      res.setHeader 'Access-Control-Max-Age', 86400
      res.setHeader 'Access-Control-Allow-Headers', 'Content-Type'
      res.setHeader 'Access-Control-Allow-Methods', 'HEAD, GET, POST'
      res.sendStatus 204

## HEAD /{collection}
## GET /{collection}

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

### Query

      req.db.query = qs.parse req.query

Prevent private documents for other API user from being returned when quering
`tilbyder` and `status` fields.

      for key, val of req.db.query
        switch key
          when 'status'
            req.db.query.tilbyder = req.user.tilbyder if val not in ['Offentlig', 'Slettet']
            break
          when 'tilbyder'
            req.db.query.status = 'Offentlig' if val isnt req.user.tilbyder
            break
          else
            if key.substr(0,6) is 'privat'
              req.db.query.tilbyder = req.user.tilbyder
              break

Apply default access control unless `status` or `tilbyder` fields are already
queried.

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

### Fields

Always return `endret`, `lisens`, `navn`, `status`, `tilbyder`, and `tags` in
addition to `\_id` ObjectID which is always returned by MongoDB.

      fields =
        endret: true
        lisens: true
        navn: true
        status: true
        tags: true
        tilbyder: true

Parse user specified fields to be returned.

      if typeof req.query.fields is 'string' and req.query.fields
        for field in req.query.fields.split ','
          fields[field] = true

If any private fields are to be returned we need to limit the query to documents
owner by the API user to prevent exposing private data publicly.

          req.db.query.tilbyder = req.user.tilbyder if field.substr(0,6) is 'privat'

### Sort

Limit sort to ascending or descending on `\_id`, `endret`, and `navn` since they
are indexed. Non-indexed fields will be slower. Also, don't allow ordering of
geospatial queries to prevent performance bottlenecks. From the [MongoDB
refference](http://docs.mongodb.org/manual/reference/operator/query/near/#behavior):

> $near always returns the documents sorted by distance. Any other sort order
> requires to sort the documents in memory, which can be inefficient.

      if not req.db.query.geojson
        sort = switch req.query.sort
          when '_id' then [['_id', 1]]
          when '-_id' then [['_id', -1]]
          when 'endret' then [['endret', 1]]
          when '-endret' then [['endret', -1]]
          when 'navn' then [['navn', 1]]
          when '-navn' then [['navn', -1]]
          else 'endret'

### Execute

Make new cursor object with the correct query, fields, and other options (limit,
skip, and sort).

      cursor = req.db.col.find req.db.query, fields,
        limit: Math.min (parseInt(req.query.limit, 10) or 20), 50
        skip: parseInt(req.query.skip, 10) or 0
        sort: sort

Count number of matching documents in MongoDB database.

      cursor.count false, (err, total) ->
        return next err if err

Calculate the total number of documents that will eventually be returned (not
the total number of matching documents) since we don't know that in advanced
(due to the nature of streaming).

        count = Math.min cursor.cmd.limit, Math.max total - cursor.cmd.skip, 0

Set `Count-Return` and `Count-Total` headers so that one can use a `HEAD` query
to look up the number of matched documents for a query without the documents
them selves. This may be useful for statistics purposes.

        res.set 'Count-Return', count
        res.set 'Count-Total', total

Return to the user if this is a `HEAD` query or there are no matching documents.

        return res.sendStatus 204 if req.method is 'HEAD'
        return res.json documents: [], count: 0, total: 0 if total is 0

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

        res.set 'Content-Type', 'application/json; charset=utf-8'

        op = '{"documents":['
        cl = '],"count":' + count + ',"total":' + total + '}'

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

## POST /{collection}

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

      req.body.tilbyder = req.user.tilbyder

      new Document(req.type, null).once('error', next).once 'ready', ->
        @insert req.body, (err, warn, data) ->
          if err
            return next(err) if err.name isnt 'ValidationError'

            sentry.captureDocumentError req, err

            return res.status(422).json
              document: req.body
              message: 'Validation Failed'
              errors: err.details #TODO(starefossen) document this

          res.set 'ETag', "\"#{data.checksum}\""
          res.set 'Last-Modified', new Date(data.endret).toUTCString()
          # res.set 'Location', req.get 'host'

          return res.status(201).json
            document: data
            message: 'Validation Warnings' if warn.length > 0
            warnings: warn if warn.length > 0

    MongoQS     = require 'mongo-querystring'
    Document    = require './model/Document'
    stringify   = require('JSONStream').stringify

    sentry      = require './db/sentry'
    mongo       = require './db/mongo'

    collections = [
      'turer'
      'steder'
      'grupper'
      'områder'
      'bilder'
      'arrangementer'
    ]

    qs = new MongoQS
      alias:
        tag: 'tags.0'
        gruppe: 'grupper'
        endret: 'after'
      blacklist:
        api_key     : true # other use
        order       : true # reserved
        sort        : true # other use
        limit       : true # other use
        skip        : true # other use
        fields      : true # other use
        _id         : true # use API endpoint
      custom:
        bbox: 'geojson'
        near: 'geojson'
        after: 'endret'

## PARAM {collection}

    exports.param = (req, res, next, col) ->
      col = decodeURIComponent col

      if col not in collections
        return res.status(404).json message: "Type #{col} not found"

      req.type = col
      req.db   = col: mongo[col], query: {}

      next()

    exports.paramCol2 = (req, res, next, col2) ->
      if col not in collections
        return res.status(404).json message: "Type #{col2} not found"

      req.type      = col2
      req.db.col    = mongo[col2]
      req.db.query  = [{status: 'Offentlig'}, {tilbyder: req.user.tilbyder}]

      next()

## OPTIONS /{collection}

    exports.options = (req, res, next) ->
      res.setHeader 'Access-Control-Expose-Headers', [
        'ETag', 'Location', 'Last-Modified', 'Count-Return', 'Count-Total'
      ].join(', ')
      res.setHeader 'Access-Control-Max-Age', 86400
      res.setHeader 'Access-Control-Allow-Headers', 'Content-Type'
      res.setHeader 'Access-Control-Allow-Methods', 'HEAD, GET, POST'
      res.sendStatus 204

## HEAD /{collection}
## GET /{collection}

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

### Query

      req.db.query = qs.parse req.query

Prevent private documents for other API user from being returned when quering
`tilbyder` and `status` fields.

      for key, val of req.query
        switch key
          when 'status'
            req.db.query.tilbyder = req.user.tilbyder if val not in ['Offentlig', 'Slettet']
            break
          when 'tilbyder'
            req.db.query.status = 'Offentlig' if val isnt req.user.tilbyder
            break
          else
            if key.substr(0,6) is 'privat'
              req.db.query.tilbyder = req.user.tilbyder
              break

Apply default access control unless `status` or `tilbyder` fields are already
queried.

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

### Fields

Always return `endret`, `lisens`, `navn`, `status`, `tilbyder`, and `tags` in
addition to `\_id` ObjectID which is always returned by MongoDB.

      fields =
        endret: true
        lisens: true
        navn: true
        status: true
        tags: true
        tilbyder: true

Parse user specified fields to be returned.

      if typeof req.query.fields is 'string' and req.query.fields
        for field in req.query.fields.split ','
          fields[field] = true

If any private fields are to be returned we need to limit the query to documents
owner by the API user to prevent exposing private data publicly.

          req.db.query.tilbyder = req.user.tilbyder if field.substr(0,6) is 'privat'

### Sort

Limit sort to ascending or descending on `\_id`, `endret`, and `navn` since they
are indexed. Non-indexed fields will be slower. Also, don't allow ordering of
geospatial queries to prevent performance bottlenecks. From the [MongoDB
refference](http://docs.mongodb.org/manual/reference/operator/query/near/#behavior):

> $near always returns the documents sorted by distance. Any other sort order
> requires to sort the documents in memory, which can be inefficient.

      if not req.db.query.geojson
        sort = switch req.query.sort
          when '_id' then [['_id', 1]]
          when '-_id' then [['_id', -1]]
          when 'endret' then [['endret', 1]]
          when '-endret' then [['endret', -1]]
          when 'navn' then [['navn', 1]]
          when '-navn' then [['navn', -1]]
          else 'endret'

### Execute

Make new cursor object with the correct query, fields, and other options (limit,
skip, and sort).

      cursor = req.db.col.find req.db.query, fields,
        limit: Math.min (parseInt(req.query.limit, 10) or 20), 50
        skip: parseInt(req.query.skip, 10) or 0
        sort: sort

Count number of matching documents in MongoDB database.

      cursor.count false, (err, total) ->
        return next err if err

Calculate the total number of documents that will eventually be returned (not
the total number of matching documents) since we don't know that in advanced
(due to the nature of streaming).

        count = Math.min cursor.cmd.limit, Math.max total - cursor.cmd.skip, 0

Set `Count-Return` and `Count-Total` headers so that one can use a `HEAD` query
to look up the number of matched documents for a query without the documents
them selves. This may be useful for statistics purposes.

        res.set 'Count-Return', count
        res.set 'Count-Total', total

Return to the user if this is a `HEAD` query or there are no matching documents.

        return res.sendStatus 204 if req.method is 'HEAD'
        return res.json documents: [], count: 0, total: 0 if total is 0

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

        res.set 'Content-Type', 'application/json; charset=utf-8'

        op = '{"documents":['
        cl = '],"count":' + count + ',"total":' + total + '}'

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

## POST /{collection}

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

      req.body.tilbyder = req.user.tilbyder

      new Document(req.type, null).once('error', next).once 'ready', ->
        @insert req.body, (err, warn, data) ->
          if err
            return next(err) if err.name isnt 'ValidationError'

            sentry.captureDocumentError req, err

            return res.status(422).json
              document: req.body
              message: 'Validation Failed'
              errors: err.details #TODO(starefossen) document this

          res.set 'ETag', "\"#{data.checksum}\""
          res.set 'Last-Modified', new Date(data.endret).toUTCString()
          # res.set 'Location', req.get 'host'

          return res.status(201).json
            document: data
            message: 'Validation Warnings' if warn.length > 0
            warnings: warn if warn.length > 0


consistent

consistent

Pretty simple setup here.

    handlebars = require 'handlebars'
    aws = require 'aws-sdk'
    shortid = require 'shortid'

Setup the connection to s3

    aws.config.update {
        accessKeyId: process.env["AWS_ACCESS_KEY"],
        secretAccessKey: process.env["AWS_SECRET_KEY"]
    }
    aws.config.region = 'us-east-1'
    s3 = new aws.S3()

Set the name for your domain.

    module.exports = (url) ->
      DOMAIN = process.env["DOMAIN"] || "shortcake.com"
      BUCKET = process.env["BUCKET"] || DOMAIN
      GA_ID = process.env["GA_ID"]
      shortid.characters "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ()"

This is our basic HTML template that we'll use for doing the redirect. It's just
going to send the user to another page as soon as it's loaded. There's no server
since it's just a static file, but everything will be tracked by GA.

      source = """

          <title>{{url}}</title>

      """

      template = handlebars.compile(source)

Data should just be the user's Google Analytics Id and the URL that they want to
minify.

      data = { url: url, ga_id: GA_ID }
      html = template(data)

We're going to generate a shortlink for the URL. [`shortid`](https://github.com/dylang/shortid) does a pretty good job at balancing between being short, and also
being unique!

      _id = shortid.generate()

We could break up the files by the [first 3 letters in the id](http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html).
This makes it much easier for S3 to distribute the bucket (and greatly improves performance).
...but we're not going to do this yet.

      params = {
          Bucket: BUCKET,
          Key: _id
          ACL: "public-read",
          Body: html
      }
      s3.putObject params, (err, data) ->
          if err
              console.log err

We'll keep a running record of all links we've shortened and throw it into a
basic HTML page just to make it easy to do lookups.

      source = """

          <title>Shortened Links</title>

Shortened Links

              {{#objs}}

{{ Key }}

              {{/objs}}

      """
      params = { Bucket: BUCKET }
      s3.listObjects params, (err, objs) ->
        if err
            console.log "[ERROR]: could not list objects: " + err
        objs = objs.Contents.filter (obj) ->
          ! /index.html$/.test obj.Key
        html = handlebars.compile(source)({ objects: objs })
        params = {
            Bucket: BUCKET,
            Key: "index.html",
            ACL: "public-read",
            Body: html
        }
        s3.putObject params, (err, data) ->
            if err
                econsole.log "[ERROR]: " + err
        console.error "Visit: https://s3.amazonaws.com/#{BUCKET}/index.html"

Pretty simple setup here.

    handlebars = require 'handlebars'
    aws = require 'aws-sdk'
    shortid = require 'shortid'

Setup the connection to s3

    aws.config.update {
        accessKeyId: process.env["AWS_ACCESS_KEY"],
        secretAccessKey: process.env["AWS_SECRET_KEY"]
    }
    aws.config.region = 'us-east-1'
    s3 = new aws.S3()

Set the name for your domain.

    module.exports = (url) ->
      DOMAIN = process.env["DOMAIN"] || "shortcake.com"
      BUCKET = process.env["BUCKET"] || DOMAIN
      GA_ID = process.env["GA_ID"]
      shortid.characters "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ()"

This is our basic HTML template that we'll use for doing the redirect. It's just
going to send the user to another page as soon as it's loaded. There's no server
since it's just a static file, but everything will be tracked by GA.

      source = """

          <title>{{url}}</title>

      """

      template = handlebars.compile(source)

Data should just be the user's Google Analytics Id and the URL that they want to
minify.

      data = { url: url, ga_id: GA_ID }
      html = template(data)

We're going to generate a shortlink for the URL. [`shortid`](https://github.com/dylang/shortid) does a pretty good job at balancing between being short, and also
being unique!

      _id = shortid.generate()

We could break up the files by the [first 3 letters in the id](http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html).
This makes it much easier for S3 to distribute the bucket (and greatly improves performance).
...but we're not going to do this yet.

      params = {
          Bucket: BUCKET,
          Key: _id
          ACL: "public-read",
          Body: html
      }
      s3.putObject params, (err, data) ->
          if err
              console.log err

We'll keep a running record of all links we've shortened and throw it into a
basic HTML page just to make it easy to do lookups.

      source = """

          <title>Shortened Links</title>

Shortened Links

              {{#objs}}

{{ Key }}

              {{/objs}}

      """
      params = { Bucket: BUCKET }
      s3.listObjects params, (err, objs) ->
        if err
            console.log "[ERROR]: could not list objects: " + err
        objs = objs.Contents.filter (obj) ->
          ! /index.html$/.test obj.Key
        html = handlebars.compile(source)({ objects: objs })
        params = {
            Bucket: BUCKET,
            Key: "index.html",
            ACL: "public-read",
            Body: html
        }
        s3.putObject params, (err, data) ->
            if err
                console.log err
        console.error "Visit: https://s3.amazonaws.com/#{BUCKET}/index.html"


Remove pluralizer from ComponentFilter

Remove pluralizer from ComponentFilter

# ComponentFilter

This class filters collections of React components, often for
the purpose of finding a DOM node with a specific CSS
class, or ID.

## Example

```
componentFilter.with.cssClass("my-class")
               .exactly(2).times
               .result()
```

This will take the list of nodes in componentFilter,
filter them by cssClass and return a matching result
if there are exactly 2 of them.

## Requirements

The [JasmineMonad](./JasmineMonad.litcoffee#a-monad-for-jasmine-tests) is a "maybe" monad that
allows us to chain our matcher functions in a fluent way.

    JasmineMonad = require("./JasmineMonad.litcoffee")

### A monad for filtering collections of React components

    class ComponentFilter extends JasmineMonad

      constructor: (@value, @util, @testers, @messages) ->
        super(@value, @util, @testers, @messages)

#### English helpers

Because this monad deals with filtering lists of components
it is nice to have a couple of dummy properties that
allow us to use a more fluent English expression.
`@with`, `@and` and `time` can be used for that purpose.

        @with = this
        @and = this
        @time = this
        @times = this

#### Filtering nodes by CSS class

      # TODO: Is this necessary?  Does anyone add className
      # to a component?  What does it mean?
      cssClass: (cssClass) ->
        @bind (nodes) =>
          match = (a, b) ->
            return false if !b?
            b.indexOf(a) != -1

          if nodes?.length
            matched = (node for node in nodes when match(cssClass, node.props.className))
          else
            matched = []

          messages = [
            "Expected to find component with className #{cssClass}, but it was not there."
            "Expected not to find component with className #{cssClass}, but there #{@was(matched.length)}."
          ]

          if matched.length > 0
            @return(matched, messages)
          else
            @return(null, messages)

#### Enforcing the number of nodes

      exactly: (num) ->
        @bind (nodes) =>
          messages = [
            "Expected to find exactly #{@count(num, 'node')}, but there #{@was(nodes.length)}"
            "Expected not find #{@count(num, 'node')}, but there #{@was(nodes.length)}."
          ]

          if nodes.length == num
            @return(nodes, messages)
          else
            @return(null, messages)

Export our matchers from this file.

    module.exports = ComponentFilter

# ComponentFilter

This class filters collections of React components, often for
the purpose of finding a DOM node with a specific CSS
class, or ID.

## Example

```
componentFilter.with.cssClass("my-class")
               .exactly(2).times
               .result()
```

This will take the list of nodes in componentFilter,
filter them by cssClass and return a matching result
if there are exactly 2 of them.

## Requirements

The [JasmineMonad](./JasmineMonad.litcoffee) is a "maybe" monad that
allows us to chain our matcher functions in a fluent way.

    JasmineMonad = require("./JasmineMonad.litcoffee")

The matchers need to pluralize strings, so we need to load
[a string pluralizer method](pluralize.litcoffee)

    require("./pluralize.litcoffee")

### A monad for filtering collections of React components

    class ComponentFilter extends JasmineMonad

      constructor: (@value, @util, @testers, @messages) ->
        super(@value, @util, @testers, @messages)

#### English helpers

Because this monad deals with filtering lists of components
it is nice to have a couple of dummy properties that
allow us to use a more fluent English expression.
`@with`, `@and` and `time` can be used for that purpose.

        @with = this
        @and = this
        @time = this
        @times = this

#### Filtering nodes by CSS class

      # TODO: Is this necessary?  Does anyone add className
      # to a component?  What does it mean?
      cssClass: (cssClass) ->
        @bind (nodes) =>
          match = (a, b) ->
            return false if !b?
            b.indexOf(a) != -1

          if nodes?.length
            matched = (node for node in nodes when match(cssClass, node.props.className))
          else
            matched = []

          messages = [
            "Expected to find component with className #{cssClass}, but it was not there."
            "Expected not to find component with className #{cssClass}, but there #{@was(matched.length)}."
          ]

          if matched.length > 0
            @return(matched, messages)
          else
            @return(null, messages)

#### Enforcing the number of nodes

      exactly: (num) ->
        @bind (nodes) =>
          messages = [
            "Expected to find exactly #{@count(num, 'node')}, but there #{@was(nodes.length)}"
            "Expected not find #{@count(num, 'node')}, but there #{@was(nodes.length)}."
          ]

          if nodes.length == num
            @return(nodes, messages)
          else
            @return(null, messages)

Export our matchers from this file.

    module.exports = ComponentFilter


more tweaks for correctness and documentedness

*This is [Literate Coffeescript](http://coffeescript.org/#literate): code interleaved with Markdown
comments. The Coffeescript compiler will strip the Markdown and compile it like any other file.*

## platform-ng config defaults

This file defines the default configuration options for platform-ng and explains
how can modify the configuration to suit your needs.

When you call `Platform#config()` with your configuration object, this configuration is deep-extended with
yours to produce the working configuration.

### General application configuration

What's the app called (`name`), and what environment is it running in (`env`)? For `env`, anything other
than the string `'production'` is automatically considered `'development'` for debuggability.

	module.exports =
		app:
			name: 'unnamed-app'
			env: 'development'

#### Sessions

For sessions, you can choose to entirely disable them by setting `enabled` to `false`. Otherwise, your
choices for `type` are currently `cookie` or `vanilla`.

The `cookie` type stores all session data in a garbled (not encrypted) client-side cookie, signed using
the `secret`.

The `vanilla` type stores the session in a server-side session store and only transmits a signed session
ID to the client.

`cookie` is default for now, but `vanilla` will replace it in the next major version. The `secure` option
determines whether the cookies are HTTPS-only or not.

			session:
				enabled: true
				type: 'cookie'
				secret: 'change-me'
				secure: false

#### Cookie parser

The cookie parser transforms the `cookie` header into `request.cookies`, `request.signedCookies`, and
`request.secureCookies` objects. You still have to use `response.cookie(...)` and/or
`response.clearCookie(...)` to actually manipulate cookies. The `secret` defined here will be used to
verify signed cookies, and, if you set `{signed: true}` in the third argument to `response.cookie(...)`,
this `secret` will be used to sign the outbound cookies too.

			cookies:
				enabled: true
				secret: 'change-me'

### HTTP server configuration

The `server` sections deals with how platform-ng handles the exchange, parsing, and encoding of HTTP
requests and responses.

		server:
			# Use automatic gzip compression for responses?
			compress: true

			# TCP port to listen on (overriden by PORT environment variable)
			port: 8001

			# Is the app behind a proxy? If so, replace request.ip with X-Forwarded-For, and trust
			# all cookies for HTTPS-only mode.
			behind_proxy: false

			# Enable/disable various body parsers, for performance and security reasons
			parsers:
				urlencoded: true
				json: true
				multipart: false # potential security problem; read http://goo.gl/N4Bci1

			# Allow requests to change HTTP verb using 'X-HTTP-Method-Override' header?
			method_override: false

### Language configuration

This section controls which protolanguages platform-ng will compile, as well as language-specific options
for some of the languages. (The NPM dependencies for these languages are listed in `package.json` as
`optionalDependencies` and can be skipped entirely by calling `npm install --no-optional`.)

		languages:
			coffeescript:
				enabled: true

			stylus:
				enabled: true
				include_css: true	# Whether to inline @include()'d CSS files
				nib: true			# Whether to automatically load the nib library

`compile` controls generic compilation options for all language compilers. The `minify` option will
cause the compiler to munge the output in order to produce the smallest possible code. The `expose_sources`
option will cause the server to serve the original files (e.g. .coffee, .styl, etc) if requested, AND it
will ask the compiler to generate source maps, if supported.

		compile:
			minify: true
			expose_sources: true

platform-ng is powered by Express. You can directly configure Express settings here. The settings are
documented on [this page](http://expressjs.com/3x/api.html#app-settings).

		express:
			'view engine': 'jade'

*This is [Literate Coffeescript](http://coffeescript.org/#literate): code interleaved with Markdown
comments. The Coffeescript compiler will strip the Markdown and compile it like any other file.*

	module.exports =

## platform-ng config defaults

This file defines the default configuration options for platform-ng and explains
how can modify the configuration to suit your needs.

When you call `Platform#config()` with your configuration object, this configuration is deep-extended with
yours to produce the working configuration.

### General application configuration

What's the app called (`name`), and what environment is it running in (`env`)? For `env`, anything other
than the string `'production'` is automatically considered `'development'` for debuggability.

		app:
			name: 'unnamed-app'
			env: 'development'

#### Sessions

For sessions, you can choose to entirely disable them by setting `enabled` to `false`. Otherwise, your
choices for `type` are currently `cookie` or `vanilla`.

The `cookie` type stores all session data in a garbled (not encrypted) client-side cookie, signed using
the `secret`.

The `vanilla` type stores the session in a server-side session store and only transmits a signed session
ID to the client.

`cookie` is default for now, but `vanilla` will replace it in the next major version. The `secure` option
determines whether the cookies are HTTPS-only or not.

			session:
				enabled: true
				type: 'cookie'
				secret: 'change-me'
				secure: false

#### Cookie parser

The cookie parser transforms the `cookie` header into `request.cookies`, `request.signedCookies`, and
`request.secureCookies` objects. You still have to use `response.cookie(...)` and/or
`response.clearCookie(...)` to actually manipulate cookies. The `secret` defined here will be used to
verify signed cookies, and, if you set `{signed: true}` in the third argument to `response.cookie(...)`,
this `secret` will be used to sign the outbound cookies too.

			cookies:
				enabled: true
				secret: 'change-me'

### HTTP server configuration

The `server` sections deals with how platform-ng handles the exchange, parsing, and encoding of HTTP
requests and responses.

		server:
			# Use automatic gzip compression for responses?
			compress: true

			# TCP port to listen on (overriden by PORT environment variable)
			port: 8001

			# Is the app behind a proxy? If so, replace request.ip with X-Forwarded-For, and trust
			# all cookies for HTTPS-only mode.
			behind_proxy: false

			# Enable/disable various body parsers, for performance and security reasons
			parsers:
				urlencoded: true
				json: true
				multipart: false # potential security problem; read http://goo.gl/N4Bci1

			# Allow requests to change HTTP verb using 'X-HTTP-Method-Override' header?
			method_override: false

### Language configuration

This section controls which protolanguages platform-ng will compile, as well as language-specific options
for some of the languages. (The NPM dependencies for these languages are listed in `package.json` as
`optionalDependencies` and can be skipped entirely by calling `npm install --no-optional`.)

		languages:
			coffeescript:
				enabled: true

			stylus:
				enabled: true
				include_css: true	# Whether to inline @include()'d CSS files
				nib: true			# Whether to automatically load the nib library

`compile` controls generic compilation options for all language compilers. The `minify` option will
cause the compiler to munge the output in order to produce the smallest possible code. The `expose_sources`
option will cause the server to serve the original files (e.g. .coffee, .styl, etc) if requested, AND it
will ask the compiler to generate source maps, if supported.

		compile:
			minify: true
			expose_sources: true

platform-ng is powered by Express. You can directly configure Express settings here. The settings are
documented on [this page](http://expressjs.com/3x/api.html#app-settings).

		express:
			'view engine': 'jade'


Be smarter about Madul checking, add support for dep alias and initer

Instead of just checking whether a required module is a function, search
the prototype chain to see if any constructors are of type `Madul`.

Add support for dependency aliasing and dependency initializers. Aliases allow
for nicer names of hydrated dependencies, and initilialzers provide an easy way
to hook madul initializer methods up to dependency configuration/initialization.

    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.MADUL_ROOT || 'dist'

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

    WRAPPED = { }

    _INITIALIZERS = { }

    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

      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
                val
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = for own key, val of proto[method].validate
                val
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ proto[method].validate ]
            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) if proto[method].before?
            decs = decs.concat(proto[method].after)  if proto[method].after?

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

              out = undefined

              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
                      proto[val].EXECUTE args[i]
                else if args_format == 'OBJECT'
                  args = arguments[0]

                  if me.validate?
                    validators = for own key, val of me.validate
                      proto[val].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) => proto[b].before args
                .then =>
                  me.behavior.apply @, @_prep_invocation proto, method, args, def
                .then (result) =>
                  out = result
                  q.all me.after.map (b) => b.after out
                .then          => def.resolve out
                .catch   (err) => def.reject  err

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

          WRAPPED[proto.constructor.name].push method

      _wrap_methods: =>
        proto = @.__proto__
        name  = proto.constructor.name

        while proto? && Object.keys(proto).length > 0 && WRAPPED[name]? == false
          for method, body of proto
            if method[0]                  != '_'         &&
               (
                typeof body.behavior       == 'function' ||
                typeof body                == 'function'
               ) &&
               typeof proto["_#{method}"] == 'undefined' &&
               WRAP(name, method)         == true

              proto._do_wrap proto, method

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

          proto = proto.__proto__

      _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, (p, next) =>
          if p.deps?
            p._do_hydrate p, p.deps, next
          else
            next()
        , done

      _init_if_madul: (path, initer, callback) =>
        mod      = require path
        proto    = mod
        is_madul = false

        while proto
          is_madul = true if proto.constructor.name == 'Madul'

          proto = proto.__super__

        if is_madul
          new mod()
            .initialize()
            .then (mod) =>
              if initer?
                mod[initer]()
                  .then => callback mod
              else
                callback mod
        else
          callback mod

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

      _check: (me, path, dep, ref, initer, 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, initer, next
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  me._load me, ref, initer, depth, => me._do_add me, dep, ref, next
                else
                  next()
            , finished

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

        me[underscore name] = mod

      _do_add: (me, name, ref, next) =>
        me._add_dependency me, ref, available[strip name]
        next()

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

      _do_hydrate: (proto, deps, callback) =>
        async.each deps, (d, next) =>
          name, alias, initer = undefined
          tokens = d.split '->'

          if tokens.length == 2
            alias = tokens[0]
            t     = tokens[1].split '::'

            if t.length == 2
              name   = t[0]
              initer = t[1]
            else
              name = t[0]
          else
            name = alias = tokens[0]

          ref = alias || name

          if proto[underscore ref]? == false
            if available[strip name]? == true
              proto._do_add proto, name, ref, next
            else
              try
                proto._add proto, name, ref, initer, d, next
              catch e
                cwd = process.cwd()
                pkg = "#{cwd}/node_modules/#{d}/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/#{d}/#{main}"

                      proto._add proto, name, ref, initer, path, next
                  else
                    proto._check proto, "#{cwd}/#{code_root}", d, ref, initer next
          else
            next()
        , callback

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

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

    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.MADUL_ROOT || 'dist'

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

    WRAPPED = { }

    _INITIALIZERS = { }

    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

      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
                val
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = for own key, val of proto[method].validate
                val
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ proto[method].validate ]
            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) if proto[method].before?
            decs = decs.concat(proto[method].after)  if proto[method].after?

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

              out = undefined

              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
                      proto[val].EXECUTE args[i]
                else if args_format == 'OBJECT'
                  args = arguments[0]

                  if me.validate?
                    validators = for own key, val of me.validate
                      proto[val].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) => proto[b].before args
                .then =>
                  me.behavior.apply @, @_prep_invocation proto, method, args, def
                .then (result) =>
                  out = result
                  q.all me.after.map (b) => b.after out
                .then          => def.resolve out
                .catch   (err) => def.reject  err

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

          WRAPPED[proto.constructor.name].push method

      _wrap_methods: =>
        proto = @.__proto__
        name  = proto.constructor.name

        while proto? && Object.keys(proto).length > 0 && WRAPPED[name]? == false
          for method, body of proto
            if method[0]                  != '_'         &&
               (
                typeof body.behavior       == 'function' ||
                typeof body                == 'function'
               ) &&
               typeof proto["_#{method}"] == 'undefined' &&
               WRAP(name, method)         == true

              proto._do_wrap proto, method

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

          proto = proto.__proto__

      _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, (p, next) =>
          if p.deps?
            p._do_hydrate p, p.deps, next
          else
            next()
        , done

      _load: (me, name, path, loaded) =>
        mod = require path

        if typeof mod == 'function'
          new mod name
            .initialize @ctor_params?[name]
            .then (mod) =>
              me._make_available name, mod
              loaded()
        else
          me._make_available name, mod
          loaded()

      _check: (me, path, dep, 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, next
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  me._load me, f.substring(0, f.length - 3), depth, => me._do_add me, dep, next
                else
                  next()
            , finished

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

        me[underscore name] = mod

      _do_add: (me, name, next) =>
        me._add_dependency me, name, available[strip name]
        next()

      _add: (me, name, resource, next) =>
        me._make_available name, require resource
        me._do_add me, name, next

      _do_hydrate: (proto, deps, callback) =>
        async.each deps, (d, next) =>
          if proto[underscore d]? == false
            if available[strip d]? == true
              proto._do_add proto, d, next
            else
              try
                proto._add proto, d, d, next
              catch e
                cwd = process.cwd()
                pkg = "#{cwd}/node_modules/#{d}/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'

                      proto._add proto, d, "#{cwd}/node_modules/#{d}/#{main}", next
                  else
                    proto._check proto, "#{cwd}/#{code_root}", d, next
          else
            next()
        , callback

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

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


Clean up and document API upload route

Clean up and document API upload route

    express = require 'express'
    multer  = require 'multer'
    async   = require 'async'
    dms2dec = require 'dms2dec'

    sentry  = require '../sentry'
    librato = require '../librato'
    s3      = require '../upload'

Make a new Express router object for this part of the application.

    api = express.Router()

## Metrics

Agregate metrics for all requests and wheter they succeded (`finish`) or closed
before the request succeeded (`close`).

    api.use (req, res, next) ->
      librato.logRequest req.method

      res.once 'close', ->
        librato.logResponse 'closed'
        sentry.captureResClose res

      res.once 'finish', ->
        librato.logResponse res.statusCode

      next()

## GET /

    api.get '/', (req, res, next) ->
      res.status(204).end()

## POST /upload

Configure [multer](https://github.com/expressjs/multer) to store files in the
OS's temorary directory `tempdir()`. This way we should not need to clean up the
uploaded files since that should be the job of the OS.

    multer = require('multer')
      putSingleFilesInArray: true
      dest: require('os').tmpdir()

Configure the `/upload` route handler.

    api.post '/upload', multer, (req, res, next) ->
      librato.logImagesUploaded Object.keys req.files

      files = []
      for key, f of req.files
        files.push file for file in f

      async.mapSeries files, (file, cb) ->
        if file.extension.toLowerCase() not in ['jpg', 'jpeg', 'png', 'gif']
          error = new Error "Invalid Image #{file.extension}"
          error.status = 422
          return cb error

        t1 = new Date().getTime()
        s3.upload file.path, {}, (err, images, meta) ->
          return cb err if err

          librato.logImageProcessingTime t1, new Date().getTime()

Format image GeoJSON correctly if the image has GPS properties.

          if meta.exif?.GPSLatitude and meta.exif?.GPSLongitude
            meta.geojson =
              type: 'Point'
              coordinates: dms2dec \
                meta.exif.GPSLatitude, \
                meta.exif.GPSLatitudeRef, \
                meta.exif.GPSLongitude, \
                meta.exif.GPSLongitudeRef
              .reverse()

We need to remove the original image (index i - 1) since it is not publicly
accessible. It gets uploaded to AWS as backup of the original image.

          images = images.splice 0, images.length - 1

Loop over all the generated images and apply `width` and `height` properties
since that is currently not set correctly. We also remove some image information
such as AWS key and local path which are not in use.

          for image in images
            # Since we
            if not image.width
              image.height = image.maxHeight
              image.width = image.maxWidth

              if image.aspect
                image.height = Math.floor image.maxHeight * 2 / 3
              else
                if meta.height > meta.width
                  image.width = Math.floor image.height * meta.width / meta.height
                else
                  image.height = Math.floor image.width * meta.height / meta.width

            image.key       = undefined
            image.maxHeight = undefined
            image.maxWidth  = undefined
            image.path      = undefined
            image.suffix    = undefined

            console.log image

          return cb null, versions: images, meta: meta
      , (err, files) ->
        return next err if err
        sentry.captureHeaderSent req, files if res._headerSent
        return res.status(201).json files

    module.exports = api

    express = require 'express'
    multer  = require 'multer'
    async   = require 'async'
    dms2dec = require 'dms2dec'

    sentry  = require '../sentry'
    librato = require '../librato'
    s3      = require '../upload'

Make a new Express router object for this part of the application.

    api = express.Router()

## Metrics

Agregate metrics for all requests and wheter they succeded (`finish`) or closed
before the request succeeded (`close`).

    api.use (req, res, next) ->
      librato.logRequest req.method

      res.once 'close', ->
        librato.logResponse 'closed'
        sentry.captureResClose res

      res.once 'finish', ->
        librato.logResponse res.statusCode

      next()

## GET /

    api.get '/', (req, res, next) ->
      res.status(204).end()

## POST /upload

Configure [multer](https://github.com/expressjs/multer) to store files in the
OS's temorary directory `tempdir()`. This way we should not need to clean up the
uploaded files since that should be the job of the OS.

    multer = require('multer')
      putSingleFilesInArray: true
      dest: require('os').tmpdir()

Configure the `/upload` route handler.

    api.post '/upload', multer, (req, res, next) ->
      librato.logImagesUploaded Object.keys req.files

      files = []
      for key, f of req.files
        files.push file for file in f

      async.mapSeries files, (file, cb) ->
        if file.extension.toLowerCase() not in ['jpg', 'jpeg', 'png', 'gif']
          error = new Error "Invalid Image #{file.extension}"
          error.status = 422
          return cb error

        t1 = new Date().getTime()
        s3.upload file.path, {}, (err, images, meta) ->
          return cb err if err

          librato.logImageProcessingTime t1, new Date().getTime()

          if meta.exif?.GPSLatitude and meta.exif?.GPSLongitude
            meta.geojson =
              type: 'Point'
              coordinates: dms2dec \
                meta.exif.GPSLatitude, \
                meta.exif.GPSLatitudeRef, \
                meta.exif.GPSLongitude, \
                meta.exif.GPSLongitudeRef
              .reverse()

          #if meta.imageSize.height > meta.imageSize.width
          #  ratio = meta.imageSize.height / meta.imageSize.width
          #  edge = 'width'
          #else
          #  ratio = meta.imageSize.width / meta.imageSize.height
          #  edge = 'height'

          images = images.splice 0, images.length - 1

            image.path = undefined
            image.src = undefined

          for image in images
            # Since we
            if not image.width
              image.height = image.maxHeight
              image.width = image.maxWidth

              if image.aspect
                image.height = Math.floor image.maxHeight * 2 / 3
              else
                if meta.height > meta.width
                  image.width = Math.floor image.height * meta.width / meta.height
                else
                  image.height = Math.floor image.width * meta.height / meta.width

            image.key       = undefined
            image.maxHeight = undefined
            image.maxWidth  = undefined
            image.path      = undefined
            image.suffix    = undefined

            console.log image

          return cb null, versions: images, meta: meta
      , (err, files) ->
        return next err if err
        sentry.captureHeaderSent req, files if res._headerSent
        return res.status(201).json files

    module.exports = api


add aclType info to README

add aclType info to README

# loopback-with-domain

run loopback server with "domain"

domain is in this context business logic, the same as Domain-Driven Design (DDD).

connection with [base-domain](https://github.com/CureApp/base-domain)

# install

```
npm install loopback-with-domain
```

# run

before running, you can prepare a directory which contains custom config information.

```text
(config-dir) # any name is acceptable
|-- model-definitions.coffee
|-- common
|   |-- server.coffee
|   `-- admin.coffee
|-- development
|   `-- datasources.coffee
`-- production
    `-- datasources.coffee
```

    lbWithDomain = require 'loopback-with-domain'

    configDir = '/path/to/config-dir'

    domain = require('base-domain').createInstance(dirname: 'domain')

    lbWithDomain.runWithDomain(domain, configDir).then ->
        # loopback started

# configs

these are the config names.

- admin
- datasources
- middleware
- server
- push-credentials

see JSON files in "default-configs" directory.
you can set the same properties as these JSONs.

## admin

 config key  | meaning
-------------|-----------------------
 accessToken | accessToken for admin

## datasources

 config key  | meaning
-------------|-----------------------
 memory      | on memory datasource
 db          | datasource for domain entities

## server

 config key  | meaning       | default
-------------|---------------|----------------
 restApiRoot | REST api root | /api
 port        | port number   | 3000

## push-credentials

 config key      | meaning
-----------------|-------------------------------------------
 gcmServerApiKey | api key for Google Cloud Messaging (GCM)
 apnsCertData    | certificate pem contents for APNs
 apnsKeyData     | key pem contents for APNs

# model definitions

    module.exports =
        player: # model name
            base: 'User'  # the same as loopback model settings.base
            aclType: 'admin' # specific for this system

        instrument:
            aclType: 'owner-read'

the same format as [loopback model definition](http://docs.strongloop.com/display/public/LB/Customizing+models)
except "aclType" value.
name, base, relations and properties are automatically set from domain information.

## aclType
loopback-with-domain generates acls from aclType.

three types are available.

 aclType     | meaning
-------------|-----------------------------------------------------
 admin       | only admin can CRUD the model
 owner       | admin and the owner of the model can CRUD
 public-read | everyone can READ the model and admin can CRUD

# switching environment

running script with environment variable "NODE\_ENV" like

```bash
$ NODE_ENV=production node app.js
```

"development" is selected by default.

when your config dir is

```text
(config-dir) # any name is acceptable
|-- common
|   |-- server.coffee
|   `-- admin.coffee
|-- development
|   `-- datasources.coffee
|-- local
|   `-- datasources.coffee
|-- production
|   `-- datasources.coffee
```

and launching script like

```bash
$ NODE_ENV=local node app.js
```
then, loopback-with-domain selects configs in "local" directory.

## passing custom environment with argument

    env = 'production'

    lbWithDomain.runWithDomain(domain, configDir, env)

env is prior to NODE\_ENV settings.

# modified loopback-datasource-juggler

using [CureApp/loopback-datasource-juggler](https://github.com/CureApp/loopback-datasource-juggler).

this repository is almost the same as original one except 'memory' connector handles id as string
(orignally integer).

# loopback-with-domain

run loopback server with "domain"

domain is in this context business logic, the same as Domain-Driven Design (DDD).

connection with [base-domain](https://github.com/CureApp/base-domain)

# install

```
npm install loopback-with-domain
```

# run

before running, you can prepare a directory which contains custom config information.

```text
(config-dir) # any name is acceptable
|-- model-definitions.coffee
|-- common
|   |-- server.coffee
|   `-- admin.coffee
|-- development
|   `-- datasources.coffee
`-- production
    `-- datasources.coffee
```

    lbWithDomain = require 'loopback-with-domain'

    configDir = '/path/to/config-dir'

    domain = require('base-domain').createInstance(dirname: 'domain')

    lbWithDomain.runWithDomain(domain, configDir).then ->
        # loopback started

# configs

these are the config names.

- admin
- datasources
- middleware
- server
- push-credentials

see JSON files in "default-configs" directory.
you can set the same properties as these JSONs.

## admin

 config key  | meaning
-------------|-----------------------
 accessToken | accessToken for admin

## datasources

 config key  | meaning
-------------|-----------------------
 memory      | on memory datasource
 db          | datasource for domain entities

## server

 config key  | meaning       | default
-------------|---------------|----------------
 restApiRoot | REST api root | /api
 port        | port number   | 3000

## push-credentials

 config key      | meaning
-----------------|-------------------------------------------
 gcmServerApiKey | api key for Google Cloud Messaging (GCM)
 apnsCertData    | certificate pem contents for APNs
 apnsKeyData     | key pem contents for APNs

# switching environment

running script with environment variable "NODE\_ENV" like

```bash
$ NODE_ENV=production node app.js
```

"development" is selected by default.

when your config dir is

```text
(config-dir) # any name is acceptable
|-- common
|   |-- server.coffee
|   `-- admin.coffee
|-- development
|   `-- datasources.coffee
|-- local
|   `-- datasources.coffee
|-- production
|   `-- datasources.coffee
```

and launching script like

```bash
$ NODE_ENV=local node app.js
```
then, loopback-with-domain selects configs in "local" directory.

## passing custom environment with argument

    env = 'production'

    lbWithDomain.runWithDomain(domain, configDir, env)

env is prior to NODE\_ENV settings.

# modified loopback-datasource-juggler

using [CureApp/loopback-datasource-juggler](https://github.com/CureApp/loopback-datasource-juggler).

this repository is almost the same as original one except 'memory' connector handles id as string
(orignally integer).


Fix missing custom after query

Fix missing custom after query

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

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

      return @

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

        if bbox.length is 4
          val = parseFloat(val) for val in bbox

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

        return

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

        if input.length is 2
          val = parseFloat(val) for val in input

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

        return

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

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

        input = new Date input

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

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

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

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

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

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

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

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

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

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

      res

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

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

      return @

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

        if bbox.length is 4
          val = parseFloat(val) for val in bbox

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

        return

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

        if input.length is 2
          val = parseFloat(val) for val in input

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

        return

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

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

        input = new Date input

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

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

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

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

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

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

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

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

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

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

      res


Added classes for game elements

Added classes for game elements

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

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

Dear Stewart

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

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

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

Diwank Singh
July 2013

*****

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

Alright, let's get on with it.

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

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

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

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

        result

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

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

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

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

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

        else  # Assume it's array otherwise
          obj.splice 0

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

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

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

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

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

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

        false

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

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

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

    class Box
      # -- Private --

      _settings:
        # Default settings
        height: 100
        width:  200
        top:    0
        left:   0

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

      _window: null  # Empty window object
      _url: '/index.html' # Fixed to current page, renders based on context

      _EDITABLE: -> Object.keys @constructor::_settings   # Editable settings

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

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

        # Return a copy of settings
        @_getAll()

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

      _getDefault: -> @constructor::_settings

      # -- Public --

      constructor: (namespace='', settings) ->
        # Make a copy of default settings
        @_settings = _.clone @_settings

        # Override settings.
        @_update settings

        # Set random name with namespace
        @id = "#{ namespace }#{ if namespace then '-' else '' }#{ _.uuid() }"
        this

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

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

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

      # Reset window settings.
      reset: ->
        @_update @_getDefault()
        this

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

        # Return coords
        _.pick @_getAll(), ['top', 'left']

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

        # Return dimensions
        _.pick @_getAll(), ['width', 'height']

Class: Brick (Box)
------------------

Now let's use the class `Box` to design the `Brick` class which
will be used to render the bricks.

It's pretty much a useless box.

    class Brick extends Box
      constructor: (args...) -> super @type(), args...
      type: -> 'brick'

Class: Ball (Box)
-----------------

Alright, so the ball is a little tricky. It has to move two-
dimensionally and bounce off of objects.

So, we need an instance that also stores it's velocity at any
instant and the methods to manipulate it.

    class Ball extends Box
      # -- Private --
      _velocity: [0, 0]

      # Override getDefault to get default velocity
      _getDefault: -> _.extend super(), velocity: _.clone @_velocity

      # -- Public --
      constructor: (args...) ->
        @_velocity = _.clone @_velocity
        super @type(), args...

      type: -> 'ball'

      # Set or retrieve velocity
      velocity: (vel...) ->
        # Set new velocity
        if vel.length then @_velocity = [
          vel[0] ? @_getDefault().velocity[0]         # vx

          # y velocity affects distance from top so inverted to preserve
          # upward positive velocity direction.
          (vel[1] ? @_getDefault().velocity[1]) * -1  # vy
        ]

        # Return velocity
        _.clone @_velocity

Class: Paddle (Ball)
--------------------

A paddle is basically an enlarged ball that's constrained to move in a
straight line.

    class Paddle extends Ball
      type: -> 'paddle'

      # Override velocity to constrain 1D motion
      velocity: (vx) ->
        if vx?
          super vx, @_velocity[1]
        else
          super()

Exports
-------

List of vars exported to global namespace.

    _.extend window ? module.exports ? this,
      _: _
      init: init
      Box: Box
      Brick: Brick
      Ball: Ball
      Paddle: Paddle

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

Dear Stewart

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

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

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

Diwank Singh
July 2013

*****

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

Alright, let's get on with it.

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

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

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

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

        result

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

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

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

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

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

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

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

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

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

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

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

        false

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

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

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

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

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

      _window: null  # Empty window object

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

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

      # -- Private --

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

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

        # Return a copy of settings
        @_getAll()

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

      _getDefaults: -> Box::_settings

      # -- Public --

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

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

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

      # Reset window settings.
      reset: ->
        @_update @_getDefaults()
        this

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

        # Return coords
        _.pick @_getAll(), ['top', 'left']

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

        # Return dimensions
        _.pick @_getAll(), ['width', 'height']